/* ──────────────────────────────────────────────────────────────
   기본 리셋 & 디자인 토큰
   ────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ═══════════════════════════════════════════════════════════════════
   hidden 은 언제나 이긴다
   ═══════════════════════════════════════════════════════════════════
   🔴 브라우저 기본은 `[hidden] { display: none }` 인데, 작성자 CSS 가
      `.btn { display: inline-flex }` 처럼 display 를 주면 **그게 이겨서
      hidden 이 무력화된다.** 실제로 두 번 당했다 (2026-08-24):
        · .kw-rest  → 팝오버가 닫기·바깥클릭·ESC 로 안 닫혔다
        · .btn      → [저장][취소] 가 편집 전에도 계속 보였다
      규칙마다 예외를 다는 대신 여기서 한 번에 못 박는다.
   ═══════════════════════════════════════════════════════════════════ */
[hidden] { display: none !important; }

:root {
    /* ── 색: 기본 팔레트 ───────────────────────────────── */
    --color-primary:      #1E40AF;
    --color-primary-dark: #1E3A8A;
    --color-primary-50:   #DBEAFE;   /* 활성 메뉴 배경 등 옅은 틴트 */
    --color-danger:       #dc2626;
    --color-success:      #16a34a;
    --color-warning:      #d97706;
    --color-text:         #111827;
    --color-text-muted:   #475569;
    --color-border:       #E2E8F0;
    --color-bg:           #F8FAFC;
    --color-surface:      #ffffff;

    /* ── 색: 위에 얹는 글자색(대비색) ────────────────────
       배경색 하나당 그 위 글자색을 짝으로 둔다. 없으면 #fff 를 직접 박게 된다. */
    --color-primary-fg:   #ffffff;
    --color-danger-fg:    #ffffff;
    --color-success-fg:   #ffffff;
    --color-warning-fg:   #ffffff;

    /* 강조(CTA) — 앰버. 값은 warning 과 공유하되 의미로 구분해 쓴다. 화면당 1곳. */
    --color-accent:       var(--color-warning);
    --color-accent-fg:    #111827;   /* 앰버 위엔 흰색이 대비 미달이라 잉크 */

    /* ── 색: 상태 알림(배경/글자/테두리 3종 세트) ────────── */
    --color-error-bg:     #fef2f2;
    --color-error-fg:     #991b1b;
    --color-error-line:   #fecaca;
    --color-success-bg:   #f0fdf4;
    --color-success-fg-2: #166534;
    --color-success-line: #bbf7d0;

    /* ── 색: 그 밖의 표면 ──────────────────────────────── */
    --color-row-hover:      #f8f9ff;      /* 표 행 hover */
    --color-toast-bg:       #1f2937;
    --color-toast-fg:       #ffffff;
    --color-backdrop:       rgba(0,0,0,.30);
    --color-backdrop-heavy: rgba(0,0,0,.45);
    --focus-ring:           0 0 0 3px rgba(30,64,175,.18);

    /* ── 간격: 4px 배수 스케일 ─────────────────────────────
       그 사이 값(예: 10px, .55rem)을 쓰지 않는다. */
    --space-1:  4px;
    --space-2:  8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 48px;

    /* ── 글꼴 ─────────────────────────────────────────── */
    --font-sans: 'Pretendard', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --font-size-xs:  12px;
    --font-size-sm:  13px;
    --font-size-md:  14px;     /* 본문 기준 */
    --font-size-lg:  16px;
    --font-size-xl:  19px;
    --font-size-2xl: 24px;
    --font-size-3xl: 28px;   /* 요약 타일 숫자 */
    --font-size-4xl: 32px;   /* 모달 안 대표 숫자 */

    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;

    /* ── 레이아웃 ──────────────────────────────────────── */
    --sidebar-width:           220px;
    --sidebar-collapsed-width:  60px;
    --header-height:            56px;

    /* ── 모양 ─────────────────────────────────────────── */
    --radius-sm:  4px;
    --radius-md:  8px;
    --radius-lg: 12px;
    --shadow-sm:  0 1px 3px rgba(0,0,0,.08);
    --shadow-md:  0 4px 12px rgba(0,0,0,.12);
    --transition: 0.2s ease;

    /* ── 모달 배경 패널 ────────────────────────────────── */
    --modal-panel-bg:       #ffffff;
    --modal-panel-bg-muted: #f3f4f6;
}

body {
    font-family: var(--font-sans);
    font-size: var(--font-size-md);
    color: var(--color-text);
    background: var(--color-bg);
}

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

/* ──────────────────────────────────────────────────────────────
   공통 유틸
   ────────────────────────────────────────────────────────────── */
.u-hidden { display: none !important; }

/* ──────────────────────────────────────────────────────────────
   헤더
   ────────────────────────────────────────────────────────────── */
.app-header {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: var(--header-height);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1rem;
    z-index: 100;
    box-shadow: var(--shadow-sm);
}

.header-left  { display: flex; align-items: center; gap: .75rem; }
.header-right { display: flex; align-items: center; gap: .75rem; }

.header-toggle {
    background: none; border: none; cursor: pointer;
    font-size: var(--font-size-lg); color: var(--color-text-muted);
    padding: .4rem;
    border-radius: var(--radius-sm);
}
.header-toggle:hover { background: var(--color-bg); color: var(--color-text); }

.app-brand {
    font-weight: 700; font-size: 1rem;
    color: var(--color-primary); text-decoration: none;
}

.header-date { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.header-user {
    display: flex; align-items: center; gap: .5rem;
    text-decoration: none; color: var(--color-text);
}
.header-user-info .user-name { font-size: var(--font-size-sm); font-weight: 600; }
.header-user-info .user-role { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.btn-header-logout {
    background: none; border: none; cursor: pointer;
    color: var(--color-text-muted); font-size: 1rem; padding: .4rem;
    border-radius: var(--radius-sm);
}
.btn-header-logout:hover { color: var(--color-danger); }

/* ──────────────────────────────────────────────────────────────
   사이드바
   ────────────────────────────────────────────────────────────── */
.sidebar {
    position: fixed;
    top: var(--header-height); left: 0; bottom: 0;
    width: var(--sidebar-width);
    background: var(--color-surface);
    border-right: 1px solid var(--color-border);
    overflow-y: auto;
    z-index: 90;
    transition: width var(--transition), transform var(--transition);
    display: flex; flex-direction: column;
}

.sidebar.collapsed { width: var(--sidebar-collapsed-width); }
.sidebar.collapsed .nav-label,
.sidebar.collapsed .sidebar-footer .user-info,
.sidebar.collapsed .sidebar-footer .user-name,
.sidebar.collapsed .sidebar-footer .user-role,
.sidebar.collapsed .nav-section { display: none; }
.sidebar.collapsed .sidebar-collapse-btn i { transform: rotate(180deg); }

.sidebar-nav { flex: 1; padding: .5rem 0; }

.nav-section {
    font-size: var(--font-size-xs); font-weight: 700; text-transform: uppercase;
    color: var(--color-text-muted); padding: .75rem 1rem .25rem;
    letter-spacing: .05em;
}

/* 접이식 상품군 메뉴 — <details>/<summary>.
   6벌 × 4개를 다 펼치면 사이드바가 길어져 스크롤해야 한다.
   지금 보고 있는 상품군만 열어 둔다(서버가 open 을 붙인다). */
.nav-group > summary {
    cursor: pointer;
    list-style: none;
    display: flex; align-items: center; justify-content: space-between;
    user-select: none;
    border-radius: var(--radius-sm);
    margin: 0 .5rem;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary:hover { background: var(--color-bg); color: var(--color-primary); }

/* 열림 표시 — 글자가 아니라 모양으로. 접힌 상태에서도 뭐가 있는지 알 수 있어야 한다. */
.nav-group > summary::after {
    content: "\203A";                     /* › */
    font-size: 1rem; line-height: 1;
    transition: transform var(--transition);
}
.nav-group[open] > summary::after { transform: rotate(90deg); }
.nav-group[open] > summary { color: var(--color-primary); }

/* 접힌 사이드바에서는 구역 이름을 숨기므로 그룹도 통째로 편다 */
.sidebar.collapsed .nav-group > summary { display: none; }

.nav-item a {
    display: flex; align-items: center; gap: .65rem;
    padding: .55rem 1rem;
    color: var(--color-text);
    border-radius: var(--radius-sm);
    margin: 0 .5rem;
    transition: background var(--transition), color var(--transition);
    text-decoration: none;
}
.nav-item a:hover { background: var(--color-bg); color: var(--color-primary); }
.nav-item a.active { background: var(--color-primary-50); color: var(--color-primary); font-weight: var(--font-weight-semibold); }
.nav-item a i { width: 1.1rem; text-align: center; flex-shrink: 0; }

.sidebar-footer {
    display: flex; align-items: center; gap: .6rem;
    padding: .75rem 1rem;
    border-top: 1px solid var(--color-border);
}
.user-avatar {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--color-primary); color: var(--color-primary-fg);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--font-size-sm); font-weight: 700; flex-shrink: 0;
}
.sidebar-footer .user-name { font-size: var(--font-size-sm); font-weight: 600; }
.sidebar-footer .user-role { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.sidebar-collapse-btn {
    width: 100%; background: none; border: none; border-top: 1px solid var(--color-border);
    padding: .5rem; cursor: pointer; color: var(--color-text-muted); font-size: var(--font-size-sm);
}
.sidebar-collapse-btn:hover { color: var(--color-primary); background: var(--color-bg); }
.sidebar-collapse-btn i { transition: transform var(--transition); }

/* 모바일 백드롭 */
.sidebar-backdrop {
    display: none; position: fixed; inset: 0;
    background: var(--color-backdrop); z-index: 89;
}
.sidebar-backdrop.show { display: block; }

/* ──────────────────────────────────────────────────────────────
   메인 콘텐츠
   ────────────────────────────────────────────────────────────── */
.main {
    margin-top: var(--header-height);
    margin-left: var(--sidebar-width);
    min-height: calc(100vh - var(--header-height));
    transition: margin-left var(--transition);
    display: flex; flex-direction: column;
}
.main.sidebar-collapsed { margin-left: var(--sidebar-collapsed-width); }

.page-content { flex: 1; padding: 1.5rem; }

.app-footer {
    padding: .75rem 1.5rem;
    font-size: var(--font-size-sm); color: var(--color-text-muted);
    border-top: 1px solid var(--color-border);
    text-align: center;
}

/* ──────────────────────────────────────────────────────────────
   페이지 공통
   ────────────────────────────────────────────────────────────── */
.page-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 1.25rem;
}
.page-title { font-size: var(--font-size-2xl); font-weight: 700; }
.page-body  { background: var(--color-surface); border-radius: var(--radius-md); padding: 1.25rem; box-shadow: var(--shadow-sm); }

/* ──────────────────────────────────────────────────────────────
   버튼
   ────────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .45rem .9rem; border-radius: var(--radius-sm);
    font-size: var(--font-size-sm); font-weight: 500;
    border: 1px solid transparent; cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
    text-decoration: none;
}
.btn-primary   { background: var(--color-primary);  color: var(--color-primary-fg); border-color: var(--color-primary); }
.btn-primary:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); }
.btn-danger    { background: var(--color-danger);   color: var(--color-danger-fg); border-color: var(--color-danger); }
.btn-outline   { background: transparent; color: var(--color-text); border-color: var(--color-border); }
.btn-outline:hover { background: var(--color-bg); }
.btn-block     { width: 100%; justify-content: center; }
/* 표 안의 행 버튼용. 값은 전부 토큰을 거친다 — 디자인시스템 규칙 1(하드코딩 금지). */
.btn-sm        { padding: var(--space-1) var(--space-2); font-size: var(--font-size-sm); }

/* ──────────────────────────────────────────────────────────────
   폼
   ────────────────────────────────────────────────────────────── */
.form-group { margin-bottom: 1rem; }
.form-group label { display: block; font-size: var(--font-size-sm); font-weight: 600; margin-bottom: .35rem; }
.form-control {
    width: 100%; padding: .5rem .7rem;
    border: 1px solid var(--color-border); border-radius: var(--radius-sm);
    font-size: var(--font-size-md); background: var(--color-surface); color: var(--color-text);
    transition: border-color var(--transition);
}
.form-control:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); }

.form-check { display: flex; align-items: center; gap: .4rem; margin-bottom: 1rem; font-size: var(--font-size-sm); }

/* 알림 */
.alert { padding: .65rem 1rem; border-radius: var(--radius-sm); font-size: var(--font-size-sm); margin-bottom: 1rem; }
.alert-error   { background: var(--color-error-bg); color: var(--color-error-fg); border: 1px solid var(--color-error-line); }
.alert-success { background: var(--color-success-bg); color: var(--color-success-fg-2); border: 1px solid var(--color-success-line); }

/* 페이지 필터 폼 공통 */
.page-filter-form { display: flex; flex-wrap: wrap; gap: .5rem; align-items: flex-end; margin-bottom: 1rem; }
.page-filter-row  { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }

/* ──────────────────────────────────────────────────────────────
   테이블
   ────────────────────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: var(--font-size-sm); }
thead th {
    background: var(--color-bg); padding: .55rem .75rem;
    font-weight: 600; text-align: left;
    border-bottom: 2px solid var(--color-border);
    white-space: nowrap;
}
tbody td { padding: .5rem .75rem; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
tbody tr:hover { background: var(--color-row-hover); }

/* ──────────────────────────────────────────────────────────────
   모달
   ────────────────────────────────────────────────────────────── */
.modal-overlay {
    display: none; position: fixed; inset: 0;
    background: var(--color-backdrop-heavy); z-index: 200;
    align-items: center; justify-content: center;
    /* 🔴 화면보다 긴 모달이 위아래로 잘리던 것(2026-08-24).
       align-items:center 만 두면 넘친 만큼 **위쪽이 잘리고 스크롤로도 못 올라간다**
       — 제목과 [X] 가 화면 밖으로 나간다. 넘칠 때를 대비해 겉을 스크롤 컨테이너로 둔다. */
    overflow-y: auto;
    padding: 1.5rem 1rem;
}
.modal-overlay.show { display: flex; }

.modal {
    background: var(--modal-panel-bg);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    min-width: 320px; max-width: 480px; width: 90%;
    position: relative;
    box-shadow: var(--shadow-md);
    /* 짧으면 가운데, 화면보다 길면 위에서부터 — flex 의 auto 여백은 남는 공간이
       음수가 되면 0 으로 접힌다(스펙). 그래서 잘리지 않는다.
       .modal 자체에 overflow 를 주지 않는 이유: 안의 콤보 목록·달력이 잘린다. */
    margin: auto;
}

/* 표가 들어가는 모달(엑셀 대량 수정)은 480px 로는 좁다. */
.modal.modal-lg { max-width: 720px; }
/* 작업 묶음 상세 — 7칸짜리 표가 들어간다. 720px 로는 키워드 칸이 눌린다. */
.modal.modal-xl { max-width: 1000px; }
.modal-loading { color: var(--color-text-muted); padding: 1.5rem 0; text-align: center; }

/* ── 짝 모달 — 하나를 왼쪽으로 밀고 오른쪽에 새 것을 띄운다 (2026-08-25 지시) ──
   정산 상세에서 [묶인 슬롯 보기]가 페이지로 나가면 **검색 조건이 날아간다.**
   그래서 나가지 않고 둘을 한 화면에 나란히 둔다.

   🔴 오른쪽 겹은 배경을 비운다 — 안 비우면 왼쪽 모달이 어둠에 잠겨 안 보인다.
      대신 그 투명한 겹이 화면 전체를 덮으므로, 왼쪽 모달을 눌러도 "바깥 클릭" 으로
      잡혀 오른쪽이 닫힌다. 왼쪽으로 돌아가는 길이라 그대로 둔다.

   1200px 미만에서는 JS 가 짝을 안 맺는다 — 나란히 놓을 자리가 없다. */
.modal-overlay.pair-left .modal {
    margin-left: 2.5vw; margin-right: auto;
    max-width: 28vw; min-width: 300px;
}
.modal-overlay.pair-right { background: transparent; z-index: 210; }
.modal-overlay.pair-right .modal {
    margin-right: 2.5vw; margin-left: auto;
    max-width: 62vw;
}

/* 모달 안의 표는 화면 기준 높이(calc(100vh - 230px))를 쓰면 모달을 뚫는다. */
.modal .table-wrap { max-height: 40vh; }

/* 모달 안 보조 줄 — 버튼과 설명을 한 줄에 세로 중앙으로 (엑셀 양식 내려받기). */
.modal-note {
    display: flex; align-items: center; gap: .6rem;
    flex-wrap: wrap; margin-bottom: 1.25rem;
}
.modal-note small { color: var(--color-text-muted); }

/* 미리보기 결과 — 위아래로 숨 쉴 틈을 준다. 없으면 표가 버튼과 붙는다. */
.modal-result:not(:empty) { margin: 1rem 0 1.25rem; }
.modal-result p { margin-bottom: .5rem; }
.modal-result .table-wrap { border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.modal h2 { font-size: var(--font-size-lg); font-weight: 700; margin-bottom: .5rem; }
.modal-sub { font-size: var(--font-size-md); color: var(--color-text-muted); margin-bottom: 1.25rem; }
.modal-actions { display: flex; justify-content: flex-end; gap: .5rem; }
/* 🔴 모달에는 × 버튼이 없다 (2026-08-25 지시).
   닫는 길은 셋이다: [닫기] 버튼 · 바깥 클릭 · ESC.
   × 를 없앤 뒤에도 그 자리를 비우던 오른쪽 여백이 남아 머리띠가 밀려 보였다 — 같이 지웠다. */

/* ──────────────────────────────────────────────────────────────
   토스트
   ────────────────────────────────────────────────────────────── */
.toast {
    position: fixed; bottom: 4.75rem; right: 1.5rem;   /* 문의하기 FAB(오른쪽 아래) 위에 쌓인다 */
    background: var(--color-toast-bg); color: var(--color-toast-fg);
    padding: .65rem 1.1rem; border-radius: var(--radius-md);
    font-size: var(--font-size-sm); box-shadow: var(--shadow-md);
    opacity: 0; transform: translateY(6px);
    transition: opacity .25s, transform .25s;
    pointer-events: none; z-index: 300;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast.error   { background: var(--color-danger); }
.toast.success { background: var(--color-success); }

/* ──────────────────────────────────────────────────────────────
   인증 페이지
   ────────────────────────────────────────────────────────────── */
.auth-body { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--color-bg); }
.auth-wrap { width: 100%; max-width: 400px; padding: 1rem; }
.auth-card { background: var(--color-surface); border-radius: var(--radius-lg); padding: 2rem; box-shadow: var(--shadow-md); }
.auth-logo { text-align: center; margin-bottom: 1.5rem; }
.brand-name { font-size: var(--font-size-2xl); font-weight: 800; color: var(--color-primary); }
.auth-form .btn-block { margin-top: .25rem; padding: .65rem; font-size: var(--font-size-md); }

/* ──────────────────────────────────────────────────────────────
   모바일 반응형
   ────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
    .sidebar {
        transform: translateX(-100%);
        width: var(--sidebar-width) !important;
    }
    .sidebar.open { transform: translateX(0); }
    .main { margin-left: 0 !important; }
}


/* ── 대시보드 ─────────────────────────────────────────────────
   소보루 dashboard.php 와 같은 카드 구성. 도넛은 conic-gradient 로 그린다 —
   숫자 하나 때문에 차트 라이브러리를 붙이지 않는다. */

.card {
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: var(--radius, .5rem);
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
}
.card-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; margin-bottom: .75rem;
}
.card-head h2 {
    font-size: 1rem; margin: 0;
    color: var(--color-primary);
}

/* 카드를 가로로 늘어놓되 좁아지면 접힌다 */
.card-row {
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}
.card-row > .card { margin-bottom: 0; }

.stat-row { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }

.stat-nums { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.stat-nums > div { display: flex; flex-direction: column; gap: .15rem; }
.stat-nums span   { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.stat-nums strong { font-size: var(--font-size-2xl); line-height: 1; }

/* 도넛 — --pct 만큼 원호를 칠한다 */
.donut {
    --pct: 0%;
    --donut-color: var(--color-primary);
    width: 6rem; height: 6rem; flex-shrink: 0;
    border-radius: 50%;
    background: conic-gradient(var(--donut-color) var(--pct), var(--color-bg, #f3f4f6) 0);
    display: grid; place-items: center;
}
.donut-hole {
    width: 4.4rem; height: 4.4rem;
    background: var(--color-surface, #fff);
    border-radius: 50%;
    display: grid; place-items: center; gap: .1rem;
    text-align: center;
}
.donut-hole strong { font-size: var(--font-size-sm); }
.donut-hole span   { font-size: var(--font-size-md); font-weight: 600; }

/* ══════════════════════════════════════════════════════════════
   디자인 시스템 보강 (2026-08-19) — 팀장 피드백 반영
   · 요약은 요약만: 접이식 카드
   · 상태·등급을 배지로 (한눈에)
   · 표 칸 너비 제어 + 숫자 정렬 (칸 깨짐/과폭 해결)
   ══════════════════════════════════════════════════════════════ */

/* ── 접이식 요약 카드 ───────────────────────────────────────────
   요약 표가 전체 목록만큼 길어지는 것을 막는다. 기본은 접혀 있고,
   summary 줄에 건수만 보여 '한눈에' 원칙을 지킨다. */
details.collapse-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    margin-bottom: 1rem;
}
details.collapse-card > summary {
    cursor: pointer; list-style: none;
    display: flex; align-items: center; gap: .5rem;
    padding: .75rem 1rem;
    font-weight: var(--font-weight-semibold);
    color: var(--color-text); user-select: none;
}
details.collapse-card > summary::-webkit-details-marker { display: none; }
details.collapse-card > summary::before {
    content: "\203A";                      /* › — 모양으로 열림 표시 */
    display: inline-block; width: 1rem; text-align: center;
    color: var(--color-text-muted); font-size: var(--font-size-lg); line-height: 1;
    transition: transform var(--transition);
}
details.collapse-card[open] > summary::before { transform: rotate(90deg); color: var(--color-primary); }
details.collapse-card > summary:hover { color: var(--color-primary); }
details.collapse-card > summary:hover::before { color: var(--color-primary); }
.collapse-count { color: var(--color-text-muted); font-weight: var(--font-weight-normal); font-size: var(--font-size-sm); }
details.collapse-card .collapse-body { padding: 0 1rem 1rem; }
details.collapse-card .collapse-body .table-wrap { margin-top: .25rem; }

/* ── 배지 (상태·등급) ───────────────────────────────────────────
   '정상'/'탈퇴' 같은 날 텍스트 대신 색이 있는 알약으로. 한눈에 상태가 읽힌다. */
.badge {
    display: inline-flex; align-items: center; gap: .25rem;
    padding: .12rem .5rem; border-radius: 999px;
    font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold);
    line-height: 1.5; white-space: nowrap; border: 1px solid transparent;
}
.badge-success { background: var(--color-success-bg); color: var(--color-success-fg-2); border-color: var(--color-success-line); }
.badge-danger  { background: var(--color-error-bg);   color: var(--color-error-fg);    border-color: var(--color-error-line); }
.badge-muted   { background: var(--color-bg);         color: var(--color-text-muted);  border-color: var(--color-border); }
.badge-level   { background: var(--color-primary-50); color: var(--color-primary-dark); }

/* ── 표 폴리시 ──────────────────────────────────────────────────
   칸 너비를 표가 스스로 정하게 두지 않는다(칸 깨짐·과폭의 원인).
   table-fixed + colgroup 으로 화면이 너비를 지정한다. */
table.table-fixed { table-layout: fixed; }
table.table-fixed td, table.table-fixed th { overflow: hidden; text-overflow: ellipsis; }
/* 금액·수치는 잘리면 값이 거짓이 된다 — 고정폭 표에서도 … 금지 (2026-08-19) */
table.table-fixed td.num, table.table-fixed th.num { overflow: visible; text-overflow: clip; }
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
th.center, td.center { text-align: center; }
td.nowrap, th.nowrap { white-space: nowrap; }
td.wrap { white-space: normal; word-break: break-word; }        /* 긴 값은 여러 줄 허용 */
.cell-sub { color: var(--color-text-muted); font-size: var(--font-size-xs); }

/* 행 구분을 또렷하게 — 가독성 지적 반영(아주 옅은 줄무늬 + 기존 hover 유지) */
tbody tr:nth-child(even) { background: #fcfcfd; }
tbody tr:hover { background: var(--color-row-hover); }

/* ══════════════════════════════════════════════════════════════
   크래프트 패스 — Emil Kowalski / Apple 디자인 원칙 중 '데이터 관리도구에
   맞는 것'만 적용 (2026-08-19). 스프링·제스처·드래그 계열은 의도적으로 제외.
   취한 원칙: 즉각 반응 · 타이포 규율 · 절제된 모션 · 깊이.
   ══════════════════════════════════════════════════════════════ */

/* ── 타이포: 큰 글자일수록 자간을 좁힌다(커질수록 벌어져 보임) ── */
.page-title       { letter-spacing: -.02em; }
.card-head h2,
.modal h2,
.brand-name       { letter-spacing: -.015em; }
.app-brand        { letter-spacing: -.01em; }

/* ── 즉각 반응: 버튼은 누르는 그 순간 반응한다(~100ms) ── */
.btn        { transition: background var(--transition), border-color var(--transition), transform .08s ease, box-shadow var(--transition); }
.btn:active { transform: scale(.97); }
.btn:focus-visible,
.form-control:focus-visible { outline: none; box-shadow: var(--focus-ring); }
a:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 2px; }

/* 행·메뉴·요약 열림도 부드럽게(빠르게) */
tbody tr,
.nav-item a,
.nav-group > summary,
details.collapse-card > summary { transition: background .12s ease, color .12s ease; }

/* ── 깊이: 고정 헤더를 반투명 유리로 — 내용이 그 아래로 흐른다 ── */
.app-header {
    background: rgba(255, 255, 255, .72);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    backdrop-filter: saturate(180%) blur(12px);
}

/* ── 절제된 모션: 요약을 펼칠 때만 살짝(그 외 모션 없음) ── */
details.collapse-card[open] > .collapse-body { animation: collapseIn .18s ease; }
@keyframes collapseIn { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: none; } }

/* ── 모션 최소화 설정을 존중한다 ── */
@media (prefers-reduced-motion: reduce) {
    .btn:active { transform: none; }
    details.collapse-card[open] > .collapse-body { animation: none; }
    *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ── 긴 텍스트 접기(clamp) ──────────────────────────────────────
   키워드 수십 개짜리 셀이 행 높이를 잡아먹지 않게 2줄에서 자른다.
   클릭하면 펼쳐진다 — 잘렸다는 사실은 ⋯(말줄임)과 개수 배지가 말해 준다. */
.cell-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    cursor: pointer;
}
.cell-clamp.open { -webkit-line-clamp: unset; }

/* 잘린 셀 표식(4차 확정) — 글을 덮지 않는다: 오른쪽에 자리를 비워 두고(padding)
   거기에 ▾ 를 세로 중앙으로. 흐림(fade) 없음, 글자 없음. 펼치면 ▴. */
.cell-clamp.has-more { position: relative; padding-right: 1.5rem; }
.cell-clamp.has-more::after {
    content: "▾";
    position: absolute; right: .15rem; top: 50%; transform: translateY(-50%);
    color: var(--color-primary);
    font-size: var(--font-size-lg);
    line-height: 1;
}
.cell-clamp.has-more.open::after { content: "▴"; }

/* ── 클램프 토글 칩 ──────────────────────────────────────────────
   개수 배지가 버튼으로 안 읽힌다는 피드백(2026-08-19) → 진짜 버튼 모양으로.
   화살표가 상태를 말한다: ▾ 펼칠 수 있음 · ▴ 접을 수 있음. */
.clamp-toggle {
    display: inline-flex; align-items: center; gap: .25rem;
    padding: .12rem .55rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-primary);
    font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold);
    cursor: pointer; line-height: 1.5; white-space: nowrap;
    transition: border-color var(--transition), background var(--transition);
}
.clamp-toggle::after { content: "▾"; font-size: var(--font-size-xs); }
.clamp-toggle.open::after { content: "▴"; }
.clamp-toggle:hover { border-color: var(--color-primary); background: var(--color-primary-50); }

/* ══════════════════════════════════════════════════════════════
   룩 패스 (2026-08-19) — "전체적으로 그대로 같다" 피드백 반영.
   구조·마크업 불변, 인상만 바꾼다: 네이비 사이드바 · 표 룩 · 표면 정돈.
   ══════════════════════════════════════════════════════════════ */

:root {
    --sidebar-bg:        #111C3D;   /* 네이비 — primary(#1E40AF)의 어두운 친척 */
    --sidebar-fg:        #B6C2E2;
    --sidebar-fg-strong: #FFFFFF;
    --sidebar-muted:     #6B7BA8;
    --sidebar-hover:     rgba(255, 255, 255, .07);
    --sidebar-active:    rgba(96, 132, 255, .22);
    --sidebar-active-fg: #C4D2FF;
    --sidebar-line:      rgba(255, 255, 255, .08);
}

/* ── 사이드바: 네이비 아이덴티티 ── */
.sidebar {
    background: var(--sidebar-bg);
    border-right: none;
}
.sidebar .nav-section { color: var(--sidebar-muted); }
.sidebar .nav-item a { color: var(--sidebar-fg); }
.sidebar .nav-item a i { color: var(--sidebar-muted); }
.sidebar .nav-item a:hover { background: var(--sidebar-hover); color: var(--sidebar-fg-strong); }
.sidebar .nav-item a:hover i { color: var(--sidebar-fg-strong); }
.sidebar .nav-item a.active {
    background: var(--sidebar-active);
    color: var(--sidebar-active-fg);
}
.sidebar .nav-item a.active i { color: var(--sidebar-active-fg); }
.sidebar .nav-group > summary { color: var(--sidebar-fg); }
.sidebar .nav-group > summary:hover { background: var(--sidebar-hover); color: var(--sidebar-fg-strong); }
.sidebar .nav-group[open] > summary { color: var(--sidebar-active-fg); }
.sidebar-footer { border-top: 1px solid var(--sidebar-line); }
.sidebar-footer .user-name { color: var(--sidebar-fg-strong); }
.sidebar-footer .user-role { color: var(--sidebar-muted); }
.sidebar-collapse-btn { border-top: 1px solid var(--sidebar-line); color: var(--sidebar-muted); }
.sidebar-collapse-btn:hover { background: var(--sidebar-hover); color: var(--sidebar-fg-strong); }
.sidebar::-webkit-scrollbar { width: 8px; }
.sidebar::-webkit-scrollbar-thumb { background: var(--sidebar-line); border-radius: 4px; }

/* ── 헤더: 브랜드를 또렷하게 ── */
.app-brand { font-size: var(--font-size-lg); }
.app-brand::before {
    content: "";
    display: inline-block; width: .55rem; height: .55rem;
    border-radius: 3px; margin-right: .45rem;
    background: var(--color-primary);
    vertical-align: baseline;
}

/* ── 표: 헤더는 라벨답게, 행은 여유 있게 ── */
thead th {
    background: transparent;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
    letter-spacing: .03em;
    padding: .5rem .75rem;
    border-bottom: 1px solid var(--color-border);
}
tbody td { padding: .6rem .75rem; }
tbody tr:nth-child(even) { background: transparent; }        /* 줄무늬 → 구분선+hover 로 단순화 */
tbody tr { border-bottom: 1px solid var(--color-bg); }

/* ── 표면: 카드·페이지 정돈 ── */
.page-content { padding: 1.75rem 2rem; }
.page-title { font-size: var(--font-size-xl); }
.page-body {
    border: 1px solid var(--color-border);
    box-shadow: 0 1px 2px rgba(17, 28, 61, .04);
}
.card {
    box-shadow: 0 1px 2px rgba(17, 28, 61, .04);
}
.btn-primary { box-shadow: 0 1px 2px rgba(30, 64, 175, .25); }
.btn-primary:active { box-shadow: none; }

/* ── 필터 폼: 툴바처럼 살짝 구분 ── */
.page-filter-form {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: .85rem 1rem;
}

/* ── 검색형 콤보박스 (긴 셀렉트 대체 — combo.js) ── */
.combo { position: relative; min-width: 11rem; }
.combo-list {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0;
    max-height: 260px; overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    z-index: 150;
}
.combo-item {
    padding: .45rem .7rem;
    font-size: var(--font-size-sm);
    cursor: pointer;
    display: flex; align-items: center; justify-content: space-between;
}
.combo-item:hover, .combo-item.active { background: var(--color-primary-50); color: var(--color-primary-dark); }
.combo-item.selected::after { content: "✓"; color: var(--color-primary); font-weight: 700; }

/* ── 입력칸 공통 편의 (inputs.js) — 지우기 × · 비밀번호 눈 ── */
.input-wrap { position: relative; display: block; }
.input-wrap .form-control { padding-right: 2.1rem; }
.combo .combo-input { padding-right: 2.1rem; }
.input-clear, .input-eye {
    position: absolute; right: .35rem; top: 50%; transform: translateY(-50%);
    border: none; background: none; cursor: pointer;
    color: var(--color-text-muted); padding: .25rem .35rem; line-height: 1;
    border-radius: var(--radius-sm);
}
.input-clear { font-size: var(--font-size-xl); }
.input-eye   { font-size: var(--font-size-md); }
.input-clear:hover, .input-eye:hover { color: var(--color-text); background: var(--color-bg); }

/* ── 키-값 표 (내정보·상세들의 라벨:값) ──────────────────────────
   라벨이 가운데 뜨고 값 옆이 휑하던 찐빠(2026-08-19 피드백) 정리. */
table.kv th {
    width: 9rem;
    text-align: left;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
    background: var(--color-bg);
    padding: .55rem .75rem;
    border-bottom: 1px solid var(--color-border);
    vertical-align: top;
}
table.kv td { border-bottom: 1px solid var(--color-border); }

/* 좁아야 읽기 좋은 화면(내정보 등) — 왼쪽에 붙인다 */
.page-narrow { max-width: 46rem; }

/* ── 본문 안 제목·캡션 타이포 통일 ──────────────────────────────
   페이지 안의 맨 h2/h3 가 브라우저 기본 크기로 튀어 "커졌다 작아졌다" 하던 것
   (2026-08-19 내정보 지적). 스케일에 맞춘다: h2=lg(16) · h3=md(14) · 캡션=sm(12.5). */
.page-body h2 {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    letter-spacing: -.01em;
    margin: 1.5rem 0 .5rem;
}
.page-body h3 {
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    margin: 1.25rem 0 .5rem;
}
.page-body h2:first-child, .page-body h3:first-child { margin-top: 0; }
.page-body p small { font-size: var(--font-size-sm); color: var(--color-text-muted); }
.form-group small  { font-size: var(--font-size-xs); color: var(--color-text-muted); }


/* ═══ 데스크톱 리뷰 반영 (2026-08-21) — 근거: docs/인계 로그 22항 ═══ */

/* 표 헤더 고정 — 100·300행을 내려도 열 이름이 따라온다 (thead 가 static 이라는 지적) */
/* ⚠️ .table-wrap 이 overflow-x:auto 라 sticky 는 문서가 아니라 래퍼에 붙는다(스크롤 컨테이너 함정).
   그래서 래퍼 자체를 화면 높이 스크롤 영역으로 만든다 — 12,000px 페이지 문제도 같이 풀린다. */
.table-wrap { max-height: calc(100vh - 230px); overflow: auto; }
thead th {
    position: sticky;
    top: 0;                              /* 래퍼 상단 기준 */
    z-index: 5;
    background: var(--color-surface);   /* 룩 패스의 transparent 는 sticky 에선 비쳐 보인다 */
    box-shadow: 0 1px 0 var(--color-border);
}

/* 필터 실행(검색·조회)은 네이비 — "화면당 파란 주 동작 1개" 원칙 복원 (CTA 만 파랑) */
.btn-dark {
    background: #24304F; color: #fff; border: 1px solid #24304F;
    font-weight: var(--font-weight-semibold);
}
.btn-dark:hover { background: #33415F; border-color: #33415F; color: #fff; }

/* ON 토글 — 파랑(주 동작)이 아니라 상태색(초록). 배지 체계와 같은 문법 */
.btn-toggle-on { background: #E7F6EE; color: #177245; border: 1px solid #BFE6CF; font-weight: var(--font-weight-semibold); }
.btn-toggle-on:hover { background: #D8F0E3; color: #116038; }

/* 사이드바 구분 제목 대비 — 11px 대 4.0:1 지적 → 밝게 */
.sidebar .nav-section, .sidebar summary.nav-section { color: #A9B7DC; }

/* 문의하기 — 흐름에 끼어 있던 생 버튼을 제대로 된 플로팅 버튼으로 */
#feedbackFab {
    position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 90;   /* 오른쪽 아래 — 사이드바를 안 가린다 */
    min-height: 42px; padding: .55rem 1.05rem;
    border-radius: 999px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
    font-size: var(--font-size-sm);
}
#feedbackFab:hover { border-color: var(--color-primary); color: var(--color-primary); }

/* 로그인 화면 한 줄 소개 */
.auth-sub { text-align: center; color: var(--color-text-muted); font-size: var(--font-size-sm); margin: .35rem 0 1.2rem; }

/* 점검 상태 [자세히] — 체크의 전체 출력 */
.check-detail {
    margin: 0; padding: .75rem 1rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--font-size-xs); line-height: 1.7;
    white-space: pre-wrap; word-break: break-all;
    max-height: 22rem; overflow: auto;
    color: var(--color-text);
}

/* ══════════════════════════════════════════════════════════════════════
   모바일 (≤768px) — 2026-08-24
   ══════════════════════════════════════════════════════════════════════
   ⚠️ 이 블록은 **파일 맨 끝**에 있어야 한다. 위쪽 427줄의 미디어쿼리는
      뒤에 오는 데스크톱 규칙(687~)에 덮여서 일부가 먹지 않았다.
      CSS 는 나중에 오는 것이 이긴다 — 모바일 규칙을 중간에 두지 말 것.

   원본 소보루는 Bootstrap4 관리자 테마라 표를 `table-responsive`(가로 스크롤)로
   흘려보낸다. 표 처리 방향은 아직 사람 결정 대기 — 여기서는 **표 밖**만 손댄다.
   ────────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {

    /* ── 헤더: 좁은 폭에서 로고가 두 줄로 쪼개지고 등급이 화면 밖으로 밀렸다 ── */
    .app-header { padding: 0 .5rem; gap: .25rem; }
    .app-brand  { white-space: nowrap; font-size: 1rem; }

    /* 날짜와 이름·등급은 모바일에서 자리만 먹는다 — 아바타로 누가 로그인했는지는 남는다.
       (이름·등급은 사이드바와 [내 정보]에서 볼 수 있다.) */
    .header-date      { display: none; }
    .header-user-info { display: none; }

    /* 손가락으로 누르는 것 — 44px 확보. 아이콘 버튼이 제일 작았다(패딩 .4rem = 30px). */
    .header-toggle,
    .btn-header-logout {
        min-width: 44px; min-height: 44px;
        display: inline-flex; align-items: center; justify-content: center;
        padding: 0;
    }

    /* ── 페이지 머리: 제목과 버튼 묶음이 한 줄을 다퉈 제목이 두 줄로 쪼개졌다 ── */
    .page-header {
        flex-direction: column;
        align-items: stretch;
        gap: .75rem;
    }
    .page-title { font-size: var(--font-size-xl); white-space: nowrap; }

    /* 버튼 묶음은 옆으로 밀어 본다 — 줄바꿈시키면 머리가 화면 절반을 먹는다.
       `-webkit-overflow-scrolling` 은 iOS 관성 스크롤. */
    .page-header > div:last-child {
        display: flex; gap: .4rem;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: .15rem;
    }
    .page-header > div:last-child::-webkit-scrollbar { display: none; }
    .page-header > div:last-child > .btn { flex: 0 0 auto; }

    /* ── 상품군 탭: 3개가 화면 밖으로 삐져나갔다 — 옆으로 밀리게 ── */
    .page-filter-row {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .page-filter-row::-webkit-scrollbar { display: none; }
    .page-filter-row > * { flex: 0 0 auto; }

    /* ── 검색 폼: 한 줄에 여러 칸을 늘어놓으면 다 찌그러진다 — 한 줄에 하나 ── */
    .page-filter-form { flex-direction: column; align-items: stretch; padding: .75rem; }
    .page-filter-form .form-group { width: 100%; }
    .page-filter-form .form-control,
    .page-filter-form .combo { width: 100%; min-width: 0; }

    /* ── 여백: 데스크톱 값(1.75rem 2rem)이 좁은 화면에선 내용 폭을 잡아먹는다 ── */
    .page-content { padding: 1rem .75rem; }
    .page-body    { padding: .85rem; }
    .card         { padding: .85rem 1rem; }

    /* ── 손가락 크기: 표 밖 버튼·입력칸을 44px 로. 표 안(.btn-sm)은 표 방향 결정 후. ── */
    .page-header .btn,
    .page-filter-form .btn,
    .modal .btn,
    .page-filter-form .form-control,
    .modal .form-control { min-height: 44px; }

    /* 탭은 44px 까지 키우면 머리가 너무 두꺼워진다 — 38px 로 타협(손가락은 닿는다). */
    .page-filter-row > .btn-sm { min-height: 38px; padding: .4rem .8rem; }

    /* ── 모달: 좁은 화면에서 min-width 320px 이 화면을 밀어낸다 ── */
    .modal { min-width: 0; width: 100%; max-width: none; }
    .modal.modal-lg { max-width: none; }
    .modal.modal-xl { max-width: none; }
    .modal-overlay { padding: .75rem .5rem; }

    /* ── 문의 버튼: 표 가로 스크롤과 겹치지 않게 조금 올린다 ── */
    #feedbackFab { right: .75rem; bottom: .75rem; }
}

/* ══════════════════════════════════════════════════════════════════════
   모바일 표 → 카드 (.cards-on-mobile) — 2026-08-24
   ══════════════════════════════════════════════════════════════════════
   375px 화면에서 슬롯 목록 표는 폭 1168px 이었다. 옆으로 밀어 봐야 번호·담당자·방식
   3열만 보여 사실상 못 쓴다. 그래서 **모바일에서만** 행 하나를 카드 하나로 바꾼다.

   원본 소보루는 Bootstrap4 `table-responsive`(가로 스크롤)로 흘려보낸다 —
   여기서만 다르게 간다. **사용자 결정(2026-08-24).**

   HTML 은 한 벌이다. 자리는 `td` 의 `data-role`, 라벨은 `data-label` 이 정한다.
   → 라벨을 지우면 모바일에서 값만 남아 무슨 값인지 알 수 없다.
   ────────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {

    /* 표 골격을 흘려보낸다. colgroup·thead 는 카드에서 의미가 없다. */
    table.cards-on-mobile          { display: block; table-layout: auto; width: 100%; }
    table.cards-on-mobile colgroup,
    table.cards-on-mobile thead    { display: none; }
    table.cards-on-mobile tbody    { display: block; }

    /* 행 하나 = 카드 하나 */
    table.cards-on-mobile tbody tr {
        display: flex; flex-wrap: wrap;
        background: var(--color-surface);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        padding: .85rem;
        margin-bottom: .6rem;
    }

    /* 칸 하나 = 라벨:값 한 줄 (기본 자리 order 4) */
    table.cards-on-mobile tbody td {
        display: flex; align-items: baseline; gap: .5rem;
        width: 100%; order: 4;
        padding: .22rem 0; border: 0;
        text-align: left !important;
        /* table-fixed 가 걸어 둔 말줄임을 푼다 — 카드에선 접을 이유가 없다 */
        overflow: visible; text-overflow: clip; white-space: normal;
    }
    table.cards-on-mobile tbody td::before {
        content: attr(data-label);
        flex: 0 0 5rem;
        color: var(--color-text-muted);
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
    }

    /* 값이 아예 없는 칸은 라벨만 남아 카드를 늘린다 — 숨긴다.
       (PHP 가 공백 없이 출력하는 칸만 :empty 로 잡힌다. 나머지는 ui.js 가 처리) */
    table.cards-on-mobile tbody td:empty { display: none; }

    /* ── 카드 머리: 번호(왼쪽) + 상태(오른쪽) 한 줄 ── */
    table.cards-on-mobile tbody td[data-role="no"] {
        order: 1; width: auto; flex: 1 1 auto;
        font-size: var(--font-size-lg); font-weight: var(--font-weight-bold);
    }
    table.cards-on-mobile tbody td[data-role="state"] {
        order: 2; width: auto; flex: 0 0 auto; justify-content: flex-end;
    }

    /* ── 제목: 키워드 — 카드에서 제일 먼저 읽는 값이다 ── */
    table.cards-on-mobile tbody td[data-role="title"] {
        order: 3; display: block; width: 100%;
        font-weight: var(--font-weight-semibold);
        margin: .35rem 0 .5rem;
        padding-bottom: .5rem;
        border-bottom: 1px solid var(--color-bg);
    }

    /* ── 버튼 묶음: 맨 아래, 폭을 나눠 갖고 손가락 크기(40px) ── */
    table.cards-on-mobile tbody td[data-role="actions"] {
        order: 5; display: flex; flex-wrap: wrap; gap: .35rem;
        margin-top: .55rem;
    }
    table.cards-on-mobile tbody td[data-role="actions"] .btn {
        flex: 1 1 auto; min-height: 40px; justify-content: center;
    }

    /* 자리를 지정한 칸은 라벨을 붙이지 않는다 — 값 자체가 무엇인지 말한다 */
    table.cards-on-mobile tbody td[data-role]::before { content: none; }

    /* 래퍼: 카드는 세로로 길게 흘러야 한다. 화면 기준 최대높이를 풀고,
       sticky thead 도 thead 가 없으니 자연히 무효가 된다. */
    .table-wrap { max-height: none; }

    /* 카드 안에서는 접기(clamp)가 필요 없다 — 폭이 넉넉하고 세로로 흐른다 */
    table.cards-on-mobile .cell-clamp { -webkit-line-clamp: unset; padding-right: 0; }
    table.cards-on-mobile .cell-clamp.has-more::after { content: none; }
    table.cards-on-mobile .clamp-toggle { display: none; }

    /* 값이 빈 카드 칸 — ui.js markBlankCardCells 가 표시한다 */
    table.cards-on-mobile tbody td.is-blank { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   검색 조건 카드 · 목록 머리 — 원본 배치 (2026-08-24)
   ══════════════════════════════════════════════════════════════════════
   🔴 클래스만 붙이고 이 CSS 를 안 만들어서 3열이 1열로 쌓였다.
      한 칸이 화면 폭을 다 먹어 세로로 여섯 줄이 됐다 — 사용자가 바로 잡아냈다.
   ────────────────────────────────────────────────────────────────────── */
.search-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1rem 1.25rem 1.1rem;
    margin-bottom: 1rem;
    box-shadow: 0 1px 2px rgba(17, 28, 61, .04);
}
.search-card-title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    margin: 0 0 .9rem;
    padding-bottom: .6rem;
    border-bottom: 1px solid var(--color-border);
}

/* 🔴 칸이 화면 1/3(450px) 씩이라 한눈에 안 들어왔다 (2026-08-24 지적).
   원본처럼 **두 줄**로 두되 칸 자체를 좁게 잡는다 — 고른 값은 짧으니 넓을 이유가 없다.
   전체를 화면 폭까지 늘리지 않고 max-width 로 묶는다. */
.search-grid {
    display: grid;
    /* 🔴 4칸이다 (2026-08-25 지시). 3칸 24rem 이면 조건이 넷일 때 하나가 다음 줄로 떨어졌다.
       칸을 좁혀 한 줄에 넷을 넣는다 — 조건 칸은 어차피 짧은 값(아이디·상태)이 들어간다. */
    grid-template-columns: repeat(4, minmax(0, 18rem));
    gap: .8rem 1.2rem;
    /* 🔴 등급에 따라 칸이 빠진다(대행사에게는 총판·대행사 필터가 없다).
       고정 3칸에 그냥 흘려 보내면 2칸짜리 기간이 다음 줄로 밀리면서
       **앞줄 끝에 빈 구멍**이 남는다 — 슬롯NO 하나가 딸랑 떠 보이던 것이 이것이다.
       dense 로 뒤 칸이 앞의 빈자리를 메우게 한다 (2026-08-25 지적). */
    grid-auto-flow: row dense;
}
@media (max-width: 1400px) { .search-grid { grid-template-columns: repeat(3, minmax(0, 20rem)); } }
@media (max-width: 1100px) { .search-grid { grid-template-columns: repeat(2, minmax(0, 24rem)); } }
@media (max-width: 760px) { .search-grid { grid-template-columns: 1fr; } }

.search-grid .form-group { margin: 0; min-width: 0; }
.search-grid .form-control { width: 100%; }
@media (max-width: 768px) {
    .search-grid .form-group,
    .search-grid .form-group.is-wide { flex: 1 1 100%; }
}

/* 체크박스 5종 + [검색][초기화] 를 한 줄에 — 카드 높이를 줄인다 */
.search-flags {
    display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1.1rem;
    margin-top: .85rem;
}
.flag-check {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: var(--font-size-sm); cursor: pointer;
    color: var(--color-text);
}
.flag-check input { cursor: pointer; }

/* [검색][초기화] — 체크박스 줄 오른쪽 끝에 붙는다 (한 줄을 아낀다) */
/* 검색·초기화 — 원본처럼 아래 줄 가운데 */
.search-actions {
    display: flex; justify-content: center; gap: .5rem;
    margin-top: 1rem;
}
.search-actions .btn { min-width: 7rem; justify-content: center; }

/* ── 목록 머리 ────────────────────────────────────────────── */
.list-title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    margin: 0 0 .6rem;
}
.list-title small { font-weight: var(--font-weight-normal); }
.list-scope { color: var(--color-text-muted); font-size: var(--font-size-xs); }

.list-summary {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    line-height: 1.8;
    margin-bottom: .75rem;
}

.list-actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
    padding-bottom: .85rem;
    margin-bottom: .5rem;
    border-bottom: 1px solid var(--color-border);
}
.selected-hint {
    font-size: var(--font-size-sm); color: var(--color-text-muted);
    margin-right: .4rem;
}
.selected-hint strong { color: var(--color-text); }
.list-actions .btn:disabled { opacity: .45; cursor: not-allowed; }

/* 표 안 사용 ON/OFF 토글 */
.btn-toggle {
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-text-muted);
    border-radius: var(--radius-sm);
    padding: .15rem .5rem;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    cursor: pointer; min-width: 2.6rem;
}
.btn-toggle-on {
    background: var(--color-success, #16a34a);
    border-color: var(--color-success, #16a34a);
    color: #fff;
}

/* 목록 버튼 줄 오른쪽 묶음 — 내려받기·등록·대량수정·재수집 */
.list-actions-right { margin-left: auto; display: flex; flex-wrap: wrap; gap: .4rem; }
.list-actions-right .btn { font-size: var(--font-size-sm); }

/* ── 작업키워드: 첫 한 개만 보이고 나머지는 접는다 (2026-08-24) ──────────
   키워드는 쉼표로 여러 개가 들어온다. 다 펼치면 행 높이가 제각각이 되고
   표가 세로로 늘어난다. 첫 개 + [+N] 칩만 보인다. */
.kw-cell { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
/* 🔴 flex 안에서는 min-width 가 auto 라 **글이 길면 칸을 밀고 나가** 잘려 보인다
   (2026-08-25 지적: "자쿨락커 저거 뒤로 잘리는거"). 0 으로 낮춰야 … 로 줄어든다. */
.kw-head {
    /* 🔴 **인라인 요소에는 text-overflow 가 안 먹는다.**
       키워드가 하나뿐인 칸은 .kw-cell(flex) 없이 span 만 놓이는데,
       그때 인라인이라 … 없이 그냥 잘려 나갔다 (2026-08-25 실측).
       display:block 이면 칸 폭에 맞춰 … 로 줄어든다 — flex 안에서도 그대로 동작한다. */
    display: block;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    max-width: 100%; min-width: 0; flex: 0 1 auto;
}
.kw-more {
    flex: 0 0 auto;
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-text-muted);
    border-radius: 999px;
    padding: .05rem .4rem;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    line-height: 1.5;
}
.kw-more:hover { background: var(--color-surface); color: var(--color-text); }
.kw-more[aria-expanded="true"] {
    background: var(--color-primary); border-color: var(--color-primary);
    color: var(--color-primary-fg);
}
/* 🔴 펼친 키워드가 셀 안에서 늘어나 행 높이를 잡아먹었다 (2026-08-24 지적 2회).
   이제 **떠서** 보인다 — 표 레이아웃을 건드리지 않으므로 행 높이가 그대로다.
   .table-wrap 이 overflow:auto 라 absolute 는 잘린다 → fixed + JS 좌표. */
/* 🔴 display 를 명시하면 브라우저 기본 `[hidden] { display: none }` 을 **덮어쓴다.**
   그래서 hidden 을 붙여도 팝오버가 안 사라졌다 — 닫기 버튼·바깥클릭·ESC 가 전부
   무력화됐다(2026-08-24). display 를 주는 규칙에는 [hidden] 예외를 반드시 같이 둔다. */
.kw-rest {
    position: fixed;
    z-index: 300;
    display: block;
    width: max-content; max-width: 24rem;
    max-height: 15rem; overflow-y: auto;
    /* 팝오버 끝까지 굴려도 페이지로 번지지 않게 — 번지면 페이지가 움직여 팝오버가 닫혔다 */
    overscroll-behavior: contain;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: .5rem;
}
.kw-rest::-webkit-scrollbar { width: 6px; }
.kw-rest::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }
.kw-chip {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: .05rem .35rem;
    font-size: var(--font-size-xs);
}

/* ── 관리 열: 버튼이 잘리지 않게 두 줄로 흘린다 ──────────────────────
   한 줄에 억지로 밀어 넣으면 '수정 환불 재수집 …' 처럼 끝이 잘린다. */
td[data-role="actions"] {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
}
/* 버튼이 아래로 내려가면 행 높이가 제각각이 된다 — 한 줄에 유지한다. */
td[data-role="actions"] {
    white-space: nowrap !important;
}
td[data-role="actions"] .btn {
    margin: 0 .08rem;
    padding: .18rem .38rem;
    font-size: var(--font-size-xs);
}

/* 키워드 팝오버 머리줄 — 몇 개인지 알려 주고 닫기를 준다 */
.kw-rest-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: .5rem; margin-bottom: .4rem;
    font-size: var(--font-size-xs); color: var(--color-text-muted);
}
.kw-close {
    background: none; border: none; cursor: pointer;
    font-size: var(--font-size-lg); line-height: 1; color: var(--color-text-muted);
    padding: 0 .15rem;
}
.kw-close:hover { color: var(--color-text); }
.kw-chips { display: flex; flex-wrap: wrap; gap: .25rem; }

/* 관리 열 버튼 — 원본 화면과 같은 색 배치 */
/* 🔴 관리 버튼 네 개 — 색은 그대로 넷이되 **톤을 낮춘다** (2026-08-25 지시).
   전에는 #f59e0b·#22c55e·#38bdf8 처럼 채도가 높아 표가 쨍했다.
   기준은 [상세]에 쓰던 파랑(#3b82f6). 나머지 셋을 그 무게에 맞춰 눌렀다. */
.btn-detail { background: #3b82f6; border-color: #3b82f6; color: #fff; }
.btn-edit   { background: #dda043; border-color: #dda043; color: #fff; }
.btn-save   { background: #16a34a; border-color: #16a34a; color: #fff; }
.btn-rank   { background: #4fae7f; border-color: #4fae7f; color: #fff; }
.btn-info   { background: #4fa8d8; border-color: #4fa8d8; color: #fff; }
.btn-detail:hover, .btn-edit:hover, .btn-save:hover,
.btn-rank:hover, .btn-info:hover { filter: brightness(.93); }

/* 표 안 편집칸 — 행 높이를 키우지 않게 작게 */
.form-control-sm { padding: .12rem .35rem; font-size: var(--font-size-xs); height: auto; }
td .cell-edit { width: 100%; min-width: 0; }
/* display 를 주는 규칙에는 [hidden] 예외를 함께 (앞서 .kw-rest 에서 당했다) */


/* ── 행 편집 패널 ────────────────────────────────────────────────
   🔴 표 칸 안에서 고치게 했더니 상품URL 칸이 56px 이라 못 썼다 (2026-08-24).
      행 아래에 표 전체 폭으로 펼쳐 넉넉하게 고친다. */
.edit-panel-row > td {
    background: color-mix(in srgb, var(--color-primary) 4%, var(--color-surface));
    border-bottom: 2px solid var(--color-primary);
    padding: .85rem 1rem !important;
}
.edit-panel {
    display: flex; flex-wrap: wrap; align-items: flex-end;
    gap: .75rem 1rem;
}
.edit-field { display: flex; flex-direction: column; gap: .25rem; flex: 1 1 12rem; min-width: 0; }
.edit-field-sm   { flex: 0 0 7rem; }
.edit-field-wide { flex: 2 1 24rem; }
.edit-field label {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
}
.edit-field label small { font-weight: var(--font-weight-normal); }
.edit-field .form-control { width: 100%; padding: .35rem .55rem; font-size: var(--font-size-sm); }
.edit-panel-actions { display: flex; gap: .4rem; flex: 0 0 auto; }

/* 편집 중인 행을 표시 */
tr.row-editing > td { background: color-mix(in srgb, var(--color-primary) 5%, transparent); }

/* 순위·상품정보 결과 모달 (원본 rankResultModal / infoResultModal) */
.result-list {
    display: grid; grid-template-columns: 5rem 1fr;
    gap: .45rem .75rem; margin: 0 0 1rem;
    font-size: var(--font-size-sm);
}
.result-list dt { color: var(--color-text-muted); font-weight: var(--font-weight-semibold); font-size: var(--font-size-sm); }
.result-list dd { margin: 0; word-break: break-all; }
.result-img { margin-bottom: 1rem; text-align: center; }
.result-img img { max-width: 100%; max-height: 12rem; border-radius: var(--radius-sm); }

/* 상세 모달은 칸이 15개다 — 두 벌로 나눠 세로를 줄인다 */
.result-list-2col { grid-template-columns: 5rem 1fr 5rem 1fr; }
@media (max-width: 768px) { .result-list-2col { grid-template-columns: 5rem 1fr; } }

/* 한 줄로 자르고 누르면 띄운다 — 상품명·태그 (키워드와 같은 방식)
   🔴 클래스만 붙이고 이 규칙을 안 만들어 두세 줄로 흘렀다 (2026-08-24). */
.cell-ellip {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
    cursor: pointer;
}
.cell-ellip:hover { text-decoration: underline; }

/* 표 칸은 기본으로 한 줄 — wrap 이 있어도 넘치면 자른다 */
table.table-fixed td.wrap { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 🔴 접기(clamp) 방식 셀은 위 규칙에서 뺀다 (2026-08-25).
   nowrap 이 걸려 있으면 -webkit-line-clamp 가 아무 일도 못 한다 —
   [70개 ▾] 를 눌러도 **무반응**이고, 글은 한 줄로 잘린 채 남는다. 실제로 그랬다. */
table.table-fixed td.wrap-clamp {
    white-space: normal; word-break: break-word;
    overflow: hidden; text-overflow: clip;
}
table.table-fixed td.wrap .kw-cell { flex-wrap: nowrap; min-width: 0; }
table.table-fixed td.wrap .kw-head { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* 한 개짜리 셀도 같은 규칙 — flex 자식이면 min-width 를 풀어 준다 */
.kw-cell > .cell-ellip { min-width: 0; flex: 0 1 auto; }

/* 팝오버 안 전체 글 */
.kw-full { font-size: var(--font-size-sm); line-height: 1.6; word-break: break-all; }

/* 기간 검색 — 날짜 두 칸 + 단축 버튼 (원본 setSchPeriod)
   🔴 칸 폭이 24rem 이라 날짜 두 개가 세로로 떨어졌다 (2026-08-24 지적).
      기간 칸만 두 칸 폭을 쓰고, 안에서는 줄바꿈하지 않는다. */
.search-grid .form-group.is-period { grid-column: span 2; }
.period-row {
    display: flex; align-items: center; gap: .3rem;
    flex-wrap: nowrap;
}
/* 🔴 날짜 칸은 내용이 'YYYY. MM. DD.' 로 고정이라 늘려 봐야 빈 자리만 는다.
   `flex: 1 1 8rem` 만 두면 남는 폭을 다 먹어 화면마다 320px 씩 차지했다 (2026-08-25 지적).
   최대 폭을 묶어 두면 조건 칸이 몇 개든 같은 크기로 보인다. */
/* 격자가 4칸이 되면서 기간(2칸)이 36rem 남짓이다. 날짜 두 칸 + ~ + 버튼 셋이
   한 줄에 들어가야 하므로 날짜 칸을 조금 더 줄인다. */
.period-row .form-control { flex: 0 1 9.5rem; min-width: 7.5rem; max-width: 9.5rem; }
.period-row .btn { flex: 0 0 auto; padding: .3rem .5rem; }
.period-tilde { flex: 0 0 auto; color: var(--color-text-muted); }
@media (max-width: 1100px) { .search-grid .form-group.is-period { grid-column: span 2; } }
@media (max-width: 760px)  {
    .search-grid .form-group.is-period { grid-column: span 1; }
    .period-row { flex-wrap: wrap; }
}

/* 표 안 버튼은 두 줄로 쪼개지지 않는다 — '상세보 / 기' 처럼 잘렸다 (2026-08-24) */
table td .btn { white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════════
   표 아래 여백 — 전 화면 공통 (2026-08-24 지적)
   ══════════════════════════════════════════════════════════════════
   🔴 표가 끝나자마자 설명글·페이지 번호가 붙어 있었다. 마지막 행과 글이
      맞닿아 어디까지가 표인지 안 보였다. 화면마다 고치지 말고 여기서 한 번에 준다.
   ══════════════════════════════════════════════════════════════════ */
.table-wrap { margin-bottom: 1rem; }

/* 표 아래 설명글 (…는 다를 수 있습니다 같은 안내) */
.table-wrap + p,
.table-wrap ~ p > small,
.page-body > p > small { color: var(--color-text-muted); }

.table-wrap + p {
    margin: .85rem 0 0;
    padding-top: .85rem;
    border-top: 1px solid var(--color-border);
    font-size: var(--font-size-sm);
    line-height: 1.7;
}

/* 페이지 번호 줄 */
.pagination,
.pager,
.page-nav {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: .3rem;
    margin: 1.25rem 0 .5rem;
}
/* 페이지 번호는 .btn 을 그대로 쓴다 — 색·테두리는 기존 버튼 규칙이 맡고
   여기서는 크기와 간격만 맞춘다 (안 그러면 두 규칙이 싸운다). */
.pagination .btn { min-width: 2.2rem; justify-content: center; padding: .32rem .55rem; }
.pagination > span { color: var(--color-text-muted); padding: 0 .25rem; }

.pagination a:not(.btn), .pagination span:not(.btn),
.pager a, .pager span,
.page-nav a, .page-nav span {
    min-width: 2.1rem; height: 2.1rem;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 .5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    text-decoration: none;
    color: var(--color-text);
}
.pagination a:hover, .pager a:hover, .page-nav a:hover { background: var(--color-bg); }
.pagination .active, .pagination [aria-current],
.pager .active, .pager [aria-current],
.page-nav .active, .page-nav [aria-current] {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-primary-fg);
    font-weight: var(--font-weight-semibold);
}
.pagination .disabled, .pager .disabled, .page-nav .disabled {
    opacity: .4; pointer-events: none;
}

/* 페이지 본문 아래도 숨 쉴 틈 */
/* 오른쪽 아래 '문의하기' 는 고정 버튼이라 맨 아래 줄(저장 버튼·페이지 번호)을 가린다.
   🔴 그렇다고 늘 자리를 비워 두면 **짧은 화면 아래가 텅 빈다**(2026-08-25 지적).
      화면이 실제로 스크롤될 때만 비운다 — 판정은 ui.js::syncFabGap 이 한다. */
.page-body { padding-bottom: 1.1rem; }
body.has-fab-gap .page-body { padding-bottom: 4.25rem; }

/* 검색어 한 줄 — 조건 격자 아래, 버튼 위 가운데 */
.search-keyword {
    display: flex; flex-direction: column; gap: .25rem;
    max-width: 34rem; margin: .9rem auto 0;
}
.search-keyword label {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
}

/* 정산 합계 금액 — 원본은 목록 버튼 줄에 크게 띄운다 */
.sum-amount { font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); margin-left: .6rem; }
.sum-amount strong { color: var(--color-primary); font-size: var(--font-size-xl); }

/* 정산 통계 표 — 원본(list_statistics.php)은 전 칸 가운데 정렬에 음수만 빨간색이다.
   총판 수만큼 줄이 깔리므로 줄 높이를 목록 화면보다 좁게 잡는다. */
.stat-table th,
.stat-table td { text-align: center; white-space: nowrap; padding: .45rem .6rem; font-size: var(--font-size-sm); }
.stat-table tbody td:first-child,
.stat-table tbody td:nth-child(2) { text-align: left; }
.stat-table tfoot th { font-weight: var(--font-weight-semibold); background: var(--color-surface-2, #f8fafc); }
.stat-table tfoot th:first-child { text-align: left; }
.amount-neg { color: var(--color-error-fg); }


/* ═══ 표 안쪽 스크롤 제거 (2026-08-24 지시) ═══════════════════════
   🔴 화면 안에 또 스크롤바가 생기면 목록을 두 번 굴려야 한다.

   전에는 표 머리 고정(sticky)을 살리려고 래퍼를 화면 높이 스크롤 영역으로 만들었다
   (`max-height: calc(100vh - 230px); overflow:auto`). 그러면 sticky 가 문서가 아니라
   래퍼에 붙는 대신 **안쪽 스크롤바**가 생긴다. 반대로 간다 —
   래퍼는 평소 `overflow: visible` 이고, 진짜로 넘치는 표에만 JS 가 `.scroll-x` 를 붙인다.
   그래서 세로 스크롤은 페이지 하나뿐이고, 표 머리는 고정 헤더 바로 아래에 붙는다. */
.table-wrap { max-height: none; overflow: visible; }
.table-wrap.scroll-x { overflow-x: auto; }
thead th { top: var(--header-height); z-index: 20; }

/* 모달 안의 표는 예외다 — 모달까지 길어지면 화면을 넘긴다. 여기서는 안쪽에서 스크롤한다. */
.modal .table-wrap { max-height: 40vh; overflow: auto; }
.modal .table-wrap thead th { top: 0; }

/* 목록 개수 선택(100·200·300개씩) — .form-control 은 width:100% 라 그냥 두면 줄을 다 먹는다.
   원본도 100px 남짓한 작은 상자다. */
.list-size { width: auto; min-width: 7.5rem; flex: 0 0 auto; }

/* 회원 관리 모달 — 원본처럼 두 칸으로 나란히 놓는다(칸이 하나씩 세로로 쌓이면 모달이 길어진다) */
.modal-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem 1rem; }
.modal-form-grid .form-group { margin: 0; min-width: 0; }
@media (max-width: 640px) { .modal-form-grid { grid-template-columns: 1fr; } }

/* 권한 두 개 + 슬롯 가격 — 원본도 한 줄에 셋을 둔다 */
.modal-form-auth {
    display: flex; align-items: flex-end; gap: 1.2rem; flex-wrap: wrap;
    margin-top: .8rem; padding-top: .8rem; border-top: 1px solid var(--color-border);
}
.modal-form-auth .form-group { margin: 0; min-width: 0; }
.modal-form-auth .form-control { max-width: 10rem; }
.modal-form-auth .flag-check { padding-bottom: .45rem; }   /* 입력칸 아랫줄에 눈높이를 맞춘다 */
.modal-actions-split { margin-top: 1rem; }

/* [정지] 는 왼쪽, [취소][저장] 은 오른쪽 — 원본 modal-footer 배치 */
.modal-actions-split { display: flex; align-items: center; gap: .4rem; }
.modal-actions-split .modal-actions-gap { flex: 1 1 auto; }

/* 검색 조건 카드·모달 안의 콤보는 칸을 꽉 채운다 (기본 min-width 11rem 이 격자를 밀어낸다) */
.search-card .combo,
.modal .combo { width: 100%; min-width: 0; }


/* ── 문의 상세 — 글 하나와 그에 대한 답변, 두 덩어리로 읽힌다 ─────────
   왼쪽 색 띠가 상태를 먼저 말해 준다(안 읽음·읽음·답변함). */
.thread {
    position: relative;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1.1rem 1.35rem;
    margin-bottom: .9rem;
    box-shadow: var(--shadow-sm);
}
.thread::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
    background: var(--color-border);
}
.thread-new::before    { background: var(--color-error-fg); }
.thread-read::before   { background: var(--color-text-muted); }
.thread-done::before   { background: var(--color-success-fg-2, #15803d); }
.thread-answer::before { background: var(--color-primary); }

.thread-head {
    display: flex; align-items: center; gap: .6rem;
    padding-bottom: .7rem; margin-bottom: .7rem;
    border-bottom: 1px solid var(--color-border);
}
.thread-head-main { display: flex; align-items: center; gap: .55rem; min-width: 0; flex: 1 1 auto; }
.thread-title {
    margin: 0; font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.thread-reply-icon { color: var(--color-primary); }
.thread-when { color: var(--color-text-muted); }

.thread-meta {
    display: flex; flex-wrap: wrap; gap: .3rem 1.4rem;
    font-size: var(--font-size-sm); color: var(--color-text-muted);
    margin-bottom: .9rem;
}
.thread-meta i { width: 1rem; text-align: center; opacity: .75; margin-right: .15rem; }

.thread-body { line-height: 1.75; word-break: break-word; }
.thread-body p:first-child { margin-top: 0; }
.thread-body p:last-child  { margin-bottom: 0; }

.thread-answer textarea { width: 100%; }
.thread-actions {
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-top: .8rem;
}
.thread-actions-note {
    flex: 1 1 auto; text-align: right;
    font-size: var(--font-size-xs); color: var(--color-text-muted);
}

/* ── 사이트 설정(시간 정보 설정) — 원본처럼 수정/환불을 좌우로 나란히 ── */
.setting-card {
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius-md); padding: 1.1rem 1.35rem;
    box-shadow: var(--shadow-sm);
}
.setting-title {
    margin: 0 0 1rem; padding-bottom: .7rem;
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold);
}
.setting-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 22rem)); gap: 1.6rem; }
@media (max-width: 760px) { .setting-grid { grid-template-columns: 1fr; } }

.setting-col-head { display: flex; align-items: center; gap: .6rem; margin-bottom: .7rem; }
.setting-col-label { font-weight: var(--font-weight-semibold); }

.setting-default { display: flex; align-items: center; gap: .5rem; margin-bottom: .6rem; }
.setting-default label { font-size: var(--font-size-sm); color: var(--color-text-muted); white-space: nowrap; }
.setting-default .form-control { max-width: 9rem; }

.setting-table th, .setting-table td { padding: .35rem .6rem; }
.setting-table thead th { text-align: center; }
.setting-table tbody td:first-child { width: 3.2rem; text-align: center; color: var(--color-text-muted); }
.setting-table .form-control { width: 100%; }

.setting-actions { display: flex; align-items: center; gap: .8rem; margin-top: 1.2rem; }
.setting-actions small { color: var(--color-text-muted); }

/* 스위치 — 원본의 on/off 토글과 같은 모양. 체크박스라 폼 제출은 그대로 된다. */
.switch { position: relative; display: inline-flex; align-items: center; cursor: pointer; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.switch-track {
    width: 2.4rem; height: 1.3rem; border-radius: 999px;
    background: var(--color-border); transition: background .15s; position: relative;
}
.switch-track::after {
    content: ""; position: absolute; top: 2px; left: 2px;
    width: 1.05rem; height: 1.05rem; border-radius: 50%;
    background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
    transition: transform .15s;
}
.switch input:checked + .switch-track { background: var(--color-primary); }
.switch input:checked + .switch-track::after { transform: translateX(1.1rem); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ── 모달 머리·본문 (슬롯 상세·순위·정보) ─────────────────────────
   값만 줄줄이 늘어놓지 않는다. 머리줄에서 무엇을 보는지·어떤 상태인지 먼저 읽는다. */
.modal-head {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    padding-bottom: .7rem; margin-bottom: .9rem;
    border-bottom: 1px solid var(--color-border);
}
.modal-head h2 { margin: 0; font-size: var(--font-size-lg); }

/* 🔴 묶음 제목(소속·기간·작업)은 그 아래 라벨과 **같은 크기·같은 색**이라
   무엇이 제목인지 안 보였다 (2026-08-25 지적).
   제목은 한 단계 크고 진하게, 아래 옅은 선으로 묶음을 끊는다. */
.modal-col-title {
    margin: 0 0 .5rem; padding-bottom: .3rem;
    font-size: var(--font-size-md);
    color: var(--color-text);
    font-weight: var(--font-weight-semibold);
    border-bottom: 1px solid var(--color-border);
}
.modal-cols { display: grid; grid-template-columns: 1fr 1fr; gap: .4rem 1.6rem; }
@media (max-width: 640px) { .modal-cols { grid-template-columns: 1fr; } }

/* 이 모달을 여는 이유가 값 하나뿐일 때 — 그 값만 크게 */
.result-hero {
    display: flex; align-items: baseline; gap: .6rem;
    padding: .8rem 1rem; margin-bottom: 1rem;
    background: var(--color-bg); border-radius: var(--radius-md);
}
.result-hero-label { color: var(--color-text-muted); font-size: var(--font-size-sm); }
.result-hero-value { font-size: var(--font-size-3xl); font-variant-numeric: tabular-nums; }

/* 상품정보 — 그림이 있으면 왼쪽, 값은 오른쪽 */
.info-body { display: flex; gap: 1rem; align-items: flex-start; }
.info-body .result-list { flex: 1 1 auto; margin: 0; }
.info-body .result-img { flex: 0 0 auto; }

/* ── 모달 머리띠 + 숫자 타일 (슬롯 상세·순위·정보) ────────────────
   값을 줄줄이 늘어놓으면 무엇을 보는 창인지 알 수 없다.
   머리띠에서 대상을, 타일에서 숫자를 먼저 읽는다. */
.modal-band {
    display: flex; align-items: flex-start; gap: .75rem;
    margin: -.25rem -.25rem 1rem;
    padding: .85rem 1rem;
    background: var(--color-bg);
    border-radius: var(--radius-md);
    border-left: 4px solid var(--color-primary);
}
.modal-band-main { flex: 1 1 auto; min-width: 0; }
.modal-band-title {
    margin: 0; font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.modal-band-sub {
    margin-top: .2rem; font-size: var(--font-size-sm); color: var(--color-text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.modal-band-dot { margin: 0 .35rem; opacity: .5; }
.modal-band-side { display: flex; gap: .35rem; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; }

.stat-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem; margin-bottom: 1rem; }
.stat-tiles-1 { grid-template-columns: 1fr; }
.stat-tile {
    display: flex; flex-direction: column; gap: .15rem; align-items: center;
    padding: .7rem .5rem;
    border: 1px solid var(--color-border); border-radius: var(--radius-md);
    background: var(--color-surface);
}
.stat-tile-label { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.stat-tile-value { font-size: var(--font-size-2xl); font-variant-numeric: tabular-nums; line-height: 1.15; }
.stat-tile-value-lg { font-size: var(--font-size-4xl); }
/* 날짜처럼 숫자가 아닌 값이 들어가는 타일 — 2xl 로는 줄이 넘친다 */
.stat-tile-value-sm { font-size: var(--font-size-md); }

.break-any { word-break: break-all; }

/* ── 요약 타일 (대시보드) ─────────────────────────────────────────
   한 칸에 큰 숫자 → 이름 → 그 숫자가 무엇인지, 세 줄로 읽는다. */
.section-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
    margin: 1.35rem 0 .55rem;
}
.section-head h2 { margin: 0; font-size: var(--font-size-lg); }
.section-head small { color: var(--color-text-muted); }

.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .7rem; }
.stat-card {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1rem .75rem;
    text-align: center;
}
/* 카드 안에 들어가면 테두리를 뺀다 — 상자 속 상자로 보인다 */
.card .stat-card { border-color: transparent; }
.stat-card-value {
    display: block;
    font-size: var(--font-size-3xl); line-height: 1.15;
    font-weight: var(--font-weight-bold, 700);
    font-variant-numeric: tabular-nums;
}
.stat-card-value.is-ok   { color: var(--color-primary); }
.stat-card-value.is-warn { color: #d97706; }
.stat-card-value.is-bad  { color: var(--color-error-fg); }
.stat-card-label { margin-top: .2rem; font-size: var(--font-size-sm); }
.stat-card-hint  { margin-top: .15rem; font-size: var(--font-size-xs); color: var(--color-text-muted); }

/* 시간 정보 — 값이 둘뿐이라 격자에 흩뿌리지 않고 왼쪽에 나란히 둔다 */
.time-strip { display: flex; align-items: center; gap: 1.75rem; flex-wrap: wrap; }
.time-item { display: flex; align-items: baseline; gap: .5rem; }
.time-item-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }
.time-item-value { font-size: var(--font-size-xl); font-variant-numeric: tabular-nums; }
/* 오늘 기준이라는 설명은 값 **아래** 한 줄로 — 오른쪽 끝에 두면 값과 멀어진다 (2026-08-25 지시) */
p.time-strip-note { margin: .6rem 0 0; font-size: var(--font-size-xs); color: var(--color-text-muted); }

/* ── 카드 배치 (2026-08-25 디자인 개편 1단계) ─────────────────────
   바깥 흰 상자 하나에 전부 담지 않고, **덩어리마다 상자**를 준다.
   상자 안에 상자가 겹쳐 보이던 것을 없앤다 — 대시보드가 이미 그 모양이다.
   화면마다 하나씩 옮기려고 갈래(class)로 둔다: <div class="page-body is-cards"> */
.page-body.is-cards {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
    border-radius: 0;
}
.page-body.is-cards > .card,
.page-body.is-cards > .search-card,
/* 폼으로 감싼 카드도 같은 간격을 받아야 한다 — 안 그러면 카드끼리 딱 붙는다 */
.page-body.is-cards > form,
.page-body.is-cards > .alert { margin-bottom: .9rem; }
.page-body.is-cards > :last-child { margin-bottom: 0; }

/* 카드 안에서는 목록 머리의 위 여백을 줄인다 — 카드 자체가 이미 띄워 준다 */
.card > .list-title:first-child { margin-top: 0; }

/* 누를 수 있는 타일 — 그 조건으로 걸러진 목록으로 간다 */
a.stat-card { text-decoration: none; color: inherit; transition: border-color .12s, background .12s; }
a.stat-card:hover { border-color: var(--color-primary); background: var(--color-primary-50); }
a.stat-card:hover .stat-card-label { color: var(--color-primary-dark, var(--color-primary)); }
.card a.stat-card:hover { border-color: var(--color-primary); }

/* 🔴 표 머리글은 **두 줄이 되지 않는다** (2026-08-25 지시).
   줄이 바뀌면 머리 높이가 들쭉날쭉해지고 글자가 잘려 보인다.
   자리가 모자라면 칸을 넓히거나 이름을 줄인다 — 줄을 바꾸지 않는다. */
thead th { white-space: nowrap; }

/* 곧 끝나는 것 — 위험(빨강)과 평범(회색) 사이 */
.badge-warn { background: #fef3c7; color: #92400e; border-color: #fde68a; }

/* 표 안 썸네일 — 줄 높이를 늘리지 않을 만큼만 */
.thumb-link { display: inline-flex; }
.thumb-mini {
    width: 2rem; height: 2rem; object-fit: cover;
    border: 1px solid var(--color-border); border-radius: var(--radius-sm);
    background: var(--color-bg); display: block;
}
.thumb-link:hover .thumb-mini { border-color: var(--color-primary); }

/* 글 편집기(Quill) — 모달 안에서 너무 커지지 않게 */
.rte { height: 18rem; background: var(--color-surface); }
.ql-toolbar.ql-snow, .ql-container.ql-snow { border-color: var(--color-border); }
.ql-toolbar.ql-snow { border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.ql-container.ql-snow { border-radius: 0 0 var(--radius-sm) var(--radius-sm); font-size: var(--font-size-md); }
.ql-editor { min-height: 12rem; }

/* 저장된 글을 다시 볼 때 정렬이 살아 있게 (Quill 이 클래스로 남긴다) */
.ql-align-center { text-align: center; }
.ql-align-right  { text-align: right; }
.ql-align-justify { text-align: justify; }

/* 슬롯 단가 — 사이트 설정 안, 개발자(1000)에게만 그려지는 칸.
   .setting-table 을 안 쓰는 이유: 그쪽은 첫 칸이 3.2rem 요일 칸이라 상품군 이름이 눌린다. */
.setting-desc { margin: 0 0 1rem; color: var(--color-text-muted); font-size: var(--font-size-sm); }
.setting-desc.is-warn { color: var(--color-warning); }
/* 🔴 위 슬롯 설정 표의 **절반 폭** (2026-08-25 지시). 표는 그 안을 꽉 채운다 —
   카드만 좁히고 표를 auto 로 두면 오른쪽이 비어 더 어색하다. */
.price-form { max-width: 50%; }
@media (max-width: 900px) { .price-form { max-width: none; } }
.price-table { width: 100%; }
.price-table th, .price-table td { padding: .4rem .5rem; white-space: nowrap; }
.price-table thead th { text-align: left; color: var(--color-text-muted); font-weight: var(--font-weight-semibold); }
.price-table thead th:not(:first-child) { text-align: right; }
.price-table tbody td:first-child { white-space: normal; }
.price-table tbody td:first-child small {
    display: block; color: var(--color-text-muted); font-size: var(--font-size-xs);
    overflow: hidden; text-overflow: ellipsis;
}
.price-table td.price-base { text-align: right; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.price-table td:last-child { text-align: right; }
.price-table .form-control { width: 100%; text-align: right; padding-left: .4rem; padding-right: .4rem; }
