/* 팩토리세인 운영 대시보드 — 스타일.
   2026-09-20: 문서 하나에 스타일·스크립트를 전부 인라인해 두었더니 1.3MB 를 넘겨
   아티팩트 읽기/게시가 403 으로 막히는 일이 있었다. 그래서 같은 아티팩트에 별도
   파일로 올리고 페이지에서는 링크로만 불러온다. */

/* ★ 이 한 줄을 지우지 마세요 ★
   브라우저가 기본으로 주는 `[hidden] { display: none }` 은 **우리가 쓴 어떤
   display 규칙에도 집니다.** 그래서 `.tx-pick { display:grid }` 같은 규칙이 붙은
   요소에 `el.hidden = true` 를 해도 그대로 보입니다.

   이 프로젝트에서 같은 함정에 세 번 빠졌습니다 — 알림 배지에 빨간 0 이 뜨고,
   로그인 화면이 안 걷히고, 거래 입력의 수입/지출 고르는 줄이 안 사라졌습니다.
   그때마다 그 자리에만 패치를 붙였는데, 이제 한 곳에서 한 번에 막습니다. */
[hidden] { display: none !important; }


  :root {
    /* SANE Corporate Identity Standard Manual 기준 — Main Color C0M0Y0K100, Sub Color K75.
       CI 원문("보조색의 사용은 주색을 보조하는 차원에서, 사인·패찰·간행물·브로슈어 등에 사용할 수
       있다")대로 두 색의 역할을 분리한다: Main(순검정)은 사이드바와 단 하나의 주 행동(Primary CTA)에만
       앵커로 남기고, 화면 곳곳의 선택/활성 상태는 더 가벼운 Sub Color(그레이)가 맡는다 — 검정 블록이
       여기저기 반복돼 전체가 무겁게 보이던 문제를 이 2단 위계로 해소. */
    --bg: #F3F3EF;
    --surface: #FFFFFF;
    --surface-2: #EAEAE4;
    --ink: #161615;
    --ink-2: #232320;
    --text: #1B1B18;
    --text-soft: #5E5E58;
    --text-faint: #67675E;   /* 2026-10-06 — #949489 는 2.69~3.06:1 로 기준(4.5) 미달. 이 값은 5.02~5.71:1 */
    --border: #DEDED5;
    --accent: #5E5E58;
    --accent-strong: #161615;
    --accent-soft: #EDEDE7;
    --accent-contrast: #FFFFFF;
    --success: #2E7A57;
    --success-soft: #E6F1EA;
    --warning: #93661E;
    --warning-soft: #F2EAD9;
    /* pill 처럼 soft 배경 위에 얹는 글자는 따로 둔다 — soft 배경은 흰 바탕보다
       밝아서, 본문용 색을 그대로 쓰면 기준(4.5:1)을 못 넘긴다.
       .pill.ok 4.49:1 · .pill.warn 4.22:1 이었다(2026-10-06 계산). */
    --success-ink: #1F6B45;   /* on --success-soft = 5.58:1 */
    --warning-ink: #7A5310;   /* on --warning-soft = 5.71:1 */
    --danger: #9B3C31;
    --danger-soft: #F4E6E3;
    --shadow: 0 1px 2px rgba(22,22,21,0.05), 0 10px 26px -16px rgba(22,22,21,0.16);
    --radius: 9px;
    /* 글자 크기·자간·행간 통일 스케일 — 화면 곳곳에 10.5px/11px/11.5px/12px처럼 미세하게
       다른 값이 흩어져 있던 걸 이 스케일로 모은다. 앱 UI(라벨·버튼·카드·표 등)에 적용하고,
       인쇄 문서(dp-*/stmt-*)는 공문서 조판 관례를 따로 쓰므로 이 스케일 대상이 아니다. */
    --fs-2xs: 10px;   --fs-xs: 11px;   --fs-sm: 12px;   --fs-base: 13px;
    --fs-md: 14.5px;  --fs-lg: 16px;   --fs-xl: 19px;   --fs-2xl: 24px;   --fs-3xl: 32px;
    --ls-tight: -0.01em;  --ls-tighter: -0.02em;  --ls-label: 0.05em;
    --lh-tight: 1.2;  --lh-snug: 1.45;  --lh-body: 1.6;
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --bg: #0C0C0B;
      --surface: #191916;
      --surface-2: #232320;
      --ink: #000000;
      --ink-2: #0B0B0A;
      --text: #F0F0EA;
      --text-soft: #ACACA2;
      --text-faint: #9A9A90;   /* 2026-10-06 — #6D6D65 는 3.02~3.75:1 로 미달. 이 값은 5.55~6.90:1 */
      --border: #33332E;
      --accent: #9C9C90;
      --accent-strong: #F0F0EA;
      --accent-soft: rgba(240,240,234,0.10);
      --accent-contrast: #131311;
      --success: #4FAD84;
      --success-soft: rgba(79,173,132,0.14);
      --warning: #C9994B;
      --warning-soft: rgba(201,153,75,0.14);
      --success-ink: #4FAD84;
      --warning-ink: #C9994B;
      --danger: #DA8175;
      --danger-soft: rgba(218,129,117,0.14);
      --shadow: 0 1px 2px rgba(0,0,0,0.32), 0 12px 28px -14px rgba(0,0,0,0.6);
    }
  }
  :root[data-theme="dark"] {
    --bg: #0C0C0B;
    --surface: #191916;
    --surface-2: #232320;
    --ink: #000000;
    --ink-2: #0B0B0A;
    --text: #F0F0EA;
    --text-soft: #ACACA2;
    --text-faint: #9A9A90;   /* 2026-10-06 — #6D6D65 는 3.02~3.75:1 로 미달. 이 값은 5.55~6.90:1 */
    --border: #33332E;
    --accent: #9C9C90;
    --accent-strong: #F0F0EA;
    --accent-soft: rgba(240,240,234,0.10);
    --accent-contrast: #131311;
    --success: #4FAD84;
    --success-soft: rgba(79,173,132,0.14);
    --warning: #C9994B;
    --warning-soft: rgba(201,153,75,0.14);
    --success-ink: #4FAD84;
    --warning-ink: #C9994B;
    --danger: #DA8175;
    --danger-soft: rgba(218,129,117,0.14);
    --shadow: 0 1px 2px rgba(0,0,0,0.32), 0 12px 28px -14px rgba(0,0,0,0.6);
  }
  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  img:not(.dp-letterhead, .dp-banner, .dp-stamp) { max-width: 100%; height: auto; }
  body {
    background: var(--bg);
    color: var(--text);
    font-family: "Noto Sans KR", "Pretendard", -apple-system, sans-serif;
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    word-break: keep-all;
    overflow-wrap: break-word;
  }
  h1, h2, h3, .serif { font-family: "Noto Sans KR", sans-serif; font-weight: 600; letter-spacing: -0.02em; }
  .num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
  button { font-family: inherit; cursor: pointer; }
  a { color: inherit; }

  .app { display: flex; min-height: 100vh; }

  /* ---------- Sidebar ---------- */
  /* 2026-10-06 — granter 는 232px **흰** 사이드바다. 어두운 사이드바가 아니다.
     여기 색이 전부 16진수로 박혀 있어서 토큰만 바꾸면 하나도 안 바뀐다 — 그래서 직접 고친다.
     경계는 바탕색 차이가 아니라 오른쪽 1px 선 하나로만 만든다(그림자 없음). */
  .sidebar {
    width: var(--sidebar-w, 232px); flex: none;
    background: var(--surface); color: var(--text);
    border-right: 1px solid var(--border);
    display: flex; flex-direction: column; padding: 0;
    position: sticky; top: 0; height: 100vh; overflow-y: auto;
  }
  .brand { display: flex; align-items: center; gap: 12px; padding: 16px; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
  /* 견적서 등 실제 발행 문서(레터헤드)에 쓰이는 로고를 그대로 잘라와서 사이드바 마크로 쓴다 —
     로고 자체는 검정 선화라 어두운 사이드바 배경에서는 흰 칩 위에 얹어야 또렷이 보인다. */
  /* 2026-10-06 — 사이드바가 흰색이 되면서 로고(검은 선화)를 받치던 흰 칩이 필요 없어졌다.
     칩을 걷어내니 오히려 또렷하다. */
  .brand-mark {
    width: 36px; height: 36px; border-radius: var(--radius-md, 8px); flex: none;
    background: transparent; border: none;
    display: flex; align-items: center; justify-content: center; padding: 0;
  }
  .brand-mark img { width: 100%; height: 100%; object-fit: contain; }
  /* G 의 워크스페이스 이름 규격: 16px/24px weight 500, 자간 -0.16px.
     굵기 800 → 500. granter 는 700 이상을 아예 쓰지 않는다. */
  .brand-name { font-family: inherit; font-weight: var(--fw-medium, 500); font-size: 16px; color: var(--text); line-height: 1.5; letter-spacing: -0.01em; }
  /* 대문자 변환도 자간 벌림도 하지 않는다 — G 는 라벨을 꾸미지 않는다 */
  .brand-sub { font-size: var(--fs-xs, 12px); color: var(--text-soft); letter-spacing: 0; text-transform: none; margin-top: 2px; }
  /* 로고 옆 글자는 사이드바 폭을 넘지 않게 한 줄로 자른다. flex 항목은 기본적으로
     내용보다 작아지지 않으므로(min-width:auto), 0 으로 낮춰야 말줄임이 걸린다.
     이름이 긴 사람이 로그인해도 레이아웃이 무너지지 않는다. */
  .brand > div:last-child { min-width: 0; flex: 1; }
  .brand-name, .brand-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mobile-topbar .brand-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* 2026-10-06 — 흰 사이드바에 맞춰 조용한 회색 트랙 + 흰 알약으로. 그림자는 쓰지 않는다. */
  .console-switch { display: flex; gap: 4px; background: var(--surface-2); border-radius: var(--radius-lg, 10px); padding: 3px; margin: 0 8px 12px; }
  .console-btn {
    flex: 1; min-height: 38px; padding: 8px 6px; border: none; background: transparent;
    color: var(--text-soft); font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500);
    border-radius: var(--radius-md, 8px);
    transition: background-color var(--dur, 200ms) var(--ease-out-strong), color var(--dur, 200ms) var(--ease-out-strong), opacity var(--dur, 200ms) var(--ease-out-strong);
  }
  .console-btn:hover { color: var(--text); opacity: .7; }
  .console-btn.active { background: var(--surface); color: var(--text); box-shadow: none; }

  /* G 의 메뉴 항목: 높이 36px · 패딩 0 8px · 둥글기 8px · 글자 14px · 기본 굵기 400 ·
     활성은 색이 아니라 연한 회색 바탕(#F5F5F5) + 검은 글자 + 굵기 500.
     높이만 44px 로 올린다(터치 기준) — 나머지는 G 값 그대로라 인상은 거의 남는다. */
  .nav { display: flex; flex-direction: column; gap: 2px; margin-top: 0; padding: 0 8px; }
  .nav-item {
    display: flex; align-items: center; gap: 8px;
    min-height: var(--nav-item-h, 44px); padding: 0 8px; border-radius: var(--radius-md, 8px);
    color: var(--text-soft); background: transparent; border: none; text-align: left;
    font-size: var(--fs-base, 14px); font-weight: var(--fw-normal, 400);
    transition: background-color var(--dur, 200ms) var(--ease-out-strong), color var(--dur, 200ms) var(--ease-out-strong);
  }
  .nav-item svg { width: 16px; height: 16px; flex: none; opacity: 1; }
  .nav-item:hover { background: var(--accent-soft); color: var(--text); }
  .nav-item.active { background: var(--accent-soft); color: var(--text); font-weight: var(--fw-medium, 500); }

  /* G 의 사이드바 바닥: 위쪽 1px 선 + 패딩 12px, 이름은 본문색 14px, 역할은 회색 12px */
  .sidebar-foot { margin-top: auto; padding: 12px; border-top: 1px solid var(--border); }
  .sidebar-foot .line { font-size: var(--fs-xs, 12px); color: var(--text-soft); line-height: 1.5; }
  .sidebar-foot .line b { color: var(--text); font-weight: var(--fw-medium, 500); }
  /* 사이드바 맨 아래 저작권 표시 */
  .sidebar-foot .copyright { font-size: var(--fs-xs, 12px); color: var(--text-faint); line-height: 1.5;
    display: flex; flex-direction: column; }
  .sidebar-foot .copyright b { color: var(--text-soft); font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500);
    letter-spacing: 0; margin-bottom: 2px; }

  /* ---------- Main ---------- */
  .main { flex: 1; min-width: 0; padding: 28px 36px 60px; }
  .topbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 22px; flex-wrap: wrap; }
  .topbar h1 { font-size: 23px; margin: 0 0 4px; font-weight: 600; }
  .topbar .sub { color: var(--text-soft); font-size: var(--fs-base); line-height: var(--lh-snug); }
  .topbar .meta-pill {
    display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px;
    background: var(--surface-2); border: 1px solid var(--border); font-size: 12px; color: var(--text-soft);
  }
  .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--success); }

  .view { display: none; }
  .view.active { display: block; }

  /* ---------- Cards / grid ---------- */
  .kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 20px; }
  @media (max-width: 980px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
  #txAllocPreview { grid-template-columns: repeat(2, 1fr); margin-bottom: 0; }
  .kpi-card {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 18px 18px 16px; box-shadow: var(--shadow); min-width: 0;
  }
  .kpi-label { font-size: var(--fs-sm); line-height: var(--lh-snug); color: var(--text-soft); margin-bottom: 8px; display:flex; align-items:center; gap:6px; }
  .kpi-value { font-size: 24px; font-weight: 600; letter-spacing: -0.01em; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
  .kpi-value.success { color: var(--success); }
  .kpi-value.danger { color: var(--danger); }
  .kpi-value.warning { color: var(--warning); }
  .kpi-note { font-size: 12px; color: var(--text-faint); margin-top: 6px; }

  /* ---------- 홈: 종합 요약 (재무·업무현황·발행견적서를 한눈에) ---------- */
  .summary-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 20px; }
  .summary-grid > * { min-width: 0; }
  @media (max-width: 1180px) { .summary-grid { grid-template-columns: 1fr; } }
  .summary-card {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 16px 18px 18px; display: flex; flex-direction: column;
  }
  .summary-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
  .summary-card-head h3 { font-size: 14px; margin: 0; font-weight: 600; }
  .summary-link {
    font-size: 12px; font-weight: 600; color: var(--text-soft); background: none; border: none;
    padding: 3px 0; display: inline-flex; align-items: center; gap: 3px;
  }
  .summary-link:hover { color: var(--text); }
  /* 홈 요약 카드 상단 — 그래프를 지우고 숫자만 남긴 자리.
     도넛(96 → 158 → 220px)도, 가로 막대도 "읽기 힘들다"는 말이 돌아왔다. 네 번 실패했으니
     크기나 차트 종류의 문제가 아니라 이 자리에 그림이 필요 없다고 봤다 — 카드가 답하는 질문이
     "얼마 벌고 얼마 썼나 / 몇 건이 돌아가나"처럼 값 하나로 끝나서, 비율을 눈대중할 일이 없다.

     대신 위계를 세 층으로 세워 눈이 볼 순서를 정해 준다.
       .sm-lead  대표값 하나. 색을 깐 상자에 25px — 카드에서 제일 먼저 보이는 것.
       .sm-sub   비교값. 이름은 왼쪽, 값은 오른쪽 끝에 붙여 자릿수가 세로로 맞게.
       .sm-note  막대가 하던 "어느 쪽이 큰가"를 비율 한 문장으로 대신한다.
     색은 장식이 아니라 좋고 나쁨의 표시라서 .is-pos/.is-neg/.is-warn 으로만 갈린다.
     443,360,805원 같은 긴 금액이 줄바꿈으로 뭉개지지 않도록 값에는 전부 nowrap 을 걸고,
     자릿수가 흔들리지 않게 tabular-nums 를 쓴다. 높이는 막대판과 같게 맞춰서 카드는 그대로다.

     .summary-donut-row / .summary-legend / .sm-bars 규칙이 여기 있었다. 그 마크업을 쓰는
     곳이 없어져 지웠다 — 쓰지 않는 규칙을 남겨 두면, 다음에 고치는 사람이 그것도 살아 있는
     줄 알고 함께 맞추려다 시간을 쓴다. */
  .sm-figs { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; gap: 10px; }
  .sm-lead {
    display: flex; flex-direction: column; gap: 2px; min-width: 0;
    padding: 10px 12px 11px; border-radius: 10px;
    background: var(--surface-2); border-left: 3px solid var(--text-faint);
  }
  .sm-lead .k { font-size: 12px; font-weight: 600; color: var(--text-soft); letter-spacing: 0.01em; }
  .sm-lead .v {
    font-size: 25px; font-weight: 600; line-height: 1.16; letter-spacing: -0.02em;
    color: var(--text); white-space: nowrap; font-variant-numeric: tabular-nums;
  }
  .sm-lead.is-pos { background: var(--success-soft); border-left-color: var(--success); }
  .sm-lead.is-pos .v { color: var(--success); }
  .sm-lead.is-neg { background: var(--danger-soft); border-left-color: var(--danger); }
  .sm-lead.is-neg .v { color: var(--danger); }
  .sm-lead.is-warn { background: var(--warning-soft); border-left-color: var(--warning); }
  .sm-lead.is-warn .v { color: var(--warning); }

  .sm-subs { display: flex; flex-direction: column; }
  .sm-sub {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    padding: 7px 2px; border-top: 1px solid var(--border);
  }
  .sm-sub:first-child { border-top: none; }
  .sm-sub .k { font-size: 13px; font-weight: 600; color: var(--text-soft); white-space: nowrap; }
  .sm-sub .v {
    font-size: 16px; font-weight: 600; letter-spacing: -0.01em;
    white-space: nowrap; font-variant-numeric: tabular-nums;
  }
  .sm-sub.is-pos .v { color: var(--success); }
  .sm-sub.is-neg .v { color: var(--danger); }
  .sm-sub.is-warn .v { color: var(--warning); }

  .sm-note { font-size: 12px; line-height: 1.5; color: var(--text-faint); }
  .summary-stats { display: flex; gap: 14px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
  .summary-stat { flex: 1; }
  .summary-stat .v { font-size: 17px; font-weight: 600; }
  .summary-stat .l { font-size: 12px; color: var(--text-faint); margin-top: 2px; }
  .mini-bar-list { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
  .mini-bar-list .row { display: flex; align-items: center; gap: 8px; font-size: 12px; margin-bottom: 7px; }
  .mini-bar-list .row:last-child { margin-bottom: 0; }
  .mini-bar-list .name { width: 66px; flex: none; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mini-bar-list .track { flex: 1; height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
  .mini-bar-list .fill { height: 100%; border-radius: 3px; background: var(--accent); }
  .mini-bar-list .n { width: 22px; flex: none; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }

  .recent-clients { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
  .recent-clients .label { font-size: 12px; color: var(--text-faint); margin-bottom: 7px; }
  .recent-clients .chips { display: flex; flex-wrap: wrap; gap: 6px; }
  .recent-clients .chip {
    font-size: 12px; font-weight: 600; padding: 5px 10px; border-radius: 999px;
    background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
    max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .recent-clients .chip:hover { border-color: var(--accent); color: var(--accent-strong); }
  .recent-clients .empty { font-size: 12px; color: var(--text-faint); }

  .row-2 { display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; align-items: start; }
  .row-2 > * { min-width: 0; }
  @media (max-width: 980px) { .row-2 { grid-template-columns: 1fr; } }

  .panel {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 18px 20px 20px; margin-bottom: 16px;
  }
  .panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 10px; }
  .panel-head h2 { font-size: var(--fs-lg); line-height: var(--lh-snug); margin: 0; font-weight: 600; }
  /* .hint는 화면 곳곳(패널 제목 옆, 필드 아래, 버튼 옆 등)에서 재사용되는 "보조 설명" 역할인데
     정작 공통 규칙이 없어서 위치마다 상속받는 크기가 제각각이었다 — 기본값을 여기서 통일한다.
     인라인 style로 크기를 따로 지정한 곳은 그 값이 그대로 우선한다(의도된 예외이므로 그대로 둠). */
  .hint { font-size: var(--fs-xs); line-height: var(--lh-snug); color: var(--text-faint); }
  .panel-head .hint { font-size: var(--fs-xs); line-height: var(--lh-snug); color: var(--text-faint); }

  .callout {
    display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: 10px;
    background: var(--warning-soft); border: 1px solid rgba(166,101,10,0.18); font-size: 13px; color: var(--warning);
    margin-bottom: 16px;
  }
  @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .callout { border-color: rgba(227,167,59,0.28); } }
  :root[data-theme="dark"] .callout { border-color: rgba(227,167,59,0.28); }
  .callout svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }
  .callout b { color: inherit; }

  /* chart */
  .chart-wrap { overflow-x: auto; }
  .bars { display: flex; align-items: flex-end; gap: 14px; height: 168px; padding: 6px 4px 0; min-width: 460px; }
  .bar-col { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1; min-width: 44px; }
  .bar-stack { width: 100%; max-width: 34px; height: 120px; display: flex; flex-direction: column; justify-content: flex-end; gap: 3px; position: relative; }
  .bar-seg { width: 100%; border-radius: 4px; transition: opacity .15s; }
  .bar-seg.income { background: var(--success); }
  .bar-seg.expense { background: var(--danger); opacity: 0.82; }
  .bar-col.dim .bar-seg { opacity: 0.22; }
  .bar-col.picked .bar-label { color: var(--text); font-weight: 600; }
  .bar-empty { width: 100%; height: 100%; border: 1.5px dashed var(--border); border-radius: 4px; }
  .bar-label { font-size: 12px; color: var(--text-soft); text-align: center; }
  .bar-label small { display: block; color: var(--text-faint); font-size: 12px; }
  .legend { display: flex; gap: 16px; font-size: 12px; color: var(--text-soft); margin-top: 10px; }
  .legend span { display: inline-flex; align-items: center; gap: 5px; }
  .legend i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; }

  /* tx list */
  .tx-list { display: flex; flex-direction: column; }
  .tx-row { display: flex; align-items: center; justify-content: space-between; padding: 9px 0; border-bottom: 1px solid var(--border); gap: 10px; }
  .tx-row:last-child { border-bottom: none; }
  .tx-left { min-width: 0; }
  .tx-desc { font-size: 13px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; }
  .tx-date { font-size: 12px; color: var(--text-faint); }
  .tx-amt { font-size: 13px; font-weight: 600; white-space: nowrap; }
  .tx-amt.in { color: var(--success); }
  .tx-amt.out { color: var(--danger); }
  .tx-list-wide .tx-row { padding: 13px 10px; border-radius: 8px; }
  .tx-list-wide .tx-row:nth-child(odd) { background: var(--surface-2); }
  .tx-list-wide .tx-row:last-child { border-bottom: none; }
  .tx-list-wide .tx-desc { font-size: 14px; font-weight: 600; max-width: 360px; }
  .tx-list-wide .tx-date { font-size: 12px; margin-top: 2px; }
  .tx-list-wide .tx-amt { font-size: 15px; }
  @media (max-width: 860px) { .tx-list-wide .tx-desc { max-width: 46vw; } }
  /* 홈 화면 위젯들 — 미수금·계좌현황을 정확히 같은 높이로 고정하고 내부 스크롤되게 함
     (max-height는 내용이 짧으면 줄어들어 높이가 안 맞을 수 있어서 고정 height를 씀) */
  .home-scroll-box { height: 340px; overflow-y: auto; }

  /* accounts grid */
  .acct-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .acct-grid > * { min-width: 0; }
  .acct-card { border: 1px solid var(--border); border-radius: 10px; padding: 12px 13px; background: var(--surface-2); }
  .acct-bank { font-size: 12px; color: var(--text-faint); letter-spacing: 0.02em; }
  .acct-name { font-size: 13px; font-weight: 600; margin: 2px 0 4px; }
  .acct-purpose { font-size: 12px; color: var(--text-soft); }
  .acct-balance { margin-top: 8px; font-size: 14px; font-weight: 600; }
  .acct-balance.zero { color: var(--text-faint); font-weight: 500; font-size: 12px; }

  /* pending payments */
  table.simple { width: 100%; border-collapse: collapse; font-size: 13px; }
  table.simple th { text-align: left; color: var(--text-faint); font-weight: 600; font-size: 12px; padding: 6px 8px; border-bottom: 1px solid var(--border); }
  table.simple td { padding: 9px 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
  table.simple tr:last-child td { border-bottom: none; }
  table.simple td.danger { color: var(--danger); }
  table.simple td.success { color: var(--success); }
  .tx-entry-row { cursor: pointer; transition: background .12s; }
  .tx-entry-row:hover { background: var(--surface-2); }
  .tx-entry-row.active { background: var(--accent-soft); }
  .tx-entry-row.active td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
  .pill { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; }
  .pill.ok { background: var(--success-soft); color: var(--success-ink, var(--success)); }
  .pill.warn { background: var(--warning-soft); color: var(--warning-ink, var(--warning)); }
  .pill.danger { background: var(--danger-soft); color: var(--danger); }
  .pill.wait { background: var(--warning-soft); color: var(--warning-ink, var(--warning)); }

  /* kanban — 가로 한 줄로 스크롤되는 보드. 칸마다 세로로도 따로 스크롤돼서(칸 높이 고정)
     카드 많은 칸(예: 진행중) 때문에 페이지 전체가 한없이 길어지는 걸 막는다. */
  /* kanban — 단계별로 칸을 나눠 가로 스크롤하던 방식이 보기 어렵다는 피드백으로, 카드 하나하나가
     각자 자기 단계 색 점을 달고 미정→드랍 순서대로 자연스럽게 흐르는 반응형 그리드로 바꿨다.
     가로 스크롤 없이 화면 폭에 맞춰 카드가 알아서 줄바꿈된다. */
  /* 한 줄에 카드가 최대 5개까지만 들어가고(그 이상이면 다음 줄로), 화면이 그보다 좁아져서
     카드가 5개보다 적게 들어갈 때는 남는 공간만큼 카드가 커지게 한다 — 각 칸의 최소 폭을
     "컨테이너의 20%(=5칸 몫)"로 잡으면 20% 폭보다 넓은 화면에서는 저절로 5칸까지만 채워지고,
     그보다 좁으면 230px 최소폭 쪽이 이겨서 그 안에서 자연스럽게 줄어든 칸 수만큼 커진다. */
  .kanban { display: grid; grid-template-columns: repeat(auto-fit, minmax(max(200px, calc(20% - 8px)), 1fr)); gap: 10px; align-content: start; }
  @media (max-width: 860px) { .kanban { grid-template-columns: 1fr; } }
  /* 홈 위젯 전용 — 업무현황 페이지와 똑같은 개별 카드 나열 방식을 쓰되, 전체를 다 펼치면 홈이
     길어지니 바깥에 높이 제한+스크롤만 걸어서 "홈은 간소하게" 보이게 한다(칸반 레이아웃 자체는
     동일, 세로 단계별 칸으로 나누지 않음). */
  #kanbanHome.kanban { max-height: 480px; overflow-y: auto; padding-right: 2px; }

  .chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 18px; }
  .chip {
    display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 999px;
    border: 1px solid var(--border); background: var(--surface-2); color: var(--text-soft);
    font-size: 12px; font-weight: 600;
  }
  .chip .n { color: var(--text-faint); font-weight: 500; }
  .chip.active { background: var(--ink); color: #fff; border-color: var(--ink); }
  .chip.active .n { color: rgba(255,255,255,0.65); }
  .deal-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 11px 12px; box-shadow: var(--shadow); cursor: pointer; }
  .deal-card:hover { border-color: var(--accent); }
  .deal-stage-row { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
  .stage-dot { width: 13px; height: 13px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 0 2px var(--surface); }
  .deal-complete-btn {
    width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
    border: 1.5px solid var(--border); background: var(--surface); color: var(--text-faint); font-size: 12px; line-height: 1; cursor: pointer;
    margin-left: auto; position: relative;
  }
  /* 시각적 크기(20px)는 그대로 두고, 실제 탭 가능 영역만 모바일 권장 최소 크기(44px)에 맞춰
     투명하게 넓힌다 — 손가락으로 누를 때 자꾸 빗나가서 카드 클릭(상세 팝업)으로 새던 문제 수정. */
  .deal-complete-btn::before {
    content: ''; position: absolute; inset: -12px; border-radius: 50%;
  }
  .deal-complete-btn:hover { border-color: var(--success); color: var(--success); }
  .deal-complete-btn.done { background: var(--success); border-color: var(--success); color: #fff; }
  .deal-stage-label { font-size: 12px; font-weight: 600; color: var(--text-soft); }
  .deal-org { font-size: 13px; font-weight: 600; }
  .deal-title { font-size: 12px; color: var(--text-soft); margin: 3px 0 7px; line-height: 1.4; }
  .deal-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
  .deal-amt { font-size: 12px; font-weight: 600; color: var(--accent-strong); }
  .deal-manager { font-size: 12px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  select.stage-select {
    margin-top: 8px; width: 100%; font-size: 12px; padding: 6px 7px; border-radius: 7px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text); font-family: inherit;
  }

  /* clients table */
  .search-box { display: flex; align-items: center; gap: 8px; border: 1px solid var(--border); background: var(--surface-2); border-radius: 10px; padding: 8px 12px; margin-bottom: 14px; max-width: 340px; }
  .search-box svg { width: 15px; height: 15px; color: var(--text-faint); flex: none; }
  .search-box input { border: none; background: transparent; outline: none; font-size: 13px; color: var(--text); width: 100%; font-family: inherit; }
  .client-table-wrap { overflow-x: auto; }
  table.clients { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 980px; }
  table.clients th { position: sticky; top: 0; background: var(--surface); text-align: left; color: var(--text-faint); font-weight: 600; font-size: 12px; padding: 8px; border-bottom: 1px solid var(--border); }
  table.clients td { padding: 8px; border-bottom: 1px solid var(--border); }
  table.clients tr:hover td { background: var(--surface-2); }
  .muted { color: var(--text-faint); }
  .result-count { font-size: 12px; color: var(--text-faint); margin-bottom: 10px; }

  /* docs view */
  .doc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
  .doc-grid > * { min-width: 0; }
  @media (max-width: 900px) { .doc-grid { grid-template-columns: repeat(2, 1fr); } }
  .doc-card { border: 1px solid var(--border); border-radius: 12px; padding: 14px; background: var(--surface); }
  .doc-card .doc-icon { width: 30px; height: 30px; border-radius: 8px; background: var(--accent-soft); color: var(--accent-strong); display: flex; align-items: center; justify-content: center; margin-bottom: 8px; }
  .doc-card .doc-icon svg { width: 16px; height: 16px; }
  .doc-name { font-size: 13px; font-weight: 600; margin-bottom: 3px; }
  .doc-desc { font-size: 12px; color: var(--text-soft); line-height: 1.5; }
  .doc-card.ready { border-color: var(--accent); background: var(--accent-soft); }
  .doc-card .doc-badge { display: inline-block; font-size: 12px; font-weight: 600; padding: 2px 7px; border-radius: 999px; margin-top: 7px; }
  .doc-card .doc-badge.ready { background: var(--accent); color: var(--accent-contrast); }
  .doc-card .doc-badge.soon { background: var(--surface-2); color: var(--text-faint); }

  /* ---------- document builder ---------- */
  /* 2026-09-20: 서류 입력 화면에 미리보기가 항상 옆에 떠 있으면 실제 발행됐을 때의 화면과 달라
     보인다는 지적으로, 미리보기 패널은 기본적으로 숨기고 입력 폼만 보이게 바꿨다 — "미리보기"를
     눌러야 새 창에서 실제 문서 모양을 확인할 수 있다(발행 시 인쇄에는 그대로 쓰이므로 print 미디어
     쿼리에서 다시 보이게 되돌려둔다). */
  .doc-builder { display: block; }
  .doc-builder .doc-form, .doc-builder .doc-preview-wrap { max-width: 640px; }
  .doc-preview-scroll { display: none; }
  @media print { .doc-preview-scroll { display: block !important; } }

  /* ---------- 견적산정 계산기 ---------- */
  .qc-grid { display: grid; grid-template-columns: 420px 1fr; gap: 20px; align-items: start; }
  .qc-grid > * { min-width: 0; }
  @media (max-width: 1100px) { .qc-grid { grid-template-columns: 1fr; } }
  .qc-5col, .qc-4col { display: grid; gap: 10px; margin-top: 10px; }
  .qc-5col > *, .qc-4col > * { min-width: 0; }
  .qc-5col { grid-template-columns: repeat(5, 1fr); }
  .qc-4col { grid-template-columns: repeat(4, 1fr); }
  @media (max-width: 700px) { .qc-5col, .qc-4col { grid-template-columns: repeat(2, 1fr); } }
  .qc-5col > div, .qc-4col > div { display: flex; flex-direction: column; gap: 5px; }
  .qc-5col label, .qc-4col label { font-size: 12px; font-weight: 600; color: var(--text-soft); }
  .qc-5col input, .qc-5col select, .qc-4col input, .qc-4col select {
    font-family: inherit; font-size: 13px; padding: 8px 10px; border-radius: 8px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text); width: 100%;
  }
  .qc-extra-item { display: flex; align-items: flex-end; gap: 6px; }
  .qc-extra-item select { flex: 1; }
  .qc-extra-remove { width: 30px; height: 34px; border: 1px solid var(--border); background: var(--surface); border-radius: 8px; color: var(--text-faint); cursor: pointer; font-size: 15px; line-height: 1; flex-shrink: 0; }
  .qc-add-extra { margin-top: 10px; display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border-radius: 8px; border: 1px dashed var(--border); background: transparent; color: var(--text-faint); font-size: 12px; cursor: pointer; }
  .qc-result-wrap { position: sticky; top: 0; }
  /* 1100px 아래로는 qc-grid가 좌우 2열에서 위아래 1열로 바뀌는데, 결과 카드(.qc-result-wrap)의
     position:sticky는 "좌우 2열일 때 오른쪽 칼럼을 화면에 붙여두는" 용도였다 — 1열로 쌓이면
     스크롤할 때 이 카드가 화면에 들러붙어서 바로 위 절사 select 등과 겹쳐 보이는 원인이 된다.
     (베이스 규칙 바로 뒤에 둬야 소스 순서상 이 규칙이 이긴다.) */
  @media (max-width: 1100px) { .qc-result-wrap { position: static; } }
  .qc-result { background: var(--surface-2); border-radius: 14px; padding: 20px; margin-top: 20px; }
  .qc-row { display: flex; justify-content: space-between; align-items: baseline; padding: 9px 0; border-bottom: 1px dashed var(--border); font-size: var(--fs-base); line-height: var(--lh-snug); }
  .qc-row .qc-label { color: var(--text-faint); }
  .qc-row .qc-val { font-variant-numeric: tabular-nums; font-weight: 600; }
  .qc-row.qc-sub .qc-label { padding-left: 12px; font-size: var(--fs-sm); }
  .qc-row.qc-sub .qc-val { font-weight: 400; color: var(--text-faint); }
  .qc-divider { height: 1px; background: var(--border); margin: 14px 0; }
  .qc-final { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 18px; }
  .qc-final > * { min-width: 0; }
  .qc-final-card { background: var(--surface); border-radius: 12px; padding: 16px; text-align: center; }
  .qc-final-card .qc-final-label { font-size: var(--fs-xs); line-height: var(--lh-snug); color: var(--text-faint); margin-bottom: 6px; }
  .qc-final-card .qc-final-value { font-size: var(--fs-2xl); line-height: var(--lh-tight); font-weight: 600; font-variant-numeric: tabular-nums; }
  .qc-final-card.qc-price .qc-final-value { color: var(--accent); }
  .qc-note { font-size: 12px; color: var(--text-faint); margin-top: 12px; line-height: 1.6; }
  .qc-cross-note { font-size: 12px; color: var(--text-faint); background: var(--surface-2); border-radius: 8px; padding: 8px 12px; margin-bottom: 14px; line-height: 1.5; }
  .doc-form { display: flex; flex-direction: column; gap: 12px; }
  /* 필드 줄 간격 통일 — 전에는 화면마다 style="margin-top:10px/12px/14px/18px"를 손으로 다르게
     붙여서 폼 하나 안에서도 줄 간격이 들쭉날쭉했다. 기본값을 하나로 고정하고(:first-child는 0),
     각 필드 자체의 상하 여백은 라벨-입력창 사이 gap(5px)으로 이미 일정하니 줄 사이만 맞추면 된다. */
  .field-row { display: flex; flex-direction: column; gap: 5px; margin-top: 14px; }
  .field-row:first-child { margin-top: 0; }
  .field-row.two { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .field-row.two > * { min-width: 0; }
  .field-row.three { display: grid; grid-template-columns: 0.8fr 1.6fr 1fr; gap: 10px; }
  .field-row.three > * { min-width: 0; }
  .field-row.four { display: grid; grid-template-columns: 0.7fr 1.4fr 0.9fr 1.6fr; gap: 10px; }
  .field-row.five { display: grid; grid-template-columns: 1.2fr 0.9fr 1.1fr 0.9fr 0.9fr; gap: 10px; }
  .field-row.four > *, .field-row.five > * { min-width: 0; }
  @media (max-width: 860px) { .field-row.four { grid-template-columns: 1fr 1fr; } .field-row.five { grid-template-columns: 1fr 1fr; } }
  /* 견적산정 할인율/가격절사 — 모바일에서 두 칸이 너무 좁게 붙어 보여서 한 줄씩 세로로 쌓는다 */
  @media (max-width: 860px) { .field-row.two.qc-discount-round-row { grid-template-columns: 1fr; gap: 14px; } }
  /* 예상원가/소비자견적가 카드 — 좁은 화면에서 두 칸이 나란히 있으면 금액 숫자가 카드 폭보다
     넓어져서 "848원"처럼 숫자 중간에서 줄바꿈되던 문제가 있었다. 세로로 쌓아서 각 카드가
     화면 전체 폭을 쓰게 한다. */
  @media (max-width: 520px) {
    .qc-final { grid-template-columns: 1fr; }
    .qc-final-card .qc-final-value { font-size: 20px; }
  }
  .field-row label { font-size: var(--fs-xs); line-height: var(--lh-snug); font-weight: 600; color: var(--text-soft); }
  .field-row input[readonly] { background: var(--surface-2); color: var(--text-soft); }
  .field-row input, .field-row select, .field-row textarea {
    font-family: inherit; font-size: 13px; padding: 8px 10px; border-radius: 8px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text); width: 100%;
  }
  .field-row textarea { resize: vertical; line-height: 1.6; box-sizing: border-box; }
  /* 날짜 입력창은 칸 전체를 클릭해도 달력이 뜨도록, 달력 아이콘(::-webkit-calendar-picker-indicator)
     자체를 칸 전체 크기로 늘려서 투명하게 덮는다 — 아이콘을 클릭하는 건 브라우저 기본 동작이라
     showPicker() 같은 JS 호출과 무관하게 항상 작동한다(showPicker() 리스너는 폴백으로 그대로 둔다). */
  input[type="date"] { position: relative; }
  input[type="date"]::-webkit-calendar-picker-indicator {
    position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer;
  }

  /* ---------- 메일 작성 ---------- */
  .mail-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border); padding-bottom: 12px; margin-bottom: 18px; }
  .mail-tab {
    display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 9px;
    border: 1px solid transparent; background: transparent; color: var(--text-soft); font-size: 13px; font-weight: 600;
  }
  .mail-tab.active { background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent); }
  .mail-tab-badge {
    display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px;
    padding: 0 4px; border-radius: 999px; background: var(--accent); color: var(--accent-contrast); font-size: 12px; font-weight: 600;
  }
  .mail-panel { max-width: 640px; display: flex; flex-direction: column; gap: 12px; }
  .mail-attach-drop {
    border: 1.5px dashed var(--border); border-radius: 12px; padding: 30px 16px; text-align: center;
    color: var(--text-faint); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 8px; font-size: 13px;
  }
  .mail-attach-drop svg { width: 26px; height: 26px; }
  .mail-attach-drop.dragover { border-color: var(--accent); color: var(--accent-strong); background: var(--accent-soft); }
  .mail-attach-list { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
  .mail-attach-item {
    display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border);
    border-radius: 8px; font-size: 13px; background: var(--surface-2);
  }
  .mail-attach-item .mail-attach-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mail-attach-item .mail-attach-size { color: var(--text-faint); font-size: 12px; }
  .mail-actions { display: flex; align-items: center; justify-content: flex-end; gap: 14px; margin-top: 22px; }
  .mail-actions .hint { color: var(--text-faint); }
  .date-picker-wrap { position: relative; }
  .date-picker-wrap input { cursor: pointer; }
  .date-cal {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; width: 260px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
    box-shadow: 0 8px 28px rgba(0,0,0,0.22); padding: 14px;
  }
  .date-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
  .date-cal-head button {
    border: none; background: var(--surface-2); border-radius: 7px; width: 26px; height: 26px;
    color: var(--text); cursor: pointer; font-size: 14px; line-height: 1;
  }
  .date-cal-head .date-cal-ym { font-size: 13px; font-weight: 600; color: var(--text); }
  .date-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; text-align: center; }
  .date-cal-grid > * { min-width: 0; }
  .date-cal-grid .dow { font-size: 12px; color: var(--text-faint); padding: 4px 0; }
  .date-cal-grid button.day { border: none; background: transparent; border-radius: 7px; padding: 6px 0; font-size: 12px; color: var(--text); cursor: pointer; }
  .date-cal-grid button.day:hover { background: var(--surface-2); }
  .date-cal-grid button.day.selected { background: var(--accent); color: var(--accent-contrast); font-weight: 600; }
  .date-cal-grid button.day.empty { visibility: hidden; cursor: default; }
  .date-cal-noday {
    width: 100%; margin-top: 10px; padding: 8px; border-radius: 8px; border: 1px dashed var(--border);
    background: transparent; color: var(--text-faint); font-size: 12px; cursor: pointer;
  }
  .date-cal-noday:hover { background: var(--surface-2); }
  .seg { display: flex; border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
  .seg-btn {
    flex: 1; border: none; background: var(--surface); color: var(--text-soft); padding: 8px 10px;
    font-size: 13px; font-weight: 600; border-right: 1px solid var(--border);
  }
  .seg-btn:last-child { border-right: none; }
  .seg-btn.active { background: var(--accent); color: var(--accent-contrast); }
  .primary-btn.sm { padding: 7px 12px; font-size: 12px; }

  /* ---------- 발행 법인 (큰 탭) / 문서 유형 선택 ---------- */
  .entity-tabs { display: flex; gap: 10px; margin: 4px 0 16px; max-width: 460px; }
  .entity-tab {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 14px 10px; border-radius: 12px; border: 1.5px solid var(--border);
    background: var(--surface-2); font-family: inherit; transition: background .15s, border-color .15s;
  }
  .entity-tab .et-label { font-size: 16px; font-weight: 600; color: var(--text); letter-spacing: -0.01em; }
  .entity-tab .et-sub { font-size: 12px; letter-spacing: 0.09em; color: var(--text-faint); }
  .entity-tab.active { background: var(--accent-strong); border-color: var(--accent-strong); }
  .entity-tab.active .et-label, .entity-tab.active .et-sub { color: var(--accent-contrast); }

  .doc-kind-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
  .dk-tab {
    padding: 10px 18px; border-radius: 10px; border: 1.5px solid var(--border);
    background: var(--surface); color: var(--text-soft); font-size: 13px; font-weight: 600; font-family: inherit;
  }
  .dk-tab.active { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }

  .contact-quick-row { display: flex; gap: 8px; }
  .contact-quick-row input { flex: 1; }
  .contact-chip-row { display: flex; flex-wrap: wrap; gap: 7px; }
  .contact-chip {
    display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; border-radius: 999px;
    border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font-size: 12px; font-weight: 600;
  }
  .contact-chip:hover { border-color: var(--accent); }
  .icon-btn-text {
    border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); border-radius: 7px;
    padding: 5px 10px; font-size: 12px; font-weight: 600; font-family: inherit;
  }
  .icon-btn-text:hover { color: var(--text); border-color: var(--accent); }
  .icon-btn-text.danger-text { color: var(--danger); border-color: var(--danger-soft); }
  .icon-btn-text.danger-text:hover { background: var(--danger-soft); border-color: var(--danger); }
  .pricing-row-actions { display: flex; gap: 6px; white-space: nowrap; }
  .pricing-row-input[readonly], .pricing-row-input:disabled { background: var(--surface-2); color: var(--text-soft); cursor: default; border-color: transparent; }
  .pricing-panel table.simple thead th { position: sticky; top: 0; z-index: 2; background: var(--surface-2); box-shadow: 0 1px 0 var(--border); }
  .pricing-panel table.simple th, .pricing-panel table.simple td { font-size: 15px; padding: 10px 9px; }
  .pricing-panel .pricing-row-input { font-size: 15px; padding: 8px 9px; }
  .pricing-panel .icon-btn-text { font-size: 13px; padding: 6px 11px; }

  .nav-item-wrap { display: flex; flex-direction: column; }
  .nav-item.has-sub { position: relative; }
  .nav-chevron { margin-left: auto; width: 13px; height: 13px; flex: none; opacity: 0.6; transition: transform .15s; }
  .nav-item.sub-open .nav-chevron { transform: rotate(90deg); }
  .nav-submenu { display: none; flex-direction: column; gap: 3px; padding: 4px 0 6px 34px; }
  .nav-submenu.open { display: flex; }
  /* 하위 메뉴 안의 중메뉴 — 단가표·서식류·보관함 셋으로 접는다(2026-09-27).
   스물셋을 한 줄로 늘어놓으면 메뉴를 열 때마다 화면이 통째로 길어진다. */
.nav-subgroup { display:flex; align-items:center; gap:6px; width:100%;
  background:transparent; border:0; cursor:pointer; text-align:left;
  font:inherit; font-size:var(--fs-base, 14px); font-weight:var(--fw-medium, 500); color:var(--text-soft);
  min-height:var(--nav-item-h, 44px); padding:0 10px; border-radius:var(--radius-md, 8px); }
.nav-subgroup:hover { background:var(--accent-soft); color:var(--text); }
.nav-subgroup.open { color:var(--accent-strong); }
.nav-subgroup .grp-chev { width:13px; height:13px; margin-left:auto; flex:0 0 auto;
  transition:transform .15s; opacity:.7; }
.nav-subgroup.open .grp-chev { transform:rotate(90deg); }
.nav-subgroup-items { display:none; padding-left:9px;
  border-left:1px solid var(--border); margin:0 0 4px 14px; }
.nav-subgroup-items.open { display:block; }
.nav-subitem.grp-solo { font-weight:var(--fw-medium, 500); font-size:var(--fs-base, 14px); color:var(--text-soft); }
.nav-submenu.open { max-height:70vh; overflow-y:auto; }

/* 2026-10-06 — 사이드바가 흰색이 되면서 여기 박혀 있던 어두운 바탕용 색들이
     흰 바탕 위에서 거의 안 보이게 됐다. 윗 메뉴(.nav-item)와 같은 규칙으로 맞춘다.
     활성은 색이 아니라 연한 회색 바탕 + 굵기 500 (G 의 방식). */
.nav-subitem {
    display: flex; align-items: center; min-height: var(--nav-item-h, 44px);
    padding: 0 10px; border-radius: var(--radius-md, 8px);
    color: var(--text-soft); background: transparent; border: none;
    text-align: left; font-size: var(--fs-base, 14px); font-weight: var(--fw-normal, 400);
    width: 100%; font-family: inherit;
    transition: background-color var(--dur, 200ms) var(--ease-out-strong), color var(--dur, 200ms) var(--ease-out-strong);
  }
  .nav-subitem:hover { background: var(--accent-soft); color: var(--text); }
  .nav-subitem.active { background: var(--accent-soft); color: var(--text); font-weight: var(--fw-medium, 500); }

  .edu-layout { display: grid; grid-template-columns: 280px 1fr; gap: 16px; align-items: start; }
  .edu-layout > * { min-width: 0; }
  @media (max-width: 900px) { .edu-layout { grid-template-columns: 1fr; } }
  .edu-toc { padding: 10px; position: sticky; top: 16px; max-height: calc(100vh - 100px); overflow-y: auto; }
  .edu-toc-group { margin-bottom: 4px; }
  .edu-toc-cat { font-size: 12px; font-weight: 600; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.04em; padding: 10px 10px 4px; }
  .edu-toc-item {
    display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; padding: 9px 10px;
    border-radius: 8px; border: none; background: transparent; color: var(--text-soft); font-size: 13px; font-weight: 500;
  }
  .edu-toc-item:hover { background: var(--surface-2); color: var(--text); }
  .edu-toc-item.active { background: var(--accent-soft, var(--surface-2)); color: var(--text); font-weight: 600; }
  .edu-toc-n { flex: none; width: 22px; height: 22px; border-radius: 6px; background: var(--surface-2); color: var(--text-soft); font-size: 12px; font-weight: 600; display: flex; align-items: center; justify-content: center; }
  .edu-toc-item.active .edu-toc-n { background: var(--accent); color: var(--accent-contrast); }
  .edu-content-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
  .edu-content-head h2 { font-size: 19px; margin: 0; }
  .edu-content-cat { font-size: 12px; font-weight: 600; color: var(--text-soft); background: var(--surface-2); padding: 4px 10px; border-radius: 999px; }
  .edu-content-body { white-space: pre-wrap; line-height: 1.75; font-size: 14px; color: var(--text); margin-top: 16px; }
  .edu-content-actions { display: flex; gap: 8px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
  .archive-row-dropped td { color: var(--text-faint); text-decoration: line-through; }
  .archive-row-dropped td.no-strike, .archive-row-dropped td:last-child { text-decoration: none; }
  .archive-link-box { padding: 14px 20px; border-bottom: 1px solid var(--border); background: var(--surface-2); }

  /* ---------- 연락처 관리 모달 ---------- */
  .contact-modal-body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 16px; max-height: 70vh; overflow-y: auto; }
  .contact-group-label { font-size: 12px; font-weight: 600; color: var(--text-soft); margin-bottom: 8px; }
  .contact-entry-row { display: flex; gap: 8px; margin-bottom: 7px; }
  .contact-entry-row input { flex: 1; }
  .contact-entry-row .item-remove-btn { flex: none; }
  .contact-add-row-btn {
    display: inline-flex; align-items: center; gap: 5px; border: 1.5px dashed var(--border); background: none;
    color: var(--text-soft); border-radius: 8px; padding: 7px 10px; font-size: 12px; font-weight: 600; font-family: inherit; align-self: flex-start;
  }
  .contact-add-row-btn:hover { border-color: var(--accent); color: var(--text); }
  .contact-modal-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 4px; border-top: 1px solid var(--border); margin-top: 2px; }

  /* ---------- 재무 현황: 구글시트 이식 (캘린더/입찰가/대출 등) ---------- */
  .fin-panel { display: block; }
  .staff-panel { display: block; }
  .pricing-panel { display: block; }
  .pricing-row-input { font-family: inherit; font-size: 12px; padding: 6px 7px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--text); width: 100%; min-width: 0; }
  .cal-nav { display: flex; align-items: center; justify-content: center; gap: 18px; margin-bottom: 10px; }
  .cal-nav-label { font-size: 14px; font-weight: 600; min-width: 110px; text-align: center; }
  .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
  .cal-dow { text-align: center; font-size: 12px; color: var(--text-faint); font-weight: 600; padding-bottom: 4px; min-width: 0; }
  .cal-cell {
    min-height: 128px; min-width: 0; border: 1px solid var(--border); border-radius: 8px; padding: 9px 10px; background: var(--surface);
    cursor: pointer; display: flex; flex-direction: column; gap: 5px; transition: border-color .15s; overflow: hidden;
  }
  .cal-cell:hover { border-color: var(--accent); }
  .cal-cell.empty { background: transparent; border: none; cursor: default; }
  .cal-cell.today { border-color: var(--accent-strong); border-width: 1.5px; }
  .cal-cell.selected { background: var(--accent-soft); }
  .cal-cell .d { font-size: 13px; font-weight: 600; color: var(--text-soft); }
  .cal-cell .amt { font-size: 12px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
  .cal-cell .amt.in { color: var(--success); }
  .cal-cell .amt.out { color: var(--danger); }
  .cal-cell .dot-row { display: flex; gap: 3px; margin-top: auto; }
  .cal-cell .dot-row i { width: 5px; height: 5px; border-radius: 50%; }

  .bid-draw-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
  .bid-draw-row input { width: 78px; flex: none; }

  /* ★ 2026-09-27 — 카드가 화면 너비에 따라 늘어난다 ★
     대표님: 「각 은행마다 박스 크기가 너무 작어, 유동적으로 바뀔 수 있게 화면 크기에
     맞춰줘」. 원인은 auto-fill 이었다 — 넓은 화면에서 빈 칸을 계속 만들어 두기 때문에
     카드 다섯 장이 240px 씩 붙어 있고 오른쪽이 텅 비었다. auto-fit 은 빈 칸을 접어
     없애서 있는 카드들이 남는 자리를 나눠 갖는다. 좁은 화면에서는 min() 이 한 줄에
     한 장으로 떨어뜨린다. */
  .loan-card-grid { display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
  .loan-card.add { display:flex; flex-direction:column; align-items:center;
    justify-content:center; border-style:dashed; min-height:150px; gap:2px; }
  .loan-card.add .plus { font-size:26px; font-weight:300; color:var(--text-faint);
    line-height:1; margin-bottom:6px; }
  .loan-card.add .nm { margin:0; }
  .loan-card.add:hover { border-color:var(--accent-strong); }
  .loan-card {
    text-align: left; border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; background: var(--surface);
    box-shadow: var(--shadow); font-family: inherit; cursor: pointer; transition: border-color .15s;
  }
  .loan-card:hover { border-color: var(--accent); }
  .loan-card.active { border-color: var(--accent-strong); border-width: 1.5px; }
  /* 대출 카드에서 가장 먼저 봐야 하는 것은 '매달 얼마가 나가는가'다.
     잔금은 그다음이다 — 잔금은 당장 통장에서 빠지는 돈이 아니지만 월 상환액은
     이번 달에 실제로 빠진다. 그런데 월 상환액은 카드에 아예 없었고, 잔금 글씨도
     작고 흐려서 눈에 들어오지 않았다. 월 상환액을 크게 세우고 색을 준다. */
  .loan-card .org { font-size: 14px; font-weight: 600; color: var(--text); }
  .loan-card .nm { font-size: 12px; color: var(--text-soft); margin: 3px 0 12px; }
  .loan-card .pay-lbl { font-size: 12px; color: var(--warning); font-weight: 600;
    letter-spacing: 0.01em; margin-bottom: 3px; }
  .loan-card .pay { font-size: 25px; font-weight: 600; color: var(--warning);
    letter-spacing: -0.015em; line-height: 1.1; margin-bottom: 13px; }
  .loan-card .bal { font-size: 17px; font-weight: 600; color: var(--text); }
  .loan-card .bal-lbl { font-size: 12px; color: var(--text-soft); margin-bottom: 2px; }
  .loan-card .bar-track { height: 7px; border-radius: 4px; background: var(--surface-2); overflow: hidden; margin-top: 11px; }
  .loan-card .bar-fill { height: 100%; border-radius: 4px; background: var(--accent); }
  .loan-card .paid-note { font-size: 12px; color: var(--text-soft); margin-top: 6px; }

  /* 대출 합계 — 카드를 일곱 장 보면서 머리로 더하게 두지 않는다 */
  #loanSumBar { margin-bottom: 16px; }
  #loanSumBar .ls { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
  #loanSumBar .i { padding: 16px 18px; border-radius: 12px; background: var(--surface-2);
    border: 1px solid var(--border); }
  #loanSumBar .l { font-size: 13px; color: var(--text-faint); font-weight: 600; }
  #loanSumBar .v { font-size: 27px; font-weight: 600; margin: 5px 0 3px;
    font-variant-numeric: tabular-nums; letter-spacing: -0.015em; }
  #loanSumBar .v.pay { color: var(--warning); }
  #loanSumBar .d { font-size: 12px; color: var(--text-faint); }

  /* ---------- 원가계산서(내부용) memo — 나머지는 견적서와 동일한 .dp-* 레터헤드 스타일 재사용 ---------- */
  .cost-memo { font-size: 12px; font-weight: 400; color: #444; border-top: 1px solid #ccc; padding-top: 10px; white-space: pre-wrap; line-height: 1.6; }
  .cost-memo .lbl { font-weight: 600; color: #1a1a1a; margin-bottom: 4px; display: block; }
  /* 급여명세서 실지급액 박스 — 한눈에 띄도록 큼직하게 */
  .cost-total-row { display: flex; justify-content: flex-end; margin-bottom: 4px; }
  .cost-total-box { border: 1.5px solid #1a1a1a; border-radius: 8px; padding: 14px 26px; text-align: right; min-width: 260px; }
  .cost-total-box .lbl { font-size: 12px; color: #666; }
  .cost-total-box .val { font-size: 24px; font-weight: 600; margin-top: 4px; color: #161616; }

  /* ---------- 영업용 서류: 담당 거래처 + 단계 탭 ---------- */
  .ai-context { display: flex; flex-direction: column; gap: 6px; max-width: 360px; margin-bottom: 16px; }
  .ai-context label { font-size: 12px; font-weight: 600; color: var(--text-soft); }
  .ai-context input {
    font-family: inherit; font-size: 14px; padding: 9px 11px; border-radius: 9px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text);
  }
  .ai-tabs, .qc-tabs { display: flex; flex-wrap: wrap; gap: 6px; border-bottom: 1px solid var(--border); padding-bottom: 12px; margin-bottom: 20px; }
  #finTabs { position: sticky; top: 0; z-index: 60; background: var(--bg); padding-top: 6px; margin-left: -4px; padding-left: 4px; margin-right: -4px; padding-right: 4px; }
  @media (max-width: 860px) { #finTabs { top: 56px; } }

  .cal-hover-preview {
    position: fixed; z-index: 300; background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: var(--shadow); padding: 10px 12px; font-size: 12px; max-width: 240px; pointer-events: none;
    opacity: 0; transform: translateY(4px); transition: opacity .12s, transform .12s;
  }
  .cal-hover-preview.show { opacity: 1; transform: translateY(0); }
  .cal-hover-preview .h-title { font-weight: 600; margin-bottom: 5px; }
  .cal-hover-preview .h-row { display: flex; justify-content: space-between; gap: 10px; padding: 2px 0; }
  .ai-tab, .qc-tab {
    display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px; border-radius: 9px;
    border: 1px solid transparent; background: transparent; color: var(--text-soft); font-size: 13px; font-weight: 600;
  }
  .ai-tab-n, .qc-tab-n {
    font-size: 12px; font-weight: 600; color: var(--text-faint); border: 1px solid var(--border);
    border-radius: 999px; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center;
  }
  .ai-tab.active, .qc-tab.active { background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent); }
  .ai-tab.active .ai-tab-n, .qc-tab.active .qc-tab-n { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }
  .ai-panel { display: none; }
  .ai-panel.active { display: block; }
  .ai-placeholder { padding: 46px 20px; text-align: center; }
  .ai-placeholder .ico {
    width: 44px; height: 44px; border-radius: 12px; background: var(--surface-2); color: var(--text-faint);
    display: flex; align-items: center; justify-content: center; margin: 0 auto 14px;
  }
  .ai-placeholder .ico svg { width: 22px; height: 22px; }
  .ai-placeholder h3 { font-size: 15px; margin: 0 0 6px; }
  .ai-placeholder p { font-size: 13px; color: var(--text-faint); margin: 0; max-width: 380px; margin: 0 auto; }

  /* 위쪽 여백(24px)은 "새 구획이 시작된다"는 걸 보여주는 간격, 아래쪽(padding-bottom 8px + 테두리)은
     그 구획의 첫 필드와 붙는 간격 — 이 둘의 차이가 뚜렷해야 구획이 나뉘어 보인다. 앞서는 필드
     줄(.field-row)이 자기 밑 여백을 안 갖고 있어서, 예전엔 위쪽 4px만으로 다음 구획 제목이 바로
     앞 입력칸에 거의 붙어 보이는 문제가 있었다. */
  .form-section-title {
    font-size: 13px; font-weight: 600; color: var(--text); margin: 24px 0 2px;
    padding-bottom: 8px; border-bottom: 1px solid var(--border);
  }
  .form-section-title:first-child { margin-top: 0; }
  /* 2026-09-20: 서류 입력창을 카드형(항목/수량/단가/금액 리스트 + 부가세 토글 + 요약)으로 간소화 —
     .items-head/.items-table 등 공유 클래스라 서식류 전체(견적서~공문)에 한 번에 적용된다. */
  .items-card {
    border: 1px solid var(--border); border-radius: 12px; background: var(--surface); padding: 14px 14px 12px;
  }
  .items-head { display: flex; align-items: center; justify-content: space-between; margin-top: 0; margin-bottom: 10px; gap: 10px; flex-wrap: wrap; }
  .items-head label { font-size: 13px; font-weight: 600; color: var(--text); }
  .items-table { display: flex; flex-direction: column; gap: 4px; max-height: 360px; overflow-y: auto; padding-right: 2px; }
  .item-row { display: grid; grid-template-columns: 1.6fr 0.7fr 0.7fr 0.7fr 1.1fr 22px; gap: 5px; align-items: center; padding: 3px 0; }
  .stmt-items-table .item-row { grid-template-columns: 0.5fr 0.5fr 1.6fr 0.8fr 0.6fr 0.9fr 22px; }
  .item-row.item-row-head {
    font-size: 12px; color: var(--text-faint); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
    padding-bottom: 8px; border-bottom: 1px solid var(--border); margin-bottom: 4px;
  }
  .item-row input {
    font-family: inherit; font-size: 12px; padding: 7px 8px; border-radius: 7px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text); width: 100%; min-width: 0;
  }
  .item-row input::placeholder { color: var(--text-faint); }
  .item-row input:focus { outline: none; border-color: var(--accent); }
  .item-row input[data-f="amount"], .item-row input[data-f="unitPrice"] { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
  .item-remove-btn {
    width: 20px; height: 20px; border-radius: 6px; border: none; background: transparent;
    color: var(--text-faint); font-size: 15px; line-height: 1; display: flex; align-items: center; justify-content: center;
  }
  .item-remove-btn:hover { background: var(--danger-soft); color: var(--danger); }
  .item-add-btn {
    display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%;
    margin-top: 8px; padding: 9px; border-radius: 9px; border: 1.5px dashed var(--border);
    background: transparent; color: var(--text-soft); font-size: 13px; font-weight: 600;
  }
  .item-add-btn:hover { border-color: var(--accent); color: var(--accent-strong); background: var(--accent-soft); }
  .item-add-btn svg { width: 14px; height: 14px; }

  /* 요약 카드(공급가액/부가세/합계) — 입력 폼 안에서도 바로 확인할 수 있게 미리보기와 별개로 표시 */
  .doc-summary-card {
    margin-top: 10px; padding: 12px 14px; border-radius: 10px; background: var(--surface-2);
    display: flex; flex-direction: column; gap: 6px; font-size: 13px;
  }
  .doc-summary-card .row { display: flex; justify-content: space-between; color: var(--text-soft); }
  .doc-summary-card .row.total { color: var(--text); font-weight: 600; font-size: 15px; padding-top: 6px; border-top: 1px solid var(--border); margin-top: 2px; }
  .doc-summary-card .row b { font-variant-numeric: tabular-nums; color: var(--text); }
  .doc-summary-card .row.total b { color: var(--accent-strong); }

  .primary-btn {
    display: inline-flex; align-items: center; gap: 7px; background: var(--accent-strong); color: var(--accent-contrast);
    border: none; border-radius: 9px; padding: 10px 16px; font-size: var(--fs-base); line-height: var(--lh-tight); font-weight: 600;
  }
  .primary-btn svg { width: 15px; height: 15px; }

  /* 서식류 전체 공통 — 입력 폼의 마지막 필드(용도 등)와 미리보기/발행 버튼 줄 사이에 여백이
     아예 없어서 붙어 보였다. .doc-builder는 flex/grid gap이 안 먹는 block 레이아웃이라 여기서
     직접 위쪽 여백을 준다. */
  .doc-preview-wrap { min-width: 0; margin-top: 24px; }
  .doc-preview-toolbar { display: flex; justify-content: flex-end; gap: 8px; margin-bottom: 10px; }
  /* 미리보기/발행 버튼 크기가 글자 수 차이("미리보기" vs "발행(PDF로 저장)")로 제각각이었다 —
     서식류 전체에서 두 버튼이 툴바 폭을 절반씩 나눠 갖게 통일한다. */
  .doc-preview-toolbar button { flex: 1; justify-content: center; }
  .primary-btn.secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
  .primary-btn.saved { background: var(--success); }
  .doc-preview-scroll { overflow-x: auto; background: var(--surface-2); border-radius: 12px; padding: 20px; }

  /* ===== 2026-09-19 재측정 — 원본 xlsm(팩토리_공식문서.xlsm 견적서 시트)의 용지 설정이
     실제로는 paperSize=9(A4, 210x297mm)라는 걸 openpyxl로 확인함(기존 186x279mm는 오차였음).
     사용자가 새로 보내준 팩토리 견적서 실물 스크린샷(920x1303px, 페이지 영역만 913x1292px)을
     픽셀 단위로 직접 측정해서(px_per_mm≈4.349, 두 축 모두 A4 비율과 정확히 일치) 팩토리 로고·
     레터헤드·하단 배너 위치를 다시 잡았다 — 임의로 고른 값 없음. 세인 쪽은 이번에 받은 스크린샷이
     없어서, 페이지 크기가 커진 비율(가로 210/186, 세로 297/279)만큼 기존 실측값을 비례 환산했다
     — 세인 실물 스크린샷을 새로 받으면 재검증 필요. */
  /* ===== 2026-09-20 여백 체계 재정비 — 견적서를 기준 삼아 상단(레터헤드 이미지 기준) 3.5cm,
     하단(배너 이미지 기준) 2cm, 좌우 2cm의 고정 여백으로 전 서식에 동일하게 통일했다. 레터헤드/배너
     이미지 자체의 실측 크기(entity별 width/height)는 그대로 두고, 위치만 이 여백 체계 위에서
     잡는다. .dp-letterhead-wrap은 display:table로 이미지 크기만큼만 감싸도록 해서, 그 안의
     .dp-stamp(직인) 퍼센트 좌표가 페이지 여백이 바뀌어도 항상 레터헤드 이미지 자체를 기준으로
     정확히 같은 자리에 붙어있게 만들었다(감싸는 박스 폭이 페이지 폭이 아니라 이미지 폭과 같아짐). */
  /* ★ 여백은 서식의 규격이다 — 내용이 넘치면 내용을 줄인다 ★
     A4 한 장에 위 35mm·좌우 20mm·아래 20mm 여백을 두고, 배너는 아래 여백 위에
     고정한다. 내용이 길다고 배너를 아래로 밀면 여백을 침범하거나 두 장으로 넘어간다.
     그래서 **본문이 쓸 수 있는 높이를 정해 두고**, 거기 맞춰 내용을 줄인다.
     넘치는지는 scripts/check-boot.mjs 가 고칠 때마다 재어 본다. */
  .doc-preview {
    width: 210mm; min-height: 297mm; margin: 0 auto; background: #ffffff; color: #161616;
    box-shadow: 0 2px 24px rgba(0,0,0,0.18); padding: 35mm 20mm 20mm; font-family: "Noto Sans KR", sans-serif;
    box-sizing: border-box; display: flow-root; position: relative;
  }
  .dp-letterhead-wrap { position: relative; display: table; margin: 0 0 0 auto; }
  .dp-letterhead { display: block; }
  .dp-stamp { position: absolute; left: 91.8%; top: 84.1%; width: 12mm; height: 12mm; border-radius: 50%; object-fit: cover; }
  /* 실측: 세인 로고는 팩토리보다 세로로 길고 더 위에서 시작함(원본 이미지 자체가 다름).
     세인 값은 팩토리 재측정 배율(가로 x1.129032, 세로 x1.064516)로 비례 환산한 값. */
  /* 「내 서류」 — 뗄 수 있는 서류 세 가지를 나란히 놓는다.
     미리보기는 서식류 화면과 같이 버튼을 눌러야 창으로 뜬다. */
  .mydoc-grid { display: grid; gap: 16px; align-items: start;
                grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
  .mydoc-grid > .panel { margin: 0; }

  .doc-preview.entity-sein .dp-letterhead { width: 137.29mm; height: 89.31mm; }
  .doc-preview.entity-sein .dp-banner { width: 170.16mm; height: 15.44mm; }
  .doc-preview.entity-factory .dp-letterhead { width: 121.6mm; height: 66.9mm; }
  .doc-preview.entity-factory .dp-banner { width: 155.9mm; height: 10.2mm; }

  .dp-title { font-size: 48px; font-weight: 700; text-align: left; color: #161616; margin: 8mm 0 0; line-height: 1; }
  .dp-intro { font-size: 16px; font-weight: 400; color: #161616; margin: 3mm 0 0; }
  .dp-meta { display: flex; justify-content: space-between; align-items: baseline; font-size: 14.5px; font-weight: 700; margin: 0; color: #161616; }
  .dp-meta.mt-gap { margin-top: 13.4mm; }
  .dp-meta .lbl { color: #161616; margin-right: 4px; }
  .dp-meta .right { font-size: 13px; }
  .dp-meta .right.recipient { font-size: 17px; }
  .dp-table { width: 100%; border-collapse: collapse; margin-top: 3.9mm; font-size: 13.5px; color: #161616; }
  .dp-table th { background: #D9D9D9; border: 0.75px solid #BFBFBF; padding: 6px 6px; font-weight: 700; font-size: 12.5px; }
  .dp-table td { border: 0.75px solid #D9D9D9; padding: 4px 6px; text-align: center; height: 20px; font-weight: 400; }
  /* ===== 급여명세서 — 세무사 공식 서식(「근로기준1」)에 맞춤 =====
     2026-09-28 대표님이 세무서에서 받은 강정선 급여명세서를 놓고 칸 이름·차례·
     단위 표기까지 맞췄다. 우리가 임의로 정한 이름을 쓰면 같은 달 같은 사람의
     명세서가 회사 것과 세무사 것 두 벌로 갈린다.
     법정 기재사항 근거는 근로기준법 제48조 제2항 · 같은 법 시행령 제27조의2. */
  /* 세무사 서식에는 레터헤드가 없다. 우리는 서식의 얼굴이라 남기되, 이 명세서는
     담을 것이 많아 한 장을 넘긴다 — 여기서만 70% 로 줄여 쓴다(실측 66.9→46.8mm). */
  #paySlipPreview .dp-letterhead { width: 85.12mm !important; height: 46.83mm !important; }
  #paySlipPreview .dp-table td { padding: 0.9mm 2mm; height: auto; font-size: 10.3px; line-height: 1.3; }
  #paySlipPreview .dp-table th { padding: 0.9mm 2mm; font-size: 9.8px; text-align: center; }
  #paySlipPreview .ps-title { font-size: 20px; font-weight: 700; text-align: center;
    margin: 4mm 0 0; letter-spacing: 1px; }
  #paySlipPreview .ps-top { display: flex; justify-content: space-between;
    font-size: 10.5px; margin: 2.5mm 0 1.5mm; }
  #paySlipPreview .ps-unit { font-size: 9px; color: #6A6A6A; text-align: right; margin: 1.6mm 0 0; }
  #paySlipPreview .dp-table td.nm { text-align: left; }
  #paySlipPreview .dp-table td.k { background: #EFEFEC; font-weight: 600; width: 19mm; text-align: center; }
  #paySlipPreview .ps-hours { margin-top: 1.5mm; }
  #paySlipPreview .ps-hours td { text-align: center; }
  #paySlipPreview .ps-main { margin-top: 1mm; }
  #paySlipPreview .ps-main td.num, #paySlipPreview .ps-main th.num { width: 27mm; }
  #paySlipPreview .ps-main tr.sub td { background: #F2F2F0; font-weight: 600; }
  #paySlipPreview .ps-main tr.total td { background: #D9D9D9; font-weight: 700; font-size: 11.5px; }
  #paySlipPreview .ps-calc { margin-top: 1mm; }
  #paySlipPreview .ps-calc td.nm { width: 26mm; }
  #paySlipPreview .ps-calc td.way { text-align: left; font-size: 9.6px; color: #4A4A4A; }
  #paySlipPreview .ps-calc td.num, #paySlipPreview .ps-calc th.num { width: 26mm; }
  #paySlipPreview .ps-foot { font-size: 9.2px; color: #5A5A5A; line-height: 1.5; margin-top: 2.5mm; }
  /* 대표님 지시(2026-09-28) — 맨 아래 당구장표시 한 줄. 이 회사는 실수령액을 먼저
     정하고 세전급여를 거꾸로 셈하므로, 공제 항목 하나하나는 실제 고지액과 다를 수 있다. */
  #paySlipPreview .ps-star { font-size: 9.6px; color: #3D3D3D; margin-top: 2mm;
    padding: 1.5mm 2.2mm; border: 0.3mm solid #C9C9C9; background: #F7F7F5; line-height: 1.45; }
  #paySlipPreview .ps-law { font-size: 8.6px; color: #9A9A9A; display: block; margin-top: 1mm; }
  #paySlipPreview .ps-thanks { font-size: 9.8px; color: #4A4A4A; text-align: center; margin-top: 3mm; }
  .dp-table td.name { text-align: left; }
  .dp-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
  .dp-table tfoot td { font-weight: 700; }
  .dp-table tfoot tr.vat td { background: #F2F2F2; }
  .dp-table tfoot tr.vat td:first-child { text-align: center; }
  .dp-table tfoot tr.total td { background: #D9D9D9; }
  .dp-table tfoot tr.total td:first-child { text-align: center; }
  /* 표 바깥 테두리 중 좌우(세로) 외곽선만 지우고, 위아래(가로) 외곽선과 칸 사이 안쪽 선은
     전부 그대로 둔다 — 좌우만 열린 형태. */
  .dp-table tr > *:first-child { border-left: none; }
  .dp-table tr > *:last-child { border-right: none; }
  .cert-table td.cert-key { width: 26%; background: #F7F7F7; font-weight: 700; }
  .cert-table td { height: 34px; }
  /* 배너는 내용 분량과 무관하게 항상 페이지 아래 여백(2cm) 위에 고정한다.
     내용이 짧은 문서(급여명세서·재직/경력증명서)는 표 바로 아래 흐름으로 두면
     배너가 중간에 붕 뜨기 때문이다. */
  .dp-banner { display: block; position: absolute; left: 0; right: 0; bottom: 20mm; margin: 0 auto; }

  /* 본문이 배너 자리로 내려앉지 않게 바닥 선을 끌어올린다.
       아래 여백 20mm + 배너 높이 + 숨 쉴 틈 6mm
     이 값이 곧 「본문이 쓸 수 있는 높이」를 정한다 — 검사가 이 값을 읽어
     내용이 넘치는지 재어 본다. 여백을 줄이는 것이 아니라 내용을 줄여야 한다. */
  .doc-preview.entity-factory { padding-bottom: 36mm; }   /* 배너 10.2mm */
  .doc-preview.entity-sein    { padding-bottom: 42mm; }   /* 배너 15.44mm */

  @page { size: A4 portrait; margin: 0; }
  @media print {
    body * { visibility: hidden; }
    #docPreview, #docPreview *, #archiveDocPreview, #archiveDocPreview *, #stmtPreview, #stmtPreview *, #costPreview, #costPreview *,
    #paySlipPreview, #paySlipPreview *, #empCertPreview, #empCertPreview *, #careerCertPreview, #careerCertPreview *,
    #propPreview, #propPreview *, #taxPreview, #taxPreview *,
    #specPreview, #specPreview *, #detailPreview, #detailPreview *, #costphotoPreview, #costphotoPreview *,
    #costmasterPreview, #costmasterPreview *, #receiptPreview, #receiptPreview *, #printspecPreview, #printspecPreview *,
    #storagePreview, #storagePreview *, #officialPreview, #officialPreview *,
    #svdPreview, #svdPreview * { visibility: visible; }
    #docPreview, #archiveDocPreview, #paySlipPreview, #empCertPreview, #careerCertPreview, #propPreview, #taxPreview, #costPreview,
    #specPreview, #detailPreview, #costphotoPreview, #costmasterPreview, #receiptPreview, #printspecPreview, #storagePreview, #officialPreview,
    #svdPreview {
      position: absolute; top: 0; left: 0; width: 210mm; min-height: 297mm; box-shadow: none; margin: 0; padding: 35mm 20mm 20mm;
    }
    /* 화면에서 안 겹쳐도 출력에서 겹치면 소용이 없다 — 같은 선을 인쇄에도 그대로 건다.
       :not(.dp-multi) 를 붙인 까닭 — 여러 장짜리 서식(.dp-multi)은 바깥 상자가 아니라
       장(.dp-sheet)마다 여백을 갖는다. 그 바깥 상자에까지 36mm 를 물리면 전체 높이가
       「장 수 × 297mm + 36mm」가 되어 PDF 자르는 자리가 통째로 밀린다. 예전에는
       #svdPreview.dp-multi{padding:0 !important} 의 명시도로 간신히 이기고 있었는데,
       !important 하나가 빠지면 바로 무너지는 구조였다. 아예 안 걸리게 한다. */
    .doc-preview.entity-factory:not(.dp-multi) { padding-bottom: 36mm !important; }
    .doc-preview.entity-sein:not(.dp-multi)    { padding-bottom: 42mm !important; }
    #stmtPreview { position: absolute; top: 0; left: 0; width: 210mm; min-height: 297mm; box-shadow: none; margin: 0; }
    .no-print { display: none !important; }
  }

  /* ---------- 거래명세서 ---------- */
  .stmt-preview {
    width: 210mm; min-height: 297mm; margin: 0 auto; background: #fff; color: #1a1a1a;
    box-shadow: 0 2px 24px rgba(0,0,0,0.18); padding: 35mm 20mm 20mm; box-sizing: border-box;
    font-family: "Noto Sans KR", sans-serif; font-size: 11px; display: flow-root;
  }
  .stmt-copy { border: 1.5px solid #333; margin-bottom: 8mm; }
  .stmt-copy-head { display: flex; justify-content: space-between; align-items: baseline; padding: 8px 12px; border-bottom: 1.5px solid #333; }
  .stmt-copy-head .stmt-title { font-size: 22px; font-weight: 800; letter-spacing: 6px; }
  .stmt-copy-head .stmt-for { font-size: 10px; color: #555; }
  .stmt-copy-head .stmt-date { font-size: 11px; }
  .stmt-parties { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid #333; }
  .stmt-party { padding: 6px 12px; }
  .stmt-party + .stmt-party { border-left: 1px solid #333; }
  .stmt-party-title { font-size: 10px; font-weight: 700; color: #333; margin-bottom: 3px; }
  .stmt-party-row { display: flex; gap: 8px; padding: 2px 0; font-size: 10.5px; }
  .stmt-party-row .lbl { width: 66px; color: #666; flex-shrink: 0; }
  .stmt-table { width: 100%; border-collapse: collapse; font-size: 10.5px; }
  .stmt-table th, .stmt-table td { border: 1px solid #333; padding: 4px 5px; text-align: center; height: 18px; }
  .stmt-table td.name { text-align: left; }
  .stmt-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
  /* 표 바깥 테두리만 지우고 안쪽 선은 유지 (거래명세서 자체는 stmt-copy 박스 테두리로 이미 감싸져 있음) */
  .stmt-table tr > *:first-child { border-left: none; }
  .stmt-table tr > *:last-child { border-right: none; }
  .stmt-table thead tr:first-child > * { border-top: none; }
  .stmt-table tbody tr:last-child > * { border-bottom: none; }
  .stmt-foot { display: flex; border-top: 1.5px solid #333; }
  .stmt-foot > div { flex: 1; padding: 7px 12px; border-left: 1px solid #333; font-size: 10.5px; }
  .stmt-foot > div:first-child { border-left: none; }
  .stmt-foot .stmt-foot-label { color: #666; font-size: 9.5px; }
  .stmt-foot .stmt-foot-value { font-weight: 700; font-variant-numeric: tabular-nums; margin-top: 2px; }

  /* ---------- 발행 견적서 아카이브 ---------- */
  .modal-overlay {
    position: fixed; inset: 0; background: rgba(10,10,9,0.55); z-index: 200;
    display: flex; align-items: flex-start; justify-content: center; padding: 30px 20px; overflow-y: auto;
  }
  .modal-box { background: var(--bg); border-radius: 16px; width: fit-content; max-width: 100%; box-shadow: var(--shadow); }
  .modal-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 18px; border-bottom: 1px solid var(--border); }
  .modal-title { font-size: 14px; font-weight: 600; }
  .icon-btn {
    width: 32px; height: 32px; border-radius: 9px; border: 1px solid var(--border); background: var(--surface);
    color: var(--text-soft); display: flex; align-items: center; justify-content: center; font-size: 15px;
  }
  table.clients tr.clickable { cursor: pointer; }

  ::-webkit-scrollbar { height: 8px; width: 8px; }
  ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

  /* ---------- 모바일 반응형 (사이드바를 드로어 메뉴로) ---------- */
  .mobile-topbar { display: none; }
  .sidebar-backdrop { display: none; }
  @media (max-width: 860px) {
    .app { flex-direction: column; }
    .mobile-topbar {
      display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--ink);
      position: sticky; top: 0; z-index: 120;
    }
    .mobile-topbar .icon-btn { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.14); color: #F0F0EA; }
    .sidebar {
      position: fixed; top: 0; left: 0; height: 100vh; z-index: 200; width: 78vw; max-width: 300px;
      transform: translateX(-100%); transition: transform .2s ease; box-shadow: 0 0 0 rgba(0,0,0,0);
    }
    .sidebar.open { transform: translateX(0); box-shadow: 10px 0 40px rgba(0,0,0,0.35); }
    .sidebar-backdrop {
      display: block; position: fixed; inset: 0; background: rgba(10,10,9,0.5); z-index: 190;
      opacity: 0; pointer-events: none; transition: opacity .2s ease;
    }
    .sidebar-backdrop.show { opacity: 1; pointer-events: auto; }
    .main { padding: 18px 14px 60px; min-width: 0; }
    .topbar h1 { font-size: 19px; }
    .kpi-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .kpi-card { padding: 13px 12px 12px; }
    .kpi-value { font-size: 17px; }
    .kpi-label, .kpi-note { font-size: 12px; }
    .summary-grid { grid-template-columns: 1fr; }
    .cal-grid { gap: 3px; }
    .cal-cell { min-height: 64px; padding: 5px 4px; }
    .cal-cell .d { font-size: 12px; }
    .cal-cell .amt { font-size: 12px; }
    .cal-dow { font-size: 12px; }
    .entity-tabs { max-width: none; }
    /* 좁은 화면 — 160px 짜리 카드는 글씨가 두 줄씩 접힌다. 한 줄에 한 장이 낫다. */
    .loan-card-grid { grid-template-columns: 1fr; }
    table.clients { min-width: 760px; }
    /* 문서 미리보기 모달 — 제목("견적서 미리보기" 등)과 전송/발행/닫기 버튼이 한 줄에 다 들어가려다
       보니 좁은 화면에서 제목이 줄바꿈되고 버튼끼리 눌려 답답해 보였다(2026-09-20 사용자 스크린샷으로
       확인). 제목 줄과 버튼 줄을 분리하고, 버튼 두 개는 폭을 균등하게 채우게 한다. */
    #docPreviewModal .modal-head { flex-direction: column; align-items: stretch; gap: 8px; padding: 10px 14px; }
    #docPreviewModal .modal-head > div { flex-wrap: nowrap; }
    #docPreviewSendBtn, #docPreviewPublishBtn { flex: 1; justify-content: center; }
    /* 버튼 두 줄(제목+버튼)이 모달 높이를 너무 많이 잡아먹으면 실제 문서 미리보기 영역이 좁아져서
       "미리보기가 작게 보인다"는 체감이 커진다 — 모바일에서만 이 모달의 버튼을 더 작게 줄여서
       문서가 보이는 실제 영역을 넓힌다. */
    #docPreviewModal .modal-title { font-size: 13px; }
    #docPreviewModal #docPreviewSendBtn, #docPreviewModal #docPreviewPublishBtn { padding: 8px 10px; font-size: 13px; gap: 5px; }
    #docPreviewModal #docPreviewSendBtn svg, #docPreviewModal #docPreviewPublishBtn svg { width: 13px; height: 13px; }
  }


/* ── 아래는 원래 문서 뒤쪽에 따로 있던 두 번째 <style> 블록 ── */


  :root {
    --bg: #F3F3EF;
    --surface: #FFFFFF;
    --surface-2: #EAEAE4;
    --ink: #161615;
    --text: #1B1B18;
    --text-soft: #5E5E58;
    /* ★ 2026-10-06 — 이 :root 블록은 파일 앞쪽(30행대) 블록을 덮어쓴다 ★
       같은 특이성이라 뒤에 온 것이 이긴다. 그래서 앞쪽만 고치면 적용되지 않는다.
       두 벌이 있는 것 자체가 문제이고(토큰의 정답이 두 곳), 합치는 것은 화면을
       한 번 전부 확인해야 하는 일이라 따로 둔다 — 지금은 값만 맞춰 둔다. */
    --text-faint: #67675E;
    --border: #DEDED5;
    --accent: #5E5E58;
    --accent-strong: #161615;
    --accent-contrast: #FFFFFF;
    --success: #2E7A57; --success-soft:#E6F1EA; --success-ink:#1F6B45;
    --warning: #93661E; --warning-soft:#F2EAD9; --warning-ink:#7A5310;
    --danger: #9B3C31; --danger-soft:#F4E6E3;
    --shadow: 0 1px 2px rgba(22,22,21,0.05), 0 10px 26px -16px rgba(22,22,21,0.16);
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --bg: #0C0C0B; --surface:#191916; --surface-2:#232320; --ink:#000000;
      --text:#F0F0EA; --text-soft:#ACACA2; --text-faint:#9A9A90; --border:#33332E;
      --accent:#9C9C90; --accent-strong:#F0F0EA; --accent-contrast:#131311;
      --success:#4FAD84; --success-soft:rgba(79,173,132,0.14); --success-ink:#4FAD84;
      --warning:#C9994B; --warning-soft:rgba(201,153,75,0.14); --warning-ink:#C9994B;
      --danger:#DA8175; --danger-soft:rgba(218,129,117,0.14);
      --shadow: 0 1px 2px rgba(0,0,0,0.32), 0 12px 28px -14px rgba(0,0,0,0.6);
    }
  }
  :root[data-theme="dark"] {
    --bg: #0C0C0B; --surface:#191916; --surface-2:#232320; --ink:#000000;
    --text:#F0F0EA; --text-soft:#ACACA2; --text-faint:#9A9A90; --border:#33332E;
    --accent:#9C9C90; --accent-strong:#F0F0EA; --accent-contrast:#131311;
    --success:#4FAD84; --success-soft:rgba(79,173,132,0.14); --success-ink:#4FAD84;
    --warning:#C9994B; --warning-soft:rgba(201,153,75,0.14); --warning-ink:#C9994B;
    --danger:#DA8175; --danger-soft:rgba(218,129,117,0.14);
    --shadow: 0 1px 2px rgba(0,0,0,0.32), 0 12px 28px -14px rgba(0,0,0,0.6);
  }
  * { box-sizing: border-box; }
  html,body{ margin:0; padding:0; }
  body{
    background:var(--bg); color:var(--text); font-family:"Noto Sans KR",-apple-system,sans-serif;
    font-size:15px; line-height:1.6; -webkit-font-smoothing:antialiased; word-break:keep-all;
  }
  .wrap{ max-width:980px; margin:0 auto; padding:100px 32px 140px; }
  .num{ font-variant-numeric:tabular-nums; }

  /* ---- cover ---- */
  .cover{ padding: 40px 0 120px; }
  .cover-mark{ width:64px; height:64px; margin-bottom:36px; color:var(--ink); }
  .eyebrow{
    font-size:13px; font-weight:600; letter-spacing:0.14em; text-transform:uppercase;
    color:var(--text-faint); margin-bottom:18px;
  }
  .cover h1{
    font-size:56px; font-weight:200; letter-spacing:-0.01em; margin:0 0 6px; line-height:1.12;
    color:var(--text-soft);
  }
  .cover h1 b{ font-weight:600; color:var(--text); }
  .cover p.lead{ font-size:15.5px; color:var(--text-soft); max-width:560px; margin:22px 0 0; }
  .cover .src{ margin-top:34px; display:flex; gap:10px; flex-wrap:wrap; }
  .src-tag{
    font-size:12px; color:var(--text-faint); border:1px solid var(--border); border-radius:999px;
    padding:6px 13px; font-weight:500;
  }

  /* ---- section frame (BS/AS 넘버링을 그대로 오마주) ---- */
  section.ds{ padding:74px 0; border-top:1px solid var(--border); }
  .ds-head{ display:flex; align-items:baseline; justify-content:space-between; gap:20px; margin-bottom:8px; }
  .ds-tag{ font-size:13px; font-weight:600; letter-spacing:0.02em; color:var(--text-faint); }
  .ds-title{ font-size:26px; font-weight:600; letter-spacing:-0.015em; margin:2px 0 0; }
  .ds-title small{ font-weight:400; color:var(--text-soft); font-size:15px; margin-left:10px; }
  .ds-desc{ font-size:14px; color:var(--text-soft); max-width:600px; margin:14px 0 40px; }

  /* ---- color ---- */
  .swatch-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; }
  @media (max-width:760px){ .swatch-grid{ grid-template-columns:repeat(2,1fr);} }
  .swatch{ border:1px solid var(--border); border-radius:10px; overflow:hidden; background:var(--surface); }
  .swatch-fill{ height:76px; }
  .swatch-meta{ padding:11px 13px; }
  .swatch-name{ font-size:13px; font-weight:600; }
  .swatch-val{ font-size:12px; color:var(--text-faint); margin-top:2px; font-family:ui-monospace,"SF Mono",monospace; }
  .swatch-note{ font-size:12px; color:var(--text-faint); margin-top:5px; }
  .color-group-label{ font-size:12px; font-weight:600; color:var(--text-faint); text-transform:uppercase; letter-spacing:0.06em; margin:34px 0 12px; }
  .color-group-label:first-child{ margin-top:0; }

  /* ---- typography ---- */
  .type-row{ display:flex; align-items:baseline; gap:24px; padding:16px 0; border-bottom:1px solid var(--border); }
  .type-row:last-child{ border-bottom:none; }
  .type-w{ width:78px; flex:none; font-size:12px; color:var(--text-faint); font-weight:600; }
  .type-sample{ font-size:26px; }
  .type-note{ margin-left:auto; font-size:12px; color:var(--text-faint); flex:none; text-align:right; }
  .pair-demo{ margin-top:36px; padding:32px; border:1px solid var(--border); border-radius:12px; background:var(--surface); }
  .pair-demo .eb{ font-size:12px; font-weight:300; color:var(--text-soft); }
  .pair-demo .eb b{ font-weight:600; color:var(--text); }
  .pair-demo .label{ font-size:12px; color:var(--text-faint); margin-bottom:10px; letter-spacing:0.05em; text-transform:uppercase; }

  /* ---- spacing / radius / shadow ---- */
  .token-strip{ display:flex; align-items:flex-end; gap:22px; flex-wrap:wrap; }
  .token-box{ text-align:center; }
  .token-box .sq{ background:var(--ink); border-radius:4px; }
  .token-box .lbl{ font-size:12px; color:var(--text-faint); margin-top:8px; font-family:ui-monospace,monospace; }
  .radius-row{ display:flex; gap:18px; flex-wrap:wrap; margin-top:8px; }
  .radius-box{ width:74px; height:74px; background:var(--surface-2); border:1px solid var(--border); display:flex; align-items:center; justify-content:center; font-size:12px; color:var(--text-faint); font-family:ui-monospace,monospace; }

  /* ---- components ---- */
  .comp-block{ margin-bottom:44px; }
  .comp-label{ font-size:12px; color:var(--text-faint); text-transform:uppercase; letter-spacing:0.06em; margin-bottom:12px; font-weight:600; }
  .comp-row{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
  .btn-primary{
    display:inline-flex; align-items:center; gap:7px; background:var(--accent-strong); color:var(--accent-contrast);
    border:none; border-radius:9px; padding:10px 18px; font-size:13px; font-weight:600; font-family:inherit;
  }
  .btn-secondary{
    background:var(--surface); color:var(--text); border:1px solid var(--border); border-radius:9px;
    padding:10px 18px; font-size:13px; font-weight:600; font-family:inherit;
  }
  .pill{ display:inline-flex; align-items:center; padding:4px 11px; border-radius:999px; font-size:12px; font-weight:600; }
  .pill.ok{ background:var(--success-soft); color:var(--success-ink, var(--success)); }
  .pill.warn{ background:var(--warning-soft); color:var(--warning-ink, var(--warning)); }
  .pill.danger{ background:var(--danger-soft); color:var(--danger); }
  .tab-demo{ display:inline-flex; gap:6px; border-bottom:1px solid var(--border); padding-bottom:10px; }
  .tab-demo span{ padding:7px 14px; border-radius:8px; font-size:13px; font-weight:600; color:var(--text-soft); }
  .tab-demo span.active{ background:var(--accent-soft, var(--surface-2)); color:var(--text); border:1px solid var(--accent); }
  .nav-demo{ background:var(--ink); border-radius:10px; padding:14px; width:200px; }
  .nav-demo .item{ display:flex; align-items:center; gap:9px; padding:9px 11px; border-radius:7px; font-size:13px; color:#B4B4AA; font-weight:500; margin-bottom:2px; }
  .nav-demo .item.active{ background:#F0F0EA; color:#161615; font-weight:600; }
  .nav-demo .item i{ width:14px; height:14px; border-radius:3px; background:currentColor; opacity:0.5; flex:none; }
  .card-demo{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:16px 18px; box-shadow:var(--shadow); width:220px; }
  .card-demo .k{ font-size:12px; color:var(--text-soft); margin-bottom:8px; }
  .card-demo .v{ font-size:22px; font-weight:600; }

  /* ---- mark ---- */
  .mark-row{ display:flex; gap:40px; align-items:center; flex-wrap:wrap; }
  .mark-tile{ display:flex; flex-direction:column; align-items:center; gap:14px; }
  .mark-tile .box{ width:110px; height:110px; border-radius:12px; display:flex; align-items:center; justify-content:center; }
  .mark-tile .box.on-dark{ background:var(--ink); color:#F0F0EA; }
  .mark-tile .box.on-light{ background:var(--surface); border:1px solid var(--border); color:var(--ink); }
  .mark-tile svg{ width:46px; height:46px; }
  .mark-tile .cap{ font-size:12px; color:var(--text-faint); }

  footer{ padding-top:60px; margin-top:60px; border-top:1px solid var(--border); }
  footer p{ font-size:12px; color:var(--text-faint); max-width:560px; }

/* 거래 내역 한 줄 — 거래처, 「직접 입력」 표시, 지우기 단추 (2026-09-21)
   지우기는 손으로 적은 기록에만 붙는다. 옮겨온 519건은 실수로 지우면 되돌릴
   방법이 없어서 단추 자체를 만들지 않는다. */
.tx-row .tx-cl { display:inline-block; margin-left:8px; font-size:12px;
  font-weight:600; color:var(--accent-strong); background:var(--surface-2);
  padding:1px 7px; border-radius:4px; vertical-align:middle; }
.tx-row .tx-hand { display:inline-block; margin-left:7px; font-size:12px;
  color:var(--text-faint); border:1px solid var(--border); padding:0 5px;
  border-radius:3px; }
.tx-row .tx-del { margin-left:10px; font-size:12px; padding:3px 9px;
  border:1px solid var(--border); border-radius:5px; background:transparent;
  color:var(--text-faint); cursor:pointer; flex:none; }
.tx-row .tx-del:hover { color:var(--danger); border-color:var(--danger); }
.tx-row .tx-cat { display:inline-block; margin-left:6px; font-size:12px;
  font-weight:600; color:var(--text-soft); background:var(--surface-2);
  padding:1px 7px; border-radius:4px; vertical-align:middle; }

/* ── 거래 내역을 통장처럼 (2026-09-26) ──────────────────────────────────
   경리나라 입출내역조회·더존 위하고T 통장관리 화면을 조사해서 옮긴 구성이다.
   두 곳 다 출금과 입금을 다른 칸에 놓고, 그 오른쪽에 그때의 잔액을 찍는다.
   한 줄만 봐도 "얼마가 나갔고 그래서 얼마 남았나"를 알 수 있어야 한다.

   표(table)가 아니라 grid 로 짠 이유 — 목록을 다시 그릴 때마다 통째로 갈아
   끼우는데, tbody 안쪽만 바꾸는 것보다 div 한 덩어리를 바꾸는 편이 단순하다.
   기존 .tx-row 는 캘린더·홈에서 그대로 쓰므로 이름을 .txt-row 로 따로 둔다. */
.tx-table { display:block; }
/* ★ 2026-09-27 대표님 지시 ★
   「적요랑 거래처 사이가 너무 멀고 뒤에 버튼이 잘 안 보여. 표 조금 조절해 줘.」

   원인은 적요 칸에 남는 폭을 다 준 것(minmax(140px,1fr))이었다. 적요 글자는
   보통 열 자 안쪽인데 칸이 화면 폭만큼 늘어나, 글자 끝과 거래처 사이에 빈 자리가
   길게 생겼다. 그리고 남는 폭을 적요가 다 먹어서 단추 칸이 58px 밖에 안 됐다 —
   단추 하나도 겨우 들어가는 폭이다.

   그래서 늘어나는 칸을 **적요에서 단추 쪽으로 옮긴다.** 적요는 최대 320px 까지만
   넓히고(그 뒤로 거래처가 바로 붙는다), 남는 폭은 단추 칸이 받는다. */
.txt-row { display:grid; align-items:start; gap:10px;
  grid-template-columns: 82px 42px 96px minmax(150px,320px) 104px 88px 92px 92px 104px minmax(168px,1fr);
  padding:8px 10px; border-bottom:1px solid var(--border); font-size:13px; }
.txt-row:last-child { border-bottom:none; }
.txt-row > div { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* 적요 칸만 예외 — 아래에 특이사항 한 줄이 붙는다 */
.txt-desc { white-space:normal; }
.txt-row > div.num, .txt-row > div.txt-date { padding-top:1px; }

/* 머리줄은 스크롤해도 붙어 있어야 한다 — 3,700건을 내려보는 동안
   어느 칸이 출금이고 어느 칸이 입금인지 계속 보여야 한다. */
.txt-head { position:sticky; top:0; z-index:2; background:var(--surface);
  border-bottom:1px solid var(--border-strong, var(--border));
  font-size:12px; font-weight:600; color:var(--text-faint); letter-spacing:.2px; }
/* 줄 색 번갈아 — 표시는 tx-table.js 가 그릴 때 붙인다(특이사항 줄이 끼어
   nth-of-type 으로는 짝·홀이 어긋난다). */
.tx-table .txt-row.txt-alt { background:var(--surface-2); }

.txt-date { color:var(--text-soft); font-variant-numeric:tabular-nums; }
.txt-time { color:var(--text-faint); font-size:12px; font-variant-numeric:tabular-nums; }
.txt-acct { font-weight:600; color:var(--text-soft); }
.txt-desc { font-weight:600; }
.txt-cl { color:var(--accent-strong); font-weight:600; font-size:12px; }
.txt-out, .txt-in, .txt-bal { text-align:right; font-variant-numeric:tabular-nums; }
.txt-out { color:var(--danger); font-weight:600; }
.txt-in  { color:var(--success); font-weight:600; }
/* 잔액은 금액이 아니라 상태다. 출금·입금보다 조용하게 둔다 — 눈이 먼저
   가야 하는 것은 이번에 움직인 돈이고, 잔액은 그 결과로 따라 읽는 값이다. */
.txt-bal { color:var(--text); font-weight:600; }
.txt-nobal { color:var(--text-faint); font-weight:400; }
/* 단추 칸 — 셋까지 들어간다(잇기·거래아님·특이사항). 넘치면 줄을 바꾼다.
   줄임표로 잘리면 「뒤에 버튼이 잘 안 보인다」가 된다. */
.txt-act { display:flex; flex-wrap:wrap; gap:5px; justify-content:flex-end;
  overflow:visible; white-space:normal; }
.txt-act > button, .txt-act > span { flex:0 0 auto; }

/* 거래아님으로 찍은 줄 — 지운 것이 아니라 「매출·매입으로 세지 않는 줄」이다.
   금액은 그대로 보이되 조용하게 둔다(통장 잔액에는 남아 있다). */
.txt-off { background:var(--surface-2); }
.txt-off .txt-desc, .txt-off .txt-cl { color:var(--text-faint); }
.txt-off .txt-out, .txt-off .txt-in { opacity:.55; text-decoration:line-through; }
.txt-offtag { margin-left:6px; font-size:12px; font-weight:600; padding:1px 6px;
  border-radius:999px; background:var(--warning-soft, var(--surface)); color:var(--warning);
  border:1px solid var(--warning); vertical-align:1px; }
.txt-memo { margin-top:3px; font-size:12px; font-weight:400; color:var(--text-soft);
  line-height:1.5; white-space:normal; }

.tx-not, .tx-memo { border:1px solid var(--border); background:var(--surface);
  color:var(--text-soft); font-size:12px; padding:3px 8px; border-radius:7px;
  cursor:pointer; white-space:nowrap; }
.tx-not:hover { border-color:var(--warning); color:var(--warning); }
.tx-not.on { border-color:var(--warning); color:var(--warning); font-weight:600; }
.tx-memo:hover { border-color:var(--accent); color:var(--accent-strong); }
.tx-memo.on { border-color:var(--accent); color:var(--accent-strong); font-weight:600; }

/* 특이사항 적는 줄 — 표 한 줄을 통째로 쓴다 */
.txt-noterow { padding:10px 12px 12px; border-bottom:1px solid var(--border);
  background:var(--surface-2); }
.txt-notein { width:100%; box-sizing:border-box; font-size:13px; line-height:1.6;
  padding:8px 10px; border-radius:8px; border:1px solid var(--border);
  background:var(--surface); color:var(--text); resize:vertical; font-family:inherit; }
.txt-notebtns { display:flex; align-items:center; gap:8px; margin-top:7px; flex-wrap:wrap; }
.txt-notehint { font-size:12px; color:var(--text-faint); }
.txt-empty { padding:22px 10px; text-align:center; color:var(--text-faint); font-size:13px; }

/* 하단 합계 — 경리나라가 목록 맨 아래에 늘 붙여 두는 줄 */
.txt-total { display:flex; flex-wrap:wrap; gap:18px; align-items:center;
  margin-top:10px; padding:11px 12px; border-radius:8px;
  background:var(--surface-2); border:1px solid var(--border); font-size:13px; }
.txt-total > div { display:flex; align-items:baseline; gap:7px; }
.txt-total-k { color:var(--text-faint); font-size:12px; }
.txt-total b { font-variant-numeric:tabular-nums; font-size:14px; }
.txt-total b.in { color:var(--success); }
.txt-total b.out { color:var(--danger); }

/* 한 거래처만 골라 놓은 표에는 잔액 칸이 없다 — 그 통장 전체의 잔액이라
   사이사이 빠진 줄 때문에 숫자가 튀고, 「이 거래처와 남은 돈」으로 오해된다.
   (2026-09-27 대표님 물음 「여기에 잔액은 왜 따라 붙는 거지?」) */
.tx-table.nobal .txt-row {
  grid-template-columns: 82px 42px 96px minmax(150px,320px) 104px 88px 92px 92px minmax(168px,1fr);
}

/* 좁은 화면에서는 시각·거래처·항목을 접는다. 날짜·적요·금액·잔액은 남긴다 —
   이 넷이 없으면 통장으로 읽을 수 없다. */
@media (max-width: 1100px) {
  .txt-row { grid-template-columns: 78px 88px minmax(120px,240px) 88px 88px 96px minmax(150px,1fr); }
  .tx-table.nobal .txt-row {
    grid-template-columns: 78px 88px minmax(120px,240px) 88px 88px minmax(150px,1fr);
  }
  .txt-time, .txt-cl, .txt-catcell { display:none; }
}
/* 폭이 더 좁아지면 단추를 아래 줄로 내린다. 예전에는 단추 칸을 아예 감췄는데,
   그러면 휴대폰에서 거래아님·특이사항을 쓸 수 없다. */
@media (max-width: 720px) {
  .txt-row { grid-template-columns: 70px minmax(90px,1fr) 78px 78px 86px; gap:7px;
    font-size:12px; padding:7px 6px; }
  .tx-table.nobal .txt-row { grid-template-columns: 70px minmax(90px,1fr) 78px 78px; }
  .txt-acct { display:none; }
  .txt-act { grid-column:1/-1; justify-content:flex-start; margin-top:4px; }
}

/* 단가표를 아직 못 불러왔을 때 견적 화면에 띄우는 안내 (2026-09-21)
   단가표를 서버로 옮기면서, 화면이 뜬 직후에는 표가 비어 있는 순간이 생겼다.
   그때 계산하면 0원이 나오는데 왜 0인지 알 수 없으면 그대로 견적서가 나간다. */
.qc-missing { font-size:13px; line-height:1.7; color:var(--text-soft);
  background:rgba(198,120,20,.12); border:1px solid var(--warning);
  border-radius:8px; padding:11px 14px; margin-bottom:14px; }
.qc-missing b { color:var(--warning); }


/* 고객 「고치기」 — 새 창을 띄우지 않고 그 줄 바로 아래에 편다 */
.client-edit-row > td { background:var(--accent-soft); padding:12px 14px !important; }
.cedit { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:9px 14px; }
.cedit label { display:flex; flex-direction:column; gap:3px; font-size:12px; color:var(--text-faint); }
.cedit label input { font:inherit; font-size:13px; padding:6px 9px; border-radius:7px;
  border:1px solid var(--border); background:var(--surface); color:var(--text); }
.cedit-btns { grid-column:1 / -1; display:flex; gap:8px; margin-top:4px; }


/* 성과 보드 — 언제 센 숫자인지 밝히는 줄 */
.mp-asof { font-size:13px; line-height:1.8; color:var(--text-soft);
  border:1px solid var(--border); border-radius:10px; padding:11px 14px;
  margin:-4px 0 16px; background:var(--surface-2); }
.mp-asof b { color:var(--text); }
.mp-asof.old { border-color:var(--warning); background:rgba(198,120,20,.07); }
.mp-asof.old b { color:var(--warning); }


/* 장부를 얼마나 받아 와 있는지 알리는 줄 */
.ledger-scope { display:flex; flex-wrap:wrap; align-items:center; gap:8px 14px;
  border:1px solid var(--border); border-radius:10px; padding:11px 14px;
  margin-bottom:14px; background:var(--surface-2); font-size:13px; line-height:1.7; }
.ledger-scope .ls-t { flex:1; min-width:220px; color:var(--text-soft); }
.ledger-scope .ls-t b { color:var(--text); }
.ledger-scope .ls-t.err { color:var(--danger); }
.ledger-scope .ls-btn { font:inherit; font-size:12px; font-weight:600; padding:5px 13px;
  border-radius:20px; cursor:pointer; border:1px solid var(--accent);
  background:var(--accent-soft); color:var(--accent-strong); white-space:nowrap; }
.ledger-scope .ls-btn.ghost { border-color:var(--border); background:var(--surface);
  color:var(--text-faint); }
.ledger-scope .ls-btn:hover { filter:brightness(1.05); }
.ledger-scope .ls-btn[disabled] { opacity:.5; cursor:default; }

/* ── 금액은 눌러야 펴진다 ──
   직원 관리·급여 지급 이력에서 한 줄을 누르면 그 줄 바로 아래에 펴지는 칸.
   새 창을 띄우지 않고 그 자리에서 보여 주기로 했다. */
.roster-money > td { background: #f7f8fa; border-top: 0; }
.rm-grid {
  display: grid; gap: 8px 22px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  padding: 10px 4px;
}
.rm-grid > div { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.rm-grid .l { color: #777; font-size: 12px; }
.rm-grid b { font-variant-numeric: tabular-nums; }
.rm-grid b.danger { color: #c0392b; }
.rm-grid b.success { color: #1a7f4b; }


/* ── 통장·카드 거래 내역 탭 ──
   통장·카드마다 펴 보던 것을 탭 하나로 갈아 끼우게 바꿨다. 넷을 다 보려고
   넷을 다 펴면 화면이 세로로 길어져 무엇을 보고 있는지 놓친다. */
.bc-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.bc-tab {
  border: 1px solid var(--line, #e3e5e9); background: transparent;
  color: var(--text-soft, #667); border-radius: 999px;
  padding: 6px 13px; font-size: 13px; cursor: pointer; line-height: 1.3;
  display: inline-flex; align-items: center; gap: 6px;
}
.bc-tab:hover { border-color: var(--text-faint, #99a); }
.bc-tab.on {
  background: var(--accent-soft, #eef4ff); border-color: var(--accent, #2557c7);
  color: var(--accent, #2557c7); font-weight: 600;
}
.bc-tab .c { font-size: 12px; opacity: .65; font-variant-numeric: tabular-nums; }
.bc-tab.on .c { opacity: .85; }
#bcTxPanel .bc-t .mt {
  color: var(--text-faint, #99a); font-size: 12px;
  min-width: 68px; text-align: right;
}
#bcTxPanel .bc-tx-rows { max-height: 520px; overflow-y: auto; }

/* 고정지출 가운데 금액이 달마다 바뀌는 줄 — 목록에는 있고 합계에서만 뺀다.
   감추면 「납입일」에서 고치려고 눌렀을 때 갈 자리가 없어진다(2026-09-27). */
#fixedExpTable tr.fx-var td { opacity: .78; }
#fixedExpTable .fx-tag { font-size: 12px; padding: 1px 7px; border-radius: 20px;
  border: 1px solid var(--border); color: var(--text-faint); white-space: nowrap;
  margin-left: 5px; }

/* 거래 내역 줄의 「견적 잇기」 — 입금 줄에만 붙는다(2026-09-27). */
.tx-link { border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  border-radius: 7px; padding: 3px 9px; font-size: 12px; cursor: pointer;
  font-family: inherit; white-space: nowrap; }
.tx-link:hover { border-color: var(--success); color: var(--success); }
/* 「견적 ✓」는 글자만 있어서 옆 단추에 달라붙어 겹쳐 보였다(2026-09-27 지적).
   단추와 같은 모양의 칩으로 만들어 사이가 벌어지게 한다. */
.tx-linked { font-size: 12px; color: var(--success); white-space: nowrap;
  display: inline-flex; align-items: center; padding: 3px 8px; border-radius: 7px;
  border: 1px solid var(--success); background: var(--success-soft); font-weight: 600; }

/* 국세·미수금 — 자료가 비어서 숫자를 믿을 수 없을 때 밝히는 알림 (2026-10-06) */
.td-empty-note, .rc-empty-note {
  margin: 0 0 14px; padding: 12px 14px;
  border: 1px solid var(--warn, #8A5A00); border-left-width: 4px;
  border-radius: 6px; background: var(--warn-soft, rgba(138,90,0,.08));
  font-size: 14px; line-height: 1.65; color: var(--text, inherit);
}
.td-empty-note b, .rc-empty-note b { font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════
   휴대폰에서 쓸 수 있게 — 2026-10-06
   ══════════════════════════════════════════════════════════════════
   점검에서 나온 것 —
     · 44px 터치 기준을 통과하는 요소가 0개, 누르는 요소에 최소 높이 지정 0건
     · 모바일 유일 진입점인 메뉴 단추가 32px
     · 입력칸이 12~13px 이라 iOS 가 포커스마다 화면을 확대한다(16px 미만이면 확대)
     · 표가 20열·18열인데 가로 스크롤 처리가 없어 화면 밖으로 밀려난다
   아래는 **휴대폰 폭에서만** 걸린다. 데스크톱의 촘촘한 표는 그대로 둔다.
   ────────────────────────────────────────────────────────────────── */

/* 표를 감싸는 칸 — mobile-fit.js 가 모든 <table> 을 이것으로 감싼다.
   표만 따로 가로로 넘기고, 페이지 본문은 좌우로 흔들리지 않게 한다. */
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.tbl-scroll > table { min-width: max-content; }

@media (max-width: 860px) {
  /* ① 손가락이 닿는 크기 — 애플·구글 둘 다 최소 44px 를 권한다 */
  button, .btn, .icon-btn, .icon-btn-text, .primary-btn, .seg-btn,
  .nav-item, .nav-subitem, .nav-subgroup, .chip, .wc-chip, .pd-b,
  a.icon-btn-text, [role="tab"], select, input[type="button"], input[type="submit"] {
    min-height: 44px;
  }
  /* 아주 작은 아이콘 단추는 정사각으로 */
  .icon-btn { min-width: 44px; width: 44px; height: 44px; }
  /* 표 안의 작은 단추는 44px 를 강제하면 줄이 지나치게 높아진다 — 40px 로 둔다 */
  table .icon-btn-text, table button { min-height: 40px; }

  /* ② iOS 가 포커스마다 확대하지 않게 — 16px 미만이면 확대한다.
        이 확대는 되돌려지지 않아서, 한 칸만 눌러도 화면 전체가 커진 채로 남는다.
        maximum-scale 로 막는 방법은 손가락 확대까지 못하게 만들어서 쓰지 않는다. */
  input, select, textarea,
  .pricing-row-input, .search-box input, .cedit label input, .pi {
    font-size: 16px;
  }
  input, select, textarea { min-height: 44px; }
  textarea { min-height: 88px; }

  /* ③ 표 — 가로로만 넘기고 페이지는 흔들리지 않게 */
  .tbl-scroll { margin-inline: calc(var(--pad-x, 0px) * -1); }
  table { font-size: 13px; }
  th, td { white-space: nowrap; }
  /* 긴 글이 들어가는 칸은 줄바꿈을 허용한다 */
  td.wrap, th.wrap, .tx-desc, .wc-card .ti, .nt .b { white-space: normal; }

  /* ④ 본문이 좌우로 넘치지 않게 — 가로 스크롤은 표·보드·코드만 가진다 */
  body { overflow-x: hidden; }
  img, svg, canvas { max-width: 100%; }
}

/* 큰 화면에서도 아이콘 단추가 32px 면 마우스로도 작다 — 36px 로 올린다 */
@media (min-width: 861px) {
  .icon-btn { width: 36px; height: 36px; }
}

/* 움직임을 줄여 달라고 설정한 사람에게는 애니메이션을 끈다 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important; scroll-behavior: auto !important;
  }
}

/* 키보드로 다닐 때 어디 있는지 보이게 — 접근성 기본 */
:focus-visible { outline: 2px solid var(--accent-strong, #161615); outline-offset: 2px; }


/* ============================================================================
   2026-10-06 — granter.biz 의 디자인 언어로 겉모습을 바꾼다 (①토큰)

   왜 맨 끝에 붙이는가.
     이 파일에는 같은 모양의 `:root` 토큰 블록이 **두 벌**(17/58/83행, 1149/1171/1181행)
     들어 있고, 특이성이 같으므로 **뒤에 오는 것이 이긴다.** 앞쪽만 고치면 화면이
     하나도 안 바뀐다(1156행에 그 경고가 이미 적혀 있다). 두 벌을 합치는 일은 화면
     전체를 다시 확인해야 하는 별도 작업이라, 지금은 **맨 끝에서 한 번에 덮는다.**
     되돌릴 때는 이 블록부터 아래를 통째로 지우면 된다.
     `body` 선언도 두 벌(113행/1193행)이고 뒤의 것이 글꼴을 되돌리므로 여기서 다시 쓴다.

   무엇이 바뀌나 (출처: granter.biz 의 컴파일된 CSS 에서 받아낸 값).
     · 바탕이 크림색(#F3F3EF) → 순백(#FFFFFF)
     · 강조색이 없다. 강조는 검정(#171717) 하나다
     · 그림자를 쓰지 않는다. 깊이는 1px 선으로만 만든다
     · 호버는 색이 아니라 opacity, 전환은 200ms cubic-bezier(.23,1,.32,1)
     · UI 글자는 14px 하나, 굵기는 400/500/600 세 단계뿐

   granter 와 **일부러 다르게 둔 것** — 전부 읽히라고 바꾼 것이다.
     · 보조 글자  #737373 → #6B6B6B   (회색 바탕 위 4.35:1 로 미달 → 4.89:1)
     · 조작 요소 테두리 #E5E5E5 → #949494 (WCAG 1.4.11 비텍스트 3:1).
       표 줄·카드 테두리는 장식이라 granter 원값 #E5E5E5 그대로 둔다
     · 포커스 링 #A1A1A1 50% → rgba(23,23,23,.4)  (2.58:1 로 미달)
     · 조작 요소 높이 40/36/32px → 44px. 둥글기·패딩·글자·색은 granter 값 그대로라
       인상은 거의 남는다. 보기 좋자고 못 누르게 만들지 않는다
     · 입력 글자 16px 고정 (iOS 가 16px 미만 입력에 자동 확대를 건다)
   ========================================================================= */

/* ── 1. 라이트 (기준) ──
   granter 는 홈(/)만 다크 고정이고 제품·기능·요금제 페이지는 전부 라이트다.
   따라서 라이트가 이 디자인의 본체다. */
:root {
  /* 바탕과 면 */
  --bg:               #FFFFFF;   /* G --background */
  --surface:          #FFFFFF;   /* G --card — bg 와 같은 흰색. 카드는 테두리로만 구분한다 */
  --surface-2:        #F5F5F5;   /* G --muted */

  /* 잉크 */
  --ink:              #171717;   /* G --primary — 주 버튼 바탕 */
  --ink-2:            #262626;   /* G neutral-800 */

  /* 글자 */
  --text:             #0A0A0A;   /* G --foreground.  on #fff = 19.80:1 */
  /* ★ 보조 글자는 회색 '한 단계'뿐이다 — granter 도 --muted-foreground 하나로 쓴다
     (다크 토큰 주석에 '더 흐린 단계를 만들지 않는다'고 적혀 있다).
     그래서 --text-soft 와 --text-faint 를 같은 값으로 둔다. 이름은 둘 다 살려 둔다 —
     109KB 안에서 두 이름이 섞여 쓰이고 있어, 이름을 지우면 전부 고쳐야 한다.
     값은 #696969 다. granter 원값 #737373 은 회색 바탕(#F5F5F5) 위에서 4.35:1 로 미달이고,
     명세서가 권한 #6B6B6B/#757575 도 이 파일에 아직 남아 있는 옛 바탕(#EAEAE4)과
     새 바탕(#F5F5F5) 조합에서 각각 4.41:1 / 4.23:1 로 걸린다.
     #696969 는 이 파일에 있는 모든 바탕(#FFFFFF 5.49 · #F3F3EF 4.93 · #EAEAE4 4.55 ·
     #F5F5F5 5.04)에서 4.5:1 을 넘는다. granter 보다 10단계 진하지만 눈에 띄지 않는다. */
  --text-soft:        #696969;
  --text-faint:       #696969;

  /* 선 */
  --border:           #E5E5E5;   /* G --border — 장식용이라 원값 그대로 */
  --border-subtle:    #F1F1F1;   /* G --border-subtle */
  --control-border:   #949494;   /* 입력칸·셀렉트처럼 '조작하는 것'의 테두리. on #fff 3.03:1 */

  /* 강조 — granter 의 강조는 색이 아니라 검정 하나다 */
  --accent:           #696969;
  --accent-strong:    #171717;   /* G --primary */
  --accent-soft:      #F5F5F5;   /* G --accent — 호버·활성 바탕 */
  --accent-contrast:  #FAFAFA;   /* G --primary-foreground. 검정 위 17.18:1 */

  /* 의미색 — granter 는 Tailwind 100 바탕 + 700 글자 짝을 쓴다 */
  --success:          #007956;   /* emerald-700. on #fff 4.60:1 */
  --success-soft:     #D0FAE5;   /* emerald-100 */
  --success-ink:      #007956;   /* on --success-soft 4.78:1 */
  --warning:          #B75000;   /* amber-700 */
  --warning-soft:     #FEF3C6;   /* amber-100 */
  --warning-ink:      #B75000;   /* on --warning-soft 4.53:1 */
  --danger:           #E40014;   /* G --destructive. on #fff 4.87:1 */
  --danger-soft:      #FFE4E6;   /* rose-100 */
  --danger-ink:       #C20039;   /* rose-700. on --danger-soft 5.22:1 */
  --info:             #0069A4;   /* sky-700. on #fff 5.90:1 */
  --info-soft:        #DFF2FE;   /* sky-100 */
  --info-ink:         #0069A4;   /* on --info-soft 5.14:1 */

  /* 브랜드색 — 아주 드물게만. #00A5EF 는 흰 바탕 2.75:1 이라 글자로 쓰지 않는다 */
  --brand:            #00A5EF;   /* 그래픽 전용 */
  --brand-strong:     #0069A4;   /* 글자로 써야 할 때 */

  /* 그림자 — ★ granter 는 그림자를 쓰지 않는다. '아주 얇은 테두리'로 대체한다 */
  --shadow:           0 0 0 0.5px rgba(0,0,0,0.12);
  --shadow-float:     0 0 0 1px rgba(10,10,10,0.10),
                      0 1px 3px 0 rgba(10,10,10,0.07),
                      0 8px 20px -8px rgba(10,10,10,0.16),
                      0 24px 48px -24px rgba(10,10,10,0.20);   /* 모달에만 */

  /* 포커스 링 */
  --ring:             #171717;
  --ring-shadow:      0 0 0 3px rgba(23,23,23,0.40);
  --selection-bg:     rgba(0,165,239,0.28);
}

/* ── 2. 다크 — OS 설정을 따를 때 ── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:               #0A0A0A;
    --surface:          #171717;   /* ★ 다크에서는 카드가 배경보다 밝다 (라이트와 반대) */
    --surface-2:        #262626;
    --ink:              #E5E5E5;   /* ★ 다크의 주 버튼은 밝은 바탕 + 어두운 글자 */
    --ink-2:            #333333;
    --text:             #FAFAFA;   /* on #0A0A0A 18.97:1 */
    --text-soft:        #A1A1A1;   /* on #262626 5.86:1 */
    --text-faint:       #A1A1A1;
    --border:           rgba(255,255,255,0.10);
    --border-subtle:    #1F1F1F;
    --control-border:   #646464;   /* on #171717 3.03:1 */
    --accent:           #A1A1A1;
    --accent-strong:    #FAFAFA;
    --accent-soft:      #262626;
    --accent-contrast:  #171717;
    --success:          #00D294;  --success-soft: rgba(0,187,127,0.15);  --success-ink: #00D294;
    --warning:          #FFD236;  --warning-soft: rgba(252,187,0,0.15);  --warning-ink: #FFD236;
    --danger:           #FF6568;  --danger-soft:  rgba(255,101,104,0.15); --danger-ink:  #FF6568;
    --info:             #77D4FF;  --info-soft:    rgba(0,188,254,0.12);   --info-ink:    #77D4FF;
    --brand:            #00A5EF;  --brand-strong: #77D4FF;
    --shadow:           0 0 0 1px rgba(255,255,255,0.10);
    --shadow-float:     0 0 0 1px rgba(255,255,255,0.10);
    --ring:             #FAFAFA;
    --ring-shadow:      0 0 0 3px rgba(250,250,250,0.40);
  }
}

/* ── 3. 다크 — 사용자가 직접 고른 경우 ──
   (위 @media 와 값이 같아야 한다. 하나만 넣으면 1181행이 이긴다) */
:root[data-theme="dark"] {
  --bg:               #0A0A0A;
  --surface:          #171717;
  --surface-2:        #262626;
  --ink:              #E5E5E5;
  --ink-2:            #333333;
  --text:             #FAFAFA;
  --text-soft:        #A1A1A1;
  --text-faint:       #A1A1A1;
  --border:           rgba(255,255,255,0.10);
  --border-subtle:    #1F1F1F;
  --control-border:   #646464;
  --accent:           #A1A1A1;
  --accent-strong:    #FAFAFA;
  --accent-soft:      #262626;
  --accent-contrast:  #171717;
  --success:          #00D294;  --success-soft: rgba(0,187,127,0.15);  --success-ink: #00D294;
  --warning:          #FFD236;  --warning-soft: rgba(252,187,0,0.15);  --warning-ink: #FFD236;
  --danger:           #FF6568;  --danger-soft:  rgba(255,101,104,0.15); --danger-ink:  #FF6568;
  --info:             #77D4FF;  --info-soft:    rgba(0,188,254,0.12);   --info-ink:    #77D4FF;
  --brand:            #00A5EF;  --brand-strong: #77D4FF;
  --shadow:           0 0 0 1px rgba(255,255,255,0.10);
  --shadow-float:     0 0 0 1px rgba(255,255,255,0.10);
  --ring:             #FAFAFA;
  --ring-shadow:      0 0 0 3px rgba(250,250,250,0.40);
}

/* ── 4. 테마와 무관한 토큰 — 모양·치수·움직임 ── */
:root {
  /* 둥글기 — G 는 --radius 하나에서 전부 파생한다 */
  --radius:        10px;   /* 우리 기존값 9px → 10px */
  --radius-sm:      6px;
  --radius-md:      8px;   /* 사이드바 항목, 칩 */
  --radius-lg:     10px;   /* 버튼, 셀렉트 */
  --radius-xl:     14px;   /* 카드, 위젯 */
  --radius-2xl:    16px;
  --radius-full: 9999px;

  /* 간격 — G 는 4px 배수 */
  --sp-0_5:  2px;  --sp-1:   4px;  --sp-1_5:  6px;  --sp-2:   8px;
  --sp-2_5: 10px;  --sp-3:  12px;  --sp-4:   16px;  --sp-5:  20px;
  --sp-6:   24px;  --sp-8:  32px;  --sp-10:  40px;  --sp-12: 48px;
  --sp-16:  64px;  --sp-20: 80px;  --sp-24:  96px;  --sp-28: 112px;

  /* 레이아웃 */
  --container-max:   1280px;
  --content-max:     1200px;
  --prose-max:        672px;
  --gutter:            20px;
  --gutter-sm:         32px;
  --gutter-lg:         40px;
  --sidebar-w:        232px;   /* G 231px 내용 + 1px 오른쪽 선 */
  --topbar-h:          64px;

  /* 글자 크기 — ★ G 는 UI 글자를 14px 하나로 통일한다.
     10.5 / 11.5 / 12.5 같은 미세한 중간값을 쓰지 않는다. */
  --fs-2xs:   12px;   /* 기존 10px → 12px (G 는 12px 밑으로 안 내려간다) */
  --fs-xs:    12px;
  --fs-sm:    13px;
  --fs-base:  14px;   /* ★ UI 기본 — 사이드바·표·상단바 전부 이것 */
  --fs-md:    15px;
  --fs-lg:    16px;   /* 버튼 글자, 입력 글자 */
  --fs-xl:    18px;
  --fs-2xl:   24px;
  --fs-3xl:   30px;
  --fs-4xl:   36px;
  --fs-5xl:   48px;

  /* 줄간격 */
  --lh-tight:  1.25;
  --lh-snug:   1.375;
  --lh-body:   1.5;
  --lh-ui:     1.4286;   /* 14px → 20px */
  --lh-prose:  1.8;

  /* 자간 — 큰 글자일수록 더 조인다 */
  --ls-tight:    -0.01em;
  --ls-tighter:  -0.02em;
  --ls-title:    -0.026em;
  --ls-display:  -0.032em;
  --ls-hero:     -0.035em;
  --ls-label:     0.05em;   /* 기존 유지 — G 는 라벨 자간을 벌리지 않는다 */

  /* 굵기 — ★ G 는 400/500/600 세 단계만 쓴다. 700/800 없음 */
  --fw-normal:   400;
  --fw-medium:   500;
  --fw-semibold: 600;

  /* 움직임 */
  --ease:              cubic-bezier(.4, 0, .2, 1);
  --ease-out:          cubic-bezier(0, 0, .2, 1);
  --ease-out-strong:   cubic-bezier(.23, 1, .32, 1);   /* ★ UI 전환은 거의 전부 이것 */
  --ease-in-out-strong:cubic-bezier(.77, 0, .175, 1);
  --ease-spring:       cubic-bezier(.34, 1.56, .64, 1);
  --dur-fast:   150ms;
  --dur:        200ms;
  --dur-slow:   300ms;

  /* 조작 요소 최소 크기 — G 원값은 40/36/32px 이지만 우리 기준(터치 44px)에 미달이다 */
  --control-h:      44px;
  --control-h-sm:   36px;   /* 마우스 전용 조밀 화면에서만 */
  --control-px:     16px;
  --control-fs:     16px;
  --nav-item-h:     44px;
  --table-head-h:   32px;
  --table-cell-px:   8px;
}

/* ── 5. 본문 기본값 ──
   body 선언이 두 벌(113행/1193행)이고 뒤의 것이 글꼴을 Noto Sans KR 로 되돌린다.
   여기서 한 번 더 덮어야 글꼴이 실제로 바뀐다. */
body {
  background: var(--bg);
  color: var(--text);
  font-family: "Pretendard Variable", Pretendard,
               -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: var(--fs-base);          /* 14px */
  font-weight: var(--fw-normal);
  line-height: var(--lh-ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  word-break: keep-all;               /* 한글 단어 중간에서 줄이 안 끊기게 */
  overflow-wrap: break-word;
  min-width: 320px;
}
html { background: var(--bg); }
::selection { background: var(--selection-bg); }

/* 제목 굵기를 600 으로 낮춘다 — G 는 700/800 을 전혀 쓰지 않는다(제목조차 600).
   인쇄 문서(.dp-title 등)는 자기 굵기를 따로 들고 있어 영향받지 않는다. */
h1, h2, h3 { font-weight: var(--fw-semibold); letter-spacing: var(--ls-tighter); }

/* 숫자는 자릿수가 세로로 맞게 */
.num, .amount, [data-num] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* 포커스 — G 의 '3px 번짐' 모양. 색만 진하게 바꿨다(#A1A1A1 50% 는 2.58:1 로 미달) */
:where(button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid transparent;    /* 고대비 모드에서도 보이게 */
  outline-offset: 2px;
  border-color: var(--ring);
  box-shadow: var(--ring-shadow);
}
:where(a):focus-visible { outline: 2px solid var(--ring); outline-offset: 4px; }

/* 스크롤바 — 마우스를 올리기 전에는 보이지 않는다 (G .slim-scrollbar) */
.slim-scrollbar { scrollbar-width: thin; scrollbar-color: transparent transparent; }
.slim-scrollbar::-webkit-scrollbar { width: 8px; height: 8px; }
.slim-scrollbar::-webkit-scrollbar-track { background: transparent; }
.slim-scrollbar::-webkit-scrollbar-thumb {
  background-color: transparent; background-clip: content-box;
  border: 2px solid transparent; border-radius: var(--radius-full);
  transition: background-color .18s var(--ease-out-strong);
}
.slim-scrollbar:hover::-webkit-scrollbar-thumb { background-color: rgba(10,10,10,0.28); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; animation-iteration-count: 1 !important;
      transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ============================================================================
   2026-10-06 — granter (②사이드바 안쪽에 JS 가 심는 조각들)

   notify.js 가 만드는 알림 단추는 `<style>` 을 **head 맨 뒤에** 꽂는다. 그래서
   같은 특이성이면 styles.css 가 아니라 그쪽이 이긴다. 한 단계 더 좁혀서 덮는다.
   (사이드바가 흰색이 되어 rgba(255,255,255,.06) 계열 색이 전부 보이지 않게 됐다)
   ========================================================================= */
.sidebar #seinBell { margin: 0 8px 12px; }
.sidebar #seinBell .bell {
  min-height: 44px;                                  /* 터치 기준 — G 원값은 36px */
  padding: 0 11px; gap: 8px;
  border-radius: var(--radius-lg, 10px);
  font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500);
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-soft); box-shadow: none;
  transition: background-color var(--dur) var(--ease-out-strong),
              border-color var(--dur) var(--ease-out-strong),
              color var(--dur) var(--ease-out-strong),
              opacity var(--dur) var(--ease-out-strong);
}
.sidebar #seinBell .bell:hover { background: var(--accent-soft); color: var(--text); }
.sidebar #seinBell .bell svg { width: 16px; height: 16px; }
/* 읽지 않은 것이 있을 때 — G 의 의미색 짝(100 바탕 + 700 글자)으로 */
.sidebar #seinBell .bell.has {
  background: var(--danger-soft); border-color: var(--danger-soft); color: var(--danger-ink);
}
.sidebar #seinBell .bell.has svg { color: var(--danger-ink); }
.sidebar #seinBell .cnt { font-weight: var(--fw-semibold, 600); background: var(--danger); color: #fff; }

/* ============================================================================
   2026-10-06 — granter (③단추·입력칸·셀렉트)

   G 의 규격 그대로 두는 것 : 둥글기(버튼/셀렉트 10px) · 패딩(좌우 16px) ·
     글자(버튼 16px) · 색(주 단추는 검정 #171717 바탕 + 흰 글자) ·
     그림자 없음 · 호버는 색이 아니라 opacity .7 · 전환 200ms cubic-bezier(.23,1,.32,1)
   우리가 다르게 두는 것 :
     · 높이 40px → 44px (터치 기준). 높이만 올리면 인상은 거의 남는다
     · 입력 글자 16px 고정 (iOS 가 16px 미만 입력에 포커스 확대를 걸고, 되돌려지지 않는다)
     · **입력칸·셀렉트의 테두리만** #949494(3.03:1). 빈 네모는 테두리가 있어야 그것이
       입력칸인 줄 알 수 있어서 WCAG 1.4.11 의 3:1 대상이다.
       반대로 **글자가 적힌 보조 단추의 테두리는 장식**이라 G 원값 #E5E5E5 를 지킨다 —
       그래야 화면이 G 처럼 얇게 남는다.
   ========================================================================= */

/* ── 공통 — 눌리는 것의 손맛 ── */
button, .btn, .primary-btn, .icon-btn, .icon-btn-text, .seg-btn, .chip, [role="tab"] {
  transition: background-color var(--dur) var(--ease-out-strong),
              border-color var(--dur) var(--ease-out-strong),
              color var(--dur) var(--ease-out-strong),
              box-shadow var(--dur) var(--ease-out-strong),
              opacity var(--dur) var(--ease-out-strong);
}

/* ── 주 단추 — G 의 유일한 강조. 검정 바탕 + 흰 글자, 호버는 투명도 ── */
.primary-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--control-h, 44px); padding: 0 var(--control-px, 16px);
  background: var(--accent-strong); color: var(--accent-contrast);
  border: none; border-radius: var(--radius-lg, 10px);
  font-size: var(--control-fs, 16px); line-height: 1.5; font-weight: var(--fw-medium, 500);
  white-space: nowrap; box-shadow: none;
}
.primary-btn:hover { opacity: .7; }
.primary-btn:disabled, .primary-btn[disabled] { opacity: .5; pointer-events: none; }
.primary-btn svg { width: 16px; height: 16px; flex: none; }
/* 보조(테두리형) — 흰 바탕 + 1px 선, 호버는 연한 회색 바탕 */
.primary-btn.secondary {
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
}
.primary-btn.secondary:hover { background: var(--accent-soft); opacity: 1; }
.primary-btn.saved { background: var(--success); }
/* 작은 변형 — 표 안에서 줄이 지나치게 높아지지 않게 마우스 화면에서만 36px.
   휴대폰 폭에서는 위쪽 `@media (max-width:860px)` 규칙이 44px 로 되돌린다. */
.primary-btn.sm { min-height: var(--control-h-sm, 36px); padding: 0 12px; font-size: var(--fs-base, 14px); }

/* ── 아이콘 단추 — G 는 36×36 이지만 손가락 기준으로 44×44 ── */
.icon-btn {
  width: var(--control-h, 44px); height: var(--control-h, 44px); min-width: var(--control-h, 44px);
  border-radius: var(--radius-md, 8px); border: 1px solid var(--border);
  background: var(--surface); color: var(--text-soft); box-shadow: none;
}
.icon-btn:hover { background: var(--accent-soft); color: var(--text); }

/* ── 글자 달린 작은 단추 — 표 안에 많이 쓰여 36px 로 둔다(휴대폰에서는 위 규칙이 44px) ── */
.icon-btn-text {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: var(--control-h-sm, 36px); padding: 0 12px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  border-radius: var(--radius-md, 8px);
  font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500); font-family: inherit;
  box-shadow: none;
}
.icon-btn-text:hover { background: var(--accent-soft); color: var(--text); border-color: var(--border); }
.icon-btn-text.danger-text { color: var(--danger); border-color: var(--border); }
.icon-btn-text.danger-text:hover { background: var(--danger-soft); border-color: var(--danger-soft); color: var(--danger-ink); }

/* ── 분절 단추 — 선택은 색이 아니라 연한 회색 바탕 + 굵기 500 (사이드바 활성과 같은 규칙) ── */
.seg { border-radius: var(--radius-lg, 10px); }
.seg-btn {
  min-height: var(--control-h-sm, 36px); padding: 0 12px;
  font-size: var(--fs-base, 14px); font-weight: var(--fw-normal, 400);
  color: var(--text-soft); background: var(--surface);
}
.seg-btn.active { background: var(--accent-soft); color: var(--text); font-weight: var(--fw-medium, 500); }

/* ── 입력칸·셀렉트·여러 줄 입력 ──
   G 의 공개 페이지에는 일반 폼 입력이 없다(번들에 컴포넌트 자체가 빠져 있었다).
   그래서 아래는 G 의 토큰(둥글기 10px · 전환 · 포커스 링 모양)에서 끌어낸 값이고,
   높이 44px·글자 16px·테두리 #949494 는 우리 접근성 기준에서 정한 값이다. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="submit"]):not([type="button"]),
select, textarea,
.field-row input, .field-row select, .field-row textarea,
.qc-5col input, .qc-5col select, .qc-4col input, .qc-4col select,
.pricing-panel .pricing-row-input {
  font-family: inherit;
  font-size: var(--control-fs, 16px); line-height: 1.5;
  min-height: var(--control-h, 44px); padding: 8px 12px;
  border: 1px solid var(--control-border); border-radius: var(--radius-lg, 10px);
  background: var(--bg); color: var(--text);
  box-shadow: none;
  transition: border-color var(--dur) var(--ease-out-strong),
              box-shadow var(--dur) var(--ease-out-strong),
              color var(--dur) var(--ease-out-strong);
}
textarea { min-height: 88px; line-height: 1.6; resize: vertical; }
::placeholder { color: var(--text-soft); opacity: 1; }
.field-row input[readonly], .pricing-row-input[readonly], .pricing-row-input:disabled,
input:disabled, select:disabled, textarea:disabled {
  background: var(--surface-2); color: var(--text-soft); border-color: var(--border);
}
/* 칸 이름 — G 는 라벨을 꾸미지 않는다. 14px 회색, 대문자 변환도 자간 벌림도 없다 */
.field-row label, .qc-5col label, .qc-4col label {
  font-size: var(--fs-base, 14px); line-height: var(--lh-ui);
  font-weight: var(--fw-normal, 400); color: var(--text-soft); letter-spacing: 0;
}

/* 작은 조작 단추들도 같은 모양으로 */
.qc-extra-remove { width: var(--control-h-sm, 36px); height: var(--control-h-sm, 36px);
  border-radius: var(--radius-md, 8px); border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); }
.qc-add-extra { min-height: var(--control-h-sm, 36px); border-radius: var(--radius-md, 8px);
  border: 1px dashed var(--border); color: var(--text-soft); font-size: var(--fs-base, 14px); }

/* ============================================================================
   2026-10-06 — granter (④표)

   G 는 <table> 을 안 쓰고 CSS Grid 로 표를 만들지만, 겉모양 규칙은 그대로 옮길 수 있다.
     · 머리글 : 바탕 없음(투명). 글자 14px/22 weight 500, 색 muted. 대문자 변환 안 함
     · 가로선만. **세로선이 없다**
     · 셀 좌우 패딩 8px, 본문 14px
     · 행 호버는 연한 회색 바탕(--accent-soft)
     · 금액은 오른쪽 정렬 + tabular-nums + weight 500, 색은 본문색 (⑥에서 이어서)
   인쇄 문서(.dp-table / .stmt-table)는 공문서 조판을 따로 쓰므로 건드리지 않는다.
   ========================================================================= */
table.simple, table.clients, table:not([class]) {
  width: 100%; border-collapse: collapse;
  font-size: var(--fs-base, 14px); line-height: var(--lh-ui);
}
table.simple th, table.clients th, table:not([class]) th {
  text-align: left;
  background: transparent;                       /* G — 머리글에 바탕을 깔지 않는다 */
  color: var(--text-soft);
  font-size: var(--fs-base, 14px); line-height: 22px; font-weight: var(--fw-medium, 500);
  letter-spacing: 0; text-transform: none;
  height: var(--table-head-h, 32px);
  padding: 4px var(--table-cell-px, 8px);
  border-bottom: 1px solid var(--border);
  border-left: none; border-right: none;         /* 세로선 없음 */
}
table.simple td, table.clients td, table:not([class]) td {
  padding: 10px var(--table-cell-px, 8px);
  border-bottom: 1px solid var(--border);
  border-left: none; border-right: none;
  font-size: var(--fs-base, 14px); line-height: var(--lh-ui);
  vertical-align: top;
}
table.simple tr:last-child td, table:not([class]) tr:last-child td { border-bottom: none; }
/* 행 호버 — 색이 아니라 연한 회색 한 겹 */
table.simple tbody tr:hover > td,
table.clients tr:hover td,
table:not([class]) tbody tr:hover > td { background: var(--accent-soft); }
/* 머리글을 화면에 붙여 둘 때도 바탕은 페이지 색 그대로 (G 는 --background 를 쓴다) */
table.clients th, .pricing-panel table.simple thead th { background: var(--surface); box-shadow: none; }
/* 숫자가 들어가는 칸 — 자릿수가 세로로 맞고 오른쪽에 붙는다 */
table.simple td.num, table.simple th.num,
table.clients td.num, table.clients th.num,
td.amt, th.amt, td.money, th.money {
  text-align: right; font-variant-numeric: tabular-nums;
}
table.simple td.num, table.clients td.num, td.amt, td.money { font-weight: var(--fw-medium, 500); }

/* ============================================================================
   2026-10-06 — granter (⑤카드·패널·탭·배지)

   · 카드는 **1px 선 하나로만** 구분한다. 그림자를 쓰지 않는다(G 의 핵심 ①).
     둥글기는 14px(--radius-xl). 큰 패널은 16px.
   · 탭은 알약이 아니라 **밑줄**이다. 선택은 색이 아니라 '본문색 + 2px 검은 밑줄'.
   · 배지·칩은 알약(9999px), 12~14px, 굵기 500. 700/800 을 쓰지 않는다.
   ========================================================================= */

/* ── 카드·패널 ── */
.kpi-card, .summary-card, .panel, .deal-card, .acct-card, .doc-summary-card,
.pricing-panel, .qc-final-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl, 14px);
  box-shadow: none;              /* ★ 깊이는 테두리 1px 로만 만든다 */
}
.panel { border-radius: var(--radius-2xl, 16px); padding: 20px 24px 24px; }
.kpi-card { padding: 16px; }
.summary-card { padding: 16px; }
.kpi-label { font-size: var(--fs-base, 14px); line-height: var(--lh-ui); color: var(--text-soft); }
.kpi-value { font-size: var(--fs-xl, 18px); line-height: 28px; font-weight: var(--fw-semibold, 600); letter-spacing: -0.01em; }
.kpi-note  { font-size: var(--fs-xs, 12px); color: var(--text-soft); }
.panel-head h2 { font-size: var(--fs-md, 15px); line-height: 24px; font-weight: var(--fw-semibold, 600); }
.summary-card-head h3 { font-size: var(--fs-md, 15px); line-height: 24px; font-weight: var(--fw-semibold, 600); }
.hint, .panel-head .hint { font-size: var(--fs-xs, 12px); line-height: var(--lh-snug); color: var(--text-soft); }
/* 떠 있는 것만 진짜 그림자를 쓴다 (G 의 .floating-surface) */
.cal-hover-preview { border-radius: var(--radius-xl, 14px); box-shadow: var(--shadow-float); }

/* 페이지 제목 — G 는 제목도 600 이 최대다. 대신 자간을 조인다 */
.topbar h1 { font-size: var(--fs-2xl, 24px); line-height: 1.3; font-weight: var(--fw-semibold, 600); letter-spacing: var(--ls-tighter); }
.topbar .sub { font-size: var(--fs-base, 14px); line-height: var(--lh-ui); color: var(--text-soft); }
.topbar .meta-pill {
  min-height: var(--control-h-sm, 36px); padding: 0 12px; border-radius: var(--radius-full);
  background: var(--surface); border: 1px solid var(--border);
  font-size: var(--fs-xs, 12px); color: var(--text-soft);
}

/* ── 탭 — 알약에서 밑줄로 ── */
.ai-tabs, .qc-tabs, .mail-tabs {
  gap: 16px; padding-bottom: 0; margin-bottom: 20px;
  border-bottom: 1px solid var(--border);
}
.ai-tab, .qc-tab, .mail-tab {
  min-height: var(--control-h, 44px); padding: 11px 4px;
  border: none; border-bottom: 2px solid transparent; border-radius: 0;
  background: transparent; color: var(--text-soft);
  font-size: var(--fs-base, 14px); line-height: 22px; font-weight: var(--fw-medium, 500);
  margin-bottom: -1px;
}
.ai-tab:hover, .qc-tab:hover, .mail-tab:hover { color: var(--text); background: transparent; }
.ai-tab.active, .qc-tab.active, .mail-tab.active {
  background: transparent; color: var(--text); border-color: transparent;
  border-bottom-color: var(--accent-strong);
}
.ai-tab-n, .qc-tab-n {
  font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500);
  color: var(--text-soft); border: 1px solid var(--border); background: transparent;
  width: auto; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-full);
}
.ai-tab.active .ai-tab-n, .qc-tab.active .qc-tab-n {
  background: var(--accent-soft); color: var(--text); border-color: var(--border);
}

/* 발행 법인 고르는 큰 탭 — 선택은 검정 하나 (G 의 강조는 검정뿐) */
.entity-tab { border-radius: var(--radius-xl, 14px); box-shadow: none; }
.entity-tab .et-label { font-size: var(--fs-lg, 16px); font-weight: var(--fw-medium, 500); letter-spacing: -0.01em; }
.entity-tab .et-sub { font-size: var(--fs-xs, 12px); letter-spacing: 0; color: var(--text-soft); }

/* ── 배지·칩 ── */
.pill {
  padding: 3px 8px; border-radius: var(--radius-full);
  font-size: var(--fs-xs, 12px); line-height: 18px; font-weight: var(--fw-medium, 500);
}
.pill.danger { background: var(--danger-soft); color: var(--danger-ink); }
.chip {
  min-height: var(--control-h-sm, 36px); padding: 0 13px; border-radius: var(--radius-full);
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  font-size: var(--fs-base, 14px); font-weight: var(--fw-normal, 400);
}
.chip:hover { background: var(--accent-soft); color: var(--text); }
.chip .n { color: var(--text-soft); font-weight: var(--fw-normal, 400); }
.chip.active { background: var(--accent-strong); color: var(--accent-contrast); border-color: var(--accent-strong); font-weight: var(--fw-medium, 500); }
.chip.active .n { color: rgba(255,255,255,0.72); }
.recent-clients .chip, .contact-chip {
  min-height: 0; padding: 4px 10px; font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500);
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
}
.src-tag { font-size: var(--fs-xs, 12px); font-weight: var(--fw-normal, 400); }

/* 알림 상자 — 테두리를 색이 아니라 같은 계열의 연한 면으로 */
.callout {
  border-radius: var(--radius-xl, 14px); border: 1px solid var(--warning-soft);
  background: var(--warning-soft); color: var(--warning-ink);
  font-size: var(--fs-base, 14px); line-height: var(--lh-snug);
}

/* ============================================================================
   2026-10-06 — granter (⑥돈에 색을 쓰지 않는다 · 굵기를 600 아래로)

   G 의 기능 페이지에서 금액을 전부 뽑아 보면 +1,092,000원 · -2,750,000원 ·
   -49,106,495원 이 **전부 같은 본문 검정**이다. 빨강=지출, 초록=수입 같은 관습을
   쓰지 않는다. 부호(+/-)와 tabular-nums 와 오른쪽 정렬로만 읽게 한다.
   회계 화면이 소란스러워지지 않는 가장 큰 까닭이 이것이다.

   ★ 왜 !important 를 쓰는가 ★
   이 색들의 상당수는 화면 코드(web/*.js)가 `<style>` 을 head **맨 뒤에** 꽂아서 넣는다.
   같은 특이성이면 뒤에 온 그쪽이 이기므로, 선택자를 아무리 길게 적어도 덮이지 않는다.
   화면 코드는 건드리지 않기로 한 작업이라 여기서 한 줄로 못 박는다.

   ※ 상태를 말하는 색(연체·미납 pill, 경고 상자 등)은 '돈의 방향'이 아니라
     '좋고 나쁨'이라서 그대로 둔다. 여기서 걷어내는 것은 수입/지출 구분색뿐이다.
   ========================================================================= */
.tx-amt.in, .tx-amt.out,
.kpi-value.success, .kpi-value.danger, .kpi-value.warning,
.sm-lead.is-pos .v, .sm-lead.is-neg .v, .sm-lead.is-warn .v,
.sm-sub.is-pos .v, .sm-sub.is-neg .v, .sm-sub.is-warn .v,
.bc-sum .in, .bc-sum .out, .bc-tx-head .in, .bc-tx-head .out,
#cpPanel .cp-fig .v, #cpPanel .amt,
.fp-line.in b, .fp-line.out b,
.lb-r .a.in, .lb-r .a.out, .lb-g .am.in, .lb-g .am.out,
.lc-i .am.in, .lc-i .am.out,
#wkBox .wk-sum .in b, #wkBox .wk-sum .out b, #wkBox .wk-d .v.in, #wkBox .wk-d .v.out {
  color: var(--text) !important;
  font-variant-numeric: tabular-nums;
}
/* 색을 깔던 자리도 조용한 회색으로 — 금액 뒤에 초록/빨강 면이 깔리지 않게 */
.sm-lead.is-pos, .sm-lead.is-neg, .sm-lead.is-warn {
  background: var(--surface-2); border-left-color: var(--border);
}

/* 지출에 부호를 붙인다.
   화면 코드는 수입에만 '+' 를 붙이고 지출에는 아무것도 안 붙인다. 색을 걷어내면
   둘을 가를 것이 없어지므로, 색 대신 **부호**가 그 일을 하게 한다(G 와 같은 방식).
   달력의 고정지출 줄은 이미 '-' 를 달고 나오므로 빼야 한다 — 그 줄에는 「고정」 pill 이
   함께 있어서 그것으로 가린다. `:has()` 를 모르는 브라우저에서는 규칙 전체가 버려져
   부호가 안 붙을 뿐, 부호가 두 번 찍히는 일은 없다. */
.tx-row:not(:has(.pill)) .tx-amt.out::before { content: "-"; }

/* ── 굵기 — G 는 700/800 을 전혀 쓰지 않는다. 제목조차 600 이 최대다 ── */
.main b, .main strong, .sidebar b,
.kpi-value, .sm-lead .v, .sm-sub .v, .summary-stat .v,
.acct-name, .acct-balance, .tx-amt, .tx-list-wide .tx-desc,
.doc-summary-card .row.total, .mini-bar-list .n {
  font-weight: var(--fw-semibold, 600);
}
#cpPanel .cp-fig .v, .bc-sum .in, .bc-sum .out { font-weight: var(--fw-semibold, 600) !important; }
/* 작은 보조 글자는 500 까지만 */
.kpi-label, .tx-date, .acct-bank, .acct-purpose, .bar-label, .legend,
.sm-lead .k, .sm-sub .k, .summary-stat .l, .recent-clients .label {
  font-weight: var(--fw-normal, 400);
}

/* ── 장부 표(.txt-*) — 우리 화면에서 가장 많이 보는 표 ──
   G 도 <table> 대신 CSS Grid 로 표를 만든다. 겉모양만 G 규격에 맞춘다.
   · 머리줄 : 바탕 없음 · 14px/22 weight 500 · 색 muted · 자간 벌리지 않음
   · 줄무늬(얼룩) 없음 — G 는 가로선 하나와 **호버**로만 줄을 구분한다
   · 금액 칸 : 오른쪽 정렬 + tabular-nums + weight 500 + 본문색 */
.txt-row { font-size: var(--fs-base, 14px); line-height: var(--lh-ui); padding: 9px 10px; }
.txt-head {
  /* 붙어 있는 머리줄은 자기가 얹힌 카드와 같은 색이어야 한다 — --bg 로 두면
     다크에서 카드(#171717)보다 어두운 띠(#0A0A0A)가 생긴다 */
  background: var(--surface);
  font-size: var(--fs-base, 14px); line-height: 22px;
  font-weight: var(--fw-medium, 500); color: var(--text-soft); letter-spacing: 0;
  min-height: var(--table-head-h, 32px);
}
.tx-table .txt-row.txt-alt { background: transparent; }        /* 얼룩을 걷는다 */
.tx-table .txt-row:not(.txt-head):hover { background: var(--accent-soft); }
.txt-row > div.num { text-align: right; font-variant-numeric: tabular-nums; font-weight: var(--fw-medium, 500); color: var(--text); }
.txt-head > div.num { font-weight: var(--fw-medium, 500); color: var(--text-soft); }
.txt-desc { font-weight: var(--fw-normal, 400); }
.txt-acct { font-weight: var(--fw-normal, 400); color: var(--text-soft); }
.txt-time { font-size: var(--fs-xs, 12px); color: var(--text-soft); }
.txt-empty { font-size: var(--fs-base, 14px); color: var(--text-soft); }
.txt-total {
  border-radius: var(--radius-lg, 10px); background: var(--surface-2);
  border: 1px solid var(--border); font-size: var(--fs-base, 14px);
}
.txt-total-k { color: var(--text-soft); font-size: var(--fs-xs, 12px); }
.txt-total b { font-size: var(--fs-base, 14px); font-weight: var(--fw-semibold, 600); }
/* 합계에도 색을 쓰지 않는다 — 이름(입금 합계/출금 합계)이 이미 방향을 말한다 */
.txt-total b.in, .txt-total b.out { color: var(--text); }

/* 달력(home-calendar.js)의 금액에도 색을 쓰지 않는다.
   ※ 일요일 빨강·토요일 파랑과 「안 나감」 같은 **상태** 색은 그대로 둔다 —
     돈의 방향이 아니라 달력 관례와 좋고 나쁨이라 G 의 ③ 규칙 대상이 아니다. */
#hcBox .hc-sum .i b, #hcBox .hc-sum .o b, #hcBox .hc-sum .p b, #hcBox .hc-sum .d b,
#hcBox .hc-d .i, #hcBox .hc-d .o, #hcBox .hc-d .p, #hcBox .hc-d .p.done,
#hcBox .hc-r b.i, #hcBox .hc-r b.o {
  color: var(--text) !important;
  font-variant-numeric: tabular-nums;
}
#hcBox .hc-d .i, #hcBox .hc-d .o, #hcBox .hc-d .p { font-size: var(--fs-xs, 12px); }

/* ============================================================================
   2026-10-06 — granter (⑦모바일 분기)

   G 는 1024px(lg) 에서 네비가 햄버거로 바뀌고, 좌우 거터는 20px(px-5) 이다.
   우리는 이미 860px 에서 사이드바가 드로어로 바뀌므로 그 분기점을 그대로 쓴다
   (분기점을 옮기면 화면 코드가 함께 걸려 있어서 겉모습만 바꾸는 일이 아니게 된다).

   바뀌는 것
     · 위쪽 바가 **검정 → 흰색 + 아래 1px 선** (사이드바가 흰색이 된 것과 짝을 맞춘다)
     · 좌우 거터 14px → 20px (G 의 px-5)
     · 입력 글자 16px 는 그대로 유지 — iOS 자동 확대 방지선이라 내리지 않는다
   ========================================================================= */
@media (max-width: 860px) {
  /* 위쪽 바 — G 의 상단바: 흰 바탕 + 아래 1px(50% 투명) 선, 그림자 없음 */
  .mobile-topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 10px var(--gutter, 20px);
    min-height: 56px;
    box-shadow: none;
  }
  .mobile-topbar .brand-name { color: var(--text) !important; font-size: var(--fs-lg, 16px) !important; font-weight: var(--fw-medium, 500); }
  .mobile-topbar .icon-btn {
    background: var(--surface); border-color: var(--border); color: var(--text-soft);
  }
  /* 드로어로 열리는 사이드바도 흰색 — 그림자 대신 1px 선 (G 는 그림자를 쓰지 않는다) */
  .sidebar { width: 82vw; max-width: 300px; }
  .sidebar.open { box-shadow: none; border-right: 1px solid var(--border); }
  .sidebar-backdrop { background: rgba(10,10,10,0.5); }

  /* 좌우 거터 — G 의 px-5 */
  .main { padding: 16px var(--gutter, 20px) 60px; }

  /* 제목·표 — 작은 글자로 더 내려가지 않는다. G 는 12px 밑으로 안 간다 */
  .topbar h1 { font-size: var(--fs-2xl, 24px); }
  .kpi-value { font-size: var(--fs-xl, 18px); }
  .kpi-label, .kpi-note { font-size: var(--fs-xs, 12px); }
  table { font-size: var(--fs-base, 14px); }
  .txt-row { font-size: var(--fs-base, 14px); }

  /* 사이드바 안쪽 항목은 이미 44px — 알림 단추와 콘솔 전환도 같은 높이로 */
  .console-btn { min-height: var(--control-h, 44px); }
}

/* ============================================================================
   2026-10-06 — granter (⑧남은 자리 마무리)

   ①번 「돈에 색을 쓰지 않는다」를 화면별 조각(web/*.js 가 심는 <style>)에도 끝까지 적용한다.
   ★ 가려서 적용한다 ★
     걷어내는 것 : **돈의 방향**을 말하는 색 (받을 돈/줄 돈, 수입/지출, 들어온/나간)
     그대로 두는 것 : **좋고 나쁨**을 말하는 색 (연체·초과·불일치·경고)과
       달력의 일요일/토요일 색. 이것들은 G 도 의미색(100 바탕 + 700 글자)으로 남겨 둔다.
   ========================================================================= */
.vd-u .am, .vd-u .am.in, .vd-stat .in, .vd-stat .out,
.vd-dsum .vv.in, .vd-dsum .vv.out, .vd-rh b, .vd-rh .s, .vd-total.on,
.vd-mg .l.in, .vd-mg .l.out, .vp-tb td.minus,
.rc-tb .pay,
#scPanel .sc-k .v.cost, #scPanel .sc-k .v.good, #scPanel .sc-k .v.bad,
#tdBox .td-sum .v.ok, #tdBox .td-sum .v.bad, #tdBox .td-card .big, #tdBox .td-card .big.ok,
#pdBox .pd-sum .v.ok, #pdBox .pd-sum .v.bad,
.sv-r .up, .sv-r .dn, .sv-rsum b.up, .sv-rsum b.dn {
  color: var(--text) !important;
  font-variant-numeric: tabular-nums;
}

/* 화면 코드가 색을 채워 만든 주 단추들 — G 의 주 단추는 **검정 하나**다.
   지금은 --accent(보조 회색)를 바탕으로 쓰고 있어서 회색 단추가 된다. */
.vd-btn, .lc-i .lc-b, .rc-go, #scPanel .sc-sg.on, .rc-cand:hover {
  background: var(--accent-strong) !important;
  border-color: var(--accent-strong) !important;
  color: var(--accent-contrast) !important;
}
.vd-btn:hover, #scPanel .sc-sg.on:hover { opacity: .7; }

/* 큰 숫자의 굵기도 600 까지만 (G 는 800 을 쓰지 않는다) */
#tdBox .td-card .big, #scPanel .sc-k .v, .vd-u .am, .rc-tb .pay,
.vd-rh .s, .vd-stat .in, .vd-stat .out {
  font-weight: var(--fw-semibold, 600) !important;
}

/* ============================================================================
   2026-10-07 — granter 2차 (A. 여백의 리듬 · 둥글기 · 제목 크기)

   1차에서는 색과 토큰을 granter 값으로 맞췄는데, 「디자인이 그대로」라는 말을 들었다.
   다시 나란히 놓고 보니 색이 아니라 **생김새**가 달랐다 —

     · granter 카드 둥글기는 12px 다. 우리는 16px 라 더 둥글고 말랑해 보였다.
     · granter 는 섹션과 섹션 사이를 크게 띄운다. 우리는 16px 라 촘촘했다.
     · granter 카드 안쪽 여백은 사방 24px 로 일정하다. 우리는 20/24 가 섞여 있었다.
     · granter 설명문은 14~15px 회색이다. 우리는 12px 라 '관리자 도구' 인상을 줬다.
     · granter 는 큰 제목일수록 자간을 과감히 조인다. 우리 제목은 24px 로 작았다.
     · granter 는 테두리 1px 하나로만 면을 가른다. 우리 --shadow 는 0.5px 링이라
       테두리와 겹쳐 가장자리가 두 겹으로 보였다.
   ========================================================================= */

/* 그림자를 완전히 걷는다 — 면의 구분은 테두리 1px 하나뿐이다 */
:root { --shadow: none; }

/* ── 카드 ── */
.panel {
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 28px;
}
.panel:last-child { margin-bottom: 0; }
.kpi-card, .summary-card, .deal-card, .acct-card, .doc-summary-card,
.pricing-panel, .qc-final-card, .doc-card, .items-card, .staff-panel, .fin-panel, .ai-panel {
  border-radius: 12px;
}
.kpi-card, .summary-card { padding: 20px; }
.modal-box { border-radius: 12px; }

/* ── 카드 제목과 설명 ── */
.panel-head { margin-bottom: 20px; gap: 16px; }
.panel-head h2 {
  font-size: var(--fs-lg, 16px); line-height: 24px;
  font-weight: var(--fw-semibold, 600); letter-spacing: -0.012em;
}
.summary-card-head h3 { font-size: var(--fs-lg, 16px); line-height: 24px; }
.form-section-title {
  font-size: var(--fs-lg, 16px); line-height: 24px;
  font-weight: var(--fw-semibold, 600); letter-spacing: -0.012em;
}
.modal-title { font-size: var(--fs-lg, 16px); font-weight: var(--fw-semibold, 600); }

/* 설명문 — granter 는 설명을 작게 쓰지 않는다. 14px 회색, 줄간격 1.55 */
.hint { font-size: var(--fs-base, 14px); line-height: 1.55; color: var(--text-soft); }
/* 제목 옆에 붙는 한 줄짜리 설명만 13px — 한 줄 안에 들어가야 하는 자리다 */
.panel-head .hint, .summary-card-head .hint { font-size: var(--fs-sm, 13px); line-height: 1.5; }

/* ── 페이지 제목 — granter 는 큰 글자일수록 자간을 과감히 조인다 ── */
.topbar { margin-bottom: 32px; gap: 24px; }
.topbar h1 {
  font-size: var(--fs-3xl, 30px); line-height: 1.22;
  font-weight: var(--fw-semibold, 600); letter-spacing: -0.028em;
  margin: 0 0 8px;
}
.topbar .sub { font-size: var(--fs-md, 15px); line-height: 1.55; color: var(--text-soft); }

/* ── 본문 바깥 여백 — granter 의 큰 화면 거터는 40px ── */
.main { padding: 32px var(--gutter-lg, 40px) 80px; }

/* ── 탭 아래 간격도 한 칸 더 ── */
.ai-tabs, .qc-tabs, .mail-tabs, .doctabs, .dk-tabs { margin-bottom: 28px; }

/* ============================================================================
   2026-10-07 — granter 2차 (B. 선으로 나뉜 격자 · 단추와 입력의 둥글기)

   granter 는 「여러 개의 둥근 상자를 띄엄띄엄 늘어놓는」 방식을 쓰지 않는다.
   칸을 붙여 놓고 **아주 연한 1px 선 하나로만** 가른다(ti-light.png 의 기능 격자가
   정확히 그 모양이다 — 세 칸이 맞붙어 있고 사이에 머리카락 같은 선 하나뿐이다).
   우리 달력은 둥근 상자 서른다섯 개가 6px 씩 떨어져 있어서 그 인상과 가장 멀었다.

   달력은 web/home-calendar.js 가 <style> 을 head 뒤에 꽂아 그리므로, 같은 특이성으로는
   덮이지 않는다. 그래서 !important 로 못 박는다(1차에서 색을 덮을 때와 같은 사정).
   ========================================================================= */

/* ── 홈 달력(#hcBox) ── */
#hcBox .hc-dow { gap: 0 !important; padding-bottom: 10px; }
#hcBox .hc-grid {
  gap: 0 !important;
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
}
#hcBox .hc-d {
  border: 0 !important; border-radius: 0 !important;
  border-right: 1px solid var(--border-subtle) !important;
  border-bottom: 1px solid var(--border-subtle) !important;
  min-height: 104px !important; padding: 10px 12px !important;
}
#hcBox .hc-d:nth-child(7n) { border-right: 0 !important; }
#hcBox .hc-d.off {
  min-height: 104px !important; background: var(--surface-2) !important;
  border-right: 1px solid var(--border-subtle) !important;
  border-bottom: 1px solid var(--border-subtle) !important;
}
#hcBox .hc-d.off:nth-child(7n) { border-right: 0 !important; }
#hcBox .hc-d:hover { background: var(--accent-soft) !important; }
#hcBox .hc-d.on { background: var(--accent-soft) !important; }
#hcBox .hc-d .n { font-size: 13px !important; font-weight: var(--fw-medium, 500) !important; }
#hcBox .hc-d .w, #hcBox .hc-d .lt { font-weight: var(--fw-medium, 500) !important; }

/* ── 재무 달력(.cal-grid) — 같은 규칙 ── */
.cal-grid { gap: 0; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.cal-cell {
  border: 0; border-radius: 0;
  border-right: 1px solid var(--border-subtle);
  border-bottom: 1px solid var(--border-subtle);
  padding: 10px 12px;
}
.cal-cell:nth-child(7n) { border-right: 0; }
.cal-cell.empty { background: var(--surface-2); border: 0;
  border-right: 1px solid var(--border-subtle); border-bottom: 1px solid var(--border-subtle); }
.cal-cell:hover { border-color: var(--border-subtle); background: var(--accent-soft); }
.cal-cell.today { border-color: var(--border-subtle); box-shadow: inset 0 2px 0 var(--accent-strong); }
.cal-cell .d { font-weight: var(--fw-medium, 500); }
.cal-dow { font-weight: var(--fw-medium, 500); color: var(--text-soft); }

/* ── 요약 카드의 큰 숫자 — granter 는 핵심 수치만 크게 키운다 ── */
.kpi-value { font-size: var(--fs-2xl, 24px); line-height: 32px; letter-spacing: -0.02em; }
.kpi-label { font-size: var(--fs-sm, 13px); }

/* ── 단추·입력의 둥글기 — granter 는 --radius(10px) 가 아니라 그보다 한 단계 작은 8px ──
   (ti-light.png 의 「3건 한 번에 발급」 검은 단추와 날짜 입력칸이 모두 8px 다) */
.primary-btn, .icon-btn, .icon-btn-text, .seg, .chip,
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
select, textarea, .field-row input, .field-row select, .field-row textarea,
.pricing-panel .pricing-row-input {
  border-radius: 8px;
}
/* 단추 글자는 14px — granter 단추는 본문과 같은 크기다. 16px 는 둔탁해 보인다
   (입력칸 글자는 iOS 자동 확대를 막아야 해서 16px 그대로 둔다) */
.primary-btn { font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500); }
.primary-btn.sm, .icon-btn-text { font-size: var(--fs-sm, 13px); }

/* ── 빈 상태 — granter 는 「없음」을 좁은 띠가 아니라 넉넉한 여백으로 보여 준다 ── */
.txt-empty, .empty-state, .no-data {
  padding: 40px 16px; text-align: center;
  font-size: var(--fs-base, 14px); color: var(--text-soft);
}

/* 달력의 빈 칸은 회색으로 덮지 않는다 — granter 는 면을 색으로 구분하지 않는다.
   격자 선만으로 충분히 읽힌다. 오늘 표시도 주황이 아니라 검정 한 줄로. */
#hcBox .hc-d.off { background: var(--surface) !important; }
#hcBox .hc-d.today { box-shadow: inset 0 2px 0 var(--accent-strong) !important; }
.cal-cell.empty { background: var(--surface); }

/* ============================================================================
   2026-10-07 — granter 2차 (C. 휴대폰 폭에서 되돌릴 것)

   위 A·B 블록은 조건 없는 규칙이라, 앞서 적힌 860px 분기 규칙들을 덮어 버린다.
   같은 값을 여기서 다시 적어 둔다 — 좁은 화면에서 40px 거터와 30px 제목은 너무 크다.
   ※ 입력칸 글자 16px 와 조작 요소 44px 는 어느 폭에서도 내리지 않는다(iOS 확대 방지·손가락).
   ========================================================================= */
@media (max-width: 860px) {
  .main { padding: 16px var(--gutter, 20px) 60px; }
  .topbar { margin-bottom: 24px; gap: 16px; }
  .topbar h1 { font-size: var(--fs-2xl, 24px); letter-spacing: -0.024em; }
  .topbar .sub { font-size: var(--fs-base, 14px); }
  .panel { padding: 16px; margin-bottom: 20px; }
  .panel-head { margin-bottom: 16px; }
  .kpi-card, .summary-card { padding: 14px; }
  .kpi-value { font-size: var(--fs-xl, 18px); line-height: 26px; }
  .kpi-label { font-size: var(--fs-xs, 12px); }
  .hint { font-size: var(--fs-sm, 13px); }
  .ai-tabs, .qc-tabs, .mail-tabs, .doctabs, .dk-tabs { margin-bottom: 20px; }
  #hcBox .hc-d, #hcBox .hc-d.off { min-height: 72px !important; padding: 6px 7px !important; }
  .cal-cell, .cal-cell.empty { min-height: 72px; padding: 6px 7px; }
}

/* ============================================================================
   2026-10-07 — granter 2차 (D. 제목 글꼴이 실제로 안 바뀌어 있던 자리)

   1차에서 body 글꼴을 Pretendard 로 바꿨는데, 120행의
     h1, h2, h3, .serif { font-family: "Noto Sans KR", sans-serif; }
   가 그대로 남아 있어서 **제목만 끝까지 Noto Sans KR 로 그려지고 있었다.**
   화면에서 가장 크고 먼저 읽히는 글자가 다른 글꼴이었으니, 토큰을 아무리 맞춰도
   granter 와 같은 인상이 날 수 없었다. body 가 가진 Pretendard 를 그대로 물려받게 한다.
   ※ 인쇄 문서(.doc-preview / .stmt-preview)는 공문서 조판이라 Noto Sans KR 그대로 둔다.
   ========================================================================= */
h1, h2, h3, h4, h5, h6, .serif,
.panel-head h2, .form-section-title, .modal-title, .topbar h1 {
  font-family: inherit;
}
.doc-preview, .doc-preview *, .stmt-preview, .stmt-preview * {
  font-family: "Noto Sans KR", sans-serif;
}

/* ============================================================================
   2026-10-07 — granter 2차 (E. 숨 쉴 공간)

   granter 를 1:1 로 떠서 재 보면 목록 한 줄이 44px 다(글자 14px + 위아래 12px).
   우리는 40px 였고, 칸 이름과 입력칸 사이가 5px 밖에 안 떨어져 있었다.
   한 줄씩 보면 미세하지만, 스무 줄이 모이면 「촘촘한 관리자 도구」와
   「여유 있는 제품」을 가르는 차이가 된다.
   ※ 가로 여백은 10px 로만 늘린다 — 임직원 표가 이미 가로로 넘치고 있어, 더 벌리면
     넘침이 더 앞당겨진다(넘침 자체는 손대지 않기로 한 기능 쪽 일이다).
   ========================================================================= */
:root { --table-cell-px: 10px; --table-head-h: 40px; }

table.simple td, table.clients td, table:not([class]) td {
  padding: 12px var(--table-cell-px, 10px);
  border-bottom-color: var(--border-subtle);
}
table.simple th, table.clients th, table:not([class]) th {
  padding: 0 var(--table-cell-px, 10px);
  font-size: var(--fs-sm, 13px);
}
.txt-row { padding: 12px var(--table-cell-px, 10px); }

/* 칸 이름과 입력칸 사이 — granter 는 8px 를 띄운다 */
.field-row { gap: 8px; margin-top: 20px; }
.field-row.two, .field-row.three { gap: 16px; }

/* 작은 제목 아래 선 — granter 는 선 위아래를 넉넉히 띄운다 */
.form-section-title { margin: 32px 0 0; padding-bottom: 12px; }
.form-section-title + * { margin-top: 16px; }
.form-section-title:first-child { margin-top: 0; }


/* ════════════════════════════════════════════════════════════════════════════
   2026-10-07 — 다우오피스(daouoffice.com) 로 방향을 바꾼다

   왜 바꾸나.
     granter 로 한 번 바꿨다가 「디자인이 마음에 안 들어」를 들었다. 까닭을 가려 보니
     granter 는 **마케팅 랜딩**이라 여백이 크고 정보 밀도가 낮다. 우리 화면은
     장부·표·달력이라 한 화면에 숫자가 많이 들어간다. 게다가 granter 를 따라
     **금액에서 색을 걷어내서** 수입/지출을 한눈에 가릴 수 없게 됐다.
     다우오피스는 업무·인사·경리(급여·근태·카드·경비·매출입·세무)를 한 화면에서
     다루는 **업무플랫폼**이라 우리와 성격이 같다.

   받아낸 값의 출처
     [CSS]  daouoffice.com/css/common_new.css · main.css (curl 로 원문 수신)
            - 글꼴 'pretendard','Noto Sans KR',... (2곳) → 우리가 쓰던 Pretendard 와 같다
            - 브랜드 파랑 #3851E7 (13회) · 파랑 #2597FF (5회)
            - 청록 #25CAD3 (8회) · #1FBCC5 (8회) · #00B3CE (4회) · #02B6D7 (3회)
            - 글자 #333 (52회) · 보조 #888 (20회) · #8D949E (6회) · #5D6777 (3회)
            - 선 #EEE (23회) · #DDD (5회) · #EAEAEA (3회)
            - 바탕 #F5F6F8 (5회) · #F5F5F7 (5회) · #F4F8FD (3회)
            - 오류 #EB5757 (2회) · #FF8989 (2회)
            - ★ CSS 변수(:root --x)를 **하나도 쓰지 않는다** — 값이 전부 직접 박혀 있다
     [화면] 제품 화면 daouoffice-mail-ui.png (1228×577) 픽셀 직접 측정
            - 가장 많이 쓰인 채도 높은 색 : #57C1D1(1022px) · #1EA7BE(481px) ← 주 단추(청록)
              #105DFB(132px) ← 알약 글자·링크(파랑) · #239DFC(39px)
              #FD5235(15px) ← 배지 · #1EBB67(14px) ← 긍정
            - 연한 바탕 : #E8F5FF(말풍선) · AI 요약 상자 안 #F1FBFF, 바로 바깥 #E8F7FE
              → **상자 안이 바깥보다 밝은 푸른끼** = 연한 색으로 칠한 상자
            - 알약 : 흰/연한 바탕 + 파란 1px 테두리 + 파란 작은 글자 + 모서리 full
            - 모서리 : 패널·상자 8~12px, 알약만 full
            - 밀도 : 3단(목록+본문+패널), 도구막대에 6개 단추가 드롭다운 화살표와 함께
     [계산] 명암비는 전부 WCAG 2.x 식으로 직접 계산했다 (아래 각 줄에 적었다)
     [미확인] 다우오피스의 간격 토큰(px 단위 규격)은 공개 CSS 에 체계가 없어
            (변수를 안 쓴다) 숫자를 그대로 가져올 수 없었다. 그래서 간격은
            「granter 때보다 좁힌다」는 방향만 가져오고 값은 우리가 정했다.

   granter 때와 **반대로** 가는 것
     ① 강조색이 돌아온다. 검정 하나 → **파랑(주) + 청록(포인트)**
     ② 금액에 색이 돌아온다. 입금/출금을 색으로 즉시 가른다
     ③ 밀도가 올라간다. 「숨 쉴 공간」보다 「한눈에 보이는 양」
     ④ 연한 색으로 칠한 상자가 생긴다 (AI 요약처럼 중요한 블록)
     ⑤ 선택은 바탕칠이 아니라 **테두리를 진하게**

   granter 때 것 중 **그대로 두는 것**
     Pretendard · 그림자 없이 1px 선 · 글자/굵기 한 벌 ·
     44px 터치 · 16px 입력 · 본문 명암비 4.5:1
   ══════════════════════════════════════════════════════════════════════════ */

/* ── D1. 토큰 (라이트) ──
   이 파일에는 :root 가 여러 벌이고 **뒤가 이긴다**. 그래서 맨 끝에서 덮는다. */
:root {
  /* 바탕·면 — 다우는 흰색이 지배하고, 보조면만 아주 연한 청회색이다 [CSS #F5F6F8] */
  --bg:               #FFFFFF;
  --surface:          #FFFFFF;
  --surface-2:        #F4F6FA;   /* [CSS] #F5F6F8 를 아주 조금 푸르게 */

  /* 글자 — [CSS] #333/#888/#5D6777 을 우리 기준(4.5:1)에 맞춰 조였다 */
  --text:             #16181D;   /* [계산] on #FFF 17.76:1 */
  --text-soft:        #5E6673;   /* [계산] on #FFF 5.79 · #F4F6FA 5.36 · #EFF3FE 5.22 */
  --text-faint:       #5E6673;   /* 보조 회색은 한 단계만 쓴다 (granter 때 결정 유지) */
  --ink:              #16181D;
  --ink-2:            #262B33;

  /* 선 — 다우는 선이 매우 연하다 [CSS #EEE/#EAEAEA] */
  --border:           #E4E8EF;
  --border-subtle:    #F0F2F6;
  --control-border:   #9299A6;   /* [계산] on #FFF 3.37:1 — WCAG 1.4.11 비텍스트 3:1 */

  /* ★ 강조 — 파랑이 주, 청록이 포인트 ★
     [CSS] 브랜드 파랑 #3851E7 가 13회로 가장 많다. [화면] 알약 글자 #105DFB.
     #3851E7 을 그대로 쓴다 — [계산] 흰 글자가 이 위에 6.00:1, 이 색이 흰 바탕 위 6.00:1.
     둘 다 4.5 를 넘어서 **바탕으로도 글자로도** 쓸 수 있다. */
  --accent:           #3851E7;
  --accent-strong:    #3851E7;
  --accent-contrast:  #FFFFFF;   /* [계산] on #3851E7 6.00:1 */
  --accent-soft:      #EFF3FE;   /* 연한 파랑 — 호버·선택·연한 상자 바탕 [화면 #E8F5FF 계열] */
  --accent-line:      #C5D4F7;   /* 연한 파랑 테두리 — 연한 상자의 1px 선 */
  --accent-ink:       #2B44C9;   /* [계산] on #EFF3FE 6.54:1 — 연한 상자 안의 글자 */

  /* 청록 포인트 — [CSS] #25CAD3/#1FBCC5/#00B3CE, [화면] 주 단추 #1EA7BE.
     원색 그대로는 흰 바탕 2.52:1 로 글자가 못 된다. 글자용은 진한 값으로 따로 둔다. */
  --teal:             #00B3CE;   /* [CSS] 그래픽 전용 — 글자로 쓰지 않는다 */
  --teal-ink:         #0E7490;   /* [계산] on #FFF 5.36 · #E4F4F8 4.74 */
  --teal-soft:        #E4F4F8;

  /* ★ 돈의 방향 — granter 때 걷어낸 것을 되돌린다 ★
     채도 높은 원색(#00C853/#FF1744)은 표 스무 줄이 모이면 소란스럽다.
     차분한 값으로 내리되 4.5:1 은 지킨다. */
  --money-in:         #0B7A5A;   /* [계산] on #FFF 5.32 · #F4F6FA 4.92 · #EFF3FE 4.80 */
  --money-out:        #C0372C;   /* [계산] on #FFF 5.49 · #F4F6FA 5.08 · #EFF3FE 4.95 */

  /* 의미색 — 상태(연체·완료·경고)에만. 다우의 #EB5757/#1EBB67 계열 */
  --success:          #0B7A5A;  --success-soft: #E3F4EE;  --success-ink: #0B6A50;
  --warning:          #9A5B00;  --warning-soft: #FDF1DC;  --warning-ink: #8A5200;
  --danger:           #C0372C;  --danger-soft:  #FBEAE8;  --danger-ink:  #AF2F25;
  --info:             #2B44C9;  --info-soft:    #EFF3FE;  --info-ink:    #2B44C9;

  --brand:            #3851E7;
  --brand-strong:     #2B44C9;

  /* 그림자 — 다우도 거의 안 쓴다. 깊이는 1px 선으로 (granter 때 결정 유지) */
  --shadow:           none;

  /* 포커스 링 — 검정에서 파랑으로 */
  --ring:             #3851E7;
  --ring-shadow:      0 0 0 3px rgba(56,81,231,0.35);
  --selection-bg:     rgba(56,81,231,0.20);
}

/* ── D2. 토큰 (다크) — @media 와 [data-theme] 두 벌에 같은 값을 넣는다 ── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0C0E12; --surface: #141821; --surface-2: #1C212C;
    --text: #F2F4F8;          /* [계산] on #0C0E12 17.6:1 */
    --text-soft: #A6ADBA;     /* [계산] on #0C0E12 8.6 · #141821 7.7 · #1C212C 6.9 */
    --text-faint: #A6ADBA;
    --ink: #E5E7EB; --ink-2: #2A3040;
    --border: rgba(255,255,255,0.11); --border-subtle: rgba(255,255,255,0.07);
    --control-border: #6B7280;
    --accent: #8FB4FF; --accent-strong: #3F63E8; --accent-contrast: #FFFFFF;
    --accent-soft: rgba(63,99,232,0.18); --accent-line: rgba(143,180,255,0.35);
    --accent-ink: #A8C2FF;
    --teal: #25CAD3; --teal-ink: #6FD6E8; --teal-soft: rgba(37,202,211,0.14);
    --money-in: #45D6A0;      /* [계산] on #0C0E12 10.6:1 */
    --money-out: #FF9B91;     /* [계산] on #0C0E12 9.6:1 */
    --success: #45D6A0; --success-soft: rgba(69,214,160,0.15); --success-ink: #45D6A0;
    --warning: #FFC861; --warning-soft: rgba(255,200,97,0.15);  --warning-ink: #FFC861;
    --danger:  #FF9B91; --danger-soft:  rgba(255,155,145,0.15); --danger-ink:  #FF9B91;
    --info:    #8FB4FF; --info-soft:    rgba(143,180,255,0.14); --info-ink:    #A8C2FF;
    --brand: #8FB4FF; --brand-strong: #A8C2FF;
    --shadow: none;
    --ring: #8FB4FF; --ring-shadow: 0 0 0 3px rgba(143,180,255,0.38);
    --selection-bg: rgba(143,180,255,0.26);
  }
}
:root[data-theme="dark"] {
  --bg: #0C0E12; --surface: #141821; --surface-2: #1C212C;
  --text: #F2F4F8; --text-soft: #A6ADBA; --text-faint: #A6ADBA;
  --ink: #E5E7EB; --ink-2: #2A3040;
  --border: rgba(255,255,255,0.11); --border-subtle: rgba(255,255,255,0.07);
  --control-border: #6B7280;
  --accent: #8FB4FF; --accent-strong: #3F63E8; --accent-contrast: #FFFFFF;
  --accent-soft: rgba(63,99,232,0.18); --accent-line: rgba(143,180,255,0.35);
  --accent-ink: #A8C2FF;
  --teal: #25CAD3; --teal-ink: #6FD6E8; --teal-soft: rgba(37,202,211,0.14);
  --money-in: #45D6A0; --money-out: #FF9B91;
  --success: #45D6A0; --success-soft: rgba(69,214,160,0.15); --success-ink: #45D6A0;
  --warning: #FFC861; --warning-soft: rgba(255,200,97,0.15);  --warning-ink: #FFC861;
  --danger:  #FF9B91; --danger-soft:  rgba(255,155,145,0.15); --danger-ink:  #FF9B91;
  --info:    #8FB4FF; --info-soft:    rgba(143,180,255,0.14); --info-ink:    #A8C2FF;
  --brand: #8FB4FF; --brand-strong: #A8C2FF;
  --shadow: none;
  --ring: #8FB4FF; --ring-shadow: 0 0 0 3px rgba(143,180,255,0.38);
  --selection-bg: rgba(143,180,255,0.26);
}

/* ── D3. 밀도 — 한 화면에 더 많이 넣는다 ──
   granter 2차(A·E 블록)에서 「숨 쉴 공간」을 이유로 넓혀 놓은 값을 되돌린다.
   그 방향이 틀렸다 — 우리 화면은 랜딩이 아니라 장부·표·달력이다.
   [화면] 다우오피스 메일 화면은 1228px 폭 안에 3단(목록+본문+패널)을 넣고
   도구막대 한 줄에 단추 6개를 드롭다운 화살표까지 달아 넣는다. 그 밀도를 따른다.
   ※ 44px 터치 기준은 **조작 요소**에만 걸린다. 표의 한 줄은 조작 요소가 아니다 —
     휴대폰 폭(≤860px)에서는 아래 D9 가 줄 높이를 44px 로 되돌린다. */

/* 본문 바깥 여백 — 40px 는 장부 화면에서 쓸모없이 크다 */
.main { padding: 18px 22px 48px; }

/* 페이지 제목 — 30px → 21px. 제목이 화면의 1/10 을 먹을 이유가 없다 */
.topbar { margin-bottom: 14px; gap: 14px; }
.topbar h1 { font-size: 21px; line-height: 1.25; letter-spacing: -0.022em; margin: 0 0 3px; }
.topbar .sub { font-size: var(--fs-sm, 13px); line-height: 1.45; }
.topbar .meta-pill { min-height: 28px; padding: 0 10px; font-size: var(--fs-xs, 12px); }

/* 패널 — 사방 24px + 아래 28px 는 카드가 셋만 쌓여도 한 화면을 넘긴다 */
.panel { border-radius: 10px; padding: 13px 14px 14px; margin-bottom: 12px; }
.panel-head { margin-bottom: 10px; gap: 12px; }
.panel-head h2 { font-size: var(--fs-md, 15px); line-height: 22px; letter-spacing: -0.014em; }
.summary-card-head h3 { font-size: var(--fs-sm, 13px); line-height: 20px; }

/* 설명문 — granter 는 14px 를 권했지만 우리 화면에선 설명이 숫자보다 커진다 */
.hint { font-size: var(--fs-xs, 12px); line-height: 1.45; }
.panel-head .hint, .summary-card-head .hint { font-size: var(--fs-xs, 12px); line-height: 1.4; }

/* 요약·KPI 카드 */
.kpi-card, .summary-card { padding: 11px 12px; border-radius: 10px; }
.kpi-grid, .summary-grid { gap: 8px; margin-bottom: 10px; }
.kpi-value { font-size: 19px; line-height: 26px; letter-spacing: -0.018em; }
.kpi-label { font-size: var(--fs-xs, 12px); line-height: 17px; }
.kpi-note  { font-size: var(--fs-2xs, 12px); line-height: 16px; }
.row-2 { gap: 12px; }

/* 탭 — 아래 28px 를 절반으로 */
.ai-tabs, .qc-tabs, .mail-tabs, .doctabs, .dk-tabs { margin-bottom: 14px; gap: 14px; }
.ai-tab, .qc-tab, .mail-tab { min-height: 38px; padding: 8px 4px; }

/* 입력 줄 — granter 2차가 20px 로 벌려 둔 것을 12px 로 */
.field-row { gap: 6px; margin-top: 12px; }
.field-row.two, .field-row.three { gap: 10px; }
.form-section-title { margin: 18px 0 0; padding-bottom: 8px; }
.form-section-title + * { margin-top: 10px; }
.form-section-title:first-child { margin-top: 0; }

/* 빈 상태 — 40px 는 「없음」 한 줄에 과하다 */
.txt-empty, .empty-state, .no-data { padding: 18px 12px; font-size: var(--fs-sm, 13px); }

/* ── D4. 표 — 가장 많이 보는 화면이다 ──
   [화면] 다우오피스 메일 목록은 한 줄이 글자 높이 + 아주 좁은 위아래 여백이다.
   줄무늬(얼룩)를 쓰지 않고 가로선 하나와 호버로만 줄을 가른다(granter 때와 같음). */
:root { --table-cell-px: 8px; --table-head-h: 28px; }

table.simple td, table.clients td, table:not([class]) td {
  padding: 6px var(--table-cell-px, 8px);
  border-bottom-color: var(--border-subtle);
}
table.simple th, table.clients th, table:not([class]) th {
  padding: 0 var(--table-cell-px, 8px);
  height: var(--table-head-h, 28px);
  font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500);
  color: var(--text-soft); letter-spacing: 0;
  border-bottom: 1px solid var(--border);
}
/* 장부 표(.txt-*) — granter 2차가 12px 로 키워 44px 짜리 줄을 만들었다. 30px 로 되돌린다 */
.txt-row { padding: 5px var(--table-cell-px, 8px); line-height: 20px; }
.txt-head { min-height: var(--table-head-h, 28px); font-size: var(--fs-xs, 12px); line-height: 18px; }
.txt-time { font-size: var(--fs-2xs, 12px); }
.txt-total { padding: 7px 10px; border-radius: 8px; }

/* 선택된 줄 — [화면] 다우는 선택한 메일 줄에 연한 파랑을 깐다 */
.tx-table .txt-row:not(.txt-head):hover,
table.simple tbody tr:hover > td, table.clients tr:hover td,
table:not([class]) tbody tr:hover > td { background: var(--accent-soft); }

/* ── D5. ★ 금액에 색을 돌려놓는다 ★ ──
   granter 블록(⑥·⑧)이 `color: var(--text) !important` 로 전부 검정으로 눌러 놨다.
   같은 선택자를 **뒤에서** 방향별로 갈라 다시 쓴다(뒤가 이긴다).
   [계산] --money-in #0B7A5A · --money-out #C0372C 는 이 파일의 모든 밝은 바탕
   (#FFFFFF 5.32/5.49 · #F4F6FA 4.92/5.08 · #EFF3FE 4.80/4.95)에서 4.5:1 을 넘는다. */
.tx-amt.in,
.bc-sum .in, .bc-tx-head .in,
.fp-line.in b,
.lb-r .a.in, .lb-g .am.in, .lc-i .am.in,
#wkBox .wk-sum .in b, #wkBox .wk-d .v.in,
.vd-u .am.in, .vd-stat .in, .vd-dsum .vv.in, .vd-mg .l.in,
.sv-r .up, .sv-rsum b.up,
#hcBox .hc-sum .i b, #hcBox .hc-d .i, #hcBox .hc-r b.i,
.txt-total b.in {
  color: var(--money-in) !important;
  font-variant-numeric: tabular-nums;
}
.tx-amt.out,
.bc-sum .out, .bc-tx-head .out,
.fp-line.out b,
.lb-r .a.out, .lb-g .am.out, .lc-i .am.out,
#wkBox .wk-sum .out b, #wkBox .wk-d .v.out,
.vd-stat .out, .vd-dsum .vv.out, .vd-mg .l.out, .vp-tb td.minus,
.sv-r .dn, .sv-rsum b.dn,
#hcBox .hc-sum .o b, #hcBox .hc-d .o, #hcBox .hc-r b.o,
.txt-total b.out {
  color: var(--money-out) !important;
  font-variant-numeric: tabular-nums;
}
/* 장부 표의 금액 칸 — 들어온 줄/나간 줄을 칸 자체에서 가른다 */
.txt-row > div.num.in  { color: var(--money-in)  !important; }
.txt-row > div.num.out { color: var(--money-out) !important; }

/* 좋고 나쁨을 말하던 자리도 색을 되돌린다 (연체·초과·미달) */
.kpi-value.success, .sm-lead.is-pos .v, .sm-sub.is-pos .v,
#tdBox .td-sum .v.ok, #pdBox .pd-sum .v.ok, #tdBox .td-card .big.ok,
#scPanel .sc-k .v.good { color: var(--success) !important; }
.kpi-value.danger, .sm-lead.is-neg .v, .sm-sub.is-neg .v,
#tdBox .td-sum .v.bad, #pdBox .pd-sum .v.bad,
#scPanel .sc-k .v.bad { color: var(--danger) !important; }
.kpi-value.warning, .sm-lead.is-warn .v, .sm-sub.is-warn .v { color: var(--warning) !important; }

/* 요약 카드의 왼쪽 띠도 방향을 말하게 — granter 가 회색으로 눌러 놓은 것을 되돌린다 */
.sm-lead.is-pos { background: var(--success-soft); border-left-color: var(--success); }
.sm-lead.is-neg { background: var(--danger-soft);  border-left-color: var(--danger); }
.sm-lead.is-warn{ background: var(--warning-soft); border-left-color: var(--warning); }

/* 숫자는 어디서든 자릿수가 세로로 맞는다 */
.num, .amount, [data-num], .kpi-value, .tx-amt, .txt-row > div.num,
.sm-lead .v, .sm-sub .v, .summary-stat .v, .acct-balance, .txt-total b {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* 장부 표의 입금/출금 전용 칸 (tx-table.js 가 .txt-in / .txt-out 으로 낸다) */
.txt-in  { color: var(--money-in)  !important; }
.txt-out { color: var(--money-out) !important; }
.txt-bal { color: var(--text); }

/* ── D6. 연한 색으로 칠한 상자 (tinted box) ──
   [화면] 다우오피스 「AI 본문 요약」은 연한 파랑 바탕 + 연한 파랑 1px 테두리 +
   모서리 8px 안팎 + 제목만 파랑이다. 상자 안(#F1FBFF)이 바깥(#E8F7FE)보다 밝다.
   우리 화면에서 눈에 띄어야 하는 블록에 같은 모양을 쓴다.
   ※ 클래스를 새로 달지 않는다 — 이미 있는 id/클래스로만 건다. */
#financeAuditText {
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: 8px;
  padding: 11px 13px;
  color: var(--text) !important;
  font-size: var(--fs-sm, 13px) !important;
  line-height: 1.65 !important;
}
/* 알림 상자 — 색은 의미색 그대로, 모양만 다우식(8px · 얇은 테두리 · 작은 글자)으로 */
.callout {
  border-radius: 8px; padding: 9px 12px; gap: 8px;
  border: 1px solid var(--warning-soft);
  background: var(--warning-soft); color: var(--warning-ink);
  font-size: var(--fs-sm, 13px); line-height: 1.45;
}
.callout svg { width: 16px; height: 16px; flex: none; }

/* ── D7. 알약(pill) · 칩(chip) · 선택 ──
   [화면] 다우오피스의 알약 : 모서리 full · 작은 글자 · 연한 바탕 또는
   흰 바탕 + 파란 1px 테두리 + 파란 글자. 사람 이름·상태·추천 동작에 두루 쓴다.
   ★ 선택은 바탕을 진하게 칠하는 것이 아니라 **테두리를 진하게** 한다. */
.pill {
  display: inline-flex; align-items: center;
  padding: 1px 8px; border-radius: 999px;
  font-size: var(--fs-xs, 12px); line-height: 18px; font-weight: var(--fw-medium, 500);
  border: 1px solid transparent;
}
.pill.ok,   .pill.good { background: var(--success-soft); border-color: var(--success-soft); color: var(--success-ink); }
.pill.warn, .pill.wait { background: var(--warning-soft); border-color: var(--warning-soft); color: var(--warning-ink); }
.pill.danger, .pill.bad{ background: var(--danger-soft);  border-color: var(--danger-soft);  color: var(--danger-ink); }
.pill.info  { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink); }

.chip {
  min-height: 30px; padding: 0 11px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  font-size: var(--fs-sm, 13px); font-weight: var(--fw-normal, 400);
}
.chip:hover { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink); }
/* ★ 선택 = 연한 파랑 바탕 + **진한 파랑 테두리** + 파란 글자 (검정으로 꽉 채우지 않는다) */
.chip.active {
  background: var(--accent-soft); border-color: var(--accent-strong);
  color: var(--accent-ink); font-weight: var(--fw-medium, 500);
}
.chip.active .n { color: var(--accent-ink); }
.recent-clients .chip, .contact-chip { min-height: 0; padding: 2px 9px; font-size: var(--fs-xs, 12px); }

/* 분절 단추 — 선택은 흰 알약 + 파란 글자 */
.seg-btn { min-height: 34px; padding: 0 11px; font-size: var(--fs-sm, 13px); }
.seg-btn.active { background: var(--surface); color: var(--accent-ink); font-weight: var(--fw-medium, 500); }

/* ── D8. 강조색이 들어가는 조작 요소 ──
   [화면] 다우의 주 CTA 는 색이 찬 단추다 (검정이 아니다). */
.primary-btn { background: var(--accent-strong); color: var(--accent-contrast); border-radius: 8px; }
.primary-btn:hover { opacity: .88; }
.primary-btn.secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.primary-btn.secondary:hover { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink); opacity: 1; }
.icon-btn:hover, .icon-btn-text:hover {
  background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink);
}
/* 밑줄 탭의 선택 표시도 파랑으로 */
.ai-tab.active, .qc-tab.active, .mail-tab.active { color: var(--accent-ink); border-bottom-color: var(--accent-strong); }
.ai-tab.active .ai-tab-n, .qc-tab.active .qc-tab-n { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent-line); }

/* ── D9. 사이드바 — 더 좁고 촘촘하게, 선택 항목에 연한 파랑 ──
   [화면] 다우는 좁은 아이콘 레일 + 목록 패널의 2단이다. DOM 을 바꾸지 않기로 했으므로
   구조는 그대로 두고, **폭을 줄이고 줄을 촘촘히 하고 선택 항목을 파랑으로** 만든다.
   ※ nav-item 높이는 40px 로 내리되, 휴대폰 폭에서는 1586행 규칙이 44px 로 되돌린다. */
:root { --sidebar-w: 206px; --nav-item-h: 40px; }
.brand { padding: 11px 12px; margin-bottom: 8px; gap: 9px; }
.brand-mark { width: 28px; height: 28px; }
.brand-name { font-size: var(--fs-sm, 13px); }
.brand-sub { font-size: var(--fs-2xs, 12px); margin-top: 1px; }
.console-switch { margin: 0 7px 8px; padding: 2px; }
.console-btn { min-height: 30px; padding: 0 6px; font-size: var(--fs-xs, 12px); }
.console-btn.active { color: var(--accent-ink); }
.nav { gap: 1px; padding: 0 7px; }
.nav-item { min-height: 36px; padding: 0 9px; gap: 9px; font-size: var(--fs-sm, 13px); border-radius: 8px; }
.nav-item svg { width: 15px; height: 15px; }
.nav-item:hover { background: var(--accent-soft); color: var(--accent-ink); }
/* 선택 — [화면] 다우는 고른 항목에 둥근 사각형 바탕을 칠하고 글자를 강조색으로 한다 */
.nav-item.active {
  background: var(--accent-soft); color: var(--accent-ink);
  font-weight: var(--fw-medium, 500);
}
.nav-item.active svg { color: var(--accent-strong); }
.sidebar-foot { padding: 9px 10px; }

/* ── D10. 달력 — 한 달이 한 화면에 들어오게 ──
   granter 2차가 칸 높이를 104px 로 잡아서 여섯 줄이면 624px 다. 74px 로 내리면 444px.
   home-calendar.js 가 <style> 을 head 뒤에 꽂으므로 !important 로 못 박는다. */
#hcBox .hc-d, #hcBox .hc-d.off { min-height: 74px !important; padding: 6px 8px !important; }
#hcBox .hc-d .n { font-size: 12px !important; }
#hcBox .hc-d .i, #hcBox .hc-d .o, #hcBox .hc-d .p { font-size: 11px !important; line-height: 15px !important; }
/* 오늘·선택 — 검정 줄이 아니라 파랑 테두리로 (선택 = 테두리 진하게) */
#hcBox .hc-d.today { box-shadow: inset 0 0 0 2px var(--accent-strong) !important; }
#hcBox .hc-d.on { background: var(--accent-soft) !important; }
.cal-grid { gap: 0; }
.cal-cell, .cal-cell.empty { min-height: 74px; padding: 6px 8px; }
.cal-cell.today { box-shadow: inset 0 0 0 2px var(--accent-strong); }
.cal-cell.on, .cal-cell.selected { background: var(--accent-soft); }

/* ── D11. 휴대폰 폭에서 되돌릴 것 ──
   위 규칙들은 조건이 없어서 1586행의 44px 터치 규칙과 2520행대 모바일 규칙을 덮는다.
   ※ 44px 터치 · 16px 입력은 어느 폭에서도 내리지 않는다. 여기서 다시 못 박는다. */
@media (max-width: 860px) {
  .main { padding: 14px 16px 56px; }
  .topbar { margin-bottom: 12px; gap: 12px; }
  .topbar h1 { font-size: 19px; }
  .panel { padding: 12px; margin-bottom: 10px; }
  .kpi-card, .summary-card { padding: 11px; }
  .kpi-value { font-size: 17px; line-height: 24px; }
  /* 표 한 줄은 휴대폰에서 손가락으로 누를 수 있어야 한다 — 44px 로 되돌린다 */
  .txt-row { padding: 12px 10px; }
  table.simple td, table.clients td, table:not([class]) td { padding: 12px 10px; }
  /* 조작 요소는 전부 44px (1586행 규칙을 다시 한 번) */
  button, .btn, .icon-btn, .icon-btn-text, .primary-btn, .seg-btn,
  .nav-item, .nav-subitem, .nav-subgroup, .chip, .wc-chip, .pd-b,
  a.icon-btn-text, [role="tab"], select, input[type="button"], input[type="submit"] { min-height: 44px; }
  .icon-btn { min-width: 44px; width: 44px; height: 44px; }
  .console-btn { min-height: 44px; }
  input, select, textarea { font-size: 16px; min-height: 44px; }
  .sidebar { width: 82vw; max-width: 300px; }
  #hcBox .hc-d, #hcBox .hc-d.off { min-height: 66px !important; padding: 5px 6px !important; }
  .cal-cell, .cal-cell.empty { min-height: 66px; padding: 5px 6px; }
}

/* ── D12. 요약 카드 안쪽 · 목록 · 링크 ──
   앞 블록을 적용하고 다시 찍어 보니, 카드 **안쪽**이 아직 granter 때 치수였다.
   특히 .sm-figs 가 `justify-content:center` 라 카드가 늘어난 만큼 가운데가 텅 빈다.
   격자가 카드를 가장 높은 형제에 맞춰 늘리는 것도 같이 끊는다(align-items:start). */
.summary-grid, .kpi-grid { align-items: start; }
.sm-figs { justify-content: flex-start; gap: 7px; }
.sm-lead { padding: 7px 10px 8px; border-radius: 8px; border-left-width: 3px; }
.sm-lead .k { font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500); letter-spacing: 0; }
.sm-lead .v { font-size: 20px; line-height: 1.2; }
.sm-sub { padding: 5px 2px; }
.sm-sub .k { font-size: var(--fs-xs, 12px); font-weight: var(--fw-normal, 400); }
.sm-sub .v { font-size: 15px; }
.sm-note { font-size: var(--fs-2xs, 12px); line-height: 1.45; }
.summary-stats { margin-top: 10px; padding-top: 9px; gap: 10px; }
.summary-stat .v { font-size: 16px; }
.summary-stat .l { font-size: var(--fs-2xs, 12px); margin-top: 1px; }
.mini-bar-list { margin-top: 10px; padding-top: 9px; }
.mini-bar-list .row { margin-bottom: 4px; }
.mini-bar-list .fill { background: var(--accent-strong); }
.chip-row { gap: 6px; margin: 10px 0 10px; }

/* 최근 거래 목록 — 한 줄 30px 안쪽으로 */
.tx-row { padding: 6px 0; }
.tx-list-wide .tx-row { padding: 8px 9px; }
.tx-desc { font-size: var(--fs-sm, 13px); }
.tx-date { font-size: var(--fs-2xs, 12px); }
.tx-amt { font-size: var(--fs-sm, 13px); }
/* 얼룩(줄무늬)은 쓰지 않는다 — 다우는 선과 호버로만 줄을 가른다 */
.tx-list-wide .tx-row:nth-child(odd) { background: transparent; }
.tx-list-wide .tx-row:hover { background: var(--accent-soft); }

/* 계좌 카드 */
.acct-grid { gap: 7px; }
.acct-card { padding: 8px 10px; border-radius: 8px; }
.acct-name { font-size: var(--fs-sm, 13px); margin: 1px 0 2px; }
.acct-balance { margin-top: 5px; font-size: var(--fs-sm, 13px); }

/* 칸반 */
.kanban { gap: 7px; }
#kanbanHome.kanban { max-height: 380px; }
.deal-card { padding: 8px 9px; border-radius: 8px; }
.deal-card:hover { border-color: var(--accent-strong); }

/* ── 링크 — [화면] 다우에서 누를 수 있는 글자는 파랑이다 ──
   [계산] #3851E7 on #FFF 6.00:1 · on #F4F6FA 5.55:1 */
.summary-link, a.summary-link, button.summary-link {
  color: var(--accent-strong); font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500);
}
.summary-link:hover { color: var(--accent-ink); text-decoration: underline; }

/* 표 안의 좋고 나쁨 — 의미색 그대로 */
table.simple td.danger { color: var(--danger); }
table.simple td.success { color: var(--success); }
/* 고른 줄 — 왼쪽에 파란 선 (선택은 테두리로 말한다) */
.tx-entry-row.active { background: var(--accent-soft); }
.tx-entry-row.active td:first-child { box-shadow: inset 3px 0 0 var(--accent-strong); }

/* 막대 그래프 — 수입/지출 방향을 색으로 */
.bar-seg.income  { background: var(--money-in); }
.bar-seg.expense { background: var(--money-out); opacity: .85; }
.bars { height: 140px; }
.bar-stack { height: 96px; }

/* ── D13. 찍어 보고 고친 것 ──
   ① 장부 표의 거래처 칸(.txt-cl)이 `--accent-strong` 을 쓰고 있었다. granter 때는 그 값이
      검정이라 눈에 안 띄었는데, 강조색을 파랑으로 바꾸자 **한 줄 걸러 한 줄, 열 하나가
      통째로 파래졌다.** 「색은 의미에만」에 어긋난다 — 거래처 이름은 상태도 돈의 방향도
      아니다. 본문색 + 굵기 500 으로 되돌린다.
   ② 금액도 마찬가지다. 가격은 「강조」가 아니라 숫자다.
   ③ 줄 끝 작은 단추들이 두 줄로 접혀 줄 높이가 들쭉날쭉했다. 간격을 1~2px 씩 줄여
      한 줄에 들어가게 한다. */
.txt-cl { color: var(--text); font-weight: var(--fw-medium, 500); }
.txt-off .txt-cl { color: var(--text-faint); }
.qc-final-card.qc-price .qc-final-value { color: var(--text); }
.txt-act { gap: 4px; }
.tx-not, .tx-memo, .tx-link, .tx-linked, .tx-del { padding: 2px 7px; font-size: var(--fs-xs, 12px); }
/* 「견적 잇기」가 가리키는 것은 돈이 아니라 상태다 — 파랑(조작)으로 둔다 */
.tx-link:hover { border-color: var(--accent-strong); color: var(--accent-ink); }

/* ── D14. granter 가 색 대신 붙여 둔 '-' 부호를 뗀다 ──
   2257행에 `.tx-row:not(:has(.pill)) .tx-amt.out::before { content: "-"; }` 가 있다.
   색을 전부 걷어냈을 때 수입/지출을 가를 것이 없어서 넣은 규칙이다.
   ★ 그런데 app.js 의 `t.amount` 는 지출이 이미 음수이고 `won()` 이 '-' 를 찍는다.
     그래서 홈 최근거래가 **「--669,333원」** 처럼 마이너스를 두 번 찍고 있었다.
   이제 색이 방향을 말하므로 이 규칙은 필요도 없고 틀리기까지 했다. 뗀다. */
.tx-row:not(:has(.pill)) .tx-amt.out::before { content: none; }

/* ═══════════════════════════════════════════════════════════════════════
   2026-10-07 — 파일함 · 메뉴 두 방식
   대표님 지시: 「사무실 서류철을 하나 만들어줘」 · L1~L4 · K1~K3

   ★ 왜 파일 맨 끝인가 ★
   위쪽 D1~D14 블록(다우오피스 디자인)은 조건 없는 선택자로 토큰과 치수를
   덮어쓴다. 그 앞에 쓰면 여기 적은 값이 그쪽에 진다. 맨 끝에 두면 그 위계를
   깨지 않으면서 이 화면만 더한다.

   ★ 어제 맞춘 다우오피스 규칙을 그대로 따른다 ★
   · 그림자를 쓰지 않는다 — 경계는 1px 선 하나로만 만든다
   · 선택은 바탕을 꽉 칠하는 것이 아니라 연한 파랑 바탕 + 진한 파랑 테두리
   · 글자는 14px(--fs-base) 하나로. 밀도는 높게, 줄 높이는 36~40px
   · 명암비 4.5:1 · 터치 44px(휴대폰) · 입력 16px(휴대폰)
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 1. 파일함 — 두 칸 고르기 ────────────────────────────────────────
   「전체/내가 만든 항목」 같은 거르개와 섞이지 않게, 칸 고르기는 **더 큰 단위**
   로 보여야 한다. 알약으로 만들면 아래 거르개 알약과 같은 무게로 읽혀서
   어느 쪽이 상위인지 알 수 없다. 그래서 설명 한 줄이 붙은 카드 두 장으로 둔다. */
.fb-bins { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 14px; }
.fb-bin {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  min-height: 56px; padding: 9px 12px; text-align: left;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md, 8px);
  color: var(--text-soft); font-family: inherit; box-shadow: none;
}
.fb-bin:hover { background: var(--accent-soft); border-color: var(--accent-line); }
/* 선택 = 연한 파랑 바탕 + 진한 파랑 테두리 (사이드바·칩과 같은 규칙) */
.fb-bin.active {
  background: var(--accent-soft); border-color: var(--accent-strong); color: var(--accent-ink);
}
.fb-bin-t { font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500); color: var(--text); }
.fb-bin.active .fb-bin-t { color: var(--accent-ink); }
.fb-bin-s { font-size: var(--fs-xs, 12px); line-height: 1.45; color: var(--text-faint); }

/* ── 2. 거르개 줄 — 참고 화면②(슬랙 파일 목록) 맨 윗줄 ──────────────
   왼쪽에 알약(.chip — 이미 있는 것을 그대로 쓴다. 선택된 것만 색 바탕),
   오른쪽에 찾기 칸과 다시 읽기. 좁아지면 두 줄로 접힌다. */
.fb-filters {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin-bottom: 10px;
}
.fb-pills { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.fb-tools { display: flex; gap: 6px; align-items: center; flex: none; }
.fb-search {
  min-height: var(--control-h-sm, 36px); padding: 0 11px; width: 210px; max-width: 100%;
  border: 1px solid var(--border); border-radius: var(--radius-md, 8px);
  background: var(--surface); color: var(--text);
  font-family: inherit; font-size: var(--fs-base, 14px);
}
.fb-search:focus { outline: 2px solid var(--accent-strong); outline-offset: -1px; }

/* ── 3. 올리기 칸 ────────────────────────────────────────────────────
   끌어다 놓는 것도 되게 한다. 「무엇을 얼마까지」를 칸 안에 적어 둔다 —
   올리고 나서 거절당하는 것보다 올리기 전에 아는 편이 낫다. */
.fb-up {
  border: 1px dashed var(--border); border-radius: var(--radius-md, 8px);
  background: var(--surface); padding: 11px 13px; margin-bottom: 12px;
}
.fb-up.over { border-color: var(--accent-strong); background: var(--accent-soft); }
.fb-up-t { font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500); color: var(--text); }
.fb-up-s { font-size: var(--fs-xs, 12px); line-height: 1.5; color: var(--text-faint); margin-top: 1px; }
.fb-up-form { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 9px; }
.fb-tag-in {
  min-height: var(--control-h-sm, 36px); padding: 0 11px; width: 240px; max-width: 100%;
  border: 1px solid var(--border); border-radius: var(--radius-md, 8px);
  background: var(--surface); color: var(--text); font-family: inherit; font-size: var(--fs-base, 14px);
}
.fb-file-in { font-size: var(--fs-sm, 13px); color: var(--text-soft); max-width: 100%; }
.fb-up-hints { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.fb-up-hints .chip { min-height: 26px; padding: 0 9px; font-size: var(--fs-xs, 12px); }
.fb-locked { margin-bottom: 12px; }
.fb-locked b { font-weight: var(--fw-medium, 500); }

/* 알림 한 줄 — 올렸다·못 올렸다를 조용히 지나치지 않게 */
.fb-say {
  margin-bottom: 10px; padding: 8px 11px; border-radius: var(--radius-md, 8px);
  font-size: var(--fs-sm, 13px); line-height: 1.5;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
}
.fb-say.ok  { background: var(--success-soft); border-color: var(--success-soft); color: var(--success-ink); }
.fb-say.bad { background: var(--danger-soft);  border-color: var(--danger-soft);  color: var(--danger-ink, var(--danger)); }

/* ── 4. 목록 — 한 줄에 파일 하나 ─────────────────────────────────────
   참고 화면② 그대로: 종류 아이콘(둥근 사각) + 이름(굵게) + 작은 배지,
   그 아래 「누가 · 언제」(연한 글자), 오른쪽 끝에 내려받기 · 별 · ⋮.
   줄 사이는 1px 선이고 전체가 둥근 모서리 상자 안에 들어간다. */
.fb-list {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md, 8px);
  overflow: visible;      /* ⋮ 쪽지가 줄 밖으로 나와야 한다 */
}
.fb-row {
  position: relative; display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-top: 1px solid var(--border);
}
.fb-row:first-child { border-top: none; }
.fb-row:hover { background: var(--accent-soft); }
/* 종류 아이콘 — 꽉 찬 색 + 흰 글자.
   [계산] 흰 글자 기준 명암비: PDF 5.44 · W 7.21 · X 6.17 · P 5.68 · 한 6.30 ·
          그림 7.38 · ZIP 6.53 · 파일 9.80 — 전부 4.5:1 위. 라이트·다크 같은 값을
          쓴다(색이 짙어서 어느 바탕에서도 흰 글자가 읽힌다). */
.fb-ico {
  flex: none; width: 34px; height: 34px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: var(--fw-medium, 500); letter-spacing: 0;
  color: #FFFFFF; background: #44443E;
}
.fb-ico-pdf { background: #C0392B; }
.fb-ico-doc { background: #2B5797; }
.fb-ico-xls { background: #1D6F42; }
.fb-ico-ppt { background: #A1510C; }
.fb-ico-hwp { background: #0F6B6B; }
.fb-ico-img { background: #6B3FA0; }
.fb-ico-zip { background: #5E5E58; }
.fb-ico-etc { background: #44443E; }

.fb-body { flex: 1; min-width: 0; }
.fb-l1 { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.fb-name {
  font-size: var(--fs-base, 14px); font-weight: var(--fw-medium, 500); color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.fb-badge { flex: none; }
/* 「누가 · 언제」 — 연한 글자. --text-faint 는 4.5:1 을 넘는 값으로 맞춰 둔 토큰이다 */
.fb-meta { font-size: var(--fs-xs, 12px); line-height: 1.45; color: var(--text-faint); margin-top: 1px; }

.fb-act { flex: none; display: flex; gap: 3px; align-items: center; }
.fb-act .icon-btn { width: 32px; height: 32px; min-width: 32px; border-color: transparent; background: transparent; }
.fb-act .icon-btn:hover { background: var(--surface-2); border-color: var(--border); }
.fb-act .icon-btn svg { width: 16px; height: 16px; }
/* 별이 켜지면 채운다 — 「켜짐」을 색 하나로만 말하지 않고 모양으로도 말한다 */
.fb-fav.on { color: var(--warning); }
.fb-fav.on svg { fill: currentColor; }

/* ⋮ 쪽지 */
.fb-more-menu {
  position: absolute; right: 8px; top: calc(100% - 6px); z-index: 30;
  min-width: 150px; padding: 4px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md, 8px);
  display: flex; flex-direction: column; gap: 1px;
}
.fb-more-menu button {
  min-height: 34px; padding: 0 10px; text-align: left;
  background: transparent; border: none; border-radius: 6px; color: var(--text);
  font-family: inherit; font-size: var(--fs-sm, 13px);
}
.fb-more-menu button:hover { background: var(--accent-soft); color: var(--accent-ink); }
.fb-more-menu button.danger { color: var(--danger); }
.fb-more-menu button.danger:hover { background: var(--danger-soft); color: var(--danger); }
.fb-more-note { padding: 7px 10px; font-size: var(--fs-xs, 12px); color: var(--text-faint); }

.fb-empty { padding: 26px 14px; text-align: center; font-size: var(--fs-sm, 13px); color: var(--text-faint); }
.fb-foot { margin-top: 8px; font-size: var(--fs-xs, 12px); color: var(--text-faint); }
.fb-path { color: var(--text-faint); opacity: .8; }

/* 휴대폰 — 칸 고르기는 한 줄에 하나, 조작 요소는 44px 로 되돌린다 */
@media (max-width: 860px) {
  .fb-bins { grid-template-columns: 1fr; }
  .fb-filters { flex-direction: column; align-items: stretch; }
  .fb-tools { width: 100%; }
  .fb-search { flex: 1; width: auto; }
  .fb-up-form { flex-direction: column; align-items: stretch; }
  .fb-tag-in { width: 100%; }
  .fb-row { padding: 10px; gap: 9px; align-items: flex-start; }
  .fb-act { flex-wrap: nowrap; }
  .fb-act .icon-btn { width: 44px; height: 44px; min-width: 44px; }
  .fb-search, .fb-tag-in { font-size: 16px; min-height: 44px; }
  .fb-up-hints .chip { min-height: 44px; }
  .fb-bin { min-height: 44px; }
  .fb-more-menu button { min-height: 44px; }
}
/* 390px 쯤에서 줄이 두 줄로 접히지 않게 — 이름이 길면 말줄임으로 자른다.
   오른쪽 세 단추는 접히면 누를 자리를 못 찾으므로 줄에서 떨어뜨리지 않는다. */
@media (max-width: 430px) {
  .fb-ico { width: 30px; height: 30px; border-radius: 6px; font-size: 10px; }
  .fb-row { gap: 7px; padding: 9px 8px; }
  .fb-act { gap: 0; }
  .fb-act .icon-btn { width: 40px; min-width: 40px; }
  .fb-foot .fb-path { display: block; }
}

/* ── 5. 메뉴 두 방식 — 접기 단추 ─────────────────────────────────────
   「버튼을 눌렀을때 글까지 함께 보이는 메뉴」(K2)와 「아이콘만」(K1)을 오가는
   단추 하나. 브랜드 줄 오른쪽 끝에 둔다. */
.nav-toggle { width: 30px; height: 30px; min-width: 30px; flex: none; border-color: transparent; background: transparent; }
.nav-toggle:hover { background: var(--surface-2); border-color: var(--border); }
.nav-toggle svg { width: 16px; height: 16px; }
.nav-toggle .nt-out { display: none; }
body.sein-nav-collapsed .nav-toggle .nt-in  { display: none; }
body.sein-nav-collapsed .nav-toggle .nt-out { display: block; }
/* 휴대폰 폭의 사이드바는 밀어 넣는 서랍이다 — 본문과 자리를 나누지 않으므로
   접을 이유가 없고, 접으면 서랍이 64px 쪼가리가 된다. 그래서 단추를 감춘다. */
@media (max-width: 860px) { .nav-toggle { display: none; } }

/* ── 6. 접힌 상태 — 아이콘만 (K1) ───────────────────────────────────
   232px → 64px. --sidebar-w 하나만 바꾸면 사이드바 폭과 본문 폭이 함께 따라온다
   (.sidebar 가 그 토큰으로 폭을 정하고 .main 은 남은 자리를 차지한다).
   ★ 861px 이상에서만 ★ 그 아래에서는 사이드바가 서랍이라 접힘이 뜻을 잃는다. */
@media (min-width: 861px) {
  body.sein-nav-collapsed { --sidebar-w: 64px; }
  body.sein-nav-collapsed .sidebar { overflow-x: hidden; }

  /* 브랜드 — 로고와 접기 단추만 세로로. 상호·사람 이름은 들어갈 자리가 없다. */
  body.sein-nav-collapsed .brand {
    flex-direction: column; gap: 5px; padding: 9px 0 8px; justify-content: center;
  }
  body.sein-nav-collapsed .brand > div:last-of-type { display: none; }
  body.sein-nav-collapsed .brand-mark { width: 26px; height: 26px; }

  /* 업무 / 마케팅 — 한 글자만. 실제 이름은 aria-label·title 에 남는다
     (web/nav-collapse.js 가 data-short 를 적어 준다). */
  body.sein-nav-collapsed .console-switch { flex-direction: column; gap: 2px; margin: 0 9px 8px; }
  body.sein-nav-collapsed .console-btn { font-size: 0; min-height: 28px; padding: 0; }
  body.sein-nav-collapsed .console-btn::after {
    content: attr(data-short); font-size: var(--fs-xs, 12px); font-weight: inherit;
  }

  /* 메뉴 — 아이콘만.
     ★ 글자를 지우지 않고 font-size:0 으로 재운다 ★
     글자(텍스트 노드)를 지우면 펼칠 때 되살릴 방법이 없고, 읽어 주는 기계도
     메뉴 이름을 잃는다. 눈에만 없애면 둘 다 해결된다. svg 치수는 px 라서
     font-size 에 끌려가지 않는다. */
  body.sein-nav-collapsed .nav { padding: 0 10px; }
  body.sein-nav-collapsed .nav-item {
    justify-content: center; gap: 0; padding: 0; font-size: 0;
    width: 44px; min-height: 40px;
  }
  body.sein-nav-collapsed .nav-item svg { width: 18px; height: 18px; }
  body.sein-nav-collapsed .nav-chevron { display: none; }
  /* 하위가 있는 메뉴에는 작은 점 하나 — 접혀도 「더 있다」가 보이게 */
  body.sein-nav-collapsed .nav-item.has-sub::after {
    content: ''; position: absolute; right: 4px; bottom: 5px;
    width: 3px; height: 3px; border-radius: 50%; background: var(--text-faint);
  }
  body.sein-nav-collapsed .nav-item.active.has-sub::after { background: var(--accent-strong); }
  /* 저작권 줄은 64px 에 들어가지 않는다 */
  body.sein-nav-collapsed .sidebar-foot { display: none; }
}

/* ── 7. 접힌 동안의 하위 메뉴 — 날아오는 상자 ───────────────────────
   「서류」·「설정」·「계정 관리」에는 하위가 있다. 64px 안에 그 글자가 들어갈
   자리가 없는데, 안 보이면 그 아래 화면 스물 몇 개에 **갈 길이 통째로 없어진다.**
   그래서 상자를 아이콘 오른쪽으로 날린다. 자리는 web/nav-collapse.js 가 잰다
   (사이드바에 overflow-y:auto 가 걸려 있어 안에 두면 잘리므로 <body> 로 옮긴다). */
/* ★ 861px 이상에서만 ★ 그 아래에서는 사이드바가 서랍이라 날릴 곳이 없다.
   (web/nav-collapse.js 도 그 폭에서는 상자를 옮기지 않는다 — 둘을 같이 걸어
   두어야, 한쪽만 고친 날 상자가 허공에 뜨는 일이 생기지 않는다.) */
@media (min-width: 861px) {
.nav-submenu.nav-flyout {
  position: fixed; z-index: 240; width: 224px; padding: 5px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 28px -14px rgba(22, 22, 21, 0.28);
  max-height: 78vh; overflow-y: auto;
}
.nav-submenu.nav-flyout::before {
  content: attr(data-title); display: block; flex: none;
  padding: 5px 9px 7px; margin-bottom: 2px; border-bottom: 1px solid var(--border);
  font-size: var(--fs-xs, 12px); font-weight: var(--fw-medium, 500); color: var(--text-faint);
}
.nav-submenu.nav-flyout .nav-subitem,
.nav-submenu.nav-flyout .nav-subgroup { font-size: var(--fs-sm, 13px); min-height: 34px; }
.nav-submenu.nav-flyout .nav-subgroup-items { margin-left: 10px; padding-left: 8px; }
/* 다크에서는 그림자 대신 테두리가 경계를 만든다 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .nav-submenu.nav-flyout { box-shadow: 0 12px 30px -14px rgba(0, 0, 0, 0.7); }
}
:root[data-theme="dark"] .nav-submenu.nav-flyout { box-shadow: 0 12px 30px -14px rgba(0, 0, 0, 0.7); }
}   /* @media (min-width: 861px) — 날아오는 상자 끝 */

/* 접힌 메뉴의 툴팁 — 「마우스를 올리면 이름이 뜨게」(대표님 지시).
   [계산] #F2F2EC on #161615 = 15.1:1 */
.nav-tip {
  position: fixed; z-index: 260; pointer-events: none; white-space: nowrap;
  background: var(--ink); color: #F2F2EC;
  font-size: var(--fs-xs, 12px); line-height: 16px; padding: 5px 9px; border-radius: 6px;
  opacity: 0; transition: opacity 120ms var(--ease-out-strong, ease-out);
}
.nav-tip.on { opacity: 1; }
/* 다크에서 --ink 는 순검정이라 흰 글자가 그대로 읽힌다. 테두리만 하나 둘러
   어두운 바탕 위에서 쪽지의 경계가 사라지지 않게 한다. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .nav-tip { border: 1px solid var(--border); }
}
:root[data-theme="dark"] .nav-tip { border: 1px solid var(--border); }
/* 움직임을 줄이기로 해 둔 사람에게는 서서히 뜨지 않게 */
@media (prefers-reduced-motion: reduce) { .nav-tip { transition: none; } }

/* ── 8. 접기 단추가 끼어들면서 되살려야 하는 규칙 하나 ──────────────
   위쪽(157행 부근)에 `.brand > div:last-child { min-width:0; flex:1 }` 가 있다.
   긴 이름(「대표 · 박지현아무개」)이 로그인했을 때 사이드바 머리가 무너지지 않게
   말줄임을 걸어 둔 규칙이다. 그런데 접기 단추를 .brand 의 **마지막 자식**으로
   넣는 바람에 `div:last-child` 가 더 이상 글자 칸을 가리키지 않는다.
   그 규칙이 하던 일을 여기서 다시 세운다 — 선택자만 `div:last-of-type`
   (= .brand 안의 마지막 div = 글자 칸) 으로 바꾼 같은 규칙이다. */
.brand > div:last-of-type { min-width: 0; flex: 1; }

/* ============================================================================
   2026-10-07 — 화면을 심플하게 (설명 접기)

   대표님 원문: 「지금은 대시보드내에 모든 설명이 옆에 나와 있고 불필요 한것들도
   다 보이게 되니 그것도 눈에 안띄고 최대한 심플했으면 좋겠어」

   화면마다 제목 아래에 설명이 한 줄씩 상주한다(19개, 가장 긴 것 279자).
   매일 쓰는 사람에게는 한 번 읽고 끝인 글인데 본문을 그만큼 아래로 밀어낸다.
   **기본을 접힘으로 바꾸고**, 제목 옆 ⓘ 로 펼친다.

   `.hint` 는 설명과 오류·상태 표시가 같은 클래스를 쓰고 있어서 일괄로 감추면
   「기록을 불러오지 못했습니다」까지 사라진다. 그래서 web/simplify.js 가 글을
   읽어 가른 뒤 `data-sein-ex="1"`(설명) / `"0"`(상태) 을 달아 둔다.
   **여기서 감추는 것은 1 뿐이다.**

   되살릴 때 `display:block` 이 아니라 `revert` 를 쓴다 — `.hint` 는 div 도
   span 도 있어서 block 으로 되살리면 한 줄 안에 있던 것이 아래로 떨어진다.
   (`.hint` 에 display 를 건 다른 규칙이 없음을 확인하고 쓴다.)
   ========================================================================= */

/* ── 접힘 (기본) ── */
.topbar .sub { display: none; }
.hint[data-sein-ex="1"] { display: none; }
/* 설명이 없으면 제목 아래 8px 빈칸도 없앤다 */
body:not(.sein-explain) .topbar h1 { margin-bottom: 0; }

/* ── 펼침 ── */
body.sein-explain .topbar .sub { display: block; }
body.sein-explain .hint[data-sein-ex="1"] { display: revert; }

/* ── 제목 옆 ⓘ 단추 ──
   `.topbar` 는 `justify-content: space-between` 이라 둘째 칸이 오른쪽 끝으로
   밀린다. `margin-right:auto` 로 남은 공간을 이 단추가 먹어서 제목 바로
   옆에 붙게 한다(그 뒤에 있던 동작 단추들은 그대로 오른쪽에 남는다).
   터치 크기는 44px 을 지킨다 — 글씨는 18px 이고 나머지는 눌리는 자리다. */
.topbar h1 { display: flex; align-items: center; gap: 2px; }
.sein-ex-btn {
  flex: 0 0 auto;
  /* 44px 을 그대로 두면 제목 줄이 그만큼 높아진다. 위아래로 당겨 상쇄한다 —
     눌리는 자리는 44px 그대로이고 차지하는 높이만 줄어든다. */
  margin: -12px 0 -12px 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-soft);          /* 흰 바탕 위 5.79:1 */
  cursor: pointer;
  transition: background-color 120ms var(--ease-out-strong, ease-out),
              color 120ms var(--ease-out-strong, ease-out);
}
.sein-ex-btn svg { width: 18px; height: 18px; }
.sein-ex-btn:hover { background: var(--surface-2); color: var(--text); }
.sein-ex-btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.sein-ex-btn[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent-ink);         /* 연한 파랑 위 6.54:1 */
}
@media (prefers-reduced-motion: reduce) { .sein-ex-btn { transition: none; } }

/* 휴대폰에서는 제목과 ⓘ 가 한 줄에 들어가야 한다 — 단추를 조금 당긴다 */
@media (max-width: 640px) {
  .sein-ex-btn { margin: -12px 0 -12px 0; }
}
