/* ===== 디자인 토큰 =====
   컬러/타이포 값을 바꿀 땐 이 :root 블록(라이트)과 아래 다크 블록만 고치면 전체에 반영됨.
   토글은 <html data-theme="dark|light">로 강제, 없으면 OS prefers-color-scheme를 따름. */
:root {
    --bg: #f6f6fb;
    --surface: #ffffff;
    --surface-2: #f0f0f8;
    --border: #e3e3f0;
    --text: #1b1c2b;
    --text-muted: #6b6d89;

    --accent: #6d5ef8;
    --accent-2: #a78bfa;
    --accent-soft: #efeaff;

    --success: #059669;
    --success-soft: #e3f7ee;
    --danger: #e11d48;
    --danger-soft: #fde8ec;
    --warning: #d97706;
    --warning-soft: #fdf1de;
    --running: #6d5ef8;
    --running-soft: #efeaff;

    --sidebar-bg: #14152a;
    --sidebar-text: #b7b8d6;
    --sidebar-text-active: #ffffff;
    --sidebar-border: #24253f;

    --shadow: 0 1px 2px rgba(27, 28, 43, .06);
    --radius-lg: 10px;
    --radius-md: 8px;
    --radius-sm: 6px;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg: #0c0d18;
        --surface: #161726;
        --surface-2: #1e2036;
        --border: #2b2d47;
        --text: #e9e9f4;
        --text-muted: #9497b8;

        --accent: #7c6bfb;
        --accent-2: #b6a3ff;
        --accent-soft: #221e42;

        --success: #34d399;
        --success-soft: #0f2e28;
        --danger: #fb7185;
        --danger-soft: #3a1620;
        --warning: #fbbf24;
        --warning-soft: #372a0d;
        --running: #a08bff;
        --running-soft: #241f45;

        --shadow: 0 1px 2px rgba(0, 0, 0, .35);
    }
}

:root[data-theme="dark"] {
    --bg: #0c0d18;
    --surface: #161726;
    --surface-2: #1e2036;
    --border: #2b2d47;
    --text: #e9e9f4;
    --text-muted: #9497b8;

    --accent: #7c6bfb;
    --accent-2: #b6a3ff;
    --accent-soft: #221e42;

    --success: #34d399;
    --success-soft: #0f2e28;
    --danger: #fb7185;
    --danger-soft: #3a1620;
    --warning: #fbbf24;
    --warning-soft: #372a0d;
    --running: #a08bff;
    --running-soft: #241f45;

    --shadow: 0 1px 2px rgba(0, 0, 0, .35);
}

* { box-sizing: border-box; }

body {
    font-family: "Noto Sans KR", -apple-system, "Segoe UI", sans-serif;
    margin: 0;
    background: var(--bg);
    color: var(--text);
    line-height: 1.55;
}

a { color: var(--accent); }

/* ===== 레이아웃 ===== */
.page { display: flex; min-height: calc(100vh - 57px); }

.sidebar {
    width: 232px;
    flex: none;
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    padding: 1.25rem 1rem;
    display: flex;
    flex-direction: column;
}

.sidebar nav { display: flex; flex-direction: column; gap: 3px; margin-bottom: 1.5rem; flex: 1; }

/* 그룹 라벨 — 위에 가는 구분선을 두어 메뉴 묶음이 눈에 띄게 갈리도록 한다. */
.nav-group-label {
    color: rgba(255, 255, 255, .38);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .6px;
    margin-top: 12px;
    padding: 16px 0.75rem 6px;
    border-top: 1px solid var(--sidebar-border);
}

.sidebar nav a {
    display: flex;
    align-items: center;
    gap: 11px;
    color: var(--sidebar-text);
    text-decoration: none;
    padding: 0.62rem 0.75rem;
    border-radius: var(--radius-md);
    font-size: 14px;
    transition: background .15s ease, color .15s ease;
}

/* 메뉴 아이콘 — 선 스타일(currentColor)이라 글자색을 따라가고, 평소엔 살짝 흐리게. */
.nav-icon {
    flex: none;
    width: 17px;
    height: 17px;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: .7;
    transition: opacity .15s ease, color .15s ease;
}

.sidebar nav a:hover { color: var(--sidebar-text-active); background: rgba(255, 255, 255, .06); }
.sidebar nav a:hover .nav-icon { opacity: 1; }

/* 활성 메뉴 — 알약 배경 + 왼쪽 강조선(inset 그림자라 둥근 모서리를 그대로 따라감) + 보라색 아이콘. */
.sidebar nav a.active {
    color: var(--sidebar-text-active);
    background: linear-gradient(90deg, rgba(124, 107, 251, .26), rgba(124, 107, 251, .05));
    box-shadow: inset 3px 0 0 var(--accent-2);
    font-weight: 700;
}

.sidebar nav a.active .nav-icon { color: #a99bff; opacity: 1; }

/* ===== 상단 바 — 사이드바까지 포함해 화면 맨 위를 좌우로 가득 채움 ===== */
.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 0.65rem 1.5rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.topbar-left { display: flex; align-items: center; gap: 10px; }

/* 모바일 전용 메뉴 버튼 — 데스크톱에선 사이드바가 항상 보이므로 숨긴다(아래 모바일 블록에서 표시). */
.nav-toggle-btn { display: none; padding: 0.4rem 0.5rem; line-height: 0; }
.nav-toggle-btn svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }

.topbar-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }

.topbar-brand-mark {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    flex: none;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    color: #fff;
    font-weight: 900;
    font-size: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.topbar-brand-name { font-weight: 700; font-size: 15px; color: var(--text); }

/* 로고 옆 버전 표시 — 작은 알약 모양 배지. */
.topbar-version {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 1px 8px;
    white-space: nowrap;
    cursor: default;
}

.topbar-actions { display: flex; align-items: center; gap: 10px; }
.topbar-actions form { display: contents; }
.topbar-user { font-size: 13px; color: var(--text-muted); }
/* 우측 상단 버튼(테마 전환·로그아웃)은 높이를 32px로 고정하고 가운데 정렬 — 이모지 버튼이 글자 버튼보다 3~4px
   더 커서 높이가 어긋났다. */
.topbar-actions button {
    height: 32px;
    padding: 0 0.75rem;
    font-size: 12.5px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.topbar-actions .theme-toggle-btn { width: 38px; padding: 0; font-size: 15px; }

/* 다크/라이트 전환 버튼 — 이모지만 표시(클릭해서 바뀔 모드를 보여준다: 지금 라이트면 🌙, 지금
   다크면 ☀️). 실제 다크모드 판정과 같은 우선순위(명시적 data-theme > OS 설정)를 그대로 따라야
   해서, 위 :root 색상 토큰 규칙과 동일한 선택자 조합을 그대로 재사용한다. */
.theme-toggle-btn::before { content: "🌙"; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .theme-toggle-btn::before { content: "☀️"; }
}

:root[data-theme="dark"] .theme-toggle-btn::before { content: "☀️"; }

/* 날짜·월 입력의 네이티브 달력 아이콘은 브라우저 기본이 검정이라 다크 배경에선 거의 안 보인다 —
   color-scheme: dark로 아이콘을 밝게 그리게 한다(이 두 입력에만 적용해 다른 폼 요소는 건드리지
   않음). 다크 판정은 위와 같은 우선순위(명시적 data-theme > OS 설정). */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) input[type="date"],
    :root:not([data-theme="light"]) input[type="month"] { color-scheme: dark; }
}

:root[data-theme="dark"] input[type="date"],
:root[data-theme="dark"] input[type="month"] { color-scheme: dark; }

/* 범용 토글 스위치(ToggleSwitch.razor) — 위 .theme-toggle과 같은 모양(알약형 트랙 + 원형 손잡이)이지만
   전역 data-theme이 아니라 아무 bool 값에나 붙일 수 있게 <input type="checkbox">로 상태를 갖는다. */
.switch { position: relative; display: inline-block; width: 40px; height: 22px; flex: none; vertical-align: middle; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch-slider {
    position: absolute;
    inset: 0;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    transition: background .18s ease, border-color .18s ease;
    pointer-events: none;
}
.switch-slider::before {
    content: "";
    position: absolute;
    top: 1px;
    left: 1px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--text-muted);
    transition: transform .18s ease, background .18s ease;
}
.switch input:checked + .switch-slider { background: var(--accent-soft); border-color: var(--accent); }
.switch input:checked + .switch-slider::before {
    transform: translateX(18px);
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
}
.switch input:disabled { cursor: not-allowed; }
.switch.disabled { opacity: .6; }

main {
    flex: 1;
    padding: 1.75rem 2.25rem;
    min-width: 0;
}

h1, h2, h3 { text-wrap: balance; }
/* h1은 항상 화면 맨 위 제목으로만 쓰여서, 브라우저 기본 margin-top(약 0.67em)까지 main의 padding-top과
   겹쳐 제목 위 여백이 과하게 보였다 — h1 자체 여백은 없애고 main의 padding-top만으로 간격을 준다. */
h1 { margin-top: 0; }
h1:focus { outline: none; }

/* 제목과 "+ 새 ~" 같은 주요 액션 버튼을 한 줄에 두고 버튼은 오른쪽 정렬 — 목록 화면에서 필터
   툴바까지 내려가 있던 생성 버튼을 제목 옆으로 끌어올릴 때 쓴다. */
.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.page-header h1 { margin-bottom: 0; }

/* 섹션 제목(h2)과 그 섹션을 접고 펴는 버튼을 한 줄에 — 조회 이력처럼 점점 길어지는 목록용. */
.section-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }

/* 접힌 섹션과 바로 아래 내용이 붙어 보이지 않게 구분선을 긋는다. */
.section-divider { border: 0; border-top: 1px solid var(--border); margin: 0 0 1.25rem; }

/* 계좌 상세 상단 "계좌 정보" — 라벨/값 쌍을 카드 하나에 격자로 나열. */
.info-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow);
    padding: 14px 18px;
    margin-bottom: 1.25rem;
}
.info-panel-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: 12px; }
.info-panel-title { font-size: 14px; font-weight: 700; }
.info-panel-source { font-size: 12px; color: var(--text-muted); }
.info-panel-toggle { margin-left: auto; }
.info-panel-head:last-child { margin-bottom: 0; } /* 접혔을 땐 머리글만 남으므로 아래 여백 제거 */
.info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px 20px; }
.info-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.info-label { font-size: 12px; color: var(--text-muted); }
.info-value { font-size: 14.5px; font-weight: 600; overflow-wrap: anywhere; }

/* ===== 버튼 ===== */
button, .btn {
    cursor: pointer;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    border-radius: var(--radius-sm);
    padding: 0.5rem 0.9rem;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    text-decoration: none;
    display: inline-block;
    line-height: 1.3;
}

table .btn, table button { padding: 0.35rem 0.7rem; font-size: 12.5px; }

/* 2026-09-17: 테이블 안 버튼은 위 규칙으로 줄어드는데 select(회원관리의 역할 선택 등)는 빠져 있어
   전역 16px 크기 그대로 혼자 커 보이던 문제 — 버튼과 같은 크기로 맞춘다. */
table select { padding: 0.35rem 0.5rem; font-size: 12.5px; }

/* 2026-09-17: 회원관리처럼 한 셀에 버튼·select를 여러 개 나열한 곳(@if로 조건부 렌더링해
   Blazor가 그 사이 공백 텍스트 노드를 남기지 않는 경우가 있음)은 간격이 아예 안 보였다 —
   인접 형제 선택자는 사이의 공백 노드 유무와 무관하게 걸리므로 여기서 한 번에 해결한다. */
table td > .btn + .btn, table td > .btn + button, table td > .btn + select,
table td > button + .btn, table td > button + button, table td > button + select,
table td > select + .btn, table td > select + button {
    margin-left: 6px;
}

button:hover, .btn:hover { border-color: var(--accent-2); }

button:disabled { opacity: .5; cursor: not-allowed; }

button.primary, .btn.primary {
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    color: #fff;
    border: none;
}

/* 삭제처럼 되돌리기 어려운 동작 — 빨간 버튼. 다크모드의 --danger는 연한 분홍(#fb7185)이라 흰 글자와
   대비가 낮아, 테마와 무관하게 진한 빨강을 고정으로 쓴다. */
button.danger, .btn.danger {
    background: linear-gradient(135deg, #e11d48, #f43f5e);
    color: #fff;
    border: none;
}

/* ===== 폼 ===== */
.field-row { margin-bottom: 0.75rem; display: flex; flex-direction: column; gap: 0.25rem; max-width: 480px; }
.field-row label { font-weight: 600; font-size: 0.9rem; color: var(--text-muted); }
/* 입력칸 제목 바로 아래 줄에 따로 보이는 설명 — 제목은 굵게, 설명은 작고 흐리게 줄바꿈해서. */
/* 체크박스 목록 한 줄 — 체크박스는 왼쪽, 오른쪽 글자 덩어리(제목 + 아래 줄 설명)가 체크박스 아래로 감기지 않게 한다. */
.field-row label.check-option { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 6px; }
.check-option input[type="checkbox"] { margin: 3px 0 0; flex: none; }

label .field-desc { display: block; font-weight: 400; font-size: 0.8rem; margin-top: 2px; }

/* ===== 조회조건 툴바 — 필터/조회기간/버튼을 한 줄에 (실측 참고 화면의
   "기간~월버튼~체크박스~상세검색~조회~초기화" 한 줄 레이아웃) ===== */
.toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 14px;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow);
    margin-bottom: 1rem;
}

.toolbar .chip-row { gap: 6px; }
.toolbar select, .toolbar input:not([type="checkbox"]) { margin: 0; }
/* 옵션 글자가 긴 셀렉트(접근 로그 자격증명 등)가 모바일에서 툴바·화면 밖으로 삐져나오지 않게 한다. */
.toolbar select { max-width: 100%; }

/* 옆 버튼/입력 크기에 맞춰 라벨도 같은 비중으로 — "구분"/"상태"/"청구년월" 등 툴바 안 모든
   라벨에 공통 적용(날짜/월 입력·셀렉트박스만 따로 작게 두면 라벨만 붕 뜨는 문제가 있었음). */
.toolbar-label {
    font-size: 15px;
    color: var(--text);
    font-weight: 700;
    white-space: nowrap;
}

.toolbar-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }

/* 툴바 안 셀렉트박스·텍스트/월 입력도 버튼·날짜입력과 같은 높이(35px)로 맞춤 — 2026-09-17: 스케줄러
   화면의 cron 입력칸(plain text)이 이 규칙에 안 걸려 혼자 커 보이던 문제를 이 자리에서 함께 고친다.
   날짜 입력(input[type="date"])은 .date-range가 이미 같은 크기로 따로 맞춰주므로 제외한다. */
.toolbar select,
.toolbar input:not([type="checkbox"]):not([type="date"]) {
    height: 35px;
    padding: 0 10px;
    font-size: 13px;
}

/* ===== 표/카드 뷰 전환 탭 ===== */
.tabbar { display: flex; gap: 18px; margin-bottom: 14px; border-bottom: 1px solid var(--border); }

.tabbar button {
    border: none;
    background: none;
    color: var(--text-muted);
    padding: 8px 2px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    border-radius: 0;
    border-bottom: 2px solid transparent;
}

.tabbar button.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ===== 대시보드 요약 카드/목록 ===== */
.dash-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin: 1rem 0 1.5rem; }

.dash-stat {
    border-radius: var(--radius-lg);
    padding: 1rem 1.1rem;
}

.dash-stat-danger { background: var(--danger-soft); }
.dash-stat-accent { background: var(--accent-soft); }
.dash-stat-warning { background: var(--warning-soft); }
.dash-stat-muted { background: var(--surface-2); }

.dash-stat-label { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; }
.dash-stat-danger .dash-stat-label, .dash-stat-danger .dash-stat-value { color: var(--danger); }
.dash-stat-accent .dash-stat-label, .dash-stat-accent .dash-stat-value { color: var(--accent); }
.dash-stat-warning .dash-stat-label, .dash-stat-warning .dash-stat-value { color: var(--warning); }
.dash-stat-muted .dash-stat-label { color: var(--text-muted); }

.dash-stat-icon { display: inline-flex; width: 16px; height: 16px; }
.dash-stat-icon svg { width: 100%; height: 100%; }
.dash-stat-value { font-size: 24px; font-weight: 700; margin-top: 6px; }

.dash-panels { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 16px; margin-bottom: 1.5rem; }
/* 1fr은 minmax(auto,1fr)이라, 행 안의 말줄임(nowrap) 문장이 긴 만큼 칸이 화면 밖으로 늘어났다 —
   minmax(0,1fr)로 칸 폭을 화면에 고정해야 말줄임이 실제로 걸린다(모바일에서 패널이 가로로 길어지던 원인). */
@media (max-width: 900px) { .dash-panels { grid-template-columns: minmax(0, 1fr); } }
.dash-panels > .qcard { min-width: 0; }

.dash-panel-title { font-size: 14px; font-weight: 700; margin: 0 0 10px; }

.dash-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border-top: 1px solid var(--border);
}
.dash-row:first-child { border-top: none; padding-top: 0; }
/* 설명이 긴 행에서 오른쪽 버튼("확인")이 flex로 줄어들어 "확/인"처럼 두 줄로 쪼개졌다 — 줄어들지 않게 고정. */
.dash-row > .btn, .dash-row > button { flex: none; white-space: nowrap; }

.dash-row-title { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; }
.dash-row-icon { display: inline-flex; width: 14px; height: 14px; flex: none; color: var(--text-muted); }
.dash-row-icon svg { width: 100%; height: 100%; }

/* "최근 변동 알림" 행 제목이 <a>에서 팝업을 여는 <button>으로 바뀌면서, 전역 button 스타일(테두리·
   배경·패딩)을 걷어내 원래 링크처럼 보이게 되돌린다. */
button.dash-row-link { background: none; border: none; padding: 0; font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer; text-align: left; }

/* ===== 변동 알림 상세 팝업 ===== */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .5);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    z-index: 1000;
}

.modal-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 1.25rem 1.5rem;
    width: 100%;
    max-width: 880px;
    max-height: 85vh;
    /* 좁은 화면에서 한글이 글자 단위로 꺾여 읽기 어려웠다 — 띄어쓰기에서만 줄바꿈하고, 공백 없는 긴
       값(서비스명 등)은 넘치지 않게 필요할 때만 강제로 끊는다. */
    word-break: keep-all;
    overflow-wrap: anywhere;
    overflow-y: auto;
}

/* 삭제 등 확인 팝업(ConfirmDialog) — 변동 알림 팝업보다 훨씬 작게. */
.confirm-box { max-width: 420px; }
.confirm-message { margin: 0.25rem 0 1.25rem; line-height: 1.6; }
/* 문구에 줄바꿈(\n)이 들어 있는 경우에만 — 그대로 줄을 나눠 보여준다. */
.confirm-message.multiline { white-space: pre-line; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }

.modal-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 0.5rem; }
.modal-header h2 { margin: 0; font-size: 16px; }

.dash-row-link { color: var(--text); text-decoration: none; }
.dash-row-link:hover { color: var(--accent); }
.dash-row-link:hover .dash-row-icon { color: var(--accent); }

.dash-row-sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.dash-row-time { font-size: 12px; color: var(--text-muted); white-space: nowrap; }

/* ===== 카드형 그리드 (자격증명 카드 뷰 등) ===== */
/* 2026-09-30 재측정 — 220px에서는 qcard-meta 한 줄(상태 배지 + 수정 + 계좌/카드·서비스 조회 버튼)이
   실제로 안 들어가서(가장 넓은 조합인 "사용안함" 배지 + "서비스 조회" 버튼 기준 최소 254px 필요)
   버튼 글자가 두 줄로 줄바꿈됐다 — 여유를 두고 260px로 올린다. */
.qgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; margin-bottom: 1.5rem; }

.qcard {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow);
    padding: 14px;
}

/* 알림 설정 화면 — 채널 카드를 세로로 안 쌓이고 가로로 나란히 배치한다(qgrid는 칸 너비가 전부
   같아서 필드 많은 이메일 카드만 세로로 길어지는 문제가 있었다). qcard-wide(이메일)는 필드가 많아
   더 넓게, 나머지(슬랙/디스코드)는 좁게 flex-basis를 준다. */
.settings-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; margin-bottom: 1.5rem; }
.settings-row .qcard { flex: 1 1 220px; }
.settings-row .qcard.qcard-wide { flex: 2 1 420px; }

/* 내 정보 > 알림 설정 — 채널 카드(이메일/슬랙/디스코드)를 위 알림 설정(관리자용) 화면과 달리
   세로로 나열한다(요청에 따라 settings-row의 가로 배치 대신 사용). */
.settings-col { display: flex; flex-direction: column; gap: 12px; margin-bottom: 1.5rem; max-width: 480px; }

/* 이메일 카드 안 SMTP 필드들을 한 줄에 여러 개씩 가로로 배치 — field-row(세로 스택)와 달리
   flex-wrap으로 카드 너비에 맞춰 자연스럽게 줄바꿈된다. */
.field-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 0.75rem; }
.field-col { display: flex; flex-direction: column; gap: 0.25rem; flex: 1 1 140px; min-width: 120px; }
.field-col.narrow { flex: 0 1 70px; min-width: 70px; }
.field-col.full { flex-basis: 100%; }
.field-col label { font-weight: 600; font-size: 0.85rem; color: var(--text-muted); }

/* 입력창 바로 아래 붙는 상태 안내문(비밀번호/웹훅 URL 설정 여부)이 입력창에 너무 붙어 보이던 문제 —
   위쪽에 여백을 준다. .hint의 기본 margin-top: -0.5rem을 이겨야 해서 클래스 두 개짜리 선택자로 준다
   (파일 안에서의 등장 순서와 무관하게 항상 이긴다). */
.hint.field-hint { margin-top: 4px; }

.qcard-tag + .qcard-tag {
    margin-left: 6px;
}

.qcard-tag {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    background: var(--accent-soft);
    padding: 2px 8px;
    border-radius: 5px;
    margin-bottom: 8px;
}

/* "구분"(기관 유형) 태그가 "기관"(이름) 태그와 색이 같아서 어떤 게 어떤 값인지 한눈에 안 들어온다는
   지적으로 무채색으로 뺐다 — 기관명 태그(강조색)가 시선을 먼저 끌고, 구분 태그는 보조 정보로 보인다. */
.qcard-tag-muted {
    color: var(--text-muted);
    background: var(--surface-2);
}

/* 구분 태그 안의 유형 아이콘(InstitutionTypeIcon) — 텍스트만으로는 은행/카드/증권사 등이 눈에 잘 안
   들어온다는 지적으로 도형까지 같이 보여준다. currentColor라 태그 글자색을 그대로 물려받는다. */
.qcard-tag-icon {
    display: inline-flex;
    width: 12px;
    height: 12px;
    margin-right: 4px;
    vertical-align: -1px;
}
.qcard-tag-icon svg { width: 100%; height: 100%; }

.qcard-title { font-size: 14px; font-weight: 700; margin-bottom: 10px; }
.qcard-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.qcard-actions { display: flex; gap: 6px; }

/* ===== 필터 칩 (기관 선택 등) ===== */
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* 칩 안에 건수 배지 — tutorial.upharos.com "전체 9 / 나의업무 1" 카운트 칩 참고. */
.chip-row .btn .cnt {
    display: inline-block;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    background: var(--surface);
    color: var(--text-muted);
}

.chip-row .btn.primary .cnt { background: rgba(255, 255, 255, .28); color: #fff; }

/* 구분 필터 칩(은행/카드/증권사 등)에 붙는 기관 유형 아이콘 — .qcard-tag-icon과 같은 원칙(currentColor로
   버튼 글자색을 그대로 물려받아 선택 여부와 무관하게 항상 잘 보인다). */
.chip-icon {
    display: inline-flex;
    width: 13px;
    height: 13px;
    margin-right: 4px;
    vertical-align: -2px;
}
.chip-icon svg { width: 100%; height: 100%; }

/* ===== 조회기간(from~to) 한 줄 컴포넌트 ===== */
.date-range-field { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.date-range { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* 옆의 조회/초기화 버튼과 높이를 맞춤 — 네이티브 date input은 폰트 크기만 줄여선
   내부 크롬(달력 아이콘 등) 때문에 박스 자체가 잘 안 줄어들어 height를 직접 지정한다.
   모바일 자동 확대 방지용 16px 규칙(전역 input 규칙)은 여기서만 예외로 둔다. */
.date-range input[type="date"] { width: auto; height: 35px; padding: 0 10px; font-size: 13px; }
.date-range-sep { color: var(--text-muted); }

/* 표 안의 이동 링크 — 밑줄 대신 글자 끝에 작은 링크(체인) 아이콘으로 "누르면 이동"을 표시한다. */
a.link-icon { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; color: inherit; }
a.link-icon svg { width: 13px; height: 13px; flex: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; opacity: .75; }
a.link-icon:hover { text-decoration: underline; text-underline-offset: 3px; }
a.link-icon:hover svg { opacity: 1; }

/* ===== 버튼 여러 개를 한 줄에 ===== */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0.6rem 0; }

/* ===== 인증서 정보 (자격증명 수정 화면) ===== */
.cert-info {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.6rem;
    font-size: 12.5px;
}

.cert-info p { margin: 0.35rem 0; line-height: 1.6; word-break: break-all; }
.cert-info .cert-label {
    display: inline-block;
    min-width: 72px;
    color: var(--text-muted);
    font-weight: 600;
    margin-right: 8px;
    word-break: keep-all;
}

input, select, textarea {
    font-family: inherit;
    font-size: 16px; /* 모바일에서 자동 확대 방지 */
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0.45rem 0.6rem;
}

input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* 파일 선택 버튼 — 브라우저 기본(밝은 회색)이라 다크 모드에서 혼자 튀었다. 다른 버튼(.btn)과 같은 모양으로. */
input[type="file"] { max-width: 100%; color: var(--text-muted); }
input[type="file"]::file-selector-button {
    cursor: pointer;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    padding: 0.4rem 0.8rem;
    margin-right: 0.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
}
input[type="file"]::file-selector-button:hover { border-color: var(--accent-2); }

/* ===== 테이블 ===== */
main { overflow-x: auto; } /* 최후 방어선 — 표는 기본적으로 .table-scroll이 각자 스크롤 처리 */

/* 표마다 스크롤바를 표 바로 아래 둬서, 페이지가 길어도(표 2개 이상) 스크롤바를 찾으러 맨 밑까지
   내려갈 필요가 없게 한다 — main 전체를 스크롤 컨테이너로 두면 스크롤바가 페이지 맨 끝에 생겨
   위쪽 표가 잘려도 알아챌 수 없는 문제가 있었음(2026-09-08). */
.table-scroll {
    overflow-x: auto;
    scrollbar-width: thin; /* Firefox */
    scrollbar-color: var(--border) var(--surface-2);
}

.table-scroll::-webkit-scrollbar { height: 9px; }
.table-scroll::-webkit-scrollbar-track { background: var(--surface-2); border-radius: 999px; }
.table-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.table-scroll::-webkit-scrollbar-thumb:hover { background: var(--accent-2); }

table {
    border-collapse: collapse;
    width: 100%;
    margin: 1rem 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    font-size: 13.5px;
}

table th, table td {
    border-bottom: 1px solid var(--border);
    padding: 0.6rem 0.85rem;
    text-align: center;
    white-space: nowrap;
}

table th:not(:last-child), table td:not(:last-child) {
    border-right: 1px solid var(--border);
}

table th {
    background: var(--accent-soft);
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
}

/* "N건 표시 중" 문구 바로 아래 표는 table 자체의 위 여백(1rem)이 문구 아래 여백에 더해져 카드 뷰
   (.qgrid)보다 간격이 16px 더 벌어졌다 — 문구 바로 뒤에 올 때만 위 여백을 없애 카드 뷰와 같게 맞춘다. */
.hint + .table-scroll > table { margin-top: 0; }

/* 안내 영역(.page-intro)도 자체 아래 여백(1.25rem)이 있어 바로 뒤 표의 위 여백이 겹쳐 더해진다 —
   표 위 여백을 0으로 빼도 20px이라 길어, 건수 문구 아래 간격(12.5px)과 비슷하게 감싸는 영역을
   -0.5rem 당긴다(overflow 컨테이너 안쪽 표에 음수 여백을 주면 위쪽이 잘려서 바깥에서 당김). */
.page-intro + .table-scroll { margin-top: -0.5rem; }
.page-intro + .table-scroll > table { margin-top: 0; }

table tbody tr:last-child td { border-bottom: none; }
table tbody tr:hover { background: var(--surface-2); }

/* ===== 상태 배지 (상태 표시에 점진 적용) ===== */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
}

.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge.success { background: var(--success-soft); color: var(--success); }
.badge.danger { background: var(--danger-soft); color: var(--danger); }
.badge.warning { background: var(--warning-soft); color: var(--warning); }
.badge.running { background: var(--running-soft); color: var(--running); }
.badge.neutral { background: var(--surface-2); color: var(--text-muted); }

.error-text { color: var(--danger); }
.ct-mobile-only { display: none; } /* 모바일 카드 표 전용 셀 — 데스크톱 표에선 숨김(모바일 규칙은 media 블록) */
.hint { color: var(--text-muted); font-size: 12.5px; margin-top: -0.5rem; }

/* ===== 안내 영역 — 제목 아래 설명문·경고문이 배경 없이 덩그러니 떠 보이던 문제 ===== */
.page-intro {
    background: var(--surface-2);
    border-radius: var(--radius-md);
    padding: 0.7rem 1.1rem;
    margin: 0.75rem 0 1.25rem;
    font-size: 13.5px;
    color: var(--text-muted);
}

.notice {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 0.75rem 1rem;
    border-radius: var(--radius-md);
    font-size: 13.5px;
    margin-bottom: 1rem;
}

.notice-icon { flex: none; width: 16px; height: 16px; margin-top: 1px; }
.notice-icon svg { width: 100%; height: 100%; }

.notice-warning { background: var(--warning-soft); color: var(--warning); }
.notice-success { background: var(--success-soft); color: var(--success); }
.notice-danger { background: var(--danger-soft); color: var(--danger); }
.notice-running { background: var(--running-soft); color: var(--running); }
.notice-neutral { background: var(--surface-2); color: var(--text-muted); }

/* .notice 안 내용은 badge/num 등 원래 색을 유지해야 해서, 배경색만 물려받고 글자색은 강제하지
   않는다 — 대신 아이콘만 영역 톤(variant color)을 따라간다. */
.notice-success, .notice-danger, .notice-running, .notice-neutral { color: var(--text); }
.notice-success .notice-icon { color: var(--success); }
.notice-danger .notice-icon { color: var(--danger); }
.notice-running .notice-icon { color: var(--running); }
.notice-neutral .notice-icon { color: var(--text-muted); }

/* 오류 메시지 등 한 줄에 담기엔 너무 긴 셀 값 — 말줄임 처리하고 title 속성(네이티브 툴팁)으로
   전체 내용을 보여준다. 표 가로 스크롤을 유발하지 않도록 최대 너비를 고정한다. */
.truncate-cell {
    display: inline-block;
    max-width: 260px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}

/* 벤더 원본 JSON(요청/응답) 표시용 — Compare.razor의 .diff-cell과 같은 모노스페이스 스타일이지만
   페이지 범위 CSS가 아니라 여러 화면(계좌 상세의 "결과 보기" 등)에서 공유해야 해서 여기 둔다. */
.output-block {
    white-space: pre-wrap;
    word-break: break-all;
    text-align: left;
    font-family: "JetBrains Mono", monospace;
    font-size: 12px;
    line-height: 1.35;
    background: var(--surface);
    padding: 10px 12px;
    border-radius: 6px;
    max-height: 400px;
    overflow-y: auto;
}

/* Input/Output을 나란히 두 칸으로 — 좁은 화면에서는 위아래로 자연스럽게 줄바꿈된다. */
.output-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

@media (max-width: 720px) {
    .output-columns { grid-template-columns: 1fr; }
}

/* ===== 로그인 화면 ===== */
.auth-wrap {
    min-height: 70vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.auth-card { width: 100%; max-width: 360px; }

.auth-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 1.25rem;
}

/* ===== 카드 (선택적 유틸리티) ===== */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 1.1rem 1.25rem;
}

/* ===== 통계 카드 (스케줄러 등 요약 화면) ===== */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 14px;
    margin: 1rem 0 1.5rem;
}

/* 스케줄러 요약 타일 — 윗줄은 [아이콘][라벨], 라벨은 아이콘 아래 선(bottom)에 맞추고 숫자는 그 아랫줄.
   마크업 순서(아이콘·숫자·라벨)는 그대로 두고 grid 영역으로만 재배치한다. */
.stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 1rem 1.1rem;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "icon label" "value value";
    align-items: end;
    column-gap: 10px;
}

.stat-icon {
    grid-area: icon;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 12px;
    color: #fff;
}

.stat-icon svg { width: 17px; height: 17px; }
.stat-value { grid-area: value; font-size: 24px; font-weight: 700; font-family: "JetBrains Mono", monospace; }
.stat-label { grid-area: label; font-size: 13px; color: var(--text-muted); margin-bottom: 12px; line-height: 1.2; }

.field-row { margin-bottom: 0.75rem; display: flex; flex-direction: column; gap: 0.25rem; max-width: 480px; }
.field-row label { font-weight: 600; font-size: 0.9rem; }

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--success);
}

.invalid {
    outline: 1px solid var(--danger);
}

.validation-message {
    color: var(--danger);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ===== 모바일 (≤768px) — 사이드바를 상단바로 접음 ===== */
@media (max-width: 768px) {
    .page { flex-direction: column; }

    /* 상단바를 한 줄로 — 줄바꿈되며 사용자·테마·로그아웃이 로고 아래로 떨어지던 것을 막는다. 이름이
       길면 말줄임, 아주 좁은 폭(≤480px)에선 로고 글자를 숨기고 "N" 마크만 둔다(아래 블록). */
    .topbar { flex-wrap: nowrap; gap: 8px; padding: 0.55rem 1rem; }
    .topbar-left { min-width: 0; }
    .topbar-actions { gap: 8px; min-width: 0; }
    .topbar-user { max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

    /* 메뉴는 기본 접힘 — 상단바의 메뉴 버튼이 <html data-nav-open>을 토글하면 펼쳐진다. */
    .nav-toggle-btn { display: inline-flex; align-items: center; }

    .sidebar {
        display: none;
        width: 100%;
        padding: 0.75rem 1rem;
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
    }

    :root[data-nav-open] .sidebar { display: flex; }

    /* 메뉴가 한 줄에 뒤섞여 줄바꿈되던 것을 칩 격자로 — 폭에 맞춰 2열(넓으면 더 많이)로 깔고 그룹
       라벨은 한 줄 전체를 써서 "모니터링"/"설정" 묶음이 구분되게 한다. */
    .sidebar nav {
        flex: 0 0 100%; /* 데스크톱의 flex:1(flex-basis 0%)을 덮어써야 width:100%가 실제로 적용됨 */
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
        gap: 6px;
        margin-bottom: 0;
        order: 3;
        width: 100%;
        padding-top: 0.75rem;
        margin-top: 0.6rem;
        border-top: 1px solid var(--sidebar-border);
    }

    .sidebar nav a { background: rgba(255, 255, 255, .04); padding: 0.6rem 0.75rem; }
    .sidebar nav > a:first-child { grid-column: 1 / -1; }
    .nav-group-label { grid-column: 1 / -1; margin-top: 6px; padding: 0.35rem 0.25rem 0; border-top: none; }

    main { padding: 1.25rem 1rem; max-width: 100%; }

    /* 제목 글자가 데스크톱 크기(h1 32px/h2 24px) 그대로라 "기관 › 번호 (구분/통화) › 상세" 같은 긴 제목이
       세 줄로 꺾이고 화면을 다 차지했다 — 모바일에선 한 단계 줄인다. */
    h1 { font-size: 1.4rem; line-height: 1.3; }
    h2 { font-size: 1.15rem; }
    .page-header { margin-bottom: 1rem; }

    /* 변동 알림 팝업 — 바깥 여백(20px)과 안쪽 패딩(1.5rem)이 겹쳐 본문 폭이 너무 좁아졌다. */
    .modal-backdrop { padding: 10px; }
    .modal-box { padding: 1rem; max-height: 90vh; }

    /* 계좌 정보 카드 — 190px 최소폭이면 모바일에서 항목이 한 줄에 하나씩 쌓여 세로로 길어진다. */
    .info-grid { grid-template-columns: repeat(auto-fill, minmax(135px, 1fr)); gap: 10px 14px; }
    /* 기준(출처) 문구가 길어 접기 버튼이 혼자 다음 줄로 밀리던 것 — 제목+접기 버튼을 윗줄에, 기준은 아랫줄 전체로. */
    .info-panel-head { row-gap: 4px; align-items: center; }
    .info-panel-source { order: 3; flex-basis: 100%; }

    /* 계좌 거래내역 — 7열 표는 가로로 한참 밀어야 보여서, 모바일에선 거래 한 건을 카드 한 장으로 쌓는다.
       윗줄: 일자·시간 ··· 구분 / 가운데: 적요 ··· 금액(강조) / 아랫줄: 잔액 ··· 지점. */
    .txn-table { display: block; margin: 0; border: none; background: transparent; border-radius: 0; overflow: visible; }
    .txn-table thead { display: none; }
    .txn-table tbody { display: block; }
    .txn-table tbody tr {
        display: grid;
        grid-template-columns: auto auto 1fr auto;
        column-gap: 0.6rem;
        row-gap: 4px;
        align-items: baseline;
        padding: 0.7rem 0.85rem;
        margin-bottom: 8px;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
    }
    .txn-table tbody tr td { padding: 0; border: 0; text-align: left; white-space: normal; }
    .txn-table td:empty { display: none; }
    .txn-date { grid-column: 1; grid-row: 1; font-size: 12.5px; color: var(--text-muted); }
    .txn-time { grid-column: 2; grid-row: 1; font-size: 12.5px; color: var(--text-muted); }
    .txn-type { grid-column: 4; grid-row: 1; justify-self: end; font-size: 12px; font-weight: 700; color: var(--accent); }
    .txn-desc { grid-column: 1 / 4; grid-row: 2; font-weight: 600; overflow-wrap: anywhere; }
    .txn-amount { grid-column: 4; grid-row: 2; justify-self: end; font-size: 15px; font-weight: 700; }
    .txn-balance { grid-column: 1 / 4; grid-row: 3; font-size: 12.5px; color: var(--text-muted); }
    .txn-balance::before { content: "잔액 "; }
    .txn-branch { grid-column: 4; grid-row: 3; justify-self: end; font-size: 12.5px; color: var(--text-muted); }
    /* 이체결과 카드 — 적요 자리에 입금은행명, 아랫줄에 입금계좌번호 ··· 수수료. */
    .txn-account { grid-column: 1 / 4; grid-row: 3; font-size: 12.5px; color: var(--text-muted); }
    .txn-fee { grid-column: 4; grid-row: 3; justify-self: end; font-size: 12.5px; color: var(--text-muted); }
    .txn-fee::before { content: "수수료 "; }

    /* 카드 승인·매입내역 카드 — 윗줄 일자·시간 ··· 카드번호 / 가운데 가맹점 ··· 금액 / 아랫줄 승인번호 ··· 원화승인금액. */
    .txn-card { grid-column: 4; grid-row: 1; justify-self: end; font-size: 12.5px; color: var(--text-muted); }
    .txn-approval { grid-column: 1 / 4; grid-row: 3; font-size: 12.5px; color: var(--text-muted); }
    .txn-approval::before { content: "승인 "; }
    .txn-krw { grid-column: 4; grid-row: 3; justify-self: end; font-size: 12.5px; color: var(--text-muted); }
    .txn-krw::before { content: "원화 "; }

    /* 카드 청구서 카드 — 청구년월 ··· 총결제금액, 그 아래 청구내역 보기 버튼. 펼친 명세는 카드 아래에 한 단 들여 붙인다. */
    .bill-month { grid-column: 1 / 4; grid-row: 1; font-weight: 600; }
    .bill-amount { grid-column: 4; grid-row: 1; justify-self: end; font-size: 15px; font-weight: 700; }
    .bill-action { grid-column: 1 / -1; grid-row: 2; justify-self: end; margin-top: 4px; }
    .txn-table tbody tr.card-detail-row { display: block; padding: 0; margin: 18px 0 8px 12px; /* 위 카드의 아래 여백(8px)과 겹쳐 합쳐지므로 그보다 크게 */ background: transparent; border: 0; }
    .card-detail-row .txn-table tbody tr { background: var(--surface-2); }

    /* 범용 모바일 카드 표(.card-table) — 자격증명 계좌/카드 목록·실행 이력 등. 셀 역할 클래스로 배치한다:
       ct-title(왼쪽 굵은 제목)·ct-badge(오른쪽 상태 배지)는 윗줄, 나머지는 DOM 순서대로 아래에 쌓이고
       ct-wide는 한 줄 전체, ct-sub는 흐린 보조 글자, ct-labeled는 data-label을 앞에 붙이며,
       ct-actions는 버튼 줄(줄바꿈 허용). 열 순서를 바꾸지 않고 order로 제목·배지만 앞으로 당긴다. */
    .card-table tbody tr { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
    .card-table tbody tr td { order: 3; grid-column: 1; }
    .card-table tbody tr td.ct-title { order: 1; grid-column: 1; font-weight: 700; font-size: 14.5px; overflow-wrap: anywhere; }
    .card-table tbody tr td.ct-badge { order: 2; grid-column: 2; justify-self: end; }
    .card-table tbody tr td.ct-wide, .card-table tbody tr td.ct-actions { grid-column: 1 / -1; }
    .card-table tbody tr td.ct-sub { font-size: 12.5px; color: var(--text-muted); }
    .card-table tbody tr td.ct-wrap { overflow-wrap: anywhere; font-size: 12.5px; }
    .card-table tbody tr td.ct-labeled { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 12.5px; }
    .card-table tbody tr td.ct-labeled::before { content: attr(data-label); color: var(--text-muted); min-width: 4.8em; }
    .card-table tbody tr td.ct-hide { display: none; } /* 카드에선 생략하는 열(표에서만 보임) */
    .card-table tbody tr td.ct-mobile-only { display: block; } /* 표에선 숨기고 카드에서만 보이는 합친 값 */
    /* 합친 값(계좌구분·통화)이 있으면 자동 스케줄 배지를 같은 줄 오른쪽에 둔다. */
    .card-table tbody tr td.ct-mobile-only ~ td.ct-auto { grid-column: 2; justify-self: end; }
    .card-table tbody tr td.ct-mobile-only ~ td.ct-auto::before { min-width: 0; }
    .card-table tbody tr td .hint { margin: 0; }
    /* 값이 길어 줄바꿈되는 칸(필요 필드·오류 메시지)은 라벨 바로 옆에서 시작해 이어서 흐르게 한다. */
    .card-table tbody tr td.ct-labeled.ct-wrap { display: block; }
    .card-table tbody tr td.ct-labeled.ct-wrap::before { display: inline-block; margin-right: 6px; }
    .card-table tbody tr td.ct-labeled .truncate-cell { max-width: none; white-space: normal; }
    .card-table tbody tr td:empty { display: none; }
    .card-table tbody tr td.ct-actions { order: 9; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }

    /* 자격증명 목록 — 모바일은 카드로만 보여주므로 표/카드 전환 탭을 숨긴다. */
    .view-tabbar { display: none; }
}

@media (max-width: 480px) {
    .topbar-brand-name, .topbar-version { display: none; }
}
