@charset "UTF-8";

/* ==========================================================================
   rs-ui — 운영자 화면용 UI 프레임
   --------------------------------------------------------------------------
   rs-* 파트너/관리자 프로젝트가 함께 쓰는 디자인 시스템이다.
   이 파일은 프로젝트에 종속되지 않는다. 브랜드 색 같은 것은 테마 파일에서만 바꾼다.

   쓰는 법
     <link rel="stylesheet" href="/css/rs-ui/rs-ui.css">        <- 프레임 (공통)
     <link rel="stylesheet" href="/css/rs-ui/theme-<이름>.css">  <- 테마 (프로젝트별)

   다른 프로젝트에 얹을 때
     1. css/rs-ui/rs-ui.css 를 그대로 복사한다. 고치지 않는다.
     2. theme-<이름>.css 를 하나 만들어 :root 의 토큰만 덮어쓴다.
        보통 --accent 계열과 --brand-name 정도면 충분하다.
     3. 화면 골격은 .app > .app-side + .app-main > .topbar + .app-body 구조를 따른다.

   설계 기준
     1) 색은 의미가 있을 때만 쓴다.
        기본은 무채색, 강조는 accent 하나, 상태는 up/down/warn 셋뿐이다.
     2) 읽기 쉬움을 밀도보다 앞에 둔다.
        나이가 있는 운영자도 쓰는 화면이다. 본문 15px, 표 14px 을 하한으로 하고
        모든 글자색은 배경 대비 4.5:1 이상을 지킨다. 누르는 것은 36px 이상으로 둔다.
     3) 간격과 글자 크기는 토큰으로만 정한다. 인라인 style 을 쓰지 않는다.
   ========================================================================== */


:root {
    /* ── 표면 ──
       하루 종일 숫자를 보는 화면이라 밝은 바탕에 어두운 글자로 간다.
       어두운 화면은 장시간 보면 눈이 빨리 지친다.
       본문은 흰색, 사이드바와 표 머리만 아주 옅은 회색으로 단을 나눈다. */
    --bg:            #f5f6f8;
    --surface:       #ffffff;
    --surface-2:     #f7f8fa;
    --surface-3:     #eef0f4;
    --border:        #e5e7eb;
    --border-strong: #d1d5db;

    /* ── 글자 ──
       나이가 있는 운영자도 쓰는 화면이라 명도 대비를 WCAG AA(4.5:1) 위로 맞춘다.
       회색 본문(#f5f6f8) 기준 text 13.6:1, text-2 7.0:1, text-3 4.8:1.
       흰 카드 위에서는 각각 14.7:1 / 7.6:1 / 5.2:1 이다. */
    --text:      #1f2937;
    --text-2:    #4b5563;
    --text-3:    #646d7b;

    /* ── 어두운 크롬 ── 상단바와 사이드바는 어둡게 두어 본문과 확실히 나눈다.
       사이드바를 상단바보다 한 단계 밝게 해 두 영역이 서로 구분된다. */
    --top-bg:    #1c2534;
    --top-text:  #ffffff;
    --top-text-2:#9ca8bd;
    --top-border:#2b3648;
    --side-bg:     #232d3f;
    --side-text:   #e6eaf0;
    --side-text-2: #a3aec2;
    --side-border: #313d52;
    --side-accent: #6ea8fb;

    /* 표 머리. 상단바보다 한 단계 밝고 사이드바와 같은 계열 */
    --head-bg:   #2b3648;
    --head-text: #eef1f6;
    --head-line: #3d4a60;

    /* 표의 줄 */
    --row-alt:   #fafbfc;   /* 짝수 줄 */
    --row-hover: #eef3fc;   /* 마우스가 있는 줄 */

    /* 조회줄. 결과(흰 카드)와 성격이 달라 한 눈에 구분되게 살짝 푸른 회색을 쓴다 */
    --tool-bg:   #e9edf4;
    --tool-line: #ccd4e0;

    /* ── 강조 ── 화면 전체에서 파랑은 "지금 선택된 것/주요 동작" 하나만 뜻한다 */
    --accent:      #2563eb;
    --accent-hover:#1d4ed8;
    --accent-weak: #e8effd;
    --accent-line: #bfd4fa;

    /* ── 돈의 색 ────────────────────────────────────────────────
       이 화면들은 숫자만 본다. 색이 뜻을 갖고 있어야 훑을 수 있다.

         수익 · 차액   0보다 크면 파랑, 작으면 빨강, 0이면 검정
         배팅 · 입금   빨강 계열   (판에 들어온 돈)
         당첨 · 출금   파랑 계열   (판에서 나간 돈)

       0 을 회색으로 흐리게 두면 "값이 없다" 로 읽힌다. 0 도 확인한 값이므로
       검정으로 두고 굵기만 낮춘다.

       모든 값은 흰 카드와 회색 본문 양쪽에서 5:1 이상이다. */
    --up:          #1d4ed8;   /* 늘어남 · 이익 */
    --up-weak:     #e8effd;   /* 바탕 */
    --up-weak-2:   #d7e3fb;   /* 마우스를 올렸을 때 */
    --up-line:     #b7cbf6;   /* 테두리 */
    --down:        #c81e1e;   /* 줄어듦 · 손실 */
    --down-weak:   #fdeaea;
    --down-weak-2: #fbdcdc;
    --down-line:   #f2b6b6;
    /* 지급 · 회수 버튼. 이건 금액이 아니라 동작이라 돈의 색과 분리한다.
       파랑을 쓰면 조회 버튼과 구분되지 않고, 빨강만 쓰면 둘 다 위험해 보인다. */
    --give:        #14733a;   /* 지급 */
    --give-weak:   #e7f6ec;
    --give-weak-2: #d6efe0;
    --give-line:   #a8d9bd;
    --take:        #c81e1e;   /* 회수 */
    --take-weak:   #fdeaea;
    --take-weak-2: #fbdcdc;
    --take-line:   #f2b6b6;

    --warn:        #a34a08;
    --warn-weak:   #fdf1e3;
    --warn-line:   #eccfa4;

    /* ── 간격 ── 4px 배수 */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 20px; --s6: 24px; --s8: 32px; --s10: 40px;

    /* ── 모양 ── */
    --r1: 4px; --r2: 6px; --r3: 10px; --r4: 14px;
    --shadow:    0 1px 2px rgba(16,24,40,.06);
    --shadow-lg: 0 12px 32px rgba(16,24,40,.14);

    /* ── 타이포 ──
       숫자는 자리폭을 고정해 세로로 줄이 맞게 한다.
       크기는 가독성을 우선해 잡았다. 본문 15px, 표 14px 이 하한이다.
       밀도를 조금 포기하더라도 글자가 확실히 보이는 쪽을 택한다. */
    --font: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI',
            'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif;
    --fs-xs: 12px;   /* 라벨, 뱃지 */
    --fs-sm: 13px;   /* 보조 문구 */
    --fs-td: 14px;   /* 표 안의 값 */
    --fs-md: 15px;   /* 본문 기준 */
    --fs-lg: 17px;   /* 화면 제목 */
    --fs-xl: 24px;   /* 지표 숫자 */

    /* ── 골격 치수 ──
       누르는 것은 36px 이상으로 둔다. 손이 정확하지 않아도 눌리게 하기 위함이다. */
    --sidebar-w: 244px;
    --topbar-h:  60px;
    --control-h: 36px;
}

/* ==========================================================================
   기본
   ========================================================================== */

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: var(--fs-md);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* 숫자가 들어가는 곳은 자리폭 고정 */
.num, td, th, .stat-value, input[type="text"] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cbd2dc; border-radius: 99px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #aab3c0; }

/* ==========================================================================
   골격 — 사이드바 + 상단바 + 본문
   ========================================================================== */

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

.app-side {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.app-main {
    flex: 1 1 auto;
    min-width: 0;             /* 넓은 테이블이 레이아웃을 밀지 못하게 한다 */
    display: flex;
    flex-direction: column;
}

.app-body { padding: var(--s5); flex: 1 1 auto; }

/* ── 브랜드 ── */
.brand {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: 0 var(--s5);
    border-bottom: 1px solid var(--border);
    font-weight: 800;
    letter-spacing: .14em;
    font-size: var(--fs-md);
    flex: 0 0 auto;
}
.brand-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }

/* ── 메뉴 ── */

/*
 * display 를 못 박는다.
 *
 * 부트스트랩에도 .nav 가 있고 그쪽은 display:flex 다. 같은 이름이라
 * 사이드바가 가로 flex 가 되어 메뉴 항목이 내용 폭만큼만 줄어 있었다.
 * 사이드바는 244px 인데 메뉴 버튼이 129px 이었고, 그래서 caret 의
 * margin-left:auto 도 밀 자리가 없어 글자 바로 뒤에 붙어 있었다.
 */
.app-side .nav { display: block; }
.nav { padding: var(--s3) var(--s3) var(--s6); }
.nav-group + .nav-group { margin-top: var(--s1); }

.nav-title {
    width: 100%;
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s2) var(--s3);
    background: none;
    border: 0;
    border-radius: var(--r2);
    color: var(--text-2);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-align: left;
}
.nav-title:hover { background: var(--surface-2); color: var(--text); }
.nav-title .ico { width: 16px; text-align: center; color: var(--text-3); flex: 0 0 16px; }
.nav-title .caret { margin-left: auto; font-size: 10px; color: var(--text-3); transition: transform .18s; }
.nav-group.open .nav-title { color: var(--text); }
.nav-group.open .nav-title .caret { transform: rotate(90deg); }
.nav-group.open .nav-title .ico { color: var(--accent); }

.nav-items { display: none; padding: var(--s1) 0 var(--s2) 0; }
.nav-group.open .nav-items { display: block; }

.nav-link {
    display: block;
    position: relative;
    padding: 7px var(--s3) 7px 43px;
    border-radius: var(--r2);
    color: var(--text-2);
    font-size: var(--fs-md);
}
.nav-link:hover { background: var(--surface-2); color: var(--text); }
.nav-link.active { background: var(--accent-weak); color: var(--text); font-weight: 600; }
.nav-link.active::before {
    content: '';
    position: absolute;
    left: 22px; top: 50%;
    width: 4px; height: 4px;
    margin-top: -2px;
    border-radius: 50%;
    background: var(--accent);
}

.nav-foot { margin-top: auto; padding: var(--s3); border-top: 1px solid var(--border); }

/* ── 상단바 ── */
.topbar {
    height: var(--topbar-h);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--s4);
    padding: 0 var(--s5);
    background: var(--top-bg);
    color: var(--top-text);
    border-bottom: 1px solid var(--top-border);
    position: sticky;
    top: 0;
    z-index: 30;
}
.topbar h1 { margin: 0; font-size: var(--fs-lg); font-weight: 700; letter-spacing: -.01em; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }

/* 상단바의 내 잔액 — 숫자만 눈에 들어오게 */
.wallet { display: flex; align-items: center; gap: var(--s4); padding-right: var(--s2); }
.wallet-item { display: flex; align-items: baseline; gap: var(--s2); }
.wallet-label { color: var(--text-3); font-size: var(--fs-xs); }
.wallet-value { font-weight: 700; font-size: var(--fs-md); }

.hamburger { display: none; background: none; border: 0; color: var(--text-2); font-size: 17px; cursor: pointer; padding: var(--s2); }

/* ==========================================================================
   버튼
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--control-h);
    padding: 0 var(--s3);
    border: 1px solid var(--border-strong);
    border-radius: var(--r2);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background .14s, border-color .14s, color .14s;
}
.btn:hover { background: var(--surface-3); border-color: var(--border-strong); color: var(--text); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; }

.btn-quiet { background: transparent; border-color: transparent; color: var(--text-2); }
.btn-quiet:hover { background: var(--surface-2); color: var(--text); }

.btn-up   { color: var(--give); border-color: var(--give-line); background: var(--give-weak); }
.btn-up:hover   { background: var(--give-weak-2); color: var(--give); }
.btn-down { color: var(--take); border-color: var(--take-line); background: var(--take-weak); }
.btn-down:hover { background: var(--take-weak-2); color: var(--take); }

.btn-xs { height: 24px; padding: 0 var(--s2); font-size: var(--fs-xs); }
.btn-sm { height: 28px; padding: 0 10px; font-size: var(--fs-sm); }

/* 표 칸 안의 작은 버튼.
   투명하게 두면 글자처럼 보여 누를 수 있다는 걸 모른다.
   이 화면은 어르신도 쓰므로 테두리와 바탕을 줘서 버튼임이 보이게 한다. */
.btn-cell {
    height: 26px; padding: 0 10px;
    font-size: var(--fs-sm); font-weight: 700;
    border-radius: var(--r2);
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    color: var(--text-2);
}
.btn-cell:hover { background: var(--surface-3); border-color: var(--text-3); }

.btn-cell.up {
    color: var(--give); background: var(--give-weak); border-color: var(--give-line);
}
.btn-cell.up:hover { background: var(--give-weak-2); }

.btn-cell.down {
    color: var(--take); background: var(--take-weak); border-color: var(--take-line);
}
.btn-cell.down:hover { background: var(--take-weak-2); }

.btn-group { display: inline-flex; gap: var(--s1); }

/* ==========================================================================
   입력
   ========================================================================== */

.field, input[type="text"].field, select.field {
    /* width:100% 를 준 칸에 padding 이 더해지면 부모보다 넓어져 오른쪽이
       삐져나온다. 로그인 화면의 아이디 칸과 비밀번호 칸이 30px 어긋나 있었다. */
    box-sizing: border-box;
    height: var(--control-h);
    padding: 0 10px;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--r2);
    color: var(--text);
    font: inherit;
    font-size: var(--fs-sm);
}
.field::placeholder { color: var(--text-3); }
.field:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
.field[readonly] { cursor: pointer; }
select.field { appearance: none; padding-right: 26px;
    background-image: linear-gradient(45deg, transparent 50%, var(--text-3) 50%), linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
    background-position: calc(100% - 14px) 14px, calc(100% - 9px) 14px;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}
textarea.field { height: auto; padding: var(--s2) 10px; line-height: 1.6; resize: vertical; }

.field-w-sm { width: 110px; }
.field-w-md { width: 180px; }
.field-w-lg { width: 260px; }

/* ==========================================================================
   카드 / 패널
   ========================================================================== */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r3);
}
.card + .card { margin-top: var(--s4); }
/* 격자 · flex 안에서는 gap 이 간격을 맡는다.
   여기서 위 여백이 남으면 둘째 칸만 아래로 밀려 카드 높이가 어긋난다. */
.rate-grid > .card + .card,
.stat-row > .card + .card,
.dash-charts > .card + .card,
.row-flex > .card + .card { margin-top: 0; }
.card-head {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--border);
}
.card-title { font-size: var(--fs-md); font-weight: 700; }
.card-body { padding: var(--s4); }
.card-body.flush { padding: 0; }

/* 필터 줄 — 화면 맨 위에서 조건을 잡는 자리 */
/* 조회줄.
   카드와 같은 흰색이면 "조건을 잡는 곳" 과 "결과" 가 구분되지 않는다.
   한 단계 낮춘 면에 테두리를 조금 진하게 두어 다른 성격임을 보인다. */
.toolbar {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
    padding: var(--s3) var(--s4);
    background: var(--tool-bg);
    border: 1px solid var(--tool-line);
    border-radius: var(--r3);
    margin-bottom: var(--s4);
}
.toolbar .spacer { flex: 1 1 auto; }
.toolbar-label { color: var(--text-3); font-size: var(--fs-xs); font-weight: 600; }
.date-sep { color: var(--text-3); }

/* ==========================================================================
   지표 카드 — 대시보드 전용
   ========================================================================== */

.stat-grid { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.stat {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r3);
    padding: var(--s4);
}
.stat-label { color: var(--text-3); font-size: var(--fs-xs); font-weight: 600; letter-spacing: .02em; }
.stat-value { margin-top: 6px; font-size: 22px; font-weight: 750; letter-spacing: -.02em; }
.stat-value.up { color: var(--up); }
.stat-value.down { color: var(--down); }
.stat-sub { margin-top: 4px; color: var(--text-3); font-size: var(--fs-xs); }

.meter { margin-top: var(--s2); height: 4px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.meter > span { display: block; height: 100%; background: var(--accent); border-radius: 99px; }

/* ==========================================================================
   표 — 이 화면들의 주인공
   ========================================================================== */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.data { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-td); }

/* 표 머리는 어두운 띠다.
   상단바 · 사이드바와 같은 계열이라 화면이 하나로 묶여 보이고,
   흰 카드 위에서 "여기부터 데이터" 라는 경계가 분명해진다.
   옅은 회색 머리는 본문과 붙어 보여 어디가 제목인지 한 번 더 봐야 한다. */
table.data thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--head-bg);
    color: var(--head-text);
    font-size: var(--fs-sm);
    font-weight: 700;
    letter-spacing: -.005em;
    text-align: left;
    white-space: nowrap;
    padding: 11px var(--s3);
    border-bottom: 0;
}
/* 칸 사이 실선. 열이 열두 개씩 되면 세로선이 있어야 눈이 따라간다. */
table.data thead th + th { box-shadow: inset 1px 0 0 var(--head-line); }

/* 여러 칸을 묶는 머리(카지노 · 슬롯 같은 것). 아래 줄과 이어져 보이도록
   밑선을 지우고 살짝 밝게 둔다. 예전에는 인라인으로 밝은 배경을 칠해
   어두운 머리 안에 흰 칸이 뚫린 것처럼 보였다. */
/*
 * 여러 칸을 묶는 머리 (카지노 · 슬롯 같은 것).
 *
 * 배경을 반투명으로 주면 안 된다. th 자체가 색을 갖는 층이라 뒤에는
 * 카드의 흰 배경이 있고, 흰색 10% 를 흰 바탕에 겹치면 그냥 흰색이 된다.
 * 실제로 글자까지 흰색이라 "카지노"와 "슬롯"이 통째로 사라져 보였다.
 * 불투명한 색으로 적는다.
 */
table.data thead th.group {
    background: #39465e;
    color: var(--head-text);
    text-align: center;
    letter-spacing: .06em;
}
table.data thead th:first-child { border-top-left-radius: var(--r3); }
table.data thead th:last-child  { border-top-right-radius: var(--r3); }
table.data thead th.right  { text-align: right; }
table.data thead th.center { text-align: center; }

/* 두 줄로 쓴 머리글이 눌리지 않게 최소 폭을 준다.
   템플릿 열두 자리가 이 이름을 쓰는데 정의가 없어 아무 효과가 없었다.
   partner/list 는 같은 표에서 style="min-width: 80px" 로 같은 일을 한다. */
table.data thead th.min-width-80 { min-width: 80px; }

table.data tbody td {
    padding: 11px var(--s3);
    border-bottom: 1px solid var(--border);
    color: var(--text);
    vertical-align: middle;
}
/* 한 줄씩 옅게 깔아 준다. 가로로 훑을 때 줄을 놓치지 않는다. */
table.data tbody tr:nth-child(even) td { background: var(--row-alt); }

/* 마우스가 있는 줄은 왼쪽에 표시가 선다.
   바탕색만 바꾸면 줄무늬와 섞여 어느 줄인지 잘 보이지 않는다. */
table.data tbody tr:hover td { background: var(--row-hover); }
table.data tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

table.data tbody tr:last-child td { border-bottom: 0; }

table.data td.right { text-align: right; }
table.data td.center { text-align: center; }
table.data td.nowrap { white-space: nowrap; }

/* 돈의 색.
 *
 * 표 안에서도 이겨야 한다. table.data tbody td 가 color 를 지정하고 있어
 * 그쪽 특이도(0,1,2)가 클래스 하나(0,1,0)보다 높다. 그래서 실제 화면에서는
 * 금액이 전부 검정으로 나왔다 — 클래스는 붙어 있는데 색만 먹지 않았다.
 * 표 안쪽 선택자를 함께 적어 특이도를 맞춘다.
 *
 * 두 갈래가 있다.
 *   .pos / .neg / .zero   계산된 값(수익 · 차액)의 부호를 따른다
 *   .amt-in / .amt-out    돈이 어느 쪽으로 움직였는지를 따른다. 부호와 무관하다
 */

/* 계산된 값의 부호. 0보다 크면 파랑, 작으면 빨강, 0이면 검정 */
.pos,  table.data tbody td .pos,  table.data tbody td.pos   { color: var(--up); }
.neg,  table.data tbody td .neg,  table.data tbody td.neg   { color: var(--down); }
.zero, table.data tbody td .zero, table.data tbody td.zero  { color: var(--text); font-weight: 400; }

/* 원시 금액. 배팅 · 입금은 판에 들어온 돈이라 빨강,
   당첨 · 출금은 나간 돈이라 파랑. 값의 부호와 무관하다. */
.amt-in,  table.data tbody td .amt-in,  table.data tbody td.amt-in   { color: var(--down); }
.amt-out, table.data tbody td .amt-out, table.data tbody td.amt-out  { color: var(--up); }

/* 한 칸에 여러 숫자를 쌓을 때 */
.stack { display: flex; flex-direction: column; gap: 1px; line-height: 1.35; }
.stack .sub { color: var(--text-3); font-size: var(--fs-xs); }

/* 조회 결과 없음.
   안내 문구는 데이터가 아니다. 본문보다 크면 빈 화면이 더 눈에 띈다. */
/* 조회 결과 없음.
 *
 * 높이를 넉넉히 준다. 표에 줄이 하나도 없으면 머리 바로 아래에 한 줄만
 * 남아 화면이 잘린 것처럼 보인다. 안내가 들어갈 자리를 만들어 둔다.
 *
 * 표 안쪽 선택자까지 적는다. table.data tbody td 가 padding 을 지정하고
 * 있어 특이도(0,1,2)가 클래스 하나(0,1,0)보다 높다. 그냥 .empty 로만
 * 적으면 여백이 먹지 않는다 — 금액 색이 안 먹던 것과 같은 이유다. */
.empty,
table.data tbody td.empty {
    padding: 56px var(--s4);
    text-align: center;
    color: var(--text-3);
}

/* ==========================================================================
   뱃지 / 태그
   ========================================================================== */

.badge {
    display: inline-flex; align-items: center;
    height: 22px; padding: 0 8px;
    border-radius: var(--r1);
    font-size: var(--fs-sm); font-weight: 700; white-space: nowrap;
    border: 1px solid transparent;
}
.badge-neutral { background: var(--surface-3); color: var(--text-2); border-color: var(--border-strong); }
.badge-accent  { background: var(--accent-weak); color: var(--accent); border-color: var(--accent-line); }
.badge-up      { background: var(--up-weak);   color: var(--up); }
.badge-down    { background: var(--down-weak); color: var(--down); }
.badge-warn    { background: var(--warn-weak); color: var(--warn); }

/* 소속(등급 + 아이디) 칸 */
.owner { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.owner-id { color: var(--text-2); }

/* ==========================================================================
   페이지네이션
   ========================================================================== */

.pager { display: flex; justify-content: center; gap: var(--s1); padding: var(--s4); }
.pager a, .pager span {
    min-width: 30px; height: 30px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 var(--s2);
    border: 1px solid var(--border);
    border-radius: var(--r2);
    color: var(--text-2);
    font-size: var(--fs-sm);
}
.pager a:hover { background: var(--surface-2); color: var(--text); }
.pager .on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }

/* ==========================================================================
   트리 (jstree)
   ========================================================================== */

.tree-panel { width: 300px; flex: 0 0 300px; }
.tree-panel .card-body { max-height: calc(100vh - 220px); overflow: auto; }

.jstree-default .jstree-anchor { color: var(--text-2); font-size: var(--fs-sm); }
.jstree-default .jstree-hovered { background: var(--surface-2) !important; color: var(--text) !important; border-radius: var(--r1); box-shadow: none; }
.jstree-default .jstree-clicked { background: var(--accent-weak) !important; color: var(--text) !important; border-radius: var(--r1); box-shadow: none; }
.jstree-default .jstree-wholerow-hovered { background: var(--surface-2) !important; }
.jstree-default .jstree-wholerow-clicked { background: var(--accent-weak) !important; }
.jstree-default .jstree-icon { filter: invert(.65); }

.tree-level-badge { font-weight: 700; margin-right: 4px; font-size: var(--fs-xs); }
.level-2 { color: #5b7cfa; }
.level-3 { color: #9b7cf6; }
.level-4 { color: #2fbf71; }
.level-5 { color: #f2b134; }
.level-6 { color: #f0546c; }
.level-7 { color: #7c8aa5; }

/* ==========================================================================
   모달
   ========================================================================== */

/* Bootstrap 의 모달 JS 를 쓰지 않는다. 여는 것은 rs-ui.js 가 .is-open 을 붙여서 한다.
   덕분에 jQuery 플러그인 의존이 하나 줄고, React 로 옮길 때도 클래스 규칙만 지키면 된다. */
.rs-modal {
    position: fixed; inset: 0; z-index: 1000;
    display: none;
    align-items: center; justify-content: center;
    padding: var(--s4);
    background: rgba(4, 7, 14, .66);
    backdrop-filter: blur(2px);
}
.rs-modal.is-open { display: flex; }
body.modal-open { overflow: hidden; }

.rs-modal-panel {
    width: 100%; max-width: 420px;
    max-height: calc(100vh - 2 * var(--s4));
    display: flex; flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--r4);
    box-shadow: var(--shadow-lg);
    animation: rs-pop .16s ease-out;
}
.rs-modal-panel.wide { max-width: 640px; }
@keyframes rs-pop { from { opacity: 0; transform: translateY(6px) scale(.99); } to { opacity: 1; transform: none; } }

.rs-modal-head {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s4);
    border-bottom: 1px solid var(--border);
}
.rs-modal-title { font-size: var(--fs-lg); font-weight: 700; }
.rs-modal-close {
    margin-left: auto;
    background: none; border: 0; cursor: pointer;
    color: var(--text-3); font-size: 16px; line-height: 1;
    padding: var(--s1) var(--s2); border-radius: var(--r1);
}
.rs-modal-close:hover { background: var(--surface-2); color: var(--text); }

.rs-modal-body { padding: var(--s4); overflow-y: auto; }
.rs-modal-foot { display: flex; gap: var(--s2); padding: var(--s4); border-top: 1px solid var(--border); }
.rs-modal-foot .btn { flex: 1 1 0; height: 38px; }

/* 모달 안의 항목 줄 */
/* 이름표와 값.
   이름표가 12px, 값이 본문 크기(15px)를 물려받아 한 줄 안에 크기가 셋이었다.
   표와 같은 14px 로 맞추고 이름표만 한 단계 낮춘다. */
.kv { display: flex; align-items: baseline; gap: var(--s3); padding: 7px 0; }
.kv + .kv { border-top: 1px solid var(--border); }
.kv-label {
    width: 92px; flex: 0 0 92px;
    color: var(--text-3);
    font-size: var(--fs-sm); font-weight: 600;
    white-space: nowrap;
}
.kv-value {
    flex: 1 1 auto; min-width: 0;
    font-size: var(--fs-td); font-weight: 600;
    line-height: 1.45;
}
/* 값 옆에 버튼이 붙는 줄은 가운데로 맞춘다 */
.kv:has(.btn-group) { align-items: center; }

/* 금액 빠른 입력 */
.chips { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); margin-top: var(--s3); }

/* ==========================================================================
   달력 (jQuery UI)
   ========================================================================== */

.ui-datepicker {
    background: var(--surface-2) !important;
    border: 1px solid var(--border-strong) !important;
    border-radius: var(--r3) !important;
    box-shadow: var(--shadow-lg) !important;
    padding: var(--s3) !important;
    width: 260px !important;
    z-index: 9999 !important;
    box-sizing: border-box;
}
.ui-datepicker .ui-widget-header, .ui-datepicker-header {
    background: transparent !important; border: 0 !important;
    color: var(--text) !important; padding: 0 0 var(--s2) 0 !important;
}
.ui-datepicker-title { font-size: var(--fs-md) !important; font-weight: 700 !important; }
.ui-datepicker-prev, .ui-datepicker-next { cursor: pointer; top: 2px !important; filter: invert(.6); }
.ui-datepicker-calendar { width: 100%; border-collapse: collapse; table-layout: fixed; }
.ui-datepicker-calendar th { color: var(--text-3) !important; font-size: var(--fs-xs) !important; font-weight: 600; padding: 4px 0 !important; border: 0 !important; text-align: center; }
.ui-datepicker-calendar td { padding: 1px !important; border: 0 !important; }
.ui-state-default, .ui-widget-content .ui-state-default {
    display: block !important; width: 100% !important;
    padding: 6px 0 !important; margin: 0 !important;
    background: transparent !important; border: 0 !important;
    color: var(--text-2) !important; text-align: center !important;
    font-size: var(--fs-sm) !important; border-radius: var(--r1) !important;
    box-sizing: border-box !important;
}
.ui-state-default:hover { background: var(--surface-3) !important; color: var(--text) !important; }
.ui-state-active, .ui-widget-content .ui-state-active { background: var(--accent) !important; color: #fff !important; font-weight: 700 !important; }
.ui-state-highlight, .ui-widget-content .ui-state-highlight { background: var(--surface-3) !important; color: var(--accent) !important; }
.ui-datepicker-calendar td:first-child .ui-state-default { color: var(--down) !important; }
.ui-datepicker-calendar td:last-child .ui-state-default { color: var(--accent) !important; }

/* ==========================================================================
   유틸
   ========================================================================== */

.row-flex { display: flex; gap: var(--s4); align-items: flex-start; }
.grow { flex: 1 1 auto; min-width: 0; }
.mt-0 { margin-top: 0 } .mt-3 { margin-top: var(--s3) } .mt-4 { margin-top: var(--s4) }
.muted { color: var(--text-3); }
.hide { display: none !important; }

/* ==========================================================================
   반응형
   ========================================================================== */

@media (max-width: 1024px) {
    .tree-panel { width: 240px; flex-basis: 240px; }
}

@media (max-width: 860px) {
    .app-side {
        position: fixed; left: 0; top: 0; bottom: 0; z-index: 60;
        transform: translateX(-100%);
        transition: transform .22s ease;
        box-shadow: var(--shadow-lg);
    }
    .app.side-open .app-side { transform: translateX(0); }
    .app.side-open::after {
        content: ''; position: fixed; inset: 0; z-index: 50;
        background: rgba(0,0,0,.55);
    }
    .hamburger { display: inline-flex; }
    .app-body { padding: var(--s3); }
    .topbar { padding: 0 var(--s3); gap: var(--s2); }
    .topbar h1 { font-size: var(--fs-md); }
    .wallet { gap: var(--s3); }
    .wallet-label { display: none; }
    .row-flex { flex-direction: column; }
    .tree-panel { width: 100%; flex-basis: auto; }
    .tree-panel .card-body { max-height: 260px; }
}

@media (max-width: 420px) {
    .ui-datepicker { width: calc(100vw - 24px) !important; max-width: 260px; }
    .stat-value { font-size: 19px; }
}

/* ==========================================================================
   섹션 라벨 — 목록 위에 붙는 작은 제목
   레퍼런스처럼 대문자 + 자간으로 두어 본문과 확실히 구분되게 한다.
   ========================================================================== */
.section-label {
    display: block;
    padding: var(--s4) var(--s3) var(--s2);
    color: var(--text-3);
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}
.nav .section-label { padding-left: var(--s3); }

/* ==========================================================================
   등급 뱃지 — ManagerUtils.getManagerBadgeHtml() 이 붙이는 클래스
   자바는 클래스만 내보내고 색은 여기서 정한다.
   ========================================================================== */
/* 색은 어두운 화면에서 쓰던 것을 그대로 두면 안 된다.
   밝은 바탕에서 옛 값들은 1.6~2.5:1 밖에 나오지 않아 글자가 보이지 않는다.
   아래 값은 각자의 바탕 위에서 모두 4.9:1 이상이다.

   등급 순서(지사 → 대본 → 부본 → 총판 → 매장)를 색으로도 느낄 수 있게
   파랑에서 시작해 보라·초록·주황·빨강으로 옮겨 간다. */
.badge.lv-a { background: #e8ebfd; color: #3b4fd8; border-color: #c3cbf7; }
.badge.lv-b { background: #f0eafc; color: #6b3fd4; border-color: #d5c6f5; }
.badge.lv-c { background: #e7f6ec; color: #14733a; border-color: #a8d9bd; }
.badge.lv-d { background: #fbf0dc; color: #8a5a06; border-color: #e6cf9c; }
.badge.lv-e { background: #fdeaea; color: #c81e1e; border-color: #f2b6b6; }
.badge.lv-f { background: #eef0f4; color: #4b5563; border-color: #d1d5db; }

/* ==========================================================================
   라이트 테마 보정
   상단바만 어둡기 때문에 그 안의 요소는 별도로 맞춰 준다.
   ========================================================================== */


/* 상단바 안의 글자와 버튼 */
.topbar .wallet-label { color: var(--top-text-2); }
.topbar .wallet-value { color: var(--top-text); }
.topbar .hamburger { color: var(--top-text-2); }
.topbar .hamburger:hover { color: var(--top-text); }

.topbar .btn {
    background: rgba(255,255,255,.08);
    border-color: rgba(255,255,255,.16);
    color: var(--top-text);
}
.topbar .btn:hover { background: rgba(255,255,255,.16); color: var(--top-text); }
.topbar .btn-up   { background: rgba(52,199,123,.16);  border-color: rgba(52,199,123,.4);  color: #6ee7a8; }
.topbar .btn-up:hover   { background: rgba(52,199,123,.26); color: #86efac; }
.topbar .btn-down { background: rgba(248,113,113,.16); border-color: rgba(248,113,113,.4); color: #fca5a5; }
.topbar .btn-down:hover { background: rgba(248,113,113,.26); color: #fecaca; }

/* 표 머리를 옅은 회색으로 두어 본문과 구분한다 */

/* 카드에 아주 옅은 그림자를 주어 흰 배경 위에서 떠 보이게 한다 */
.card, .stat { box-shadow: var(--shadow); }

/* 모달 뒷배경은 밝은 화면에 맞춰 옅게 */
.rs-modal { background: rgba(17,24,39,.45); backdrop-filter: blur(2px); }

/* 트리 아이콘은 밝은 배경에서 반전하면 안 된다 */
.jstree-default .jstree-icon { filter: none; }

/* ==========================================================================
   서체 마무리
   --------------------------------------------------------------------------
   Pretendard 는 가변 폰트라 무게를 세밀하게 줄 수 있다.
   숫자는 조금 굵게 두어야 밝은 배경에서 또렷하게 읽힌다.
   ========================================================================== */

body { letter-spacing: -0.003em; }          /* 한글은 아주 살짝 좁혀야 덩어리로 읽힌다 */

table.data tbody td { font-weight: 450; }    /* 본문보다 살짝 굵게 */
table.data tbody td.right,
.num, .stat-value, .wallet-value { font-weight: 600; }   /* 숫자는 또렷하게 */

/* 아이디처럼 눌러서 들어가는 값은 굵기로도 구분해 준다 */
table.data tbody td a { font-weight: 600; }

/* 흐린 0 은 굵기까지 낮춰 배경으로 물러나게 한다 */

/* 소속 칸은 뱃지와 아이디를 한 줄에 둔다. 줄바꿈되면 행이 두 배로 높아진다.
 *
 * 최소 폭을 준다. 표가 칸 너비를 내용에 맞춰 나누는데, 이 칸은 뱃지 하나와
 * 짧은 아이디뿐이라 다른 칸보다 눈에 띄게 좁게 잡혔다. 옆 칸들과 비슷한
 * 자리를 차지하도록 바닥을 깔아 준다. */
.owner { flex-wrap: nowrap; }
.owner-id { white-space: nowrap; }
table.data td:has(> .owner) { min-width: 130px; }

/* 표 안의 작은 버튼은 글자만 보이므로 굵기로 존재감을 준다 */
.btn-cell { font-weight: 700; }

/* ==========================================================================
   어두운 사이드바
   상단바와 함께 화면의 테두리를 이루고, 본문은 밝게 두어 대비를 만든다.
   ========================================================================== */

.app-side {
    background: var(--side-bg);
    border-right: 1px solid var(--side-border);
}

.brand {
    background: var(--top-bg);
    color: var(--top-text);
    border-bottom: 1px solid var(--side-border);
}

.nav-title { color: var(--side-text-2); }
.nav-title:hover { background: rgba(255,255,255,.06); color: var(--side-text); }
.nav-title .ico,
.nav-title .caret { color: var(--side-text-2); }
.nav-group.open .nav-title { color: var(--side-text); }
.nav-group.open .nav-title .ico { color: var(--side-accent); }

.nav-link { color: var(--side-text-2); }
.nav-link:hover { background: rgba(255,255,255,.06); color: var(--side-text); }
/*
 * 고른 항목은 사이드바 폭 전체를 칠한다.
 *
 * 예전에는 .nav 의 좌우 여백 안쪽에서만 칠해져, 띠가 가운데 떠 있는 것처럼
 * 보였다. 여백만큼 밖으로 늘리고 그만큼 안쪽 여백을 되돌린다.
 *
 * 글자색도 다르게 준다. 배경만 바뀌면 어두운 사이드바에서 잘 보이지 않는다.
 */
.nav-link.active {
    margin: 0 calc(var(--s3) * -1);
    padding-left: calc(43px + var(--s3));
    padding-right: calc(var(--s3) * 2);
    border-radius: 0;
    background: rgba(110,168,251,.16);
    box-shadow: inset 3px 0 0 var(--side-accent);
    color: var(--side-accent);
    font-weight: 700;
}
.nav-link.active::before { left: calc(22px + var(--s3)); background: var(--side-accent); }

.nav-foot { border-top: 1px solid var(--side-border); }
.nav-foot .nav-title:hover { background: rgba(255,255,255,.06); }

/* 사이드바 안의 스크롤바도 어두운 배경에 맞춘다 */
.app-side::-webkit-scrollbar-thumb { background: #3a465c; border-color: var(--side-bg); }
.app-side::-webkit-scrollbar-thumb:hover { background: #4a5872; }

/* 본문이 옅은 회색이므로 카드는 흰색으로 두어 떠 보이게 한다.
   조회줄은 성격이 달라 흰색으로 만들지 않는다. */
.card, .stat, table.data { background: var(--surface); }

/* ==========================================================================
   화면을 옮기며 필요해진 것들
   ========================================================================== */

/* 한 줄에 나란히. 부트스트랩 input-group 은 자식 테두리를 붙여 버려서 쓰지 않는다. */
.inline { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.inline-tight { display: inline-flex; align-items: center; gap: var(--s1); }

/* 정렬은 표 밖에서도 쓴다. */
.center { text-align: center; }
.right  { text-align: right; }
.left   { text-align: left; }
.nowrap { white-space: nowrap; }

/* 표 전체를 가운데로 두는 화면이 많다. 칸마다 붙이지 않고 표에 한 번만 붙인다. */
table.data.center th, table.data.center td { text-align: center; }
table.data.center td.right, table.data.center th.right { text-align: right; }
table.data.center td.left,  table.data.center th.left  { text-align: left; }

/* 표 머리 고정.
   내역 화면은 수백 줄을 훑는다. 내려가면 무슨 칸인지 잊어버리므로 머리를 붙여 둔다.
   .table-wrap 이 스크롤을 갖고 있으면 그 안에서, 아니면 화면 기준으로 붙는다. */
/* 머리 아래에 옅은 그림자를 둔다. 내려가며 볼 때 머리가 떠 있는 게 보인다. */
table.data thead th { box-shadow: 0 1px 0 rgba(17,24,39,.10); }
table.data thead th + th { box-shadow: inset 1px 0 0 var(--head-line), 0 1px 0 rgba(17,24,39,.10); }

/*
 * 머리가 두 줄인 표 (일별 정산처럼 묶음 머리가 있는 것).
 *
 * sticky top:0 을 모든 th 에 걸면 둘째 줄도 맨 위에 붙어 첫 줄을 덮는다.
 * 첫 줄은 0, 둘째 줄은 첫 줄 높이만큼 내려서 붙인다.
 * 41px = 글자 19px + 위아래 여백 11px씩.
 */
table.data thead tr:first-child th  { top: 0; z-index: 3; }
table.data thead tr:nth-child(2) th { top: 41px; z-index: 2; }

/* 페이지네이션 — 서버가 li > a 로 그린다. */
.pager { list-style: none; margin: 0; flex-wrap: wrap; }
.pager li { display: inline-flex; }
.pager li a, .pager li span {
    min-width: 34px; height: 34px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 var(--s2);
    border: 1px solid var(--border);
    border-radius: var(--r2);
    background: var(--surface);
    color: var(--text-2);
    font-size: var(--fs-sm); font-weight: 600;
    text-decoration: none;
}
.pager li a:hover { background: var(--accent-weak); border-color: var(--accent-line); color: var(--accent); }
.pager li.active a, .pager li.on a {
    background: var(--accent); border-color: var(--accent); color: #fff;
}
.pager li.disabled a { opacity: .4; pointer-events: none; }

.card-foot {
    padding: var(--s3) var(--s4);
    border-top: 1px solid var(--border);
    display: flex; align-items: center; gap: var(--s2);
}

/* 화면 위에 걸리는 요약 줄. 합계처럼 "먼저 봐야 하는 숫자"를 둔다. */
.summary {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--s6);
    padding: var(--s3) var(--s4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r3);
    margin-bottom: var(--s3);
}
.summary-item { display: flex; align-items: baseline; gap: var(--s2); }
.summary-label { color: var(--text-3); font-size: var(--fs-xs); font-weight: 600; }
.summary-value { font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   명령 팔레트 (Ctrl+K)
   --------------------------------------------------------------------------
   화면이 쉰 개가 넘어가면 사이드바를 접었다 폈다 하며 찾는 게 제일 번거롭다.
   목록은 사이드바에서 그대로 읽어 오므로 여기에 따로 관리할 목록이 없다.
   ========================================================================== */

.palette {
    position: fixed; inset: 0; z-index: 200;
    display: none;
    background: rgba(17, 24, 39, .45);
    padding: 12vh var(--s4) var(--s4);
}
.palette.is-open { display: block; }

.palette-panel {
    max-width: 560px; margin: 0 auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r4);
    box-shadow: 0 24px 60px rgba(17, 24, 39, .28);
    overflow: hidden;
}
.palette-input {
    width: 100%; height: 54px;
    padding: 0 var(--s5);
    border: 0; border-bottom: 1px solid var(--border);
    background: transparent;
    font-size: var(--fs-lg); font-family: inherit; color: var(--text);
}
.palette-input:focus { outline: none; }
.palette-input::placeholder { color: var(--text-3); }

.palette-list { max-height: 46vh; overflow-y: auto; padding: var(--s2); }
.palette-item {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-radius: var(--r2);
    color: var(--text);
    font-size: var(--fs-md);
    cursor: pointer;
    text-decoration: none;
}
.palette-item:hover, .palette-item.on { background: var(--accent-weak); color: var(--accent); }
.palette-item .ico { width: 18px; text-align: center; color: var(--text-3); flex: 0 0 18px; }
.palette-item.on .ico { color: var(--accent); }
.palette-group { margin-left: auto; color: var(--text-3); font-size: var(--fs-xs); }
.palette-item.on .palette-group { color: var(--accent); }

.palette-foot {
    display: flex; gap: var(--s4); align-items: center;
    padding: var(--s2) var(--s5);
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-3); font-size: var(--fs-xs);
}
.palette-foot kbd {
    display: inline-block; min-width: 18px; padding: 1px 5px;
    border: 1px solid var(--border-strong); border-bottom-width: 2px;
    border-radius: 4px; background: var(--surface);
    font-family: inherit; font-size: 11px; color: var(--text-2);
}
.palette-empty { padding: var(--s8) var(--s4); text-align: center; color: var(--text-3); }

/* 상단바의 검색 단추 — 팔레트가 있다는 걸 알려 준다. */
.palette-hint {
    display: inline-flex; align-items: center; gap: var(--s2);
    height: 34px; padding: 0 var(--s3);
    border: 1px solid var(--top-border); border-radius: var(--r2);
    background: rgba(255, 255, 255, .06);
    color: var(--top-text-2); font-size: var(--fs-sm);
    cursor: pointer;
}
.palette-hint:hover { background: rgba(255, 255, 255, .12); color: var(--top-text); }
.palette-hint kbd {
    border: 0; background: rgba(255, 255, 255, .12); border-radius: 3px;
    padding: 1px 5px; font-family: inherit; font-size: 11px; color: inherit;
}
@media (max-width: 900px) { .palette-hint span.label { display: none; } }

/* ==========================================================================
   대시보드
   --------------------------------------------------------------------------
   같은 크기 카드 여덟 장을 늘어놓으면 무엇이 중요한지 알 수 없다.
   덩어리마다 "결론"이 되는 값 하나를 크게 두고 나머지를 곁에 둔다.
   ========================================================================== */

.dash-section { margin-bottom: var(--s6); }

.section-label {
    display: flex; align-items: center; gap: var(--s2);
    margin-bottom: var(--s3);
    color: var(--text-2);
    font-size: var(--fs-md); font-weight: 700;
}
.section-label > i { color: var(--accent); }
.section-note { margin-left: var(--s1); color: var(--text-3); font-size: var(--fs-xs); font-weight: 500; }

/* 결론 카드가 먼저, 그 뒤로 설명하는 값 셋.
   두 덩어리 모두 넷으로 맞춰 두면 위아래 칸이 세로로 정렬된다.
   auto-fit 을 쓰면 덩어리마다 칸 수가 달라져 줄이 어긋난다. */
.dash-grid {
    display: grid; gap: var(--s3);
    /* 넷 다 같은 폭. 첫 칸만 1.4배로 넓혀 뒀는데, 카드 크기가 다르면
       위아래 두 줄의 칸 경계가 어긋나 보인다. 결론 카드는 폭이 아니라
       왼쪽 선과 숫자 크기(.stat-lead)로 구분한다. */
    grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 1100px) { .dash-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px)  { .dash-grid { grid-template-columns: 1fr; } }

/* 덩어리의 결론. 왼쪽 굵은 선과 큰 숫자로 구분한다. */
.stat-lead {
    border-left: 3px solid var(--accent);
    background: linear-gradient(180deg, var(--accent-weak) 0%, var(--surface) 60%);
}
.stat-lead .stat-value { font-size: 30px; }

/* 차트 넉 장을 2열 2줄로. 좁아지면 한 줄에 하나씩 내려온다. */
.dash-charts { display: grid; gap: var(--s3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1100px) { .dash-charts { grid-template-columns: 1fr; } }
.chart-area { height: 300px; position: relative; }

/* 페이지 번호 줄. 표 아래 가운데. */
.pager-wrap { display: flex; justify-content: center; padding: var(--s4) 0 var(--s2); }

/* 조회 결과 없음 */
.empty { display: table-cell; }
.empty i { display: block; font-size: 20px; opacity: .3; margin-bottom: var(--s2); }
.empty span { font-size: var(--fs-sm); }

/* 카드 제목 앞의 아이콘. 붙어 있으면 글자와 한 덩어리로 보인다. */
.card-title > i:first-child,
.section-label > i:first-child { margin-right: 6px; }

/* 옛 마크업에서 넘어온 파트너 정보 칸 */
.stat-card {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r2);
    padding: var(--s3);
    height: 100%;
}
.stat-header {
    color: var(--text-3);
    font-size: var(--fs-sm); font-weight: 600;
    white-space: nowrap;
}
.stat-body { margin-top: 3px; }
/* 값 길이가 제각각(mom7200 / 16,458,386 / 매달 1일 정산)이라 17px 로 두면
   긴 값만 줄바꿈되어 칸마다 높이가 달라 보였다. 표와 같은 눈금에 얹는다.
   break-all 은 한글을 글자 단위로 끊어 버려 keep-all 로 바꾼다. */
.stat-card .stat-value {
    margin: 0;
    font-size: var(--fs-md); font-weight: 700;
    font-variant-numeric: tabular-nums;
    word-break: keep-all; overflow-wrap: anywhere;
    line-height: 1.4;
}

/* 글자색 유틸. 화면에 색을 박는 대신 뜻을 붙인다. */
.accent { color: var(--accent); }
.warn   { color: var(--warn); }

/* ==========================================================================
   조회줄 안의 크기 맞추기
   --------------------------------------------------------------------------
   화면마다 btn-sm, field, datepicker 가 섞여 있어 높이가 제각각이었다.
   조회줄 안에서는 무엇이든 같은 높이로 맞춘다. 줄이 들쭉날쭉하면
   어디를 눌러야 하는지 한눈에 들어오지 않는다.
   ========================================================================== */

.toolbar .field,
.toolbar .btn,
.toolbar select,
.toolbar input[type="text"] {
    height: var(--control-h);
    box-sizing: border-box;
}
.toolbar .btn { padding: 0 var(--s4); font-size: var(--fs-sm); }
.toolbar .btn-primary { padding: 0 var(--s5); }

/* 조회줄 바탕이 한 단계 낮으므로 입력칸은 흰색으로 띄운다 */
.toolbar .field { background: var(--surface); }

/* 라벨은 text-3 이면 이 바탕에서 4.45:1 로 기준에 못 미친다 */
.toolbar .toolbar-label,
.toolbar .date-sep { color: var(--text-2); }

/* 옛 부트스트랩 input-group 껍데기가 남아 있어도 줄이 깨지지 않게 */
.toolbar .input-group-prepend,
.toolbar .input-group-append,
.toolbar .d-flex { display: flex; align-items: center; gap: var(--s2); }
.toolbar .input-group-text {
    border: 0; background: transparent; padding: 0;
}

/* ==========================================================================
   요약 줄
   --------------------------------------------------------------------------
   합계는 조회 조건이 아니다. 조회줄 안에 끼워 두면 조건과 결과가 뒤섞이고
   화면이 넓어질수록 왼쪽 끝에 홀로 남는다. 조회줄 위에 따로 둔다.
   ========================================================================== */

.summary { border-color: var(--border); }
.summary-item + .summary-item { padding-left: var(--s6); border-left: 1px solid var(--border); }
.summary-value.up   { color: var(--up); }
.summary-value.down { color: var(--down); }
.summary-item .ico  { color: var(--text-3); margin-right: 2px; }

/* ==========================================================================
   사이드바와 본문의 글자 크기 맞추기
   --------------------------------------------------------------------------
   메뉴가 15px, 표 본문이 14px 이었다. 1px 차이지만 메뉴는 여백이 넉넉해
   실제보다 더 커 보이고, 두 영역이 따로 노는 느낌을 준다.

   화면에서 가장 많이 읽는 글자는 표 안의 값이고 그건 칸 수 때문에 키울 수 없다.
   그래서 메뉴를 표에 맞춘다.
   ========================================================================== */

.nav-title,
.nav-foot .nav-title { font-size: var(--fs-td); }

/* 서브메뉴는 한 단계 작게. 제목과 항목이 같은 크기면 위계가 보이지 않는다. */
.nav-link { font-size: var(--fs-sm); }

/* 크기를 낮춘 만큼 굵기와 자간으로 또렷함을 지킨다 */
.nav-title { font-weight: 700; letter-spacing: -0.01em; }
.nav-link  { font-weight: 500; letter-spacing: -0.01em; }
.nav-link.active { font-weight: 700; }

.brand { font-size: var(--fs-td); letter-spacing: .16em; }

/* 옛 부트스트랩 모달에서 넘어온 껍데기.
   modal-dialog 는 하는 일이 없지만 지우면 </div> 겹이 어긋난다.
   자리만 차지하지 않게 두고, 가운데 정렬은 .rs-modal 이 그대로 맡는다. */
.rs-modal-shell { display: contents; }

/* 옛 모달 안에는 표가 들어 있는 경우가 많다. 넘치면 그 안에서 스크롤한다. */
.rs-modal-body .table-wrap { max-height: 60vh; }
.rs-modal-body > .card { border: 0; box-shadow: none; }

/* ==========================================================================
   상세 팝업 (새 창으로 뜨는 화면)
   --------------------------------------------------------------------------
   사이드바도 상단바도 없다. 내용만 있는 화면이다.
   ========================================================================== */

body.popup { background: var(--bg); }
.popup-body { padding: var(--s5); }

/* 탭 */
.tabs {
    display: flex; flex-wrap: wrap; gap: var(--s1);
    border-bottom: 1px solid var(--border);
    margin-bottom: var(--s4);
}
.tab {
    padding: var(--s3) var(--s4);
    margin-bottom: -1px;
    border: 1px solid transparent;
    border-bottom: 2px solid transparent;
    border-radius: var(--r2) var(--r2) 0 0;
    color: var(--text-2);
    font-size: var(--fs-td); font-weight: 600;
    text-decoration: none;
}
.tab:hover { background: var(--surface-2); color: var(--text); }
.tab.on {
    color: var(--accent);
    border-bottom-color: var(--accent);
    background: var(--surface);
}

/* 회원 요약 — 어느 탭에 있든 같은 자리에 있다 */
.member-head { margin-bottom: var(--s4); }
.member-grid {
    display: grid; gap: var(--s4);
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.member-cell + .member-cell { padding-left: var(--s4); border-left: 1px solid var(--border); }
@media (max-width: 1000px) {
    .member-cell + .member-cell { padding-left: 0; border-left: 0; }
}

/* IPv6 는 길다. 넘치면 이 칸에서만 자르고 전체는 title 로 본다. */
.kv-value.ip {
    max-width: 200px; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap;
    font-size: var(--fs-sm); color: var(--text-2);
}

/* 요율 설정.
   두 카드의 높이가 어긋나 있었다. 격자 칸은 늘어나는데 카드가 내용만큼만
   차지했기 때문이다. 카드를 칸 높이에 맞추고 안쪽을 아래로 정렬한다. */
.rate-grid {
    display: grid; gap: var(--s3);
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    align-items: stretch;
}
.rate-grid > .card { display: flex; flex-direction: column; }
.rate-grid > .card > .card-body { flex: 1 1 auto; display: flex; align-items: flex-end; }

.rate-row { display: flex; align-items: flex-end; gap: var(--s4); width: 100%; }
.rate-field { flex: 1 1 auto; min-width: 0; }
.rate-field .field { width: 100%; height: 42px; font-size: var(--fs-lg); font-weight: 700; margin-top: var(--s2); }
.rate-max { flex: 0 0 auto; text-align: right; }
.rate-max .badge {
    height: 42px; padding: 0 var(--s4);
    font-size: var(--fs-md); margin-top: var(--s2);
    box-sizing: border-box;
}
.rate-field .toolbar-label,
.rate-max .toolbar-label { display: block; }

/* 상위 한도를 넘긴 칸 */
.rate.over { border-color: var(--down); background: var(--down-weak); }

.rate-actions { display: flex; justify-content: center; padding: var(--s6) 0; }
.rate-actions .btn { height: 42px; padding: 0 var(--s8); font-size: var(--fs-md); }

/* 돈의 방향 뱃지. 입출금 목록처럼 두 종류가 섞여 나오는 표에서 쓴다. */
.badge-in  { background: var(--down-weak); color: var(--down); border-color: var(--down-line); }
.badge-out { background: var(--up-weak);   color: var(--up);   border-color: var(--up-line); }

/* ==========================================================================
   지표 줄
   --------------------------------------------------------------------------
   .summary 는 한 줄짜리 요약, .stat-row 는 카드로 늘어놓는 요약이다.
   숫자가 셋 이상이거나 그중 하나가 결론일 때 카드를 쓴다.
   ========================================================================== */

.stat-row {
    display: grid; gap: var(--s3);
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    margin-bottom: var(--s4);
}

/* 금액 뒤의 단위. 숫자와 같은 크기로 두면 자릿수를 세는 데 방해가 된다. */
.stat-value .unit,
.summary-value .unit {
    margin-left: 2px;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--text-3);
}

/* ==========================================================================
   화면의 리듬
   --------------------------------------------------------------------------
   화면이 [조회줄][표] 둘뿐이라 어느 화면이든 같은 모양으로 보였다.
   표 위에 그 표가 무엇인지와 몇 건인지를 두면 화면마다 얼굴이 생긴다.
   ========================================================================== */

.page-head {
    display: flex; align-items: baseline; gap: var(--s3);
    margin-bottom: var(--s3);
}
.page-head h2 {
    margin: 0;
    font-size: var(--fs-lg); font-weight: 800;
    letter-spacing: -.02em;
    color: var(--text);
}
/* 건수. 표를 보기 전에 규모를 안다. */
.page-count {
    display: inline-flex; align-items: center;
    height: 22px; padding: 0 9px;
    border-radius: 99px;
    background: var(--accent-weak);
    border: 1px solid var(--accent-line);
    color: var(--accent);
    font-size: var(--fs-xs); font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.page-head .spacer { flex: 1 1 auto; }
.page-head .hint { color: var(--text-3); font-size: var(--fs-sm); }

/* 본문 여백을 넓혔다. 카드가 가장자리에 붙어 있으면 화면이 답답하다. */
.app-body { padding: var(--s6) var(--s6) var(--s10); }
@media (max-width: 860px) { .app-body { padding: var(--s4); } }

/* 카드 모서리를 조금 더 둥글게. 표의 어두운 머리와 짝이 맞는다. */
.card { border-radius: var(--r4); overflow: hidden; }
.toolbar { border-radius: var(--r4); }

/* jQuery UI 달력은 닫혀 있어도 빈 상자로 화면 아래에 남는다.
   플러그인이 display 로만 감추는데 우리 규칙이 테두리와 바탕을 그려 두기 때문이다. */
#ui-datepicker-div:not(.ui-datepicker-inline) { display: none; }
#ui-datepicker-div[style*="block"] { display: block !important; }

/* 요율 카드의 머리 높이.
   아이콘마다 글자 높이가 달라 두 카드의 머리가 어긋나 있었다. */
.rate-grid .card-head { min-height: 46px; }
.card-title { display: inline-flex; align-items: center; gap: 6px; line-height: 1.3; }
.card-title > i {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px;
    font-size: 15px; line-height: 1;
    margin-right: 0;
}
/* 위에서 아이콘에 margin-right 를 주던 규칙이 gap 과 겹친다 */
.card-title > i:first-child { margin-right: 0; }
