/* =============================================================
   NEST UI 디자인시스템 (Design System)
   "UI 디자인시스템 가이드.txt" 를 코드로 구현한 공통 스타일 레이어.

   레이어 순서
   1. Tokens      : 색상 / 타이포 / 간격 / radius / shadow
   2. Base        : 문서 기본값
   3. Bootstrap   : 부트스트랩 컴포넌트 재정의(버튼/카드/폼/테이블/뱃지 등)
   4. Components   : 가이드 공통 컴포넌트 (PageHeader, SearchPanel, ActionBar,
                     EmptyState, StatusBadge, MetaGrid, FormSection ...)
   5. Utilities    : 폭 컨테이너, 상태 유틸

   * 신규/기존 화면 모두 이 파일의 토큰과 컴포넌트를 재사용한다.
   * 한 화면만을 위한 색상/폰트크기/버튼유형을 템플릿에 새로 정의하지 않는다.
   ============================================================= */

/* =============================================================
   1. TOKENS
   ============================================================= */
:root {
    /* --- Brand & Neutral --- */
    --ds-brand-primary:        #4f46e5;
    --ds-brand-primary-hover:  #4338ca;
    --ds-brand-primary-subtle: #eef2ff;
    --ds-header-bg:            #d5edfb;
    --ds-page-bg:             #f4f5f7;
    --ds-surface:             #ffffff;
    --ds-surface-subtle:      #f9fafb;
    --ds-text-primary:        #1a1a2e;
    --ds-text-secondary:      #6b7280;
    --ds-text-disabled:       #9ca3af;
    --ds-border:              #e5e7eb;
    --ds-border-strong:       #d1d5db;

    /* --- Semantic (Text/Icon · Surface) --- */
    --ds-info:            #0284c7;
    --ds-info-surface:    #f0f9ff;
    --ds-success:         #15803d;
    --ds-success-surface: #f0fdf4;
    --ds-warning:         #b45309;
    --ds-warning-surface: #fff3cd;
    --ds-danger:          #dc2626;
    --ds-danger-surface:  #fef2f2;
    --ds-neutral:         #6b7280;
    --ds-neutral-surface: #f3f4f6;

    /* --- Typography --- */
    --ds-font-family: 'Pretendard', 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;

    --ds-fs-display:       28px;  --ds-lh-display:       38px;
    --ds-fs-page-title:    24px;  --ds-lh-page-title:    34px;
    --ds-fs-section-title: 18px;  --ds-lh-section-title: 28px;
    --ds-fs-card-title:    16px;  --ds-lh-card-title:    24px;
    --ds-fs-body:          15px;  --ds-lh-body:          24px;
    --ds-fs-label:         14px;  --ds-lh-label:         20px;
    --ds-fs-table:         14px;  --ds-lh-table:         20px;
    --ds-fs-caption:       13px;  --ds-lh-caption:       18px;
    --ds-fs-button:        14px;  --ds-lh-button:        20px;

    /* --- Spacing (4px 단위) --- */
    --ds-space-1: 4px;
    --ds-space-2: 8px;
    --ds-space-3: 12px;
    --ds-space-4: 16px;
    --ds-space-5: 20px;
    --ds-space-6: 24px;
    --ds-space-8: 32px;
    --ds-space-10: 40px;
    --ds-space-12: 48px;
    --ds-space-16: 64px;

    /* --- Size --- */
    --ds-header-h:       64px;
    --ds-sidebar-w:      240px;
    --ds-control-h:      44px;   /* Input / Default Button */
    --ds-control-h-sm:   36px;   /* Compact Button */
    --ds-control-h-lg:   48px;   /* Large CTA */

    /* --- Radius --- */
    --ds-radius-control: 8px;    /* Input / Button */
    --ds-radius-card:    10px;   /* Card / Table */
    --ds-radius-dialog:  12px;   /* Dialog / Drawer */
    --ds-radius-pill:    999px;

    /* --- Shadow (가이드 §3: 약한 그림자로 Surface 를 배경에서 띄운다) --- */
    --ds-shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.04);
    --ds-shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08);
    --ds-shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.14);

    /* --- Focus ring --- */
    --ds-focus-ring: 0 0 0 3px rgba(79, 70, 229, 0.24);

    /* --- Content width --- */
    --ds-w-full:     1440px;
    --ds-w-standard: 1440px;   /* 목록·관리 화면은 가용 폭 전체 사용 */
    --ds-w-form:     960px;
    --ds-w-readable: 880px;

    /* -------------------------------------------------------
       기존 템플릿 호환용 alias (base.html / dashboard 등에서 사용)
       ------------------------------------------------------- */
    --bg-body:      var(--ds-page-bg);
    --bg-nav:       var(--ds-surface);
    --bg-card:      var(--ds-surface);
    --text-primary: var(--ds-text-primary);
    --text-muted:   var(--ds-text-secondary);
    --text-nav:     #374151;
    --border:       var(--ds-border);
    --border-strong: var(--ds-border-strong);
    --shadow:       var(--ds-shadow-sm);
    --shadow-md:    var(--ds-shadow-md);
    --shadow-lg:    var(--ds-shadow-lg);
    --accent:       var(--ds-brand-primary);
    --accent-hover: var(--ds-brand-primary-hover);
    --accent-light: var(--ds-brand-primary-subtle);
    --nav-hover:    var(--ds-brand-primary-subtle);
    --dropdown-bg:  var(--ds-surface);
    --input-bg:     var(--ds-surface);
    --table-stripe: var(--ds-surface-subtle);
    --table-hover:  var(--ds-neutral-surface);
    --nav-link-hover-color: var(--ds-brand-primary);
}

/* =============================================================
   2. BASE
   ============================================================= */
*, *::before, *::after { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    min-height: 100%;
    font-family: var(--ds-font-family);
    font-size: var(--ds-fs-body);
    line-height: var(--ds-lh-body);
    background: var(--ds-page-bg);
    color: var(--ds-text-primary);
}

a { color: var(--ds-brand-primary); }
a:hover { color: var(--ds-brand-primary-hover); }

:focus-visible {
    outline: 2px solid transparent;
    box-shadow: var(--ds-focus-ring);
    border-radius: var(--ds-radius-control);
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

/* --- 스크롤바 --- */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--ds-border-strong); border-radius: var(--ds-radius-pill); }

/* =============================================================
   3. BOOTSTRAP 컴포넌트 재정의
   ============================================================= */

/* =============================================================
   3a. AppShell : GlobalHeader + Sidebar + Main
   base.html 구조:
     <header.ds-header>  (fixed, 64px, 전체 폭)
     <aside.ds-sidebar>  (fixed, 240px, Desktop 고정 / <1024px Drawer)
     <div.ds-main> > <div.main-container> > .title-bar + .content-wrapper
   ============================================================= */
:root { --ds-z-header: 1040; --ds-z-sidebar: 1035; --ds-z-backdrop: 1030; }

.ds-skip-link {
    position: fixed; top: 8px; left: 8px; z-index: 2000;
    background: var(--ds-surface); color: var(--ds-brand-primary);
    padding: var(--ds-space-2) var(--ds-space-4); border-radius: var(--ds-radius-control);
    box-shadow: var(--ds-shadow-md); transform: translateY(-150%); transition: transform 0.15s;
}
.ds-skip-link:focus { transform: translateY(0); }

/* ---------- GlobalHeader ---------- */
.ds-header {
    position: fixed; inset: 0 0 auto 0;
    height: var(--ds-header-h); z-index: var(--ds-z-header);
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ds-space-3);
    padding: 0 var(--ds-space-5);
    background: var(--ds-header-bg);
    border-bottom: 1px solid var(--ds-border);
    box-shadow: var(--ds-shadow-sm);
}
.ds-header__left, .ds-header__right { display: flex; align-items: center; gap: var(--ds-space-2); }
.ds-header__menu-toggle {
    display: none;
    width: 40px; height: 40px; align-items: center; justify-content: center;
    border: none; background: transparent; border-radius: var(--ds-radius-control);
    color: var(--ds-brand-primary); font-size: 18px; cursor: pointer;
}
.ds-header__menu-toggle:hover { background: rgba(255, 255, 255, 0.5); }
.ds-brand {
    display: inline-flex; align-items: center; gap: var(--ds-space-2);
    font-weight: 800; font-size: 1.3rem; letter-spacing: -0.3px;
    color: var(--ds-brand-primary); text-decoration: none;
}
.ds-brand:hover { color: var(--ds-brand-primary); opacity: 0.85; }
.ds-header__user {
    display: inline-flex; align-items: center; gap: var(--ds-space-2);
    min-height: 40px; padding: 0 var(--ds-space-3);
    border: none; background: transparent; border-radius: var(--ds-radius-control);
    color: var(--ds-text-primary); font-size: var(--ds-fs-label); font-weight: 600; cursor: pointer;
}
.ds-header__user:hover { background: rgba(255, 255, 255, 0.5); }
.ds-header__user img { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; }

/* ---------- Avatar (이미지 없음/로딩 실패 시 이니셜 fallback) ----------
   가이드 §4·§17-1단계: 깨진 이미지 아이콘 대신 이니셜/기본 아바타 노출 */
.ds-avatar {
    position: relative; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--ds-brand-primary-subtle); color: var(--ds-brand-primary);
    font-weight: 700; font-size: 12px; line-height: 1; overflow: hidden;
    text-transform: uppercase;
}
.ds-avatar > img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover; border-radius: 50%;
}
.ds-avatar--lg { width: 56px; height: 56px; font-size: 20px; }
.ds-header__icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border: none; background: transparent;
    border-radius: var(--ds-radius-control); color: var(--ds-text-secondary); cursor: pointer;
}
.ds-header__icon-btn:hover { background: rgba(255, 255, 255, 0.5); color: var(--ds-text-primary); }

/* ---------- Sidebar ---------- */
.ds-sidebar {
    position: fixed; top: var(--ds-header-h); left: 0; bottom: 0;
    width: var(--ds-sidebar-w); z-index: var(--ds-z-sidebar);
    background: var(--ds-surface);
    border-right: 1px solid var(--ds-border);
    display: flex; flex-direction: column;
    overflow-y: auto; overscroll-behavior: contain;
}
.ds-sidebar__profile {
    padding: var(--ds-space-5) var(--ds-space-5) var(--ds-space-4);
    border-bottom: 1px solid var(--ds-border);
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--ds-space-1);
}
.ds-sidebar__avatar {
    position: relative;
    width: 56px; height: 56px; border-radius: 50%;
    background: var(--ds-brand-primary-subtle); color: var(--ds-brand-primary);
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; font-weight: 700; text-transform: uppercase;
    overflow: hidden; margin-bottom: var(--ds-space-2);
}
.ds-sidebar__avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ds-sidebar__name { font-size: var(--ds-fs-card-title); font-weight: 700; color: var(--ds-text-primary); }
.ds-sidebar__meta { font-size: var(--ds-fs-caption); color: var(--ds-text-secondary); }
.ds-sidebar__nav { padding: var(--ds-space-3) var(--ds-space-3) var(--ds-space-8); flex: 1; }

.ds-nav-group { margin-bottom: var(--ds-space-5); }
.ds-nav-group__title {
    margin: 0 0 var(--ds-space-1);
    padding: 0 var(--ds-space-3);
    font-size: 12px; font-weight: 700; letter-spacing: 0.4px;
    color: var(--ds-text-disabled); text-transform: uppercase;
}
.ds-nav-group ul { list-style: none; margin: 0; padding: 0; }
.ds-nav-link {
    display: flex; align-items: center; gap: var(--ds-space-3);
    padding: var(--ds-space-2) var(--ds-space-3);
    min-height: 40px;
    border-radius: var(--ds-radius-control);
    font-size: var(--ds-fs-label); font-weight: 600;
    color: var(--ds-text-primary); text-decoration: none;
    border-left: 3px solid transparent;
}
.ds-nav-link .ds-nav-link__icon {
    width: 20px; text-align: center; color: var(--ds-text-secondary); flex-shrink: 0;
}
.ds-nav-link:hover { background: var(--ds-surface-subtle); color: var(--ds-text-primary); }
.ds-nav-link.is-active {
    background: var(--ds-brand-primary-subtle);
    color: var(--ds-brand-primary);
    border-left-color: var(--ds-brand-primary);
}
.ds-nav-link.is-active .ds-nav-link__icon { color: var(--ds-brand-primary); }
.ds-nav-sub {
    padding-left: 44px; font-weight: 500; font-size: var(--ds-fs-caption);
    min-height: 34px; color: var(--ds-text-secondary);
}
.ds-nav-sub.is-active { color: var(--ds-brand-primary); font-weight: 600; }

.ds-sidebar-backdrop {
    position: fixed; inset: var(--ds-header-h) 0 0 0; z-index: var(--ds-z-backdrop);
    background: rgba(15, 23, 42, 0.4);
}
.ds-sidebar-backdrop[hidden] { display: none; }

/* ---------- Main ---------- */
.ds-main { padding-top: var(--ds-header-h); margin-left: var(--ds-sidebar-w); min-height: 100vh; }
.ds-main--full { margin-left: 0; }

.dropdown-toggle::after { border-top-color: var(--ds-text-secondary); }

/* 부트스트랩 navbar 잔재가 남은 화면 대비 최소 안전장치 */
.navbar { background: var(--ds-header-bg) !important; }
.nav-link { color: var(--ds-text-primary) !important; }
.nav-link.active { color: var(--ds-brand-primary) !important; font-weight: 700; }

.dropdown-menu {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-md);
    padding: var(--ds-space-1);
    min-width: 180px;
}
.dropdown-item {
    color: var(--ds-text-primary) !important;
    font-size: var(--ds-fs-body);
    padding: var(--ds-space-2) var(--ds-space-3);
    border-radius: 6px;
    transition: background 0.12s;
}
.dropdown-item:hover, .dropdown-item:focus {
    background: var(--ds-brand-primary-subtle) !important;
    color: var(--ds-brand-primary) !important;
}
.dropdown-item.active, .dropdown-item:active {
    background: var(--ds-brand-primary) !important;
    color: #fff !important;
}
.dropdown-divider { border-color: var(--ds-border); }

/* ---------- 레이아웃 컨테이너 ---------- */
.main-container { display: flex; flex-direction: column; min-height: calc(100vh - var(--ds-header-h)); }
.container {
    width: 100%;
    max-width: var(--ds-w-full);
    margin: 0 auto;
    padding-left: var(--ds-space-4);
    padding-right: var(--ds-space-4);
}
@media (min-width: 768px) {
    .container { padding-left: var(--ds-space-6); padding-right: var(--ds-space-6); }
}
@media (min-width: 992px) {
    .container { padding-left: var(--ds-space-8); padding-right: var(--ds-space-8); }
}
.content-wrapper { flex: 1; padding-bottom: var(--ds-space-12); }

/* 폭 변형 : 템플릿 최상단 래퍼에 클래스로 지정 */
.ds-w-full     .container,
.container.ds-w-full     { max-width: var(--ds-w-full); }
.ds-w-standard .container,
.container.ds-w-standard { max-width: var(--ds-w-standard); }
.ds-w-form     .container,
.container.ds-w-form     { max-width: var(--ds-w-form); }
.ds-w-readable .container,
.container.ds-w-readable { max-width: var(--ds-w-readable); }

/* -------------------------------------------------------------------
   조회·목록·관리 화면은 화면 사이즈에 맞춰 가용 폭 전체 사용.
   템플릿은 {% block content %} 안에서 래퍼 div 에 .ds-w-standard /
   .ds-w-full 을, 대량 테이블은 .ds-fill 을 붙인다. base.html 의
   .title-bar > .container 와 .content-wrapper > .container 두 곳 모두
   1440px 캡을 풀어 폭을 맞춘다. (폼/상세: .ds-w-form·.ds-w-readable 은 유지)
   ------------------------------------------------------------------- */
.main-container:has(.content-wrapper .ds-w-standard) .container,
.main-container:has(.content-wrapper .ds-w-full) .container,
.main-container:has(.content-wrapper .ds-fill) .container {
    max-width: none;
}

/* ---------- Typography helpers ---------- */
.ds-display       { font-size: var(--ds-fs-display); line-height: var(--ds-lh-display); font-weight: 700; }
.ds-page-title    { font-size: var(--ds-fs-page-title); line-height: var(--ds-lh-page-title); font-weight: 700; }
.ds-section-title { font-size: var(--ds-fs-section-title); line-height: var(--ds-lh-section-title); font-weight: 700; margin: 0; }
.ds-card-title    { font-size: var(--ds-fs-card-title); line-height: var(--ds-lh-card-title); font-weight: 700; margin: 0; }
.ds-caption       { font-size: var(--ds-fs-caption); line-height: var(--ds-lh-caption); color: var(--ds-text-secondary); }
.text-muted       { color: var(--ds-text-secondary) !important; }

h1, .h1 { font-size: var(--ds-fs-page-title); line-height: var(--ds-lh-page-title); font-weight: 700; }
h2, .h2 { font-size: var(--ds-fs-section-title); line-height: var(--ds-lh-section-title); font-weight: 700; }
h3, .h3 { font-size: var(--ds-fs-section-title); line-height: var(--ds-lh-section-title); font-weight: 700; }
h4, .h4, h5, .h5 { font-size: var(--ds-fs-card-title); line-height: var(--ds-lh-card-title); font-weight: 700; }
h6, .h6 { font-size: var(--ds-fs-label); line-height: var(--ds-lh-label); font-weight: 600; }

/* ---------- Button ----------
   가이드 §2: 일반 버튼 40~44px, 주요 CTA(primary/danger/success/lg) 44~50px.
   모바일에서는 접근성(터치 44px)을 위해 모든 버튼을 44px로. */
.btn {
    --bs-btn-focus-box-shadow: var(--ds-focus-ring);
    display: inline-flex; align-items: center; justify-content: center;
    gap: var(--ds-space-2);
    min-height: 40px;
    padding: 0 var(--ds-space-4);
    border-radius: var(--ds-radius-control);
    font-size: var(--ds-fs-button);
    line-height: var(--ds-lh-button);
    font-weight: 600;
    border: 1px solid transparent;
    transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.btn-primary, .btn-danger, .btn-success, .btn-lg { min-height: var(--ds-control-h); }
@media (max-width: 767.98px) { .btn { min-height: var(--ds-control-h); } }
.btn:focus-visible { box-shadow: var(--ds-focus-ring); }
.btn-sm { min-height: var(--ds-control-h-sm); padding: 0 var(--ds-space-3); font-size: var(--ds-fs-caption); }
.btn-lg { min-height: var(--ds-control-h-lg); padding: 0 var(--ds-space-5); font-size: var(--ds-fs-body); }

/* Primary : 현재 화면 핵심 실행 */
.btn-primary {
    background: var(--ds-brand-primary); border-color: var(--ds-brand-primary);
    color: #fff !important;
}
.btn-primary:hover, .btn-primary:focus {
    background: var(--ds-brand-primary-hover); border-color: var(--ds-brand-primary-hover);
    color: #fff !important;
}
/* Secondary : 보조 실행·이동 */
.btn-secondary,
.btn-outline-secondary {
    background: var(--ds-surface); border-color: var(--ds-border-strong);
    color: var(--ds-text-primary) !important;
}
.btn-secondary:hover, .btn-secondary:focus,
.btn-outline-secondary:hover, .btn-outline-secondary:focus {
    background: var(--ds-surface-subtle); border-color: var(--ds-border-strong);
    color: var(--ds-text-primary) !important;
}
/* Tertiary : 낮은 강도 (초기화/닫기/취소) -> btn-light / btn-link */
.btn-light, .btn-tertiary {
    background: transparent; border-color: transparent;
    color: var(--ds-text-secondary) !important;
}
.btn-light:hover, .btn-tertiary:hover {
    background: var(--ds-neutral-surface); color: var(--ds-text-primary) !important;
}
.btn-link {
    color: var(--ds-brand-primary) !important; text-decoration: none;
    border: none; min-height: auto; padding: 0 var(--ds-space-1);
}
.btn-link:hover { color: var(--ds-brand-primary-hover) !important; text-decoration: underline; }
/* Danger : 파괴적 행동 */
.btn-danger {
    background: var(--ds-danger); border-color: var(--ds-danger);
    color: #fff !important;
}
.btn-danger:hover, .btn-danger:focus { background: #b91c1c; border-color: #b91c1c; color: #fff !important; }
.btn-outline-danger {
    background: transparent; border-color: var(--ds-danger);
    color: var(--ds-danger) !important;
}
.btn-outline-danger:hover, .btn-outline-danger:focus { background: var(--ds-danger); color: #fff !important; }
/* Outline primary */
.btn-outline-primary {
    background: transparent; border-color: var(--ds-brand-primary);
    color: var(--ds-brand-primary) !important;
}
.btn-outline-primary:hover, .btn-outline-primary:focus { background: var(--ds-brand-primary); color: #fff !important; }

/* success / warning / info / danger 는 "상태를 알리는 액션"에만 제한적으로 사용.
   기능별 색버튼 남용 방지를 위해 톤을 절제한다. */
.btn-success {
    background: var(--ds-success); border-color: var(--ds-success); color: #fff !important;
}
.btn-success:hover, .btn-success:focus { background: #166534; border-color: #166534; color: #fff !important; }
.btn-warning {
    background: var(--ds-warning); border-color: var(--ds-warning); color: #fff !important;
}
.btn-warning:hover, .btn-warning:focus { background: #92400e; border-color: #92400e; color: #fff !important; }
.btn-info {
    background: var(--ds-info); border-color: var(--ds-info); color: #fff !important;
}
.btn-info:hover, .btn-info:focus { background: #0369a1; border-color: #0369a1; color: #fff !important; }
.btn-outline-warning {
    background: transparent; border-color: var(--ds-warning); color: var(--ds-warning) !important;
}
.btn-outline-warning:hover { background: var(--ds-warning); color: #fff !important; }

.btn:disabled, .btn.disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }

/* Icon Button : 44x44 터치 타깃 */
.ds-icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--ds-control-h); height: var(--ds-control-h);
    min-height: var(--ds-control-h);
    padding: 0;
    border-radius: var(--ds-radius-control);
    border: 1px solid var(--ds-border);
    background: var(--ds-surface);
    color: var(--ds-text-secondary);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.ds-icon-btn:hover { background: var(--ds-surface-subtle); color: var(--ds-text-primary); }

/* ---------- Card ---------- */
.card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-sm);
    color: var(--ds-text-primary);
}
.card + .card { margin-top: var(--ds-space-6); }
.card-header {
    background: var(--ds-surface);
    border-bottom: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card) var(--ds-radius-card) 0 0 !important;
    padding: var(--ds-space-4) var(--ds-space-6);
    font-size: var(--ds-fs-card-title);
    font-weight: 700;
    color: var(--ds-text-primary);
}
.card-body { padding: var(--ds-space-6); color: var(--ds-text-primary); }
.card-footer {
    background: var(--ds-surface-subtle);
    border-top: 1px solid var(--ds-border);
    padding: var(--ds-space-4) var(--ds-space-6);
}
.card-title { font-size: var(--ds-fs-card-title); font-weight: 700; }
.card-text { color: var(--ds-text-secondary); }

/* ---------- Form ---------- */
.form-label {
    display: block;
    font-size: var(--ds-fs-label);
    line-height: var(--ds-lh-label);
    font-weight: 600;
    color: var(--ds-text-primary);
    margin-bottom: var(--ds-space-2);
}
.form-label .ds-req { color: var(--ds-danger); margin-left: 2px; }
.form-label .ds-opt { color: var(--ds-text-secondary); font-weight: 400; margin-left: var(--ds-space-1); }

.form-control, .form-select {
    width: 100%;
    min-height: var(--ds-control-h);
    padding: var(--ds-space-2) var(--ds-space-3);
    background: var(--ds-surface) !important;
    border: 1px solid var(--ds-border-strong);
    color: var(--ds-text-primary) !important;
    border-radius: var(--ds-radius-control);
    font-size: var(--ds-fs-body);
    line-height: var(--ds-lh-body);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.form-control:hover, .form-select:hover { border-color: var(--ds-border-strong); box-shadow: var(--ds-shadow-sm); }
.form-control:focus, .form-select:focus {
    border-color: var(--ds-brand-primary);
    box-shadow: var(--ds-focus-ring);
    background: var(--ds-surface) !important;
    color: var(--ds-text-primary) !important;
    outline: none;
}
.form-control::placeholder { color: var(--ds-text-disabled); }
.form-control:disabled, .form-select:disabled,
.form-control[readonly] {
    background: var(--ds-surface-subtle) !important;
    color: var(--ds-text-secondary) !important;
    cursor: not-allowed;
}
.form-control[readonly] { cursor: default; }
textarea.form-control { min-height: 120px; resize: vertical; }

.form-text, .form-hint {
    display: block;
    margin-top: var(--ds-space-1);
    font-size: var(--ds-fs-caption);
    line-height: var(--ds-lh-caption);
    color: var(--ds-text-secondary);
}
.invalid-feedback, .text-danger.field-error, .ds-error-text {
    display: block;
    margin-top: var(--ds-space-1);
    font-size: var(--ds-fs-caption);
    line-height: var(--ds-lh-caption);
    color: var(--ds-danger);
    text-align: left;
}
.form-control.is-invalid, .form-select.is-invalid { border-color: var(--ds-danger); }
.form-control.is-invalid:focus { box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.20); }

.form-control-plaintext {
    min-height: var(--ds-control-h);
    padding: var(--ds-space-2) 0;
    color: var(--ds-text-primary);
}

/* 체크박스 / 라디오 터치타깃 */
.form-check-input { width: 18px; height: 18px; margin-top: 3px; }
.form-check-input:checked { background-color: var(--ds-brand-primary); border-color: var(--ds-brand-primary); }
.form-check-input:focus { box-shadow: var(--ds-focus-ring); border-color: var(--ds-brand-primary); }
.form-check-label { font-size: var(--ds-fs-body); }

/* ---------- Table ---------- */
.table {
    width: 100%;
    color: var(--ds-text-primary);
    border-collapse: separate;
    border-spacing: 0;
    margin-bottom: 0;
}
/* 가이드 §9: Header 48~52px, Row 52~56px, Header 14/600 · Cell 14/400 */
.table > thead th, .table th {
    background: var(--ds-surface-subtle);
    color: var(--ds-text-secondary);
    font-size: var(--ds-fs-table);
    font-weight: 600;
    line-height: var(--ds-lh-table);
    text-transform: none;
    letter-spacing: 0;
    border-bottom: 1px solid var(--ds-border);
    padding: var(--ds-space-4);
    white-space: nowrap;
    vertical-align: middle;
}
.table > tbody td, .table td {
    padding: var(--ds-space-3) var(--ds-space-4);
    border-bottom: 1px solid var(--ds-border);
    vertical-align: middle;
    font-size: var(--ds-fs-table);
    line-height: var(--ds-lh-table);
    color: var(--ds-text-primary);
    height: 54px;
}
.table > tbody tr:hover { background: var(--ds-neutral-surface); }
.table td.ds-num, .table th.ds-num { text-align: right; font-variant-numeric: tabular-nums; }
.table td.ds-actions, .table th.ds-actions { text-align: right; white-space: nowrap; }
.table-striped > tbody > tr:nth-of-type(odd) > * { background: var(--ds-surface-subtle); }
.table-responsive {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-sm);
    overflow-x: auto;
}
.table-responsive > .table { border: 0; }

/* ---------- Badge / StatusBadge ---------- */
.badge {
    display: inline-flex; align-items: center; gap: var(--ds-space-1);
    border-radius: var(--ds-radius-pill);
    padding: 3px var(--ds-space-2);
    font-size: var(--ds-fs-caption);
    line-height: var(--ds-lh-caption);
    font-weight: 600;
    letter-spacing: 0;
}
/* 부트스트랩 색상 유틸을 시맨틱 토큰으로 매핑 (color-only 금지: 항상 텍스트 라벨과 함께 사용) */
.badge.bg-primary,   .badge.text-bg-primary   { background: var(--ds-brand-primary-subtle) !important; color: var(--ds-brand-primary) !important; }
.badge.bg-success,   .badge.text-bg-success   { background: var(--ds-success-surface) !important; color: var(--ds-success) !important; }
.badge.bg-warning,   .badge.text-bg-warning   { background: var(--ds-warning-surface) !important; color: var(--ds-warning) !important; }
.badge.bg-danger,    .badge.text-bg-danger    { background: var(--ds-danger-surface) !important; color: var(--ds-danger) !important; }
.badge.bg-info,      .badge.text-bg-info      { background: var(--ds-info-surface) !important; color: var(--ds-info) !important; }
.badge.bg-secondary, .badge.text-bg-secondary { background: var(--ds-neutral-surface) !important; color: var(--ds-neutral) !important; }
.badge.bg-light,     .badge.text-bg-light     { background: var(--ds-neutral-surface) !important; color: var(--ds-text-secondary) !important; }
.badge.bg-dark { background: var(--ds-text-primary) !important; color: #fff !important; }
.badge.bg-warning.text-dark, .badge.bg-light.text-dark, .badge.bg-info.text-dark { color: var(--ds-warning); }

/* 시맨틱 StatusBadge (권장 클래스) */
.ds-status {
    display: inline-flex; align-items: center; gap: var(--ds-space-1);
    border-radius: var(--ds-radius-pill);
    padding: 3px var(--ds-space-2);
    font-size: var(--ds-fs-caption);
    line-height: var(--ds-lh-caption);
    font-weight: 600;
}
.ds-status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.ds-status--success { background: var(--ds-success-surface); color: var(--ds-success); }
.ds-status--warning { background: var(--ds-warning-surface); color: var(--ds-warning); }
.ds-status--danger  { background: var(--ds-danger-surface);  color: var(--ds-danger); }
.ds-status--info    { background: var(--ds-info-surface);    color: var(--ds-info); }
.ds-status--neutral { background: var(--ds-neutral-surface); color: var(--ds-neutral); }

/* ---------- Alert ---------- */
.alert {
    border: 1px solid transparent;
    border-radius: var(--ds-radius-control);
    font-size: var(--ds-fs-body);
    padding: var(--ds-space-3) var(--ds-space-4);
}
.alert-success { background: var(--ds-success-surface); border-color: #bbf7d0; color: var(--ds-success); }
.alert-info    { background: var(--ds-info-surface);    border-color: #bae6fd; color: var(--ds-info); }
.alert-warning { background: var(--ds-warning-surface); border-color: #fde68a; color: var(--ds-warning); }
.alert-danger, .alert-error { background: var(--ds-danger-surface); border-color: #fecaca; color: var(--ds-danger); }

.messages-container { display: flex; flex-direction: column; align-items: center; gap: var(--ds-space-2); margin: var(--ds-space-4) 0; }
.messages-container .alert { max-width: 640px; width: 100%; text-align: center; }

/* ---------- List group ---------- */
.list-group { border-radius: var(--ds-radius-card); }
.list-group-item {
    background: var(--ds-surface);
    border-color: var(--ds-border);
    color: var(--ds-text-primary);
    padding: var(--ds-space-4);
    transition: background 0.12s;
}
.list-group-item-action:hover, .list-group-item-action:focus { background: var(--ds-brand-primary-subtle); }
.list-group-item h5, .list-group-item .list-title {
    font-size: var(--ds-fs-card-title); line-height: var(--ds-lh-card-title); font-weight: 700;
    color: var(--ds-text-primary); margin-bottom: var(--ds-space-1);
}
.list-group-item p { color: var(--ds-text-secondary); font-size: var(--ds-fs-body); margin-bottom: var(--ds-space-1); }
.list-group-item small { color: var(--ds-text-secondary); font-size: var(--ds-fs-caption); }

/* ---------- Pagination ---------- */
.pagination { gap: var(--ds-space-1); }
.page-link {
    min-width: var(--ds-control-h-sm); min-height: var(--ds-control-h-sm);
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--ds-text-secondary);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-control) !important;
    margin: 0;
    font-size: var(--ds-fs-label);
}
.page-link:hover { background: var(--ds-surface-subtle); color: var(--ds-text-primary); }
.page-link:focus { box-shadow: var(--ds-focus-ring); z-index: 2; }
.page-item.active .page-link { background: var(--ds-brand-primary); border-color: var(--ds-brand-primary); color: #fff; }
.page-item.disabled .page-link { color: var(--ds-text-disabled); background: var(--ds-surface); }

/* ---------- Tabs / Segmented ---------- */
.nav-tabs { border-bottom: 1px solid var(--ds-border); gap: var(--ds-space-1); }
.nav-tabs .nav-link {
    border: none; border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--ds-text-secondary) !important;
    font-weight: 600;
    padding: var(--ds-space-3) var(--ds-space-4) !important;
}
.nav-tabs .nav-link:hover { background: transparent !important; color: var(--ds-text-primary) !important; border-bottom-color: var(--ds-border-strong); }
.nav-tabs .nav-link.active {
    color: var(--ds-brand-primary) !important;
    background: transparent !important;
    border-bottom-color: var(--ds-brand-primary);
}
.ds-segmented {
    display: inline-flex;
    padding: var(--ds-space-1);
    background: var(--ds-surface-subtle);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-control);
    gap: 2px;
}
.ds-segmented > button, .ds-segmented > a {
    border: none; background: transparent;
    padding: var(--ds-space-2) var(--ds-space-4);
    border-radius: 6px;
    font-size: var(--ds-fs-label); font-weight: 600;
    color: var(--ds-text-secondary); text-decoration: none;
    min-height: var(--ds-control-h-sm);
}
.ds-segmented > .active, .ds-segmented > [aria-selected="true"] {
    background: var(--ds-surface);
    color: var(--ds-brand-primary);
    box-shadow: var(--ds-shadow-sm);
}

/* ---------- Modal ---------- */
.modal-content { border: none; border-radius: var(--ds-radius-dialog); box-shadow: var(--ds-shadow-lg); }
.modal-header { border-bottom: 1px solid var(--ds-border); padding: var(--ds-space-5) var(--ds-space-6); }
.modal-title { font-size: var(--ds-fs-section-title); font-weight: 700; }
.modal-body { padding: var(--ds-space-6); }
.modal-footer { border-top: 1px solid var(--ds-border); padding: var(--ds-space-4) var(--ds-space-6); gap: var(--ds-space-2); }

/* =============================================================
   4. 공통 컴포넌트
   ============================================================= */

/* ---------- PageHeader ---------- */
.ds-page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ds-space-4);
    flex-wrap: wrap;
    padding: var(--ds-space-6) 0 var(--ds-space-5);
}
.ds-page-header__titles { min-width: 0; }
.ds-page-header__title {
    font-size: var(--ds-fs-page-title);
    line-height: var(--ds-lh-page-title);
    font-weight: 700;
    color: var(--ds-text-primary);
    margin: 0;
}
.ds-page-header__desc {
    margin: var(--ds-space-2) 0 0;
    font-size: var(--ds-fs-body);
    color: var(--ds-text-secondary);
}
.ds-page-header__actions { display: flex; align-items: center; gap: var(--ds-space-2); flex-wrap: wrap; }
.ds-breadcrumb {
    display: flex; flex-wrap: wrap; gap: var(--ds-space-2);
    font-size: var(--ds-fs-caption);
    color: var(--ds-text-secondary);
    margin-bottom: var(--ds-space-2);
    list-style: none; padding: 0;
}
.ds-breadcrumb a { color: var(--ds-text-secondary); text-decoration: none; }
.ds-breadcrumb a:hover { color: var(--ds-brand-primary); }
.ds-breadcrumb li + li::before { content: "/"; margin-right: var(--ds-space-2); color: var(--ds-border-strong); }

/* base.html 의 .title-bar (PageHeader 컨테이너)
   가이드 §3·§5·§17-1단계: PageHeader 는 배경색 없이 투명하게 유지하고,
   Page Background 위에 여백으로만 구분한다. (흰색 바 제거) */
.title-bar {
    background: transparent;
    border-bottom: none;
    padding: var(--ds-space-6) 0 0;
}
.title-bar .ds-page-header { padding: 0 0 var(--ds-space-5); }
.title-bar h1, .title-bar h2, .title-bar .ds-page-header__title {
    font-size: var(--ds-fs-page-title);
    line-height: var(--ds-lh-page-title);
    font-weight: 700;
    color: var(--ds-text-primary);
    margin: 0;
}

/* ---------- SearchPanel ----------
   가이드 §6: 모든 검색 영역은 Card 형으로 통일 — 흰색 배경, Border, Radius, 약한 그림자.
   조건이 적어도 Card 구조는 유지하되 높이를 축소한다(.ds-search-toolbar). */
.ds-search-panel {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-sm);
    padding: var(--ds-space-5) var(--ds-space-6);
    margin-bottom: var(--ds-space-6);
}
.ds-search-panel__title {
    font-size: var(--ds-fs-section-title);
    line-height: var(--ds-lh-section-title);
    font-weight: 700; margin: 0 0 var(--ds-space-4);
}
/* 검색 조건 1~2개: 높이를 축소한 컴팩트 Card */
.ds-search-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--ds-space-3);
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-sm);
    padding: var(--ds-space-4) var(--ds-space-5);
    margin-bottom: var(--ds-space-5);
}
.ds-search-toolbar .ds-search-panel__field { flex: 1 1 260px; }
.ds-search-panel__row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--ds-space-4);
}
.ds-search-panel__field { display: flex; flex-direction: column; gap: var(--ds-space-2); flex: 1 1 200px; min-width: 0; }
.ds-search-panel__actions { display: flex; gap: var(--ds-space-2); margin-left: auto; }

/* 모바일: 검색 조건 간격을 최소화해 데이터 영역을 넓게 확보한다 */
@media (max-width: 767.98px) {
    .ds-search-panel { padding: var(--ds-space-4); margin-bottom: var(--ds-space-4); }
    .ds-search-panel__title { margin-bottom: var(--ds-space-3); }

    .ds-search-panel__row { flex-direction: column; align-items: stretch; gap: var(--ds-space-2); }
    .ds-search-panel__field { gap: var(--ds-space-1); }
    /* 인라인 flex:0 0 <px> 가 세로 축에서 큰 빈칸을 만드는 것을 방지 */
    .ds-search-panel__row > .ds-search-panel__field { flex: 0 0 auto !important; }
    .ds-search-panel__actions { margin-left: 0; margin-top: var(--ds-space-1); gap: var(--ds-space-2); }
    .ds-search-panel__actions .btn { flex: 1; }

    /* 1~2개 조건용 컴팩트 Card: 조건은 한 줄, 버튼은 그 아래 한 줄에 나란히 */
    .ds-search-toolbar { flex-flow: row wrap; align-items: stretch; gap: var(--ds-space-2); padding: var(--ds-space-4); margin-bottom: var(--ds-space-4); }
    .ds-search-toolbar .ds-search-panel__field { flex: 1 1 100%; gap: var(--ds-space-1); }
    .ds-search-toolbar > .btn, .ds-search-toolbar > a.btn { flex: 1 1 0; width: auto; }

    /* 대량 Table 화면의 카드형 검색 폼 (attendance_list 등) */
    .search-card .card-body { padding: var(--ds-space-4); }
}

/* ---------- Disclosure (접이식 보조 패널) ---------- */
.ds-disclosure {
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    background: var(--ds-surface);
    padding: 0 var(--ds-space-5);
}
.ds-disclosure > summary {
    cursor: pointer; list-style: none;
    padding: var(--ds-space-4) 0;
    font-size: var(--ds-fs-label); font-weight: 600; color: var(--ds-text-primary);
    display: flex; align-items: center; gap: var(--ds-space-2);
}
.ds-disclosure > summary::-webkit-details-marker { display: none; }
.ds-disclosure > summary::before {
    content: "\f105"; font-family: "Font Awesome 5 Free"; font-weight: 900;
    color: var(--ds-text-secondary); transition: transform 0.15s;
}
.ds-disclosure[open] > summary::before { transform: rotate(90deg); }
.ds-disclosure[open] > summary { border-bottom: 1px solid var(--ds-border); }
.ds-disclosure > *:not(summary) { padding-bottom: var(--ds-space-5); }

/* ---------- ResultSummary / FilterChip ---------- */
.ds-result-summary {
    display: flex; align-items: center; gap: var(--ds-space-3);
    flex-wrap: wrap;
    margin-bottom: var(--ds-space-4);
    font-size: var(--ds-fs-label);
    color: var(--ds-text-secondary);
}
.ds-result-summary strong { color: var(--ds-text-primary); font-weight: 700; }
.ds-filter-chip {
    display: inline-flex; align-items: center; gap: var(--ds-space-1);
    padding: var(--ds-space-1) var(--ds-space-2);
    background: var(--ds-brand-primary-subtle);
    color: var(--ds-brand-primary);
    border-radius: 6px;
    font-size: var(--ds-fs-caption);
    font-weight: 600;
}
.ds-filter-chip button {
    border: none; background: none; color: inherit; cursor: pointer;
    padding: 0; line-height: 1; font-size: var(--ds-fs-body);
}

/* ---------- ActionBar ---------- */
.ds-action-bar {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ds-space-3);
    flex-wrap: wrap;
    margin-top: var(--ds-space-8);
    padding-top: var(--ds-space-5);
    border-top: 1px solid var(--ds-border);
}
.ds-action-bar__left { display: flex; gap: var(--ds-space-2); }
.ds-action-bar__right { display: flex; gap: var(--ds-space-2); margin-left: auto; }
.ds-action-bar--sticky {
    position: sticky; bottom: 0;
    background: var(--ds-surface);
    box-shadow: var(--ds-shadow-md);
    padding: var(--ds-space-4);
    margin-left: calc(-1 * var(--ds-space-4));
    margin-right: calc(-1 * var(--ds-space-4));
    border-radius: 0;
}
@media (max-width: 767.98px) {
    .ds-action-bar { flex-direction: column-reverse; align-items: stretch; }
    .ds-action-bar__left, .ds-action-bar__right { margin-left: 0; }
    .ds-action-bar__right { flex-direction: column-reverse; }
    .ds-action-bar .btn { width: 100%; }
}

/* ---------- FormSection ---------- */
.ds-form-section { margin-bottom: var(--ds-space-8); }
.ds-form-section__title {
    font-size: var(--ds-fs-section-title);
    line-height: var(--ds-lh-section-title);
    font-weight: 700;
    color: var(--ds-text-primary);
    margin: 0 0 var(--ds-space-2);
}
.ds-form-section__desc {
    margin: 0 0 var(--ds-space-4);
    font-size: var(--ds-fs-caption);
    color: var(--ds-text-secondary);
}
.ds-field { margin-bottom: var(--ds-space-6); }
.ds-field:last-child { margin-bottom: 0; }
.ds-form-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--ds-space-6); }
@media (max-width: 767.98px) { .ds-form-grid-2 { grid-template-columns: 1fr; } }

.ds-form-error-summary {
    background: var(--ds-danger-surface);
    border: 1px solid #fecaca;
    color: var(--ds-danger);
    border-radius: var(--ds-radius-control);
    padding: var(--ds-space-3) var(--ds-space-4);
    margin-bottom: var(--ds-space-6);
    font-size: var(--ds-fs-label);
}

/* ---------- MetaGrid (Detail 메타정보) ---------- */
.ds-meta-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--ds-space-4) var(--ds-space-6);
    padding: var(--ds-space-5) 0;
}
.ds-meta-grid__item { display: flex; flex-direction: column; gap: var(--ds-space-1); }
.ds-meta-grid__label { font-size: var(--ds-fs-caption); color: var(--ds-text-secondary); font-weight: 600; }
.ds-meta-grid__value { font-size: var(--ds-fs-body); color: var(--ds-text-primary); }

/* ---------- ContentList ----------
   가이드 §7·§8: 콘텐츠 탐색형 목록. 흰색 Card 하나로 감싸고 얇은 Divider 로 구분.
   행 높이를 줄여 더 많은 항목을 노출한다. */
.ds-content-list {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-sm);
    overflow: hidden;
}
.ds-content-list__item {
    display: block;
    padding: var(--ds-space-3) var(--ds-space-4);
    border-bottom: 1px solid var(--ds-border);
    border-left: 3px solid transparent;
    text-decoration: none;
    color: inherit;
    transition: background 0.12s, border-color 0.12s;
}
.ds-content-list__item:last-child { border-bottom: none; }
.ds-content-list__item:hover { background: var(--ds-brand-primary-subtle); color: inherit; }
/* 중요 공지: 노란 배경 대신 좌측 강조선 (가이드 §8) */
.ds-content-list__item--important { border-left-color: var(--ds-warning); }
.ds-content-list__title {
    font-size: var(--ds-fs-card-title);
    line-height: var(--ds-lh-card-title);
    font-weight: 700;
    color: var(--ds-text-primary);
    display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
}
.ds-content-list__summary {
    margin: var(--ds-space-1) 0 0;
    font-size: var(--ds-fs-body);
    color: var(--ds-text-secondary);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ds-content-list__meta {
    margin-top: var(--ds-space-2);
    font-size: var(--ds-fs-caption);
    color: var(--ds-text-secondary);
    display: flex; flex-wrap: wrap; gap: var(--ds-space-3); align-items: center;
}

/* ---------- EmptyState ----------
   가이드 §12·§14: 빈 상태는 흰색 Surface 안에 아이콘 · 설명 · 다음 행동을 함께 표시 */
.ds-empty {
    text-align: center;
    padding: var(--ds-space-16) var(--ds-space-4);
    color: var(--ds-text-secondary);
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    box-shadow: var(--ds-shadow-sm);
}
/* Card/Table 내부에서 쓰일 때는 중복 테두리 제거 */
.card .ds-empty, .table-responsive .ds-empty, .ds-content-list .ds-empty,
.data-card .ds-empty {
    border: none; box-shadow: none; background: transparent;
}
.ds-empty__icon { font-size: 32px; color: var(--ds-border-strong); margin-bottom: var(--ds-space-4); }
.ds-empty__title { font-size: var(--ds-fs-card-title); font-weight: 700; color: var(--ds-text-primary); margin: 0 0 var(--ds-space-2); }
.ds-empty__desc { font-size: var(--ds-fs-body); margin: 0 0 var(--ds-space-5); }

/* ---------- Skeleton (Loading) ---------- */
.ds-skeleton {
    background: linear-gradient(90deg, var(--ds-neutral-surface) 25%, #eceef1 37%, var(--ds-neutral-surface) 63%);
    background-size: 400% 100%;
    animation: ds-skeleton 1.4s ease infinite;
    border-radius: 6px;
}
@keyframes ds-skeleton { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ---------- Upload ---------- */
.ds-upload {
    border: 1px dashed var(--ds-border-strong);
    border-radius: var(--ds-radius-card);
    padding: var(--ds-space-6);
    text-align: center;
    background: var(--ds-surface-subtle);
}
.ds-upload__hint { font-size: var(--ds-fs-caption); color: var(--ds-text-secondary); margin-top: var(--ds-space-2); }
.ds-upload-item {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ds-space-3);
    padding: var(--ds-space-3) var(--ds-space-4);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-control);
    margin-top: var(--ds-space-2);
    background: var(--ds-surface);
}
.ds-upload-item__meta { font-size: var(--ds-fs-caption); color: var(--ds-text-secondary); }

/* =============================================================
   5. TinyMCE
   ============================================================= */
.tox-tinymce {
    border: 1px solid var(--ds-border-strong) !important;
    border-radius: var(--ds-radius-control) !important;
}
.tox .tox-edit-area__iframe { background: var(--ds-surface) !important; }

/* 본문 콘텐츠 안의 표 (TinyMCE 산출물) */
.ds-rich-content table, .card-body .content table {
    border-collapse: collapse; width: 100%; margin: var(--ds-space-4) 0;
    font-size: var(--ds-fs-body);
}
.ds-rich-content th, .ds-rich-content td {
    border: 1px solid var(--ds-border); padding: var(--ds-space-2) var(--ds-space-3);
}
.ds-rich-content th { background: var(--ds-surface-subtle); font-weight: 700; }

/* =============================================================
   5b. 전체 높이 고정 레이아웃 (대량 데이터 Table 화면)
   템플릿에서 <div class="page-layout ds-fill"> 로 감싸고
   내부에 .data-card > .card-body.p-0 > .scroll-wrap > table 구조를 둔다.
   ============================================================= */
.ds-fill { display: flex; flex-direction: column; gap: var(--ds-space-3); }
.ds-fill .search-card { flex-shrink: 0; }
.ds-fill .data-card { display: flex; flex-direction: column; margin-bottom: 0; }
.ds-fill .data-card > .card-header { flex-shrink: 0; }
.ds-fill .scroll-wrap { overflow: auto; }
.ds-fill .data-card > .card-body { min-height: 0; }
.ds-fill table thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--ds-surface-subtle);
    border-bottom: 1px solid var(--ds-border);
}

@media (min-width: 992px) {
    .ds-main:has(.ds-fill) { min-height: 0; }
    .main-container:has(.ds-fill) {
        overflow: hidden !important;
        height: calc(100vh - var(--ds-header-h));
        min-height: 0;
    }
    .main-container:has(.ds-fill) > .title-bar { flex-shrink: 0; }
    .main-container:has(.ds-fill) .content-wrapper {
        flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column;
        padding-bottom: 0;
    }
    .main-container:has(.ds-fill) .content-wrapper > .container {
        flex: 1; overflow: hidden; display: flex; flex-direction: column;
        padding-top: var(--ds-space-4); padding-bottom: 0;
    }
    .ds-fill { flex: 1; overflow: hidden; }
    .ds-fill .data-card { flex: 1; min-height: 0; overflow: hidden; }
    .ds-fill .data-card > .card-body { flex: 1; overflow: hidden; display: flex; flex-direction: column; }
    .ds-fill .scroll-wrap { flex: 1; min-height: 0; }
}
@media (max-width: 991.98px) {
    .main-container:has(.ds-fill) { overflow-x: auto !important; }
    .ds-fill { display: block; padding: var(--ds-space-4) 0; }
    .ds-fill .search-card { margin-bottom: var(--ds-space-3); }
    .ds-fill .scroll-wrap { overflow: visible !important; }
}

/* JS 로 그리는 Table 안의 주말 행 표시(색상만 의존 금지 — 요일 텍스트도 함께 강조) */
.ds-fill td.ds-weekend, .table td.ds-weekend { color: var(--ds-danger); font-weight: 600; }
.ds-fill tr.ds-weekend-row > td, .table tr.ds-weekend-row > td { background: var(--ds-danger-surface); }

/* =============================================================
   5c. Calendar (일정관리)
   ============================================================= */
.ds-cal-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ds-space-3); flex-wrap: wrap;
    margin-bottom: var(--ds-space-4);
}
.ds-cal-toolbar__nav { display: flex; align-items: center; gap: var(--ds-space-2); }
.ds-cal-toolbar__title { font-size: var(--ds-fs-section-title); font-weight: 700; }

.ds-calendar {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-card);
    overflow: hidden;
}
.ds-calendar .calendar-weekdays {
    display: grid; grid-template-columns: repeat(7, 1fr);
    background: var(--ds-surface-subtle);
    border-bottom: 1px solid var(--ds-border);
    font-weight: 700; font-size: var(--ds-fs-caption);
}
.ds-calendar .weekday-header { text-align: center; padding: var(--ds-space-3) 0; color: var(--ds-text-secondary); }
.ds-calendar .weekday-header.sunday { color: var(--ds-danger); }
.ds-calendar .weekday-header.saturday { color: var(--ds-info); }

.ds-calendar .calendar-week { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--ds-border); }
.ds-calendar .calendar-week:last-child { border-bottom: none; }
.ds-calendar .calendar-day {
    min-height: 120px; border-right: 1px solid var(--ds-border);
    padding: var(--ds-space-2); background: var(--ds-surface); overflow: hidden; position: relative;
}
.ds-calendar .calendar-day:last-child { border-right: none; }
.ds-calendar .calendar-day:hover { background: var(--ds-surface-subtle); }
.ds-calendar .calendar-day.other-month { background: var(--ds-surface-subtle); color: var(--ds-text-disabled); }
.ds-calendar .calendar-day.today { background: var(--ds-brand-primary-subtle); box-shadow: inset 0 0 0 2px var(--ds-brand-primary); }
.ds-calendar .day-number {
    display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center;
    border-radius: 50%; font-size: var(--ds-fs-caption); font-weight: 600; color: var(--ds-text-secondary);
}
.ds-calendar .calendar-day.today .day-number { background: var(--ds-brand-primary); color: #fff; }
.ds-calendar .day-content { display: flex; flex-direction: column; gap: 2px; max-height: 92px; overflow: hidden; margin-top: var(--ds-space-1); }
.ds-calendar .schedule-link { text-decoration: none; display: block; }
.ds-calendar .schedule-bar {
    background: var(--ds-brand-primary); color: #fff;
    padding: 2px var(--ds-space-1); border-radius: 4px;
    font-size: 11px; line-height: 1.3;
    display: flex; justify-content: space-between; gap: var(--ds-space-1); align-items: center;
}
.ds-calendar .schedule-bar:hover { background: var(--ds-brand-primary-hover); }
.ds-calendar .schedule-title { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ds-calendar .schedule-time { font-size: 10px; opacity: 0.9; white-space: nowrap; }

@media (max-width: 767.98px) {
    .ds-calendar .calendar-day { min-height: 76px; padding: var(--ds-space-1); }
    .ds-calendar .day-content { max-height: 54px; }
    .ds-calendar .schedule-time { display: none; }
}

/* =============================================================
   6. RESPONSIVE (AppShell)
   ============================================================= */

/* Desktop(≥1024px): Sidebar 고정 */
@media (min-width: 1024px) {
    .ds-header__menu-toggle { display: none !important; }
}

/* <1024px: Sidebar 를 Drawer 로 전환 */
@media (max-width: 1023.98px) {
    .ds-header__menu-toggle { display: inline-flex; }
    .ds-main, .ds-main--full { margin-left: 0; }
    .ds-sidebar {
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        box-shadow: var(--ds-shadow-lg);
        width: min(280px, 84vw);
    }
    body.ds-drawer-open .ds-sidebar { transform: translateX(0); }
    body.ds-drawer-open { overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) {
    .ds-sidebar { transition: none; }
}

@media (max-width: 767.98px) {
    .ds-header { padding: 0 var(--ds-space-3); }
    .ds-brand { font-size: 1.1rem; }
    .ds-header__user span { display: none; }
    .title-bar { padding: var(--ds-space-5) 0 0; }
    .title-bar .ds-page-header { padding: 0 0 var(--ds-space-4); }
    .ds-page-header { flex-direction: column; align-items: stretch; }
    .ds-page-header__actions { width: 100%; }
    .ds-page-header__actions .btn { flex: 1; }
}
