/* ==========================================================================
   해녀의부엌 통합 예약 관리 — 공통 디자인 시스템
   Popup Studio Design System 기반 (docs/specs/dashboard.md §V-2, docs/ui_guide.md)

   규칙
   - 색은 «반드시» 아래 토큰(var(--…))으로만 쓴다. 페이지 CSS 에 hex 하드코딩 금지.
   - 상태는 positive/warning/danger 3색만. 브랜드 강조색(--brand)은 상태 표현에 쓰지 않는다.
   - --brand 는 글자색으로 쓰지 않는다(흰 배경 대비 3.33:1, WCAG AA 미달). 글자는 --brand-ink(7.3:1).
   - 예외: --brand «면 위» 글자(--brand-on)는 흰색이다. 대비 3.33:1(다크 2.68:1)로 AA 미달이지만
     브랜드 표현을 우선한 제품 결정이다(2026-09-10). 로고색 #CF7710 은 톤 고정이라 면을 어둡게 깔 수 없다.
   - 카드는 흰 면 + 1px 테두리 + radius 8. 그림자는 드롭다운·다이얼로그 전용(현재 없음).
   - 중립색은 DS 회색을 유지한다. 따뜻한 중립색(#F9F6F0 계열)은 2026-09-10 폐기 — 재시도 금지.
   ========================================================================== */

/* ============================================
   0. 서체 — Pretendard 자체 호스팅(가변)
   고객명이 임의 한글이라 서브셋을 쓸 수 없어 전체 커버리지 파일을 싣는다.
   ============================================ */
@font-face {
    font-family: 'Pretendard';
    src: url("../fonts/PretendardVariable.302ec55f5b43.woff2") format('woff2-variations');
    font-weight: 45 920;
    font-style: normal;
    font-display: swap;
}

/* ============================================
   1. 토큰
   ============================================ */
:root {
    /* 면 */
    --bg: #FFFFFF;
    --bg-2: #F5F5F5;
    --bg-3: #E6E6E6;

    /* 글자 */
    --text: #1E1E1E;
    --text-2: #757575;
    --text-3: #B3B3B3;

    /* 경계 */
    --border: #D9D9D9;
    --border-strong: #757575;

    /* 상태 — positive */
    --pos-bg: #EBFFEE;
    --pos-bd: #14AE5C;
    --pos-fg: #02542D;

    /* 상태 — warning */
    --warn-bg: #FFFBEB;
    --warn-bd: #E8B931;
    --warn-fg: #522504;

    /* 상태 — danger */
    --dan-bg: #FEE9E7;
    --dan-bd: #EC221F;
    --dan-fg: #900B09;

    /* 상태 — info(회색 계열, 주목도 중간) */
    --info-bg: #F5F5F5;
    --info-bd: #757575;
    --info-fg: #1E1E1E;

    /* 브랜드 — 해녀의부엌 */
    --brand: #CF7710;        /* 면·테두리·아이콘·활성 표시 전용 */
    --brand-ink: #774D28;    /* 브랜드 계열 «글자» 는 이것만 (흰 배경 대비 7.3:1) */
    --brand-tint: #FFEEDB;   /* 활성 탭 배경 등 옅은 면 */
    --brand-on: #FFFFFF;     /* --brand 면 «위에» 얹는 글자. 3.33:1 — AA 미달을 감수한 제품 결정 */

    /* 모서리 */
    --r-sm: 4px;
    --r: 8px;
    --r-full: 9999px;

    /* 간격 (8px 배수) */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 24px;
    --sp-6: 32px;

    /* 타이포 스케일 */
    --fs-xs: 12px;
    --fs-sm: 13px;
    --fs: 14px;
    --fs-md: 16px;
    --fs-lg: 20px;
    --fs-xl: 24px;
    --fs-2xl: 30px;

    --page-max: 1280px;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #1E1E1E;
        --bg-2: #2A2A2A;
        --bg-3: #3B3B3B;

        --text: #F5F5F5;
        --text-2: #B3B3B3;
        --text-3: #757575;

        --border: #3B3B3B;
        --border-strong: #8A8A8A;

        --pos-bg: #0C3A22;
        --pos-bd: #14AE5C;
        --pos-fg: #7FE0A6;

        --warn-bg: #3A2E0B;
        --warn-bd: #E8B931;
        --warn-fg: #F2D98A;

        --dan-bg: #45120F;
        --dan-bd: #EC221F;
        --dan-fg: #F6A9A6;

        --info-bg: #2A2A2A;
        --info-bd: #8A8A8A;
        --info-fg: #F5F5F5;

        --brand: #E08A22;
        --brand-ink: #E8C39A;
        --brand-tint: #3A2409;
        --brand-on: #FFFFFF;   /* 라이트와 같은 흰 글자로 통일 — 다크 면(#E08A22) 위 대비 2.68:1 */
    }
}

/* ============================================
   1-b. 박스 모델 — base.css 를 부르는 페이지는 이것만으로도 레이아웃이 성립해야 한다.
   `templates/accounts/*` 는 전역 리셋(style.css)을 «부르지 않는다» — 그 결과 `width:100%` 에
   padding 이 더해져 로그인 화면이 폭 430px 에서 가로 스크롤이 생겼다(실측). box-sizing 은
   중복 선언돼도 무해하므로 리셋을 못 받는 페이지를 위해 여기서도 깐다.
   ============================================ */
*, *::before, *::after {
    box-sizing: border-box;
}

/* ============================================
   2. 기본 요소
   ============================================ */
body {
    font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI',
                 'Apple SD Gothic Neo', 'Malgun Gothic', Roboto, sans-serif;
    font-size: var(--fs);
    line-height: 1.6;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

h1, h2, h3 {
    font-weight: 600;
    line-height: 1.35;
    text-wrap: balance;
}

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
}

:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

/* ============================================
   3. 상단바 (_layout.html)
   ============================================ */
.topbar {
    display: flex;
    align-items: center;
    gap: var(--sp-5);
    flex-wrap: wrap;
    padding: var(--sp-3) var(--sp-4);
    background: var(--bg);
    border-bottom: 1px solid var(--border);
}

.topbar-brand {
    display: inline-flex;
    align-items: baseline;
    gap: var(--sp-3);
    text-decoration: none;
    flex-shrink: 0;
}

/* 로고는 단색 벡터(#CF7710) — 크기만 지정한다. */
.topbar-logo {
    height: 22px;
    width: auto;
    display: block;
    align-self: center;
}

.topbar-name {
    font-size: var(--fs);
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
}

.topbar-nav {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    flex-wrap: wrap;
}

.topbar-link {
    padding: 6px 10px;
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    color: var(--text-2);
    text-decoration: none;
    white-space: nowrap;
}

.topbar-link:hover { background: var(--bg-2); color: var(--text); }

.topbar-link.is-active {
    background: var(--brand-tint);
    color: var(--brand-ink);
    font-weight: 600;
}

.topbar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    font-size: var(--fs-xs);
    color: var(--text-2);
    min-width: 0;
}

/* 로그인 계정 — 사람 아이콘 + 볼드로 «계정»임을 드러낸다. 회색 글자만이면 로그아웃 버튼과 따로 떠 보인다.
   테두리는 두지 않는다(옆 로그아웃 버튼이 이미 테두리라 둘이 나란히 서면 상단바가 무거워진다). */
.topbar-user {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    color: var(--text);
}

/* 길면 잘리되 title 로 전체를 볼 수 있다(긴 이메일이 상단바를 밀어내지 않게) */
.topbar-user-name {
    font-weight: 700;
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.topbar-logout { display: flex; }

/* ============================================
   4. 페이지 골격
   ============================================ */
.page {
    max-width: var(--page-max);
    margin: 0 auto;
    padding-inline: var(--sp-4);
    padding-block: var(--sp-5) var(--sp-6);
}

.page-header {
    margin-bottom: var(--sp-4);
}

/* 제목 오른쪽에 «이 화면에서 시작하는 작업» 버튼을 두는 변형(2026-09-15). 제목 블록을 감싼 자식 하나 +
   액션이 형제로 온다. 좁은 폭에서는 액션이 아래로 떨어진다(폭 400px 규약). */
.page-header--action {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
}

/* 미인증 화면(로그인·회원가입 등)의 «타이틀». 상단바가 없어 이게 유일한 식별 표시이므로
   아래 화면 제목(「로그인」)보다 크게 둔다 — 무슨 서비스인지가 먼저고 무엇을 하는지가 다음이다.
   로고는 넣지 않기로 했으므로(§V-1) 제품명 전체를 텍스트로 쓴다. */
.brand-line {
    font-size: var(--fs-2xl);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
    color: var(--brand-ink);
    /* 타이틀은 위에 두고 폼은 화면 «중간쯤» 으로 내린다 — 미인증 화면은 컨테이너가 min-height:100vh 라
       세로 여백이 있다. 고정값 대신 뷰포트 비례(clamp)로 둬야 짧은 화면에서 폼이 잘리지 않는다. */
    margin-bottom: clamp(12px, 3.7vh, 34px);
}

/* 브랜드 줄이 타이틀을 맡으므로 그 아래 화면 제목은 한 단계 낮춘다(미인증 화면 한정 —
   대시보드에는 .brand-line 이 없어 영향이 없다). */
.brand-line + .page-header h1 {
    font-size: var(--fs-lg);
    color: var(--text-2);
    font-weight: 600;
}

.page-header h1 {
    margin: 0;   /* 브라우저 기본 h1 여백 제거 — 화면별 제목 시작 위치를 통일(간격은 .page-header 가 담당) */
    font-size: var(--fs-xl);
    letter-spacing: -0.01em;
}

.page-header p {
    margin-top: var(--sp-1);
    font-size: var(--fs-sm);
    color: var(--text-2);
}

/* 툴바 — 좌측 조작, 우측 최종갱신시각(마스터 §2) */
.toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-4);
}

.toolbar-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.toolbar-meta {
    font-size: var(--fs-xs);
    color: var(--text-2);
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.section-title {
    font-size: var(--fs-md);
    margin-bottom: var(--sp-2);
}

/* ============================================
   5. 카드 (그림자 없음 — DS 규칙)
   ============================================ */
.card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: var(--sp-4);
}

.card + .card { margin-top: var(--sp-4); }

.card > h2 {
    font-size: var(--fs-md);
    margin-bottom: var(--sp-3);
}

.card-strong { border-color: var(--border-strong); }

/* ============================================
   6. 탭 (지점 전환 등)
   ============================================ */
/* 지점 전환 — 세그먼트 컨트롤. 「둘 중 하나」라는 배타 선택을 형태로 드러낸다(떨어진 pill 은 필터처럼 읽힌다).
   지점이 2개라 세그먼트가 맞고, 늘어나면 아래 반응형에서 pill 로 풀린다. */
.tabs {
    display: inline-flex;
    flex-wrap: wrap;
    margin-bottom: var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r);
    overflow: hidden;
    background: var(--bg);
}

.tab {
    padding: 7px var(--sp-4);
    border: 0;
    border-right: 1px solid var(--border);
    font-size: var(--fs-sm);
    color: var(--text-2);
    text-decoration: none;
    background: var(--bg);
    white-space: nowrap;
}

.tab:last-child { border-right: 0; }

.tab:hover { background: var(--bg-2); }

/* 선택 상태는 브랜드 «면» + 흰 글자(--brand-on). 대비 3.33:1 로 AA(4.5:1) 미달이지만, 로고색
   #CF7710 은 톤 고정이라 면을 어둡게 깔 수 없고 브랜드 표현을 우선한 제품 결정이다(2026-09-10).
   어두운 글자(#1E1E1E, 5.0:1)로 되돌리려면 --brand-on 한 줄만 바꾸면 된다(스펙 §V-6·§V-12). */
.tab.is-active {
    background: var(--brand);
    color: var(--brand-on);
    font-weight: 600;
}

.tab.is-active:hover { background: var(--brand); }

/* 지점이 4개 이상이면 세그먼트가 좁아진다 — 그때는 원래의 pill 배치로 풀어준다. */
.tabs:has(> .tab:nth-child(4)) {
    display: flex;
    gap: var(--sp-1);
    border: 0;
    border-radius: 0;
    overflow: visible;
}

.tabs:has(> .tab:nth-child(4)) .tab {
    border: 1px solid var(--border);
    border-radius: var(--r-full);
    padding: 6px var(--sp-3);
}

.tabs:has(> .tab:nth-child(4)) .tab.is-active { border-color: var(--brand); }

/* ============================================
   7. 버튼
   ============================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 7px var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r);
    background: var(--bg);
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: 500;
    line-height: 1.4;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}

.btn:hover:not(:disabled) { background: var(--bg-2); }

.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn svg { width: 14px; height: 14px; }

.btn-outline { /* 기본형과 동일 — 기존 마크업 호환 */ }

/* 브랜드 «면» + 흰 글자(--brand-on). 버튼 글자는 13px/600 이라 large-text 예외(3:1)에 해당하지 않아
   3.33:1 은 AA 미달이다 — 지점 토글과 같은 토큰을 공유하므로 §V-12 의 제품 결정이 여기에도 걸린다. */
.btn-primary {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--brand-on);
    font-weight: 600;
}

.btn-primary:hover:not(:disabled) { background: var(--brand-ink); border-color: var(--brand-ink); color: var(--bg); }

.btn-destructive {
    background: var(--bg);
    border-color: var(--dan-bd);
    color: var(--dan-fg);
}

.btn-destructive:hover:not(:disabled) { background: var(--dan-bg); }

.btn-full { width: 100%; }

/* 상단바처럼 줄 높이가 빠듯한 자리 */
.btn-sm { padding: 4px var(--sp-2); font-size: var(--fs-xs); }

/* 뒤로가기 — 계층 이동 전용(상단바와 중복되지 않는 자리) */
/* 뒤로가기 — 텍스트 링크로 두면 «누를 수 있는 것»으로 안 보인다. 흰 면 + 1px 테두리(카드와 같은 규칙).
   회색 채움이던 옛 스타일은 쓰지 않는다 — 새 시스템은 채움 대신 테두리로 경계를 만든다. */
.back-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    margin-bottom: var(--sp-3);
    padding: 5px var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r);
    background: var(--bg);
    font-size: var(--fs-sm);
    color: var(--text-2);
    text-decoration: none;
    white-space: nowrap;
}

.back-btn:hover { background: var(--bg-2); color: var(--text); }

.back-btn svg { width: 14px; height: 14px; }

/* ============================================
   8. 폼
   ============================================ */
.form-section {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: var(--sp-5);
}

.form-group { margin-bottom: var(--sp-4); }

.form-group label {
    display: block;
    margin-bottom: 6px;
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--text);
}

.form-group small {
    display: block;
    margin-top: var(--sp-1);
    font-size: var(--fs-xs);
    color: var(--text-2);
}

input[type="text"],
input[type="number"],
input[type="date"],
/* time 이 빠져 있어 「새 회차 시각」만 브라우저 기본 모양으로 떨어졌다(2026-09-15 실측).
   새 input type 을 쓸 때마다 이 목록에 넣어야 한다 — 빠지면 그 칸만 디자인 밖으로 나간다. */
input[type="time"],
input[type="email"],
input[type="password"],
input[type="tel"],
select,
textarea {
    width: 100%;
    padding: 7px var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r);
    background: var(--bg);
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs);
    line-height: 1.4;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-tint);
}

input::placeholder, textarea::placeholder { color: var(--text-3); }

textarea { resize: vertical; }

/* 인라인 폼 — 라벨 + 컨트롤이 한 줄로 붙는 자리 */
.field {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-sm);
    color: var(--text-2);
}

.field input, .field select { width: auto; }

/* 필수 표시 — 상세·생성 «두 화면»이 쓴다. 페이지 CSS 에 두면 그 파일을 안 싣는 화면에서
   별표가 본문 색으로 떨어져 필수인지 안 보인다(이슈 #23 과 같은 형태). */
.req {
    color: var(--dan-fg);
    font-weight: 700;
}

.form-row {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.form-col {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    max-width: 560px;
}

.form-col label {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    font-size: var(--fs-sm);
    color: var(--text-2);
}

/* ============================================
   8-b. 기본 정보 표 (gd-info) — 단체 «상세·생성» 두 화면이 쓴다(2026-09-16 통일).
   조밀한 라벨/값 key-value 그리드. 넓은 화면(≥900px)에서 두 단으로 접는다.
   두 화면이 쓰므로 base.css 에 둔다 — 페이지 CSS 에 두면 그 파일을 안 싣는 화면에서
   표가 브라우저 기본값으로 튄다(이슈 #23).
   ============================================ */
.gd-info {
    --gd-k: 6.5rem;              /* 라벨 열 — 「계약금 기한」(6자)이 한 줄에 들어가는 폭 */
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 var(--sp-5);
    font-size: var(--fs-sm);
}

/* 두 단은 «가로 여백이 실제로 남을 때만». 좁은 화면에서 접으면 라벨과 값이 붙어 못 읽는다. */
@media (min-width: 900px) {
    .gd-info { grid-template-columns: 1fr 1fr; }
}

.gd-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2);
    padding: var(--sp-2) 0;
    border-top: 1px solid var(--border);
}

/* hidden 속성이 display:flex 에 밀리지 않게 못박는다 — 회차 지정에 따라 여닫는 「회차 선택·새
   회차 시각」칸이 이게 없으면 늘 보인다(이 세션의 note-edit-form 과 같은 형태의 잠재 결함). */
.gd-row[hidden], .gd-sub[hidden] { display: none; }

/* 표 맨 윗줄엔 선을 긋지 않는다 — 카드 제목과 붙어 이중선으로 보인다.
   두 단일 때는 «두 열의 첫 행»이 모두 맨 윗줄이라 둘 다 지운다(한쪽만 지우면 어긋나 보인다). */
.gd-info > .gd-row:first-child { border-top: 0; }

@media (min-width: 900px) {
    .gd-info > .gd-row:nth-child(2) { border-top: 0; }
}

/* 전 폭을 쓰는 행 — 회차(딸린 입력이 5개)·그 미리보기·잔금기한. */
.gd-row--full { grid-column: 1 / -1; }

/* 칸 줄은 «열 사이 여백을 건너» 이어진다 — 행마다 자기 열에서만 그으면 가운데가 끊겨,
   한 줄로 읽히지 않고 칸이 구분되지 않는다(2026-09-15 피드백).
   테두리 상자만 여백의 절반씩 넓히고 같은 값의 padding 으로 되밀어, 글자 위치는 그대로 둔다.
   왼/오 칸을 «명시 클래스»(.gd-c1/.gd-c2)로 표시한다 — nth-child(odd/even) 로 잡으면 중간에 전 폭
   행(구분·대관)이 하나 끼는 순간 그 아래 모든 행의 홀짝이 뒤집혀 다리가 반대로 뻗는다(2026-09-16). */
@media (min-width: 900px) {
    .gd-info > .gd-c1:not(.gd-row--full) {
        margin-right: calc(var(--sp-5) / -2);
        padding-right: calc(var(--sp-5) / 2);
    }

    .gd-info > .gd-c2:not(.gd-row--full) {
        margin-left: calc(var(--sp-5) / -2);
        padding-left: calc(var(--sp-5) / 2);
    }
}

/* 라벨 없이 블록만 놓는 행(미리보기·확인 체크박스) — 선을 긋지 않는다. */
.gd-row--plain {
    display: block;
    border-top: 0;
}

.gd-k {
    flex: 0 0 var(--gd-k);
    color: var(--text-2);
}

/* 값 열 — 입력칸이 «행마다 같은 폭»이 되도록 남은 폭을 그대로 준다. */
.gd-v {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2);
    color: var(--text);
}

/* 읽기 전용 값(구분·잔금기한) — 입력칸 글자와 같은 높이에 앉힌다. */
.gd-v--text { padding: 5px 0; }

/* 입력칸은 «항상 같은 모양»이다 — hover/focus 에서 테두리·크기·글자 위치가 바뀌지 않는다.
   행마다 폭을 따로 주지 않는다(값 열을 꽉 채워 자동으로 일정해진다). */
.gd-v input[type="text"],
.gd-v input[type="number"],
.gd-v input[type="date"],
.gd-v input[type="time"],
.gd-v input[type="email"],
.gd-v textarea,
.gd-v select {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    max-width: 22rem;
    padding-top: 5px;
    padding-bottom: 5px;
}

/* 비활성 입력칸 — 회색으로 「지금은 못 고치는 칸」임을 드러낸다(예: 대관 시 홀드좌석·홀드채널). */
.gd-v input:disabled,
.gd-v select:disabled {
    background: var(--bg-2);
    color: var(--text-3);
    cursor: not-allowed;
}

/* 회차 — 한 행에 지점·날짜·회차지정·회차선택·시각이 들어간다(전 폭). */
.gd-slot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    align-items: flex-end;
}

.gd-sub {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    flex: 1 1 11rem;
    min-width: 0;
    font-size: var(--fs-xs);
    color: var(--text-2);
}

/* 라벨 글자와 별표는 «한 덩어리»다 — .gd-sub 가 세로 배치라 감싸지 않으면 텍스트와 <b> 가
   각각 한 줄을 차지해 별표가 아래로 떨어진다(2026-09-15 실측). */
.gd-sub-k { display: block; }

.gd-sub input, .gd-sub select { width: 100%; font-size: var(--fs-sm); }

/* 저장/만들기 — 표 전체를 한 번에 받는다(액션은 서버에서 나뉜다). */
.gd-act {
    display: flex;
    justify-content: flex-end;
    margin-top: var(--sp-4);
}

/* ============================================
   8-c. 코멘트 컴포저 + @멘션 인라인 고스트 — 단체 «상세·생성» 두 화면이 쓴다(2026-09-16 통일).
   ============================================ */
/* 입력칸을 테두리 박스로 감싸고 하단 바엔 버튼만. 안내 문구(코멘트 남기기 · @멘션)는
   흰 입력칸 플레이스홀더로 합친다. 멘션 고스트 오버레이(.cm-mention-wrap)는 이 안에서 동작. */
.cm-composer {
    border: 1px solid var(--border);
    border-radius: var(--r);
    background: var(--bg);
    overflow: hidden;
}
.cm-composer:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
.cm-composer textarea { border: 0; border-radius: 0; resize: none; display: block; width: 100%; }
.cm-composer textarea:focus { outline: none; box-shadow: none; }
.cm-composer-foot {
    display: flex;
    justify-content: flex-end;
    padding: var(--sp-2);
    border-top: 1px solid var(--border);
    background: var(--bg-2);
}

/* @멘션 인라인 자동완성(고스트) — 입력칸 위에 같은 글자꼴 오버레이를 겹쳐, @ 뒤 매칭 아이디의
   «남은 글자»만 회색으로 보인다. 미러의 입력값 부분은 투명이라 실제 입력은 입력칸이 그대로 그린다. */
.cm-mention-wrap { position: relative; }
.cm-ghost {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    margin: 0;
    pointer-events: none;        /* 클릭·커서는 입력칸으로 통과 */
    overflow: hidden;
    box-sizing: border-box;
    border-style: solid;
    border-color: transparent;   /* 폭만 입력칸과 맞추고 안 보이게 */
    background: transparent;
    color: transparent;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    word-break: break-word;
}
.cm-ghost-suffix { color: var(--text-3); }

/* ============================================
   9. 표
   ============================================ */
.table-scroll {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--r);
}

.tbl {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-sm);
}

.tbl th, .tbl td {
    padding: var(--sp-2) var(--sp-3);
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--border);
}

.tbl thead th {
    position: sticky;
    top: 0;
    background: var(--bg-2);
    font-size: var(--fs-xs);
    font-weight: 600;
    color: var(--text-2);
    white-space: nowrap;
}

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

/* 행 hover 배경은 «기본»으로 두지 않는다 — 이 프로젝트의 표는 행 전체가 클릭 대상이 아니라, hover 강조가
   「누르면 넘어간다」는 오해를 준다(2026-09-10). 행 클릭이 생기는 표는 `.row-link` 로 opt-in 한다. */

/* `.row-link` = «이 행은 눌러서 넘어간다» 는 선언. hover 강조는 여기에만 붙는다(2026-09-14).
   회차 상세의 예약 표와 주/월 표의 회차 행이 같이 쓴다 — 한 곳에 두어야 두 화면의 감각이 갈라지지 않는다.
   하루에 회차가 여러 개라 어느 행 위에 있는지 보이는 것이 실제 오클릭을 줄인다. */
.row-link { cursor: pointer; }
.row-link:hover td { background: var(--bg-2); }

/* 숫자가 세로로 비교되는 자리 */
.tbl td.num, .tbl th.num, .num {
    font-variant-numeric: tabular-nums;
}

.tbl-note {
    margin-top: var(--sp-2);
    font-size: var(--fs-xs);
    color: var(--text-2);
}

/* ============================================
   10. 칩 — 상태·분류 표시 (status-badge 대체)
   variant 는 «의미» 로만 5종. 브랜드색은 여기 쓰지 않는다.
   ============================================ */
.chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 1px var(--sp-2);
    border: 1px solid var(--border);
    border-radius: var(--r-full);
    background: var(--bg-2);
    color: var(--text-2);
    font-size: var(--fs-xs);
    font-weight: 500;
    line-height: 1.7;
    white-space: nowrap;
}

.chip svg {
    width: 13px;
    height: 13px;
    flex-shrink: 0;
}

.chip b {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.chip--ok      { background: var(--pos-bg);  border-color: var(--pos-bd);  color: var(--pos-fg); }
.chip--warn    { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-fg); }
.chip--danger  { background: var(--dan-bg);  border-color: var(--dan-bd);  color: var(--dan-fg); font-weight: 600; }
.chip--info    { background: var(--info-bg); border-color: var(--info-bd); color: var(--info-fg); }
.chip--neutral { background: var(--bg-2);    border-color: var(--border);  color: var(--text-2); }

/* ============================================
   11. 정의목록 · 타임라인
   ============================================ */
.dl {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--sp-2) var(--sp-4);
    font-size: var(--fs-sm);
}

.dl dt { color: var(--text-2); }
.dl dd { color: var(--text); }

.tl {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: var(--fs-sm);
}

.tl li {
    display: flex;
    gap: var(--sp-2);
    flex-wrap: wrap;
    align-items: baseline;
    padding-left: var(--sp-3);
    border-left: 2px solid var(--border);
}

.tl-time {
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.tl-type { font-weight: 600; }

/* 변경 이력(사람이 한 일) — 「언제 · 누가 · 무엇을 · 어떻게」 한 줄. 영문 event_type 은 노출하지 않는다. */
.tl-who {
    color: var(--text-2);
    white-space: nowrap;
}
.tl-what { font-weight: 600; }
.tl-detail { color: var(--text-2); }
/* 수집 로그는 접힌 안쪽이라 한 단계 더 죽인다 — 평소 읽을 정보가 아니다. */
.tl-dim li { border-left-color: var(--border); opacity: 0.85; }
.tl-dim .tl-what { font-weight: 500; }

/* ============================================
   12. 알림 배너 · 메시지 (경고는 버튼을 잠그지 않는다 — 소프트 게이트)
   ============================================ */
.banner {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--r);
    background: var(--bg-2);
    font-size: var(--fs-sm);
    margin-bottom: var(--sp-4);
}

.banner svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; }

.banner--danger  { background: var(--dan-bg);  border-color: var(--dan-bd);  color: var(--dan-fg); }
.banner--warn    { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-fg); }
.banner--ok      { background: var(--pos-bg);  border-color: var(--pos-bd);  color: var(--pos-fg); }

/* Django messages 의 tag 이름(success/error/warning/info/debug)을 위 3색에 잇는다.
   템플릿이 `banner--{{ m.tags }}` 를 그대로 쓰므로 별칭이 없으면 무채색으로 떨어진다. */
.banner--success { background: var(--pos-bg);  border-color: var(--pos-bd);  color: var(--pos-fg); }
.banner--error   { background: var(--dan-bg);  border-color: var(--dan-bd);  color: var(--dan-fg); }
.banner--warning { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-fg); }
.banner--info,
.banner--debug   { background: var(--bg-2);    border-color: var(--border);  color: var(--text); }

.messages { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-4); }

/* ============================================
   12-b. 특이사항 노트 — 회차 상세·단체 상세·예약 상세가 공유
   같은 category 2건 이상은 «서로 다른 문항»에서 온 별개 정보다(스펙 §V-9). 합치지 않고 한 블록으로 묶는다.
   ============================================ */
.note-groups { display: flex; flex-direction: column; gap: var(--sp-3); }

.note-group {
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: var(--sp-3);
}

/* 2건 이상인 블록은 테두리를 한 단계 진하게 — 한 덩어리임을 드러낸다. */
.note-group.is-multi { border-color: var(--border-strong); }

.note-group-head {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-bottom: var(--sp-2);
    font-size: var(--fs-sm);
    color: var(--text-2);
}

.note-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

.note {
    padding: var(--sp-2) 0;
    border-top: 1px solid var(--border);
    font-size: var(--fs-sm);
}

.note-list > .note:first-child { border-top: 0; padding-top: 0; }

/* 노트가 «어느 문항»에서 나왔는지 — 중복을 남기기로 한 이상 이게 있어야 구분이 된다. */
.note-origin {
    font-size: var(--fs-xs);
    color: var(--text-2);
    margin-bottom: 2px;
}

.note-body { color: var(--text); }

.note-meta {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    flex-wrap: wrap;
    margin-top: var(--sp-1);
}

/* 반려 노트는 지우지 않고 같은 블록 안에 흐리게 남긴다(판단 이력 보존). */
.note.is-rejected {
    opacity: 0.55;
    background: var(--bg-2);
}

.note.is-rejected .note-body,
.note.is-rejected .note-body-inline { text-decoration: line-through; }

.note-actions { display: inline-flex; gap: var(--sp-1); }

.note-actions .btn { padding: 2px var(--sp-2); font-size: var(--fs-xs); }

/* 인라인 폼 버튼(확인·반려 등) — 예약 상세·단체 상세가 같이 쓴다. */
.rv-inline { display: inline; }
.rv-inline .btn { padding: 2px var(--sp-2); font-size: var(--fs-xs); }

/* 특이사항 노트 «리딩 줄» — 칩이 먼저 온다(분류→내용). 회차(이름 옆 칩)·예약(칩 줄+본문 아래)·
   단체(칩+짧은 본문 한 줄)가 공유한다(2026-09-16 통일, _note_chips.html). */
.note-lead {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    flex-wrap: wrap;
    margin-bottom: 2px;
}
.note-owner { font-weight: 700; color: var(--text); }
.note-lead .note-owner { margin-right: var(--sp-1); }
.note-lead .note-body-inline { color: var(--text); }   /* 칩과 같은 줄에 오는 짧은 본문(단체) */
.note-lead .note-actions { margin-left: auto; }          /* 교정 버튼은 줄 오른쪽 */

/* 특이사항 추가 툴바 — 목록과 «같은 카드» 하단(예약·단체 공유, _note_form.html). 한 줄 인라인. */
.note-add {
    display: flex;
    align-items: stretch;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-top: var(--sp-4);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--border);
}
.note-add select { width: auto; flex: 0 0 auto; }
.note-add .note-add-body { width: auto; flex: 1 1 12rem; }

/* 노트 «수정» 인라인 편집 폼 — 우상단 «수정» 버튼(.js-note-edit, note_edit.js)이 여닫고, 노트 «아래»에서
   바로 펼쳐진다(추가 툴바 .note-add 와 같은 결). 저장하면 자동 확정(is_confirmed). 버튼은 note-actions 에. */
.note-edit-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); }
/* display:flex 가 UA 의 [hidden]{display:none} 을 origin 우선순위로 이기므로 «닫힘»이 안 먹는다 —
   같은-요소 [hidden] 규칙으로 명시적으로 숨긴다(안 그러면 모든 편집 폼이 로드 시 펼쳐진 채 보인다). */
.note-edit-form[hidden] { display: none; }
.note-edit-form select { width: auto; flex: 0 0 auto; }
.note-edit-form .note-edit-body { width: auto; flex: 1 1 12rem; }

/* 행 전체가 클릭 영역인 행(tr.row-link)의 링크는 밑줄을 긋지 않는다 — 한 셀에만 밑줄이 서면
   거기만 눌린다고 읽힌다. 단체 목록·회차 상세 예약 표가 같은 규약을 쓴다.
   **행 클릭이 없는 표는 제외한다** — 거기선 링크가 유일한 진입 경로라 링크로 보여야 한다
   (회차 상세 단체 표가 그렇다). `.tbl a` 로 넓히면 그 표의 단서까지 지워진다. */
.row-link a { text-decoration: none; color: inherit; }

/* 취소 행 강조 — 목록·회차 상세 공통(2026-09-18). 취소는 «지난·무효» 건이라 행 전체를 죽여 구별한다.
   미납은 취소와 달라 행 음영을 주지 않고 입금열 「미납」 칩으로만 구분한다(옛 tr.is-unpaid 제거). */
tr.is-cancelled { background: var(--dan-bg); }

/* ============================================
   13. 빈 상태
   ============================================ */
.empty-state {
    padding: var(--sp-6) var(--sp-4);
    border: 1px dashed var(--border);
    border-radius: var(--r);
    text-align: center;
    color: var(--text-2);
    font-size: var(--fs-sm);
}

.empty-state h3 {
    font-size: var(--fs-md);
    color: var(--text);
    margin-bottom: var(--sp-1);
}

/* ============================================
   14. 유틸
   ============================================ */
/* 인라인 아이콘 — <svg class="ico"><use href="#ic-…"></use></svg> */
.ico {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    vertical-align: -2px;
}

.ico-sm { width: 13px; height: 13px; }

.muted { color: var(--text-2); }
/* 블록 헬퍼 문단(카드 설명·빈 상태 안내 등)은 보조 텍스트 크기(--fs-sm)로 통일한다.
   인라인 span.muted·표 셀 muted 는 문맥 크기를 유지(색만 죽임). */
p.muted { font-size: var(--fs-sm); }
.dim { color: var(--text-3); }
.neg { color: var(--dan-fg); font-weight: 600; }
/* 잔여 음수의 «원인» 색 — 주황=원장 낡음(플랫폼엔 더 열려 있음, 좌석 자체는 문제없음) /
   빨강=확인 필요. `.neg` 뒤에 두어 같은 특이도에서 이 규칙이 이긴다(둘 다 걸린 요소). */
.rem-warn, .rem-warn b { color: var(--warn-fg); }
.rem-danger, .rem-danger b { color: var(--dan-fg); }
.nowrap { white-space: nowrap; }
/* 카드 헤더 — 제목 + (칩 / 안내문구)을 제목 «바로 옆»에 붙인다(우측 정렬 아님).
   페이지 CSS 가 아니라 여기 둔다: 한 화면의 CSS 에만 있으면 그 파일을 안 싣는 화면이
   같은 class 를 쓰는 순간 스타일이 통째로 빠진다(h2 가 브라우저 기본 크기로 커진다). */
.card-head {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-3);
}

/* 카드 제목은 목적과 무관하게 한 크기로 통일 — `.card > h2`(--fs-md)와 동일하게.
   card-head 로 감싼 h2 는 `.card > h2` 선택자를 못 탄다. */
.card-head h2 { margin: 0; font-size: var(--fs-md); }

.stack { display: flex; flex-direction: column; gap: var(--sp-4); }
.row { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }
.visually-hidden {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ============================================
   15. 반응형 — 폭 400px 에서 동작. body 가로 스크롤 금지.
   ============================================ */
@media (max-width: 768px) {
    .page { padding-block: var(--sp-4) var(--sp-5); }
    .page-header h1 { font-size: var(--fs-lg); }
    .topbar { gap: var(--sp-3); }
    .topbar-right { margin-left: 0; width: 100%; }
    .dl { grid-template-columns: 1fr; gap: var(--sp-1); }
    .dl dd { margin-bottom: var(--sp-2); }
}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
