/* ─────────────────────────────────────────────────────────────
   UFaceOK 디자인 시스템 — 블루·네이비 B2B SaaS. 기본 글자 15px(가독성), 반응형.
   ───────────────────────────────────────────────────────────── */
/* 파일 구성(위 → 아래):
   1) 색·크기 변수(:root)와 기본 요소 스타일
   2) 앱 셸(MainLayout·Sidebar·Topbar) → 페이지 헤더(PageHeader) → 카드·그리드·StatCard·kv 목록·split 2단 배치
   3) 버튼·입력·배지·알림 → 표(.tbl) → 트리(Sites) → 상태 표시(StateView) → 차트(BarChart·DonutChart)
   4) 모달·토스트 → 인증 화면(AuthLayout·Login·Signup) → Blazor 오류 바 → 반응형(@media)
   5) 목록 공통(필터·페이저) → MatchPicker → 상세/칩/공지 → 탭·얼굴등록·공개 페이지 → 약관·사용설명서·사업자 정보
   6) 뒤에 덧붙인 보정 규칙들(표 행 높이, 필터 줄 정렬 등) → 모바일 전용 화면 → 캡처 방지 → 기타 개별 화면 보정
   ※ 같은 선택자가 뒤에서 여러 번 다시 정의된 곳이 있다(특히 .tbl td 패딩) — CSS 는 나중 규칙이 이기므로 수정 시 파일 끝쪽 값을 확인할 것. */
/* ── 디자인 토큰: 색상(네이비·파랑·상태색), 모서리, 그림자, 사이드바·상단바 크기, 글꼴 ── */
:root {
  --navy: #0f2a4a; --navy-700: #163a63; --primary: #1e5eff; --primary-600: #1a4fd6; --primary-50: #eaf0ff;
  --bg: #f3f5f9; --card: #ffffff; --border: #e2e7ef; --border-strong: #c9d2df;
  --text: #1b2433; --muted: #66748a; --ok: #12b886; --ok-50: #e6f8f1; --warn: #f08c00; --warn-50: #fff4e1;
  --danger: #e03131; --danger-50: #fdecec; --info: #1c7ed6; --info-50: #e7f2fc;
  --radius: 12px; --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .08);
  --sidebar-w: 256px; --sidebar-w-collapsed: 72px; --topbar-h: 60px; --font: "Pretendard Variable", Pretendard, -apple-system, "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", Roboto, sans-serif;
}
/* ── 기본 요소·공용 유틸리티(.muted .hint .mt .row .gap .grow .num) ── */
* { box-sizing: border-box; }
html { font-size: 15px; }
body { margin: 0; font-family: var(--font); color: var(--text); background: var(--bg); line-height: 1.5; -webkit-font-smoothing: antialiased; word-break: keep-all; overflow-wrap: break-word; }
a { color: var(--primary); text-decoration: none; } a:hover { text-decoration: underline; }
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -.01em; }
code { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: .92em; background: #f0f3f8; padding: 1px 6px; border-radius: 6px; }
.muted { color: var(--muted); } .hint { color: var(--muted); font-size: .9rem; display: flex; gap: 6px; align-items: flex-start; }
.mt { margin-top: 12px; } .row { display: flex; align-items: center; } .gap { gap: 10px; } .grow { flex: 1; } .num { text-align: right; }
.ico { flex: 0 0 auto; vertical-align: -3px; }
:focus-visible { outline: 3px solid rgba(30, 94, 255, .35); outline-offset: 2px; border-radius: 6px; }
h1:focus, h1:focus-visible { outline: none; } /* FocusOnNavigate 가 페이지 이동마다 h1 에 포커스를 주므로 링을 숨긴다 */

/* ── 앱 셸 ── */
/* MainLayout(.shell 2열 그리드: 사이드바 | 본문), Sidebar.razor(.sidebar·.nav-item), 접기 버튼(.sidebar-collapse-btn),
   Topbar.razor(.topbar·사이트 선택·로그인 타이머·사용자 칩), 본문 영역(.content) */
.shell { --cur-sidebar-w: var(--sidebar-w); display: grid; grid-template-columns: var(--cur-sidebar-w) 1fr; min-height: 100vh; transition: grid-template-columns .18s; }
.shell.collapsed { --cur-sidebar-w: var(--sidebar-w-collapsed); }
.sidebar { background: var(--navy); color: #d8e2f2; display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; overflow-y: auto; overflow-x: hidden; width: var(--sidebar-w); transition: width .18s; }
.sidebar.collapsed { width: var(--sidebar-w-collapsed); }
.sidebar-brand { display: flex; align-items: center; gap: 10px; padding: 18px 18px 14px; }
.brand-name { font-weight: 800; color: #fff; font-size: 1.1rem; letter-spacing: .01em; white-space: nowrap; } .brand-sub { font-size: .8rem; color: #9fb3d1; white-space: nowrap; }
.brand-logo-full { display: block; height: 38px; width: auto; filter: brightness(0) invert(1); }
button.nav-toggle { display: none; }
button.sidebar-collapse-btn {
  position: fixed; top: 74px; left: var(--cur-sidebar-w); transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%; background: #fff; border: 1px solid var(--border-strong);
  display: flex; align-items: center; justify-content: center; color: var(--muted); box-shadow: var(--shadow);
  z-index: 30; padding: 0; cursor: pointer; transition: left .18s;
}
button.sidebar-collapse-btn:hover { color: var(--text); background: var(--bg); }
.sidebar-tenant { margin: 0 14px 10px; padding: 10px 12px; background: rgba(255, 255, 255, .07); border-radius: 10px; }
.tenant-name { color: #fff; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .tenant-role { font-size: .8rem; color: #a9bbd8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-nav { flex: 1; padding: 16px 10px 4px; }
.nav-section { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: #7f95b8; padding: 7px 10px 3px; white-space: nowrap; overflow: hidden; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 4px 12px; line-height: 1.45; border-radius: 9px; color: #d8e2f2; font-weight: 500; text-decoration: none !important; white-space: nowrap; overflow: hidden; }
.nav-item:hover { background: rgba(255, 255, 255, .08); color: #fff; }
.nav-item.active { background: var(--primary); color: #fff; box-shadow: 0 4px 12px rgba(30, 94, 255, .35); }
/* 메뉴 오른쪽 끝의 건수 배지(출장 출퇴근 신청 승인 대기) — Sidebar.razor */
.nav-item .nav-badge { margin-left: auto; min-width: 20px; padding: 0 6px; border-radius: 10px; background: #e5484d; color: #fff; font-size: .72rem; font-weight: 700; line-height: 20px; text-align: center; }
.nav-btn { width: 100%; background: none; border: 0; font: inherit; cursor: pointer; }
.sidebar-foot { padding: 10px 10px 14px; border-top: 1px solid rgba(255, 255, 255, .08); } .version { font-size: .75rem; color: #7f95b8; padding: 6px 12px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 접힘 상태: 아이콘만 남기고 텍스트를 숨긴다(레이아웃은 유지해 다시 펼 때 깜빡이지 않게). */
.sidebar.collapsed .brand-sub, .sidebar.collapsed .sidebar-tenant, .sidebar.collapsed .nav-section, .sidebar.collapsed .version,
.sidebar.collapsed .brand-name, .sidebar.collapsed .brand-logo-full, .sidebar.collapsed .nav-item span, .sidebar.collapsed .nav-btn span { display: none; }
.sidebar.collapsed .sidebar-brand { justify-content: center; padding: 18px 0 14px; }
.sidebar.collapsed .nav-item, .sidebar.collapsed .nav-btn { justify-content: center; padding: 9px; }
/* 본문 열 + 상단바(Topbar.razor) */
.main { min-width: 0; display: flex; flex-direction: column; }
.topbar { height: var(--topbar-h); display: flex; align-items: center; gap: 14px; padding: 0 22px; background: var(--card); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 20; }
.topbar-scope { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.scope-label { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-size: .9rem; } .scope-value { font-weight: 700; } .scope-sep { color: var(--border-strong); }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.user-chip { display: flex; align-items: center; gap: 8px; } .user-name { font-weight: 600; }
.login-timer { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: .9rem; }
.login-timer-value { font-family: ui-monospace, Consolas, monospace; font-weight: 700; color: var(--text); min-width: 3.2em; }
.login-timer.disabled .login-timer-value { color: var(--muted); text-decoration: line-through; }
.login-timer-label { white-space: nowrap; }
.avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--primary-50); color: var(--primary-600); display: grid; place-items: center; font-weight: 800; }
.content { padding: 22px; max-width: 1400px; width: 100%; }
.backdrop { display: none; }

/* ── 페이지 헤더 ── */
/* Shared/PageHeader.razor: 제목(.page-title)·부제(.page-sub, \n 줄바꿈 유지)·오른쪽 버튼 영역(.page-actions) */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.page-title { font-size: 1.45rem; } .page-sub { margin: 4px 0 0; color: var(--muted); white-space: pre-line; } .page-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* ── 카드·그리드 ── */
/* 모든 화면의 흰 카드(.card), 카드 머리글(.card-head), 열 그리드(.grid.cols-*), Shared/StatCard.razor(.stat-*·.tone-*),
   키-값 목록(.kv, 상세 정보), 대시보드 바로가기(.quick), 좌우 2단 배치(.split + 화면별 비율 변형) */
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px; margin-bottom: 18px; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.card-head h3 { font-size: 1.05rem; display: flex; align-items: center; gap: 8px; } .card-head h3 .ico { color: var(--primary); }
.grid { display: grid; gap: 16px; margin-bottom: 18px; }
.grid.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } .grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .grid.cols-3-2 { grid-template-columns: 3fr 2fr; } .grid .card { margin-bottom: 0; }
.stat-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 16px 18px; display: flex; gap: 14px; align-items: center; }
.stat-card.clickable { cursor: pointer; transition: transform .12s, box-shadow .12s; } .stat-card.clickable:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(16, 24, 40, .1); }
.stat-icon { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; flex: 0 0 auto; }
.tone-primary { background: var(--primary-50); color: var(--primary-600); } .tone-ok { background: var(--ok-50); color: var(--ok); } .tone-warn { background: var(--warn-50); color: var(--warn); }
.tone-danger { background: var(--danger-50); color: var(--danger); } .tone-info { background: var(--info-50); color: var(--info); } .tone-muted { background: #eef1f6; color: var(--muted); }
.stat-label { color: var(--muted); font-size: .9rem; font-weight: 700; } .stat-value { font-size: 1.7rem; font-weight: 800; line-height: 1.15; } .stat-unit { font-size: .95rem; font-weight: 600; color: var(--muted); margin-left: 4px; } .stat-sub { font-size: .85rem; color: var(--muted); margin-top: 2px; white-space: pre-line; }
.kv { display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px; margin: 0; } .kv dt { color: var(--muted); font-weight: 700; } .kv dd { margin: 0; }
.kv dt, .kv dd { padding-bottom: 10px; border-bottom: 1px solid var(--border); } .kv dt:nth-last-of-type(1), .kv dd:nth-last-of-type(1) { border-bottom: none; padding-bottom: 0; }
.kv-roomy { gap: 0; } .kv-roomy dt, .kv-roomy dd { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-height: 46px; padding: 8px 0; } .kv-roomy dd { padding-left: 12px; } .kv-roomy dt:nth-last-of-type(1), .kv-roomy dd:nth-last-of-type(1) { padding-bottom: 8px; } /* 이벤트 상세: 행 높이·세로 정렬 통일, 밑줄 끊김 없음 */
.quick-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.quick { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 8px; border: 1px solid var(--border); border-radius: 10px; color: var(--text); font-weight: 600; font-size: .92rem; text-decoration: none !important; }
.quick:hover { border-color: var(--primary); color: var(--primary-600); background: var(--primary-50); } .quick .ico { color: var(--primary); }
.split { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 18px; align-items: start; }
/* 설치 위치 매칭: 왼쪽 "새 매칭" 폭을 줄이고 오른쪽 "매칭된 단말기" 목록에 더 내준다. */
.split-match { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
.split-settings { grid-template-columns: minmax(0, .9fr) minmax(0, 1.3fr); }
.split-rotation { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); }
.split-rules { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); } /* 근무 규칙·근태 집계 단말기 두 표 모두 가로 스크롤 없이 */
table.tbl.att-dev-table th, table.tbl.att-dev-table td, table.tbl.rules-table th, table.tbl.rules-table td { white-space: normal; } /* 좁은 폭에서는 긴 내용 줄바꿈 */
table.tbl.att-dev-table th, table.tbl.att-dev-table td { padding-left: 6px; padding-right: 6px; } /* 좁은 화면(1400px)에서도 근태 집계 단말기 표가 가로 스크롤 없이 */
.split-list { padding: 0; overflow: hidden; }
/* 두 칼럼의 하단을 맞출 때: split-stretch 는 두 칼럼을 같은 높이로 늘리고, 칼럼 안의 card-fill 이 그 높이를 채운다. */
.split-stretch { align-items: stretch; }
.split-fill { display: flex; flex-direction: column; min-height: 0; }
.split-fill .card-fill { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.split-fill .state-empty { flex: 1; }
.split-fill > form { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.split-fill > form > .card { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.split-fill > form > .card > .card-cols { flex: 1; min-height: 0; }
/* 기타 카드 내부 보조: 2열 구분(.card-cols), 소제목, 비밀번호 눈 버튼 자리(.input-eye), 진행 막대(.meter — SendProgressBar·요금 예산),
   코드 블록, 카드 채움 본문(.card-fill-body — MatchPicker 를 담는 영역) */
.gap-half { margin-bottom: 9px; }
.card-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 14px; padding-top: 16px; border-top: 1px solid var(--border); position: relative; }
.card-cols::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: var(--border); }
.sub-head { font-size: .95rem; font-weight: 700; display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.btn-save-preset { padding: 14px 22px; justify-content: center; width: 100%; margin-top: 14px; }
.row-nowrap { display: flex; gap: 10px; align-items: center; flex-wrap: nowrap; }
.row-nowrap .select { min-width: 0; flex: 1 1 auto; }
.row-nowrap .btn { flex: none; white-space: nowrap; }
.input-eye { position: relative; }
.input-eye .input { padding-right: 38px; }
.input-eye .eye-btn { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); }
.card-fill-body { flex: 1; min-height: 0; padding: 14px 16px; display: flex; align-items: flex-start; }
.meter { position: relative; height: 8px; border-radius: 999px; background: var(--border); overflow: hidden; }
.meter-fill { height: 100%; border-radius: 999px; background: var(--primary); transition: width .3s; }
.meter-fill.warn { background: var(--warn); }
.meter-fill.danger { background: var(--danger); }
.code-block { background: #f0f3f8; border-radius: 10px; padding: 12px 14px; overflow-x: auto; margin: 8px 0; }
.code-block code { background: none; padding: 0; white-space: pre; }
.card-fill-body .mp-widget { flex: 1; min-width: 0; }
.card-fill-body .table-wrap { flex: 1; min-width: 0; }

/* ── 버튼·입력 ── */
/* 버튼(.btn + primary/danger/ghost/sm/lg/block, 소셜 로그인 kakao/naver), 아이콘 버튼(.icon-btn), 입력·선택(.input .select),
   폼 배치(.form .field), 체크박스(.check), 토글 스위치(.switch), 배지(.badge.*), 알림 상자(.alert-*) */
.btn { display: inline-flex; align-items: center; gap: 7px; padding: 9px 15px; border-radius: 9px; border: 1px solid var(--border-strong); background: var(--card); color: var(--text); font: inherit; font-weight: 600; cursor: pointer; text-decoration: none !important; line-height: 1.2; transition: background .12s, border-color .12s; }
.btn:hover { background: #f6f8fc; } .btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; } .btn-primary:hover { background: var(--primary-600); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; } .btn-danger:hover { background: #c92a2a; }
.btn-ghost { background: transparent; } .btn-ghost.danger { color: var(--danger); } .btn-sm { padding: 6px 10px; font-size: .9rem; } .btn-lg { padding: 12px 20px; font-size: 1.02rem; } .btn-block { width: 100%; justify-content: center; }
.btn-kakao { background: #fee500; border-color: #fee500; color: #191919; } .btn-naver { background: #03c75a; border-color: #03c75a; color: #fff; }
.icon-btn { background: none; border: 0; padding: 6px; border-radius: 8px; color: var(--muted); cursor: pointer; display: inline-flex; } .icon-btn:hover { background: #eef1f6; color: var(--text); } .icon-btn.danger:hover { color: var(--danger); background: var(--danger-50); }
.input, .select { width: 100%; font: inherit; padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 9px; background: #fff; color: var(--text); }
.input:focus, .select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(30, 94, 255, .15); outline: none; }
.select { appearance: auto; } .select-sm { width: auto; padding: 6px 30px 6px 10px; font-size: .95rem; }
.input-code { font-size: 1.5rem; letter-spacing: .4em; text-align: center; font-family: ui-monospace, monospace; }
textarea.input { resize: vertical; }
.form { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 6px; } .field > span { font-weight: 600; font-size: .95rem; } .field em { color: var(--danger); font-style: normal; }
/* 라벨 안의 괄호 힌트는 항상 자기 줄로 통째로 내려간다 — 글자 단위로 어색하게 잘려서 줄바꿈되는 것을 막는다. */
.field > span > .muted { display: block; font-weight: 400; }
/* 같은 행의 필드들이 라벨 힌트 길이(한 줄/두 줄)가 달라도 입력창끼리 아래로 나란히 맞춰지도록. */
.row.align-end { align-items: flex-end; } .row.align-end .field { justify-content: flex-end; }
.check { display: flex; align-items: center; gap: 8px; cursor: pointer; } .check input { width: 18px; height: 18px; accent-color: var(--primary); } .check.big { font-weight: 700; font-size: 1.05rem; }
/* iOS 스타일 on/off 토글 스위치. */
.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; font-weight: 600; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track { flex: none; width: 40px; height: 22px; background: var(--border-strong); border-radius: 999px; position: relative; transition: background .15s; }
.switch .track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; background: #fff; border-radius: 50%; transition: transform .15s; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); }
.switch input:checked + .track { background: var(--primary); }
.switch input:checked + .track::after { transform: translateX(18px); }
.switch input:focus-visible + .track { outline: 3px solid rgba(30, 94, 255, .35); outline-offset: 2px; }
.link { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; }
.badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border-radius: 999px; font-size: .8rem; font-weight: 700; line-height: 1.6; }
.badge.ok { background: var(--ok-50); color: #0b8a63; } .badge.warn { background: var(--warn-50); color: #b86a00; } .badge.danger { background: var(--danger-50); color: #b42323; }
.badge.info { background: var(--info-50); color: #135e9f; } .badge.muted { background: #eef1f6; color: var(--muted); }
/* 근태 판정 배지(2026-09-30, 2판) — 전용 클래스라 다른 화면의 .badge.ok/warn/... 은 건드리지 않는다.
   1판은 연한 파스텔이었는데 표에서 전혀 갈리지 않았다. 손봐야 하는 상태(결근·조퇴·지각)는 **채운 색 + 흰 글씨**로
   확실히 튀게 하고, 쉬는 날·판단 전은 테두리만 있는 연한 배지로 눌러 둔다. */
.badge[class*="v-"] { border: 1px solid transparent; }
.badge.v-normal  { background: #15803d; color: #fff; }                        /* 정상 — 초록 채움 */
.badge.v-late    { background: #d97706; color: #fff; }                        /* 지각 — 호박 채움 */
.badge.v-early   { background: #ea580c; color: #fff; }                        /* 조퇴 — 주황 채움 */
.badge.v-both    { background: #9a3412; color: #fff; }                        /* 지각조퇴 — 진한 주황 */
.badge.v-unrec   { background: #7c3aed; color: #fff; }                        /* 미기록(퇴근 안 찍음) — 보라 채움 */
.badge.v-absent  { background: #dc2626; color: #fff; }                        /* 결근 — 빨강 채움 */
.badge.v-pending { background: #4338ca; color: #fff; }                        /* 미확정 — 남색 채움 */
.badge.v-await   { background: #fff; color: #475569; border-color: #94a3b8; }  /* 미출근 — 흰 바탕 + 회색 테두리 */
.badge.v-offduty { background: #ccfbf1; color: #0f766e; border-color: #5eead4; }/* 비번 — 청록 연함 + 테두리 */
.badge.v-leave   { background: #1d4ed8; color: #fff; }                        /* 휴가·출장·외근·휴일근무 — 파랑 채움 */
.badge.v-rest    { background: #f1f5f9; color: #94a3b8; border-color: #e2e8f0; font-weight: 600; } /* 휴일·휴무 — 가장 연하게 */
.badge.v-none    { background: #fff; color: #cbd5e1; border-color: #e2e8f0; font-weight: 600; }    /* 대상 아님 */

.alert { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 9px; font-size: .95rem; }
.alert-danger { background: var(--danger-50); color: #b42323; } .alert-ok { background: var(--ok-50); color: #0b8a63; } .alert-info { background: var(--info-50); color: #135e9f; }
.alert-warn { background: var(--warn-50, #fff7e6); color: #8a5a00; }
/* 회원가입 인증코드 남은 시간(2026-09-29). 만료되면 붉은색으로 바꿔 재발송을 유도한다 */
.code-timer { display: flex; align-items: center; gap: 6px; margin: 2px 0 10px; font-size: .95rem; color: var(--muted); }
.code-timer b { color: var(--text); font-variant-numeric: tabular-nums; }
.code-timer.expired, .code-timer.expired b { color: #b42323; }
/* 근무일이 아닌데 인증 기록이 있는 줄 — 눈에 띄되 오류(빨강)로 읽히지 않게 노랑 계열로 둔다(2026-09-28) */
/* 확정 전 값(오늘 근무 종료 전의 퇴근 시각·근무시간) — 엷게 보여 "아직 확정이 아니다"를 알린다(2026-09-30).
   지우거나 감추지 않는 이유: 관리자가 마지막 인증 시각 자체는 봐야 하기 때문이다. */
.pending-time { color: var(--muted, #8a94a6); opacity: .65; font-style: italic; }

.tbl tbody tr.offday-worked { background: var(--warn-50, #fff7e6); box-shadow: inset 3px 0 0 var(--warn, #f0a500); }
.tbl.selectable tbody tr.offday-worked:hover:not(.active) { background: #fdeec9; }
.offday-legend { background: var(--warn-50, #fff7e6); box-shadow: inset 2px 0 0 var(--warn, #f0a500); padding: 0 6px; border-radius: 4px; }
.alert .code { font-family: ui-monospace, monospace; font-size: 1.2rem; letter-spacing: .2em; }

/* ── 표 ── */
/* 목록 표(.tbl): 가로 스크롤 감싸개(.table-wrap), 행 클릭 가능(.selectable), 선택 행(.active), 숫자 오른쪽 정렬(.num),
   요금 사용량 표 가운데 구분선(.split-mid). 좁은 화면 카드형 변환은 아래 반응형(.tbl.responsive)에서 */
.table-wrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: .95rem; }
.tbl th { text-align: left; font-weight: 700; color: var(--muted); font-size: .85rem; padding: 10px 12px; border-bottom: 1px solid var(--border); background: #fafbfd; white-space: nowrap; }
.tbl td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; } .tbl tbody tr:last-child td { border-bottom: 0; }
.tbl.selectable tbody tr { cursor: pointer; } .tbl.selectable tbody tr:hover:not(.active) { background: #f6f8fc; } .tbl tbody tr.active { background: var(--primary-50); } .tbl tbody tr.active:hover { background: var(--primary-100, #dbe6fb); }
.tbl th.num, .tbl td.num { text-align: right; }
.tbl.split-mid td:nth-child(3) { border-left: 1px solid var(--border); padding-left: 16px; }

/* ── 트리 ── */
/* 사이트 관리(Sites.razor)의 건물 > 설치 위치 트리, 행에 마우스를 올리면 편집 버튼(.tree-actions)이 진해진다 */
.tree, .tree ul { list-style: none; margin: 0; padding: 0; } .tree > li { border: 1px solid var(--border); border-radius: 10px; padding: 5px 8px; margin-bottom: 6px; }
.tree ul { margin: 2px 0 0 20px; border-left: 2px solid var(--border); padding-left: 8px; }
.tree-row { display: flex; align-items: center; gap: 8px; padding: 2px 4px; border-radius: 8px; } .tree-row:hover { background: #f6f8fc; }
.tree-row .ico { color: var(--primary); } .tree-actions { margin-left: auto; display: inline-flex; gap: 2px; opacity: .55; } .tree-row:hover .tree-actions { opacity: 1; } .tree-empty { padding: 4px; font-size: .9rem; }
.tree-row.selectable { cursor: pointer; } .tree-row.active { background: var(--primary-50); color: var(--primary-600); font-weight: 700; } .tree-row.active:hover { background: var(--primary-50); }

/* ── 상태 ── */
/* Shared/StateView.razor·Routes.razor 의 로딩/빈 목록/오류/권한 없음 안내(.state-*), 스피너, ComingSoon.razor */
.state { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; padding: 40px 20px; color: var(--muted); }
.state.compact { padding: 22px; } .state.tall { min-height: 60vh; } .state-title { font-weight: 700; font-size: 1.1rem; color: var(--text); }
.state-error .ico { color: var(--danger); } .state-forbidden .ico { color: var(--warn); } .state-ok .ico { color: var(--ok); } .state-empty .ico { color: var(--border-strong); }
.spinner { width: 28px; height: 28px; border: 3px solid var(--border); border-top-color: var(--primary); border-radius: 50%; animation: spin .8s linear infinite; } .spinner.sm { width: 14px; height: 14px; border-width: 2px; }
@keyframes spin { to { transform: rotate(360deg); } }
.coming-soon .coming-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 12px; } .coming-head .ico { color: var(--primary); }
.feature-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; } .feature-list li { display: flex; gap: 8px; align-items: center; } .feature-list .ico { color: var(--ok); }

/* ── 차트 ── */
/* Shared/BarChart.razor(.bar-chart·.bar-labels) 와 Shared/DonutChart.razor(.donut·.legend) — 대시보드에서 사용 */
.chart-wrap { position: relative; display: flex; flex-direction: column; } .bar-chart { flex: 1; width: 100%; } .bar { fill: var(--primary); opacity: .9; } .bar:hover { opacity: 1; } .grid-line { stroke: var(--border); stroke-width: .3; }
.bar-labels { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; text-align: center; font-size: .8rem; color: var(--muted); } .bar-label { display: flex; flex-direction: column; } .bar-val { font-weight: 700; color: var(--text); }
.chart-empty { position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); }
.donut-wrap { display: flex; align-items: center; justify-content: center; gap: 18px; padding-right: 50px; } .donut { width: 200px; height: 200px; flex: 0 0 auto; }
.donut-total { font-size: 7px; font-weight: 800; text-anchor: middle; fill: var(--text); } .donut-caption { font-size: 3.2px; text-anchor: middle; fill: var(--muted); }
.legend { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; } .legend-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; }

/* ── 모달·토스트 ── */
/* Shared/Modal.razor(.modal-backdrop z-index 50, 크기 .modal-sm/.modal-lg), ConfirmDialog.razor(.confirm-*),
   Shared/Toasts.razor(우하단 .toast-stack z-index 100, 종류별 색 .toast-success/error/warning/info) */
.modal-backdrop { position: fixed; inset: 0; background: rgba(15, 42, 74, .45); display: grid; place-items: center; z-index: 50; padding: 16px; }
.modal { background: var(--card); border-radius: 14px; width: min(640px, 100%); max-height: 92vh; overflow: auto; box-shadow: 0 20px 60px rgba(0, 0, 0, .25); }
.modal-sm { width: min(460px, 100%); } .modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px 8px; } .modal-body { padding: 8px 20px 16px; }
.modal-foot { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 10px; padding: 12px 20px 18px; border-top: 1px solid var(--border); }
.modal-foot .btn { white-space: nowrap; }
.confirm-body { display: flex; gap: 14px; align-items: flex-start; } .confirm-icon { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; flex: 0 0 auto; }
.confirm-icon.danger { background: var(--danger-50); color: var(--danger); } .confirm-icon.warn { background: var(--warn-50); color: var(--warn); }
.toast-stack { position: fixed; right: 18px; bottom: 18px; display: flex; flex-direction: column; gap: 8px; z-index: 100; max-width: min(420px, 90vw); }
.toast { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 10px; background: var(--navy); color: #fff; box-shadow: 0 10px 30px rgba(0, 0, 0, .25); animation: rise .2s ease-out; }
.toast .icon-btn { margin-left: auto; color: #fff; } .toast-success { background: #0b8a63; } .toast-error { background: #c92a2a; } .toast-warning { background: #b86a00; } .toast-info { background: var(--navy); }
@keyframes rise { from { transform: translateY(8px); opacity: 0; } }

/* ── 인증 화면 ── */
/* Layout/AuthLayout.razor(왼쪽 소개 .auth-side | 오른쪽 .auth-main), 로그인·가입 카드(.auth-card), 소셜 구분선,
   Signup.razor 단계 표시(.steps li.active/.done) */
.auth-shell { min-height: 100vh; display: grid; grid-template-columns: 420px 1fr; }
.auth-side { background: linear-gradient(160deg, var(--navy) 0%, #143b6e 60%, #1e5eff 140%); color: #e2ebf8; padding: 40px 36px; display: flex; flex-direction: column; gap: 28px; }
.auth-brand { display: flex; align-items: center; gap: 12px; } .auth-brand .brand-name { font-size: 1.5rem; } .auth-points { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; } .auth-points li { display: flex; gap: 10px; align-items: flex-start; } .auth-points .ico { color: #9ec0ff; margin-top: 3px; }
.auth-foot { margin-top: auto; font-size: .82rem; color: #a9bbd8; }
.auth-main { display: grid; place-items: center; padding: 30px 18px; }
.auth-card { width: min(440px, 100%); background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); padding: 30px 28px; } .auth-card-wide { width: min(620px, 100%); }
.auth-card .form > .field + .field, .auth-card .form > .field:first-of-type { margin-top: 10px; } /* 로그인·가입 입력 라벨 위 여백 */
.auth-title { font-size: 1.5rem; margin-bottom: 16px; } .auth-desc { color: var(--muted); margin: 0 0 18px; }
.auth-divider { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: .85rem; margin: 18px 0 12px; } .auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.social-row { display: grid; gap: 8px; } .auth-links { text-align: center; margin: 18px 0 0; color: var(--muted); }
.steps { list-style: none; padding: 0; margin: 0 0 18px; display: flex; gap: 6px; flex-wrap: wrap; } .steps li { display: flex; align-items: center; gap: 6px; font-size: .85rem; color: var(--muted); padding: 4px 10px; border-radius: 999px; background: #f0f3f8; }
.steps li span { width: 20px; height: 20px; border-radius: 50%; background: var(--border-strong); color: #fff; display: grid; place-items: center; font-size: .75rem; font-weight: 700; }
.steps li.active { background: var(--primary-50); color: var(--primary-600); font-weight: 700; } .steps li.active span { background: var(--primary); } .steps li.done span { background: var(--ok); }

/* ── 오류 UI ── */
/* App.razor 의 #blazor-error-ui: 평소 숨김, 서버 연결 끊김·처리 안 된 오류 때 Blazor 가 표시하는 하단 노란 바 */
#blazor-error-ui { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: #fff3cd; color: #5c4a00; padding: 12px 20px; border-top: 1px solid #f0d78a; z-index: 200; }
#blazor-error-ui .reload { margin-left: 10px; } #blazor-error-ui .dismiss { float: right; cursor: pointer; }

/* App.razor 의 #components-reconnect-modal: 서버 연결이 끊겼을 때의 한국어 안내(평소 숨김).
   Blazor 가 상태에 따라 class 를 붙인다 — show(다시 연결 중) / failed(서버 응답 없음) / rejected(곧 새로고침).
   반투명 배경 위 가운데 카드로 **폰에서도 분명히 보이게** 한다(기본 화면은 영어·작은 글씨로 머리글 뒤에 가려졌다). */
#components-reconnect-modal { display: none; position: fixed; inset: 0; z-index: 1000; background: rgba(15, 23, 42, .45); align-items: center; justify-content: center; padding: 16px; }
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected { display: flex; }
#components-reconnect-modal .rc-card { background: var(--card); border-radius: 16px; padding: 24px 20px; width: 100%; max-width: 340px; text-align: center; box-shadow: 0 10px 30px rgba(0,0,0,.2); }
#components-reconnect-modal .rc-card .spinner { display: inline-block; margin-bottom: 12px; }
#components-reconnect-modal .rc-title { font-weight: 700; font-size: 1.05rem; margin-bottom: 6px; }
#components-reconnect-modal .rc-sub { color: var(--muted); font-size: .9rem; margin-bottom: 14px; }
/* 상태별 문구는 해당 상태일 때만 보인다 */
#components-reconnect-modal .rc-show, #components-reconnect-modal .rc-failed, #components-reconnect-modal .rc-rejected { display: none; }
#components-reconnect-modal.components-reconnect-show .rc-show,
#components-reconnect-modal.components-reconnect-failed .rc-failed,
#components-reconnect-modal.components-reconnect-rejected .rc-rejected { display: block; }

/* ── 반응형 ── */
/* ≤1100px: 4·3열 그리드 → 2열, split 2단 → 1단
   ≤900px : 사이드바가 화면 밖 슬라이드 메뉴로 바뀜(햄버거 .nav-toggle + 어두운 배경 .backdrop), 접힘 상태 해제,
            상단바 일부 숨김, 인증 화면 왼쪽 소개 숨김, 표(.tbl.responsive)는 행마다 "라벨: 값" 카드형(data-label 사용)
   ≤560px : 그리드 1열, 제목·숫자 글자 축소 / 움직임 줄이기 설정 시 애니메이션 제거 */
@media (max-width: 1100px) { .grid.cols-4 { grid-template-columns: repeat(2, 1fr); } .grid.cols-3 { grid-template-columns: repeat(2, 1fr); } .grid.cols-3-2 { grid-template-columns: 1fr; } .split { grid-template-columns: 1fr; } }
@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar, .sidebar.collapsed { position: fixed; left: 0; top: 0; bottom: 0; width: min(300px, 86vw); transform: translateX(-100%); transition: transform .2s; z-index: 60; }
  .sidebar.open { transform: none; }
  .sidebar.collapsed .brand-sub, .sidebar.collapsed .sidebar-tenant, .sidebar.collapsed .nav-section, .sidebar.collapsed .version,
  .sidebar.collapsed .brand-name, .sidebar.collapsed .brand-logo-full, .sidebar.collapsed .nav-item span, .sidebar.collapsed .nav-btn span { display: revert; }
  .sidebar.collapsed .sidebar-brand { justify-content: flex-start; padding: 18px 18px 14px; }
  .sidebar.collapsed .nav-item, .sidebar.collapsed .nav-btn { justify-content: flex-start; padding: 9px 12px; }
  .backdrop.show { display: block; position: fixed; inset: 0; background: rgba(15, 42, 74, .45); z-index: 55; }
  button.nav-toggle { display: inline-flex; position: fixed; top: 12px; left: 12px; z-index: 65; background: var(--navy); color: #fff; border-radius: 8px; padding: 8px; box-shadow: var(--shadow); }
  .nav-toggle:hover { background: var(--navy-700); }
  button.sidebar-collapse-btn { display: none; }
  .topbar { padding: 0 14px 0 54px; } .user-name { display: none; } .scope-value { display: none; } .scope-sep { display: none; } .scope-label:first-child { display: none; }
  .login-timer-label { display: none; }
  .content { padding: 14px; } .auth-shell { grid-template-columns: 1fr; } .auth-side { display: none; } .quick-grid { grid-template-columns: repeat(2, 1fr); } .kv { grid-template-columns: 1fr; }
  .tbl.responsive thead { display: none; } .tbl.responsive tr { display: block; border-bottom: 1px solid var(--border); padding: 8px 4px; }
  .tbl.responsive td { display: flex; justify-content: space-between; gap: 10px; border: 0; padding: 4px 8px; text-align: left !important; }
  .tbl.responsive td::before { content: attr(data-label); color: var(--muted); font-size: .85rem; flex: 0 0 90px; }
  .donut-wrap { flex-direction: column; }
}
@media (max-width: 560px) { .grid.cols-4 { grid-template-columns: 1fr; } .grid.cols-3 { grid-template-columns: 1fr; } html { font-size: 15px; } .page-title { font-size: 1.25rem; } .stat-value { font-size: 1.5rem; } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* ── 목록 화면 공통 (필터·일괄 작업·페이저) ── */
/* 필터 카드(.filters .filter-row), 검색칸(.search — 돋보기 아이콘 겹침), 목록 카드(.list-card), 일괄 작업 바(.bulk-bar),
   목록 툴바(.list-toolbar — PageSizeSelect 자리), 정렬 머리글(.sortable), 메뉴 권한 표(.menu-perm-table), 중지 행(.row-disabled) */
.filters { padding: 12px 16px; }
.filter-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.filter-row .select { width: auto; min-width: 130px; }
.search { position: relative; flex: 1 1 260px; min-width: 200px; }
.search .ico { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.search .input { padding-left: 34px; }
.list-card { padding: 0; overflow: hidden; }
.bulk-bar { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--border); background: #fafbfd; flex-wrap: wrap; }
.bulk-bar .page-size-slot { margin-left: auto; }
.list-toolbar { display: flex; justify-content: flex-end; padding: 10px 14px; border-bottom: 1px solid var(--border); background: #fafbfd; }
.w-check { width: 36px; } .w-check input { width: 17px; height: 17px; accent-color: var(--primary); }
.sortable { cursor: pointer; user-select: none; } .sortable:hover { color: var(--primary-600); }
.menu-perm-table td.center, .menu-perm-table th.center { text-align: center; }
.menu-perm-table td.center input[type=checkbox] { width: 17px; height: 17px; accent-color: var(--primary); }
.menu-perm-table .w-order { width: 64px; white-space: nowrap; }
.menu-perm-table .menu-perm-section-row td { background: #fafbfd; color: var(--muted); font-size: .82rem; font-weight: 700; padding: 6px 12px; }
.icon-btn.xs { padding: 3px; border-radius: 6px; }
.icon-btn.xs:disabled { opacity: .3; cursor: default; }
.icon-btn.xs:disabled:hover { background: none; }
.row-disabled td { color: var(--muted); }

/* 전체/매칭됨 듀얼 리스트 (MatchPicker.razor) */
/* 3열(왼쪽 목록 | 화살표 | 오른쪽 목록), ≤720px 에서는 세로로 쌓임. 드래그 중 항목 .mp-dragging, 놓을 목록 강조 .mp-drop-hover(app.js 가 붙임) */
.mp-widget { min-width: 0; }
.mp-hint { margin: -14px 0 6px; line-height: 1.3; }
.match-picker { display: grid; grid-template-columns: 1fr auto 1fr; gap: 14px; align-items: stretch; }
@media (max-width: 720px) { .match-picker { grid-template-columns: 1fr; } .mp-arrows { flex-direction: row; justify-content: center; } }
.mp-col { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: #fff; min-width: 0; }
.mp-col > *:not(.mp-list) { flex: none; }
.mp-col-head { padding: 10px 14px; font-weight: 700; font-size: .9rem; border-bottom: 1px solid var(--border); background: #fafbfd; }
.mp-col-head .muted { font-weight: 400; }
.mp-search { padding: 8px 10px; border-bottom: 1px solid var(--border); }
.mp-search .input { padding-left: 32px; }
.mp-filter { display: flex; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--border); background: #fafbfd; align-items: center; }
.mp-filter .select { flex: 1; min-width: 0; }
.mp-filter .btn { white-space: nowrap; flex: none; }
.mp-pager { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 8px 10px; border-top: 1px solid var(--border); }
.mp-pager .btn { flex: none; }
.mp-list { flex: 1; min-height: 0; overflow-y: auto; }
.mp-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border); cursor: grab; font-size: .92rem; user-select: none; -webkit-user-drag: element; }
.mp-item:last-child { border-bottom: 0; }
.mp-item:hover { background: #f6f8fc; }
.mp-item:active { cursor: grabbing; }
.mp-item input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--primary); flex: none; }
.mp-item.mp-dragging { opacity: .4; }
/* 한 항목은 한 줄로 보여 준다(2026-09-24 사용자 요청) — 길면 이름 쪽을 줄여서 … 로 자르고, 사번·배지·오른쪽 메모는 줄이지 않는다. */
.mp-item { flex-wrap: nowrap; }
.mp-text { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; min-width: 0; overflow: hidden; }
/* 이름이 먼저 보여야 한다 — 폭이 모자라면 사이트·부서 쪽을 먼저 줄이고, 이름은 최소 4글자는 남긴다. */
.mp-text > b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 4em; }
.mp-text > code, .mp-text > .badge { flex: none; white-space: nowrap; }
.mp-text > .muted { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-text code { font-size: .82rem; color: var(--muted); }
/* 오른쪽 목록 줄 끝 보조 글(예: 단말기 등록 시각) */
.mp-note { margin-left: auto; white-space: nowrap; padding-left: 8px; flex: none; }
/* 잠긴 항목(선택 불가): 흐리게, 일반 화살표 커서 */
.mp-item.mp-locked { opacity: .55; cursor: not-allowed; background: #fafafa; }
.mp-item.mp-locked:hover { background: #fafafa; }
.mp-empty { padding: 24px 12px; text-align: center; font-size: .88rem; }
.mp-drop-hover { background: var(--primary-50); box-shadow: inset 0 0 0 2px var(--primary); }
.mp-arrows { display: flex; flex-direction: column; gap: 8px; justify-content: center; align-self: center; }
.mp-arrow { border: 1px solid var(--border-strong); border-radius: 8px; background: #fff; }
.mp-arrow:disabled { opacity: .4; }
/* 작은 글씨·줄바꿈 유틸 / Shared/Pager.razor(.pager) / 큰 모달·이벤트 상세 모달 / 상세 2단(.detail-grid) / 이력 목록 /
   필드셋(.fs)·선택 칩(.chips .chip.on — 사이트·요일 선택) / 글자색 유틸(.c-*) / 코드 크게(.code-box) / 공지 본문(.notice-body) */
.small { font-size: .82rem; } .wrap { flex-wrap: wrap; }
.pager { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.pager-ctl { display: flex; gap: 4px; align-items: center; } .pager-ctl .btn-sm { min-width: 34px; justify-content: center; }
.modal-lg { width: min(900px, 100%); }
.modal-event { width: min(760px, 100%); } @media (min-width: 901px) { .kv-roomy { grid-template-columns: 84px 1fr; } } /* 이벤트 상세: 창·항목명 칸 폭 축소 */
.detail-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 12px; } .detail-grid h4 { margin: 0 0 8px; font-size: .95rem; } .detail-grid h4 + * { margin-bottom: 14px; }
.detail-grid > *:not(:first-child) { border-left: 1px solid var(--border); padding-left: 16px; }
.detail-grid h4:not(:first-child) { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.stack { display: flex; flex-direction: column; gap: 2px; }
/* 단말기 상세: 왼쪽 첫 행(입력창 있는 "단말기명")만큼 오른쪽 칸을 내려서 "지원 기능" 제목을 왼쪽 "시리얼" 행과 맞춘다. */
.align-second-row { margin-top: 62px; }
/* 왼쪽 칸 내용(예: 얼굴 미리보기)이 고정 최대폭이라 fr 비율로 나누면 빈 공간이 남는 경우 — 왼쪽을 내용 폭만큼만 잡는다. */
.detail-grid-tight { grid-template-columns: minmax(0, 320px) 1fr; }
.plain-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 0; } .plain-list li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 0; border-bottom: 1px solid var(--border); } .plain-list li:last-child { border-bottom: none; padding-bottom: 0; }
.history li { font-size: .9rem; }
.fs { border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px 12px; margin: 0; } .fs legend { font-weight: 700; padding: 0 6px; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border: 1px solid var(--border-strong); border-radius: 999px; cursor: pointer; font-size: .92rem; background: #fff; }
.chip.on { background: var(--primary-50); border-color: var(--primary); color: var(--primary-600); font-weight: 600; }
.chip input { width: 15px; height: 15px; accent-color: var(--primary); }
/* 얼굴등록 화면의 부서 선택 줄 — 부서를 여러 개 체크해 그 부서만 보고 일괄 발송한다(2026-09-21).
   부서가 많아도 한 줄에 몰리지 않게 줄바꿈하고, 칩 사이 간격을 조금 좁혀 한눈에 들어오게 한다. */
.dept-row { flex-wrap: wrap; gap: 6px; margin-top: 8px; align-items: center; }
.dept-row .chip { padding: 4px 10px; font-size: .88rem; }
/* 연결이 끊긴 단말기 칩 — 선택할 수 없음을 회색·커서로 알린다(사용자 수정 창의 출입 가능 단말기). 이미 지정된 것은 .on 과 함께 쓰여 옅은 강조를 유지한다. */
.chip-off { background: var(--bg-soft, #f6f7f9); color: var(--muted); border-style: dashed; cursor: not-allowed; }
.chip-off input { cursor: not-allowed; }
.chip-off.on { background: var(--bg-soft, #f6f7f9); border-color: var(--border-strong); color: var(--muted); }
.c-ok { color: var(--ok); } .c-muted { color: var(--muted); } .c-danger { color: var(--danger); }
.code-box { font-family: ui-monospace, Consolas, monospace; font-size: 2rem; letter-spacing: .3em; text-align: center; padding: 14px; background: var(--primary-50); border-radius: 12px; color: var(--primary-600); font-weight: 800; }
.notice-body { line-height: 1.7; } .notice-body p { margin: 0 0 10px; } .notice-body ul, .notice-body ol { margin: 0 0 10px; padding-left: 22px; } .notice-body img { max-width: 100%; border-radius: 8px; } .notice-body a { color: var(--primary); }
@media (max-width: 900px) { .detail-grid { grid-template-columns: 1fr; } .detail-grid > *:not(:first-child) { border-left: none; padding-left: 0; border-top: 1px solid var(--border); padding-top: 14px; } .align-second-row { margin-top: 14px; } .filter-row .select { min-width: 0; flex: 1 1 45%; } }
.steps-v { margin: 14px 0; padding-left: 22px; display: grid; gap: 6px; } .steps-v li { padding-left: 4px; }
fieldset[disabled] label, fieldset[disabled] .input { opacity: .55; }

/* ── 탭 · 얼굴등록 · 공개 페이지 ── */
/* 화면 상단 탭(.tabs .tab.active — 근태·요금 등), 목록 썸네일(.thumb .ev-thumb), 얼굴 사진 미리보기(.face-preview 4:5),
   사진 격자(.photo-grid), PublicLayout(.public-shell/.public-head/.public-main), 얼굴등록 링크 화면(.enroll, .capture-guide) */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 16px; overflow-x: auto; }
.tab { background: none; border: 0; border-bottom: 3px solid transparent; padding: 10px 14px; font: inherit; font-weight: 600; color: var(--muted); cursor: pointer; display: inline-flex; gap: 6px; align-items: center; white-space: nowrap; }
.tab.active { color: var(--primary-600); border-bottom-color: var(--primary); }
.thumb { width: 36px; height: 36px; border-radius: 50%; background: var(--primary-50); color: var(--primary-600); display: grid; place-items: center; } .thumb.empty { background: #eef1f6; color: var(--muted); }
/* 얼굴 사진 없음(2026-10-06): 빨간 바탕 + 빨간 우는 얼굴 — 얼굴등록 목록에서 사진 없는 사용자를 확실히 구분 */
.thumb.missing { background: var(--danger-50); color: var(--danger); }
/* 모바일 얼굴등록 목록의 같은 표시(이름 첫 글자 동그라미 자리) */
.mobile-avatar.face-ok { background: var(--primary-50); color: var(--primary-600); } .mobile-avatar.face-missing { background: var(--danger-50); color: var(--danger); }
.face-preview { width: 100%; max-width: 320px; aspect-ratio: 3/4; border-radius: 14px; overflow: hidden; background: #eef1f6; display: grid; place-items: center; border: 1px solid var(--border); }
.face-preview.sm { max-width: 160px; }
/* 얼굴등록 창(관리자) 방법 1 보정본 미리보기 — 창 안에서 너무 커지지 않게 가운데 작게 */
.face-preview.admin-preview { max-width: 200px; margin: 10px auto; } .face-preview img { width: 100%; height: 100%; object-fit: contain; display: block; } .face-none { text-align: center; color: var(--muted); }
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.photo-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; padding: 0; cursor: pointer; text-align: left; font: inherit; color: var(--text); }
.photo-card:hover { border-color: var(--primary); } .photo-card img { width: 100%; aspect-ratio: 4/5; object-fit: cover; display: block; background: #eef1f6; } .photo-meta { padding: 8px 10px; font-size: .9rem; }
.public-shell { min-height: 100vh; background: var(--bg); } .public-head { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: var(--navy); } .public-head .brand-name { color: #fff; }
.public-main { padding: 16px; max-width: 520px; margin: 0 auto; }
.enroll { background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 22px 18px; }
.enroll-head { margin-bottom: 14px; } .enroll-head h1 { font-size: 1.35rem; margin: 4px 0; } .enroll-foot { text-align: center; margin-top: 14px; }
/* 얼굴등록 촬영 예시 실루엣(2026-10-06): 폰 화면에서 버튼이 아래로 밀리지 않게 작게(최대 180px) 가운데 둔다 */
.face-sample { text-align: center; } .face-sample img { width: 100%; max-width: 180px; aspect-ratio: 3/4; border-radius: 14px; border: 1px solid var(--border); display: block; margin: 0 auto 4px; } .face-sample p { margin: 0; }
.capture-guide { display: flex; gap: 14px; align-items: center; padding: 12px; background: var(--primary-50); border-radius: 12px; } .capture-guide .ico { color: var(--primary); } .capture-guide ul { margin: 0; padding-left: 18px; }
.enroll .input-code { font-size: 1.6rem; }
/* 얼굴등록 동의 항목: "보기" 링크를 줄 끝(오른쪽)에 맞춘다 — 문구 길이가 달라도 두 줄의 "보기" 위치가 같게.
   체크박스·[필수] 표시·보기 링크는 줄어들지 않게 하고, 긴 문구만 줄바꿈된다. */
.enroll .check > a { margin-left: auto; padding-left: 8px; flex-shrink: 0; white-space: nowrap; }
.enroll .check > input, .enroll .check > b { flex-shrink: 0; }
.ev-thumb { width: 36px; height: 44px; object-fit: cover; border-radius: 6px; background: #eef1f6; display: block; }
pre.raw { background: #0f2a4a; color: #d8e2f2; padding: 12px; border-radius: 10px; font-size: .8rem; max-height: 360px; overflow: auto; white-space: pre-wrap; word-break: break-all; }
.public-main .alert { margin-bottom: 12px; }

/* ── 약관 · 사업자 정보 ── */
/* 이용약관·개인정보 처리방침(.legal), 사용설명서(.manual·.manual-toc 2단 목차·.manual-table·.manual-faq),
   AuthLayout 본문 폭(.auth-main-inner), Shared/BusinessFooter.razor(.biz-foot) */
.legal { background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 28px 26px; line-height: 1.7; }
.legal h1 { font-size: 1.5rem; margin-bottom: 6px; } .legal .lead { color: var(--muted); margin: 0 0 22px; }
.legal section { margin-bottom: 22px; } .legal h2 { font-size: 1.05rem; margin-bottom: 8px; }
.legal ul { margin: 0; padding-left: 20px; display: grid; gap: 4px; } .legal ul.plain { list-style: none; padding: 0; } .legal p { margin: 0 0 6px; }
.legal .tbl { font-size: .9rem; }
.manual section { scroll-margin-top: 80px; } .manual h3 { font-size: .98rem; margin: 16px 0 6px; } .manual ol { margin: 0 0 8px; padding-left: 22px; display: grid; gap: 4px; } .manual ul ul { margin-top: 4px; }
.manual-toc { background: var(--primary-50); border: 1px solid rgba(30, 94, 255, .18); border-radius: 12px; padding: 14px 18px; margin: 0 0 26px; } .manual-toc ol { margin: 8px 0 0; columns: 2; column-gap: 28px; display: block; } .manual-toc li { margin-bottom: 4px; break-inside: avoid; }
@media (max-width: 640px) { .manual-toc ol { columns: 1; } }
.manual-table { width: 100%; border-collapse: collapse; margin: 6px 0 10px; font-size: .9rem; } .manual-table th, .manual-table td { border: 1px solid var(--border); padding: 7px 10px; text-align: left; vertical-align: top; } .manual-table th { background: #f5f7fb; white-space: nowrap; }
.manual-faq dt { font-weight: 700; margin-top: 12px; } .manual-faq dd { margin: 4px 0 0; color: var(--text, inherit); }
.manual .hint { background: #f7f9fc; border-left: 3px solid var(--primary); padding: 8px 12px; border-radius: 6px; margin: 8px 0 10px; }
.public-main:has(.legal) { max-width: 800px; }
/* 사용설명서 화면 그림(2026-10-13): 그림이 읽히도록 설명서만 폭을 넓힌다(약관·처리방침은 800px 그대로).
   .manual-shot = 그림 한 장(누르면 원본), .mid/.small = 대화상자처럼 폭이 좁은 그림, .manual-shot-row = 모바일 화면 3장 나란히. */
.public-main:has(.manual) { max-width: 1040px; }
.manual-shot { margin: 12px 0 18px; }
.manual-shot.mid { max-width: 720px; } .manual-shot.small { max-width: 420px; }
.manual-shot a { display: block; }
.manual-shot img { display: block; width: 100%; height: auto; border: 1px solid var(--border); border-radius: 10px; background: #f3f5f9; box-shadow: 0 2px 10px rgba(15, 23, 42, .06); }
.manual-shot figcaption { margin-top: 6px; font-size: .86rem; line-height: 1.55; color: var(--muted); }
.manual-shot-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; max-width: 720px; }
.manual-shot-row figure { margin: 0; } .manual-shot-row figcaption { text-align: center; }
@media (max-width: 640px) { .manual-shot-row { gap: 8px; } }
/* 인쇄·PDF 저장: 그림이 쪽 사이에서 잘리지 않게 하고, 한 쪽을 넘지 않게 높이를 제한한다. */
@media print { .manual-shot, .manual-shot-row, .manual-shot-row figure { break-inside: avoid; } .manual-shot img { max-height: 235mm; width: auto; max-width: 100%; box-shadow: none; } .manual h3 { break-after: avoid; } }
.public-brand { display: inline-flex; align-items: center; gap: 8px; text-decoration: none !important; }
.auth-main-inner { width: 100%; max-width: 640px; display: flex; flex-direction: column; align-items: center; }
.biz-foot { margin-top: 44px; padding-top: 18px; border-top: 1px solid var(--border); text-align: center; font-size: .78rem; color: var(--muted); line-height: 1.6; } .biz-foot p { margin: 2px 0; } .biz-foot a { color: var(--muted); text-decoration: underline; } .biz-foot .sep { margin: 0 4px; }
.version a { color: #7f95b8; }

/* ── 브랜드 로고 ── */
/* 사이드바는 펼침=전체 로고, 접힘=정사각 아이콘(.brand-icon). 인증 카드 상단 로고(.auth-logo) */
.brand-icon { border-radius: 10px; }
.sidebar:not(.collapsed) .brand-icon { display: none; }
.auth-logo { display: flex; align-items: center; justify-content: center; margin: 34px 0 52px; } .auth-logo img { width: min(260px, 70vw); height: auto; }

/* ── 표 행간 축소 ── */
/* 참고: 이 아래(행간 축소·필터 정렬·행 높이 통일)에서 .tbl td/th 패딩·높이가 여러 번 덮어써진다. 실제 적용값은 가장 마지막 규칙
   (.tbl td { height: 36px; padding: 4px 12px; } .tbl th { padding: 7px 12px; })이다. 썸네일 크기도 마지막 .ev-thumb/.thumb 값이 적용. */
.tbl td { padding: 7px 12px; } .tbl th { padding: 8px 12px; }
.ev-thumb { width: 26px; height: 32px; border-radius: 5px; }
.thumb { width: 28px; height: 28px; }
.tbl td { padding: 4px 10px; line-height: 1.35; } .tbl th { padding: 6px 10px; }
.ev-thumb { width: 22px; height: 26px; border-radius: 4px; }
.thumb { width: 24px; height: 24px; }
.tbl .badge { padding: 1px 7px; line-height: 1.5; }

/* ── 필터 줄 정렬: 라벨 유무와 상관없이 입력칸 아래선을 맞춘다 ── */
/* 목록 화면 필터 카드의 입력·선택·버튼 높이를 42px 로 통일, 날짜·월·시각 입력 높이도 동일하게 */
.filter-row { align-items: flex-end; }
.filter-row .field { gap: 4px; } .filter-row .field > span { line-height: 1.2; }
.filter-row .search, .filter-row > .select, .filter-row .btn, .filter-row .check { align-self: flex-end; }
.filter-row .check { padding-bottom: 10px; } .filter-row .btn-sm { padding-top: 10px; padding-bottom: 10px; }
.filter-row .search .input, .filter-row .field .input, .filter-row .field .select, .filter-row > .select { height: 42px; }
.input[type=date], .input[type=month], .input[type=time] { height: 42px; padding: 6px 12px; line-height: 28px; box-sizing: border-box; }
.filter-row .field { justify-content: flex-end; }
.filter-row .field > span { margin-bottom: 0; }
.tbl td { padding: 6px 10px; line-height: 1.4; } .tbl th { padding: 7px 10px; }
.tbl td { padding: 8px 12px; line-height: 1.45; } .tbl th { padding: 9px 12px; }

/* ── 표 행 높이 통일: 배지·굵은 글씨 유무와 무관하게 같은 높이 ── */
.tbl td { height: 44px; padding: 6px 12px; line-height: 1.4; } .tbl th { padding: 9px 12px; }
.tbl td .badge, .tbl td code, .tbl td .ico { vertical-align: middle; }
.tbl td:first-child, .tbl td b, .tbl td code, .badge { white-space: nowrap; }
.tbl td, .tbl th { white-space: nowrap; }
.tbl td.wrap { white-space: normal; }
@media (max-width: 900px) { .tbl.responsive td { white-space: normal; height: auto; } }
/* 목록 카드 머리글 높이 통일 (좌우 나란한 표의 시작선을 맞춘다) */
.list-card > .card-head { min-height: 58px; flex-wrap: nowrap; align-items: center; margin-bottom: 8px; }
.list-card > .card-head h3 { white-space: nowrap; }
.list-card > .card-head .row { flex-wrap: nowrap; }
@media (max-width: 900px) { .list-card > .card-head { flex-wrap: wrap; min-height: 0; } }
/* 2열 격자 — 같은 줄 카드 높이 통일. colflow 는 왼쪽 열부터 세로로 채운다 */
.grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.grid.cols-2.colflow { grid-template-rows: auto auto; grid-auto-flow: column; }
.grid.cols-2 > .card { height: 100%; }
@media (max-width: 1100px) { .grid.cols-2 { grid-template-columns: 1fr; } .grid.cols-2.colflow { grid-auto-flow: row; grid-template-rows: none; } }
.tbl td { height: 40px; padding: 5px 12px; } .tbl th { padding: 8px 12px; }
.tbl td { height: 36px; padding: 4px 12px; } .tbl th { padding: 7px 12px; }

/* hint/alert: 문장 안의 <b>, <a>, <code> 가 flex 항목으로 쪼개져 빈 공간이 생기던 문제 → 블록 + 인라인 아이콘 */
/* (앞쪽 .hint/.alert 의 display:flex 를 여기서 block 으로 덮어쓴다. 아이콘+span 구조만 파일 끝쪽 :has() 규칙으로 다시 flex) */
.hint, .alert { display: block; line-height: 1.55; margin: 0; }
.mt-lg, .hint.mt-lg { margin-top: 18px; }
.hint > .ico, .alert > .ico { display: inline-block; vertical-align: -3px; margin-right: 6px; }
.alert > .ico { vertical-align: -4px; }
.company .kv { grid-template-columns: 130px 1fr; margin-bottom: 4px; }
.company .field .row .input { min-width: 0; }

/* 계정 페이지 "내 정보" 카드에 비밀번호 변경을 한 카드로 합칠 때 쓰는 구분선/부제목 */
.section-divider { border-top: 1px solid var(--border); margin: 18px 0 18px; }
.section-title { display: flex; align-items: center; gap: 6px; font-size: .95rem; font-weight: 700; color: var(--muted); margin: 4px 0 -4px; }
.section-title .ico { color: var(--primary); }

/* 비밀번호 입력칸 안쪽에 표시/숨김 눈 아이콘을 겹쳐 넣는다(검색창의 돋보기 아이콘과 같은 방식). */
.pw-field { position: relative; }
.pw-field .input { padding-right: 40px; }
.pw-field .pw-toggle { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.pw-field .pw-toggle:hover { color: var(--text); }

/* 사용자 편집 - 임시 출입 제한 규칙 한 줄(요일 칩 + 날짜·시간 + 메모)을 감싸는 작은 카드. */
.schedule-row { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; display: flex; flex-direction: column; gap: 8px; }

/* 라벨+입력칸(.field)과 체크박스(.check)가 한 줄에 같이 있으면, 체크박스가 라벨 텍스트까지 포함한 전체 높이의
   가운데가 아니라 입력칸 쪽에 맞춰 보이도록 그 줄의 아래쪽 기준으로 정렬한다(예: 근무 규칙 이름 + 기본/사용 체크박스). */
.row.gap:has(> .field) > .check { align-self: flex-end; margin-bottom: 10px; }

/* ── 모바일 전용 화면 (mobile/ 폴더, /mobile 등) — Toss·당근마켓류를 참고한 카드+그림자 기반 현대적 모바일 UI ── */
/* 구성: 모바일 셸(최대 560px 가운데 정렬) → 상단바(흐림 배경) → 하단 탭바(.mobile-tabbar, 고정) → 통계 카드 → 목록 행·아바타(8색)
   → 메뉴 목록 → 검색·뒤로가기·빈 상태 → 세그먼트 탭(.mobile-tabs) → 플로팅 추가 버튼(.mobile-fab) → 바텀시트(.sheet) */
:root {
  --m-bg: #f4f5f8; --m-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 3px 14px rgba(16, 24, 40, .06);
  --m-shadow-lg: 0 10px 30px rgba(16, 24, 40, .16); --m-radius: 16px; --m-radius-sm: 12px;
}
.mobile-shell { display: flex; flex-direction: column; min-height: 100vh; background: var(--m-bg); max-width: 560px; margin: 0 auto; position: relative; }
.mobile-topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; justify-content: space-between; height: 56px; padding: 0 16px; background: rgba(255, 255, 255, .92); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); }
.mobile-topbar-title { font-weight: 800; font-size: 1.05rem; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mobile-icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 999px; border: 0; background: transparent; color: var(--muted); cursor: pointer; transition: background .15s, color .15s; }
.mobile-icon-btn:hover { background: var(--primary-50); color: var(--primary); }
.mobile-content { flex: 1; padding: 14px 14px 92px; }
.mobile-tabbar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 0; width: 100%; max-width: 560px; display: flex; gap: 4px; background: rgba(255, 255, 255, .94); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-top: 1px solid var(--border); padding: 8px 10px max(8px, env(safe-area-inset-bottom)); z-index: 40; }
.mobile-tab { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 6px 0; border-radius: 14px; color: var(--muted); font-size: .7rem; font-weight: 700; transition: background .15s, color .15s; }
.mobile-tab.active, .mobile-tab[aria-current] { color: var(--primary-600); background: var(--primary-50); }
.mobile-stack { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mobile-stat-card { background: var(--card); border: 0; border-radius: var(--m-radius); padding: 16px 18px; box-shadow: var(--m-shadow); }
.mobile-stat-label { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: .85rem; font-weight: 700; margin-bottom: 6px; }
.mobile-stat-icon { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 8px; flex: 0 0 auto; }
/* 아이콘 칩이 없는 미니 통계 카드(근태 현황 등)는 숫자 색으로 톤을 준다 */
.mobile-stat-card.tone-ok .mobile-stat-value { color: var(--ok); } .mobile-stat-card.tone-warn .mobile-stat-value { color: var(--warn); }
.mobile-stat-card.tone-danger .mobile-stat-value { color: var(--danger); } .mobile-stat-card.tone-info .mobile-stat-value { color: var(--info); }
.mobile-stat-card.tone-primary .mobile-stat-value { color: var(--primary-600); }
.mobile-stat-value { font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; }
.mobile-stat-unit { font-size: .95rem; font-weight: 500; color: var(--muted); margin-left: 4px; }
.mobile-stat-sub { margin-top: 4px; color: var(--muted); font-size: .85rem; }
.mobile-section-title { margin: 20px 2px 10px; font-weight: 800; color: var(--text); font-size: .92rem; display: flex; align-items: center; justify-content: space-between; }
.mobile-list { display: flex; flex-direction: column; gap: 8px; }
/* 기본은 세로로 쌓는 카드(main 위 · sub 아래) — 아바타 칩이 있는 행만 가로 배치로 전환한다(아바타 + 본문). */
.mobile-list-row { background: var(--card); border: 0; border-radius: var(--m-radius-sm); padding: 12px 14px; box-shadow: var(--m-shadow); transition: transform .1s, box-shadow .1s; }
.mobile-list-row:has(.mobile-avatar) { display: flex; align-items: center; gap: 12px; }
/* 체크리스트 행(매칭 단말기·매칭 인원 등) — 체크박스 + 본문을 한 줄로 배치 */
.mobile-list-row.mobile-checklist-row { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.mobile-list-row.mobile-checklist-row input[type="checkbox"] { flex: 0 0 auto; width: 18px; height: 18px; }
.mobile-list-row.tappable { cursor: pointer; } .mobile-list-row.tappable:active { transform: scale(.98); background: var(--primary-50); }
.mobile-list-main { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.mobile-list-name { font-weight: 700; min-width: 0; }
.mobile-list-sub { margin-top: 3px; color: var(--muted); font-size: .82rem; }
.mobile-list-body { flex: 1; min-width: 0; }
/* 아바타 칩 — 이름 이니셜을 고정 팔레트 색으로. 8색 순환(해시), 리스트 행/상세 헤더에서 재사용 */
.mobile-avatar { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: .95rem; color: #fff; }
.mobile-avatar.lg { width: 56px; height: 56px; font-size: 1.3rem; }
.mobile-avatar.c0 { background: #1e5eff; } .mobile-avatar.c1 { background: #12b886; } .mobile-avatar.c2 { background: #f08c00; }
.mobile-avatar.c3 { background: #e8590c; } .mobile-avatar.c4 { background: #7048e8; } .mobile-avatar.c5 { background: #e64980; }
.mobile-avatar.c6 { background: #1c7ed6; } .mobile-avatar.c7 { background: #099268; }
.mobile-menu-list { display: flex; flex-direction: column; gap: 8px; }
.mobile-menu-item { display: flex; align-items: center; gap: 10px; background: var(--card); border: 0; border-radius: var(--m-radius-sm); padding: 14px 15px; color: var(--text); font-weight: 700; box-shadow: var(--m-shadow); transition: transform .1s; }
.mobile-menu-item:active { transform: scale(.98); }
.mobile-menu-item:hover { text-decoration: none; background: var(--primary-50); }
.mobile-menu-item span { flex: 1; }
.mobile-menu-item .ico:first-child { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 10px; background: var(--primary-50); color: var(--primary); display: inline-flex; align-items: center; justify-content: center; }
.mobile-menu-item .ico:last-child { color: var(--border-strong); }
.mobile-menu-item-alt { color: var(--primary); }
.mobile-search { position: relative; margin-bottom: 12px; }
.mobile-search .ico { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.mobile-search input { width: 100%; padding: 11px 14px 11px 40px; border-radius: 999px; border: 0; background: var(--card); font-size: .95rem; box-shadow: var(--m-shadow); }
.mobile-back { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-weight: 700; font-size: .88rem; margin-bottom: 10px; background: none; border: 0; padding: 0; cursor: pointer; }
.mobile-back:hover { color: var(--primary); }
.mobile-empty { text-align: center; padding: 40px 16px; color: var(--muted); }
.mobile-tabs { display: flex; gap: 4px; margin-bottom: 14px; background: #eceef3; padding: 4px; border-radius: 14px; }
.mobile-tabs button { flex: 1; padding: 8px 0; border-radius: 11px; border: 0; background: transparent; color: var(--muted); font-weight: 700; font-size: .85rem; transition: background .15s, color .15s, box-shadow .15s; }
.mobile-tabs button.active { background: #fff; border-color: transparent; color: var(--primary-600); box-shadow: 0 1px 4px rgba(16, 24, 40, .14); }

/* 플로팅 액션 버튼(FAB) — 화면 우하단, 새 항목 추가 진입점 */
.mobile-fab { position: fixed; right: max(20px, calc(50% - 280px + 20px)); bottom: calc(76px + env(safe-area-inset-bottom)); width: 56px; height: 56px; border-radius: 50%; background: var(--primary); color: #fff; display: flex; align-items: center; justify-content: center; border: 0; box-shadow: 0 8px 20px rgba(30, 94, 255, .4); z-index: 35; cursor: pointer; transition: transform .12s; }
.mobile-fab:active { transform: scale(.94); }

/* 바텀시트 — 추가/수정 폼용, Modal.razor 와 별개(중앙 모달 대신 하단에서 슬라이드업) */
/* z-index 는 .modal-backdrop(ConfirmDialog 등)과 동일하게 맞춘다 — 바텀시트 위에서 뜨는 확인창은 DOM 순서(항상 나중에 렌더)로 위에 쌓인다. */
.sheet-backdrop { position: fixed; inset: 0; background: rgba(15, 23, 42, .45); z-index: 50; display: flex; align-items: flex-end; justify-content: center; }
.sheet { width: 100%; max-width: 560px; background: #fff; border-radius: 20px 20px 0 0; max-height: 90vh; display: flex; flex-direction: column; box-shadow: var(--m-shadow-lg); animation: sheetUp .22s ease-out; }
@keyframes sheetUp { from { transform: translateY(28px); opacity: .3; } to { transform: translateY(0); opacity: 1; } }
.sheet-handle { width: 40px; height: 5px; background: var(--border-strong); border-radius: 3px; margin: 10px auto 2px; flex: 0 0 auto; }
.sheet-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 18px 12px; flex: 0 0 auto; }
.sheet-head h3 { margin: 0; font-size: 1.05rem; }
.sheet-body { padding: 2px 18px 16px; overflow-y: auto; }
.sheet-foot { display: flex; gap: 10px; padding: 12px 18px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); flex: 0 0 auto; }
.sheet-foot .btn { flex: 1; }
/* ── 개별 화면 보정: kv 자동 폭(요금·결제 카드), 좁은 화면 kv-roomy, 사용자 관리 부서 탭 비율, 상단바 사용설명서 버튼 ── */
.kv-auto { grid-template-columns: max-content 1fr; } .kv-auto dt { white-space: nowrap; } /* 항목명이 긴 목록: 항목명 칸을 글자 길이에 맞추고 줄바꿈 금지 */
@media (max-width: 900px) { .kv-roomy dt, .kv-roomy dd { min-height: 0; } .kv-roomy dt { padding: 10px 0 2px; border-bottom: none; } .kv-roomy dd { padding: 0 0 10px; } .kv-roomy dt:nth-last-of-type(1) { padding-bottom: 2px; } .kv-roomy dd:nth-last-of-type(1) { padding-bottom: 4px; } } /* 좁은 화면(항목명·값이 한 줄씩 쌓임): 넓은 행 높이를 적용하지 않음 */
@media (min-width: 1101px) { .split.split-dept { grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); } } /* 사용자 관리 > 부서 탭: 왼쪽(부서 목록) 1/5 줄이고 오른쪽(매칭) 넓힘 */
.manual-btn { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px; background: var(--primary-50); color: var(--primary-600); border: 1px solid rgba(30, 94, 255, .3); font-weight: 700; font-size: .85rem; line-height: 1; white-space: nowrap; text-decoration: none !important; transition: background .15s, color .15s; } /* 상단바 사용설명서 버튼: 물음표 아이콘 + 글자로 누구나 알아보게 */
.manual-btn:hover, .manual-btn:focus-visible { background: var(--primary); color: #fff; border-color: var(--primary); }
@media (max-width: 560px) { .manual-btn { padding: 6px; } .manual-btn span { display: none; } }

/* 이미지 복사·저장 방지 (항상): 끌어다 놓기·길게 눌러 저장(모바일) 차단 */
img { -webkit-user-drag: none; user-drag: none; -webkit-touch-callout: none; }
.face-preview img, .ev-thumb, .photo-compare img { user-select: none; -webkit-user-select: none; }

/* 화면 캡처·복사 방지 (운영관리자 설정 시): 글자 선택 차단, 인쇄 차단, 포커스 잃으면 흐림, 워터마크 */
/* body.cg-on / body.cg-blur 클래스와 .cg-watermark 요소는 app.js ufaceok.captureGuard 가 붙인다(CaptureGuard.razor 설정 기준) */
body.cg-on { -webkit-user-select: none; user-select: none; }
body.cg-on input, body.cg-on textarea, body.cg-on select, body.cg-on [contenteditable="true"] { -webkit-user-select: text; user-select: text; }
body.cg-on.cg-blur .shell, body.cg-on.cg-blur .mobile-shell, body.cg-on.cg-blur .modal-backdrop, body.cg-on.cg-blur .modal, body.cg-on.cg-blur .bottom-sheet { filter: blur(18px); }
.cg-watermark { position: fixed; inset: 0; z-index: 2147483000; pointer-events: none; opacity: .07; background-repeat: repeat; }
@media print { body.cg-on * { visibility: hidden !important; } body.cg-on::after { content: "보안 설정으로 인쇄할 수 없습니다."; visibility: visible; display: block; padding: 40px; font-size: 18px; } }

/* 메뉴 권한: 드래그로 순서 바꾸기 */
/* (행에 data-drag 가 있으면 app.js 의 전역 dragstart/dragover 보조 처리가 함께 동작) */
.menu-perm-table tr[draggable="true"] { cursor: grab; }
.menu-perm-table tr[draggable="true"]:active { cursor: grabbing; }
.menu-perm-table .drag-handle { display: inline-block; width: 14px; margin-right: 6px; color: var(--muted); font-size: 13px; line-height: 1; user-select: none; }
.menu-perm-table tr.dragging { opacity: .45; }
.menu-perm-table tr.drop-target td { box-shadow: inset 0 2px 0 var(--primary); }

/* Alert with icon + text span: wrapped lines start at the text, not under the icon */
.alert:has(> .ico + span) { display: flex; align-items: flex-start; gap: 6px; }
.alert:has(> .ico + span) > .ico { flex: none; margin-top: 3px; vertical-align: 0; }

/* Billing: widen "billing basis" (right) and narrow "invoices by period" (left) so the basis table does not scroll horizontally */
/* 요금·결제(Billing.razor) "월별 청구·결제 내역" 탭: 왼쪽 청구 목록 | 오른쪽 산출 근거 비율 */
@media (min-width: 1101px) {
  .split.split-billing { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
}
.split-billing > .card:last-child table.tbl td:nth-child(2) { white-space: normal; }

/* Hint with icon + text span: wrapped/broken lines start at the text, not under the icon (same as alerts) */
.hint:has(> .ico + span) { display: flex; align-items: flex-start; gap: 6px; }
.hint:has(> .ico + span) > .ico { flex: none; margin-top: 3px; vertical-align: 0; }

/* Terms change notice banner: shown at the top of the content until the account acknowledges it */
/* 약관 개정 안내 배너(Shared/TermsChangeNotice.razor) — 데스크톱·모바일 본문 최상단 */
.terms-notice { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; }
.terms-notice > span { flex: 1 1 auto; }
.terms-notice > .btn { flex: none; margin-left: auto; white-space: nowrap; }
.mobile-content > .terms-notice { margin: 12px 0; }
@media (max-width: 640px) {
  .terms-notice { flex-wrap: wrap; align-items: flex-start; }
  .terms-notice > .btn { margin-left: 0; }
}

/* Time picker (hour:minute selects) — replaces <input type="time">, whose AM/PM column loses the value mid-typing in Korean locale */
/* 시각 입력(Shared/TimeField.razor): 시·분 두 드롭다운을 한 줄로 */
/* 시각 입력(TimeField.razor): [시:분 입력칸][오전/오후 선택] — 2026-10-09 형식 변경. 입력칸은 다섯 글자("09:30")가 들어갈 너비로 고정한다 */
.time-field { display: inline-flex; align-items: center; gap: 6px; }
.time-field > .time-field-hm { width: 4.6em; min-width: 4.6em; flex: 0 0 auto; padding-left: 8px; padding-right: 8px; text-align: center; font-variant-numeric: tabular-nums; }
.time-field > .time-field-hm.invalid { border-color: #e5484d; box-shadow: 0 0 0 3px rgba(229, 72, 77, .15); }
.time-field > .time-field-ap { width: auto; min-width: 70px; flex: 0 0 auto; padding-left: 8px; padding-right: 4px; }
.field > .time-field { margin-top: 2px; }
/* 시각 범위([시작] ~ [종료], AccessModeField.razor): 휴대폰 폭에서도 한 줄에 들어가게 칸을 조금 좁힌다. 그래도 모자라면 종료 칸이 다음 줄로 내려간다 */
.time-range { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.time-range .time-field { gap: 4px; }
.time-range .time-field > .time-field-hm { width: 4.1em; min-width: 4.1em; padding-left: 6px; padding-right: 6px; }
.time-range .time-field > .time-field-ap { min-width: 62px; padding-left: 6px; padding-right: 2px; }
/* 날짜+시각 입력(DateTimeField.razor): [날짜][시:분][오전/오후] — 기본 모달(640px)의 두 칸 배치에서도 한 줄에 들어가게 폭을 잡았다.
   그보다 좁으면(휴대폰에서 두 칸 배치 등) 시각 칸이 다음 줄로 내려간다 */
.datetime-field { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 날짜 칸: 달력 스크립트(js/datepicker.js)가 type 을 text 로 바꾸므로 type 으로 고르지 않고 "바로 아래 입력칸"으로 고른다(시각 칸은 .time-field 안에 있다) */
.datetime-field > .input { flex: 1 1 8.2em; width: auto; min-width: 8.2em; padding-left: 10px; padding-right: 6px; }
.field > .datetime-field { margin-top: 2px; }
.field > span > .muted.inline { display: inline; margin-left: 6px; }   /* 라벨 설명을 같은 줄에 두는 경우 */

/* ── 아래 블록은 2026-10-10 에 UAPT 의 임시출입자 관리 화면과 함께 가져왔다 ── */
/* 달력 팝업(flatpickr) 보조 — 하단 삭제/오늘 버튼(js/datepicker.js 가 만든다) */
.flatpickr-calendar .fp-actions { display: flex; justify-content: space-between; padding: 6px 12px 10px; border-top: 1px solid var(--border, #e5e7eb); }
.flatpickr-calendar .fp-actions button { background: none; border: 0; padding: 4px 6px; color: var(--primary, #2563eb); font: inherit; font-size: 13px; cursor: pointer; }
.flatpickr-calendar .fp-actions button:hover { text-decoration: underline; }
.flatpickr-calendar { font-family: inherit; z-index: 100000 !important; }
/* 출입 가능 시간대 목록(하루 여러 번 — TimeSlotsField.razor) */
.slots { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.slots .slot-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.slots .slot-del { padding: 6px 8px; }
/* 요일별 출입 규칙(DayRulesField.razor) — 규칙 하나 = 출입 가능 시간 + 출입 가능 요일이 위아래로 쌓인다 */
.dayrules { display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
.dayrule { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; background: #fafbfd; }
.dayrule-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.dayrules > .btn { align-self: flex-start; }

/* Capture guard message box — only created at the moment a capture / print attempt is blocked (nothing is shown otherwise) */
/* 캡처·인쇄 시도 안내 상자(app.js captureGuard 의 notice 가 생성). 워터마크보다 위(z-index 최상위), 흐림 효과 제외 */
.cg-msgbox-backdrop { position: fixed; inset: 0; z-index: 2147483600; display: flex; align-items: center; justify-content: center; padding: 16px;
  background: rgba(15, 23, 42, .45); filter: none !important; }
.cg-msgbox { width: 100%; max-width: 380px; background: #fff; border-radius: 14px; padding: 22px 22px 18px; box-shadow: 0 16px 40px rgba(0,0,0,.25); }
.cg-msgbox-title { font-size: 1.05rem; font-weight: 700; margin-bottom: 8px; color: #111827; }
.cg-msgbox-text { font-size: .95rem; line-height: 1.55; color: #374151; }
.cg-msgbox-actions { display: flex; justify-content: flex-end; margin-top: 18px; }

/* Field validation — invalid input border and message under the field */
/* 입력 오류 표시(예: Signup.razor 이메일 칸 .input-invalid + 아래 .field-error 문구) */
.input.input-invalid { border-color: var(--danger); box-shadow: 0 0 0 3px rgba(220, 38, 38, .12); }
.field-error { display: block; margin-top: 4px; color: var(--danger) !important; }

/* 단말기 현재 설정 조회 표 — 서버 설정과 다른 행 강조 */
.tbl.compact td, .tbl.compact th { padding: 2px 8px; font-size: .84rem; line-height: 1.35; height: auto; }
.tbl tr.row-warn td { background: color-mix(in srgb, var(--warn, #f59e0b) 10%, transparent); }
/* 상세 창 왼쪽 정보(kv)는 오른쪽 칸이 길어져도 위에서부터 붙여 쌓는다 — 기본(stretch)이면 행 간격이 벌어진다 */
.detail-grid > .kv { align-content: start; }

/* 얼굴등록 창 방법 1 "사진 확인" 팝업: 원본(왼쪽)·보정본(오른쪽)을 같은 크기로 나란히 비교한다. 좁은 화면에서는 위아래로. */
.photo-compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.photo-compare-grid .face-preview { max-width: none; margin-top: 6px; }
@media (max-width: 520px) { .photo-compare-grid { grid-template-columns: 1fr; } }

/* 촬영·앨범 버튼(label.file-btn) 위에 **투명한 파일 입력칸**(.file-overlay)을 그대로 겹친다.
   아이폰 Safari 는 display:none 으로 숨긴 입력칸을 label 이 대신 눌러 주면 카메라·앨범 창을 띄우지 않는 경우가 있다
   (2026-09-21 진단 기록으로 확인). 손가락이 입력칸 자체를 누르게 하면 모든 기기에서 확실히 창이 뜬다.
   opacity:0 이라 보이지는 않고, 버튼 전체 영역을 덮어 어디를 눌러도 된다. */
.file-btn { position: relative; overflow: hidden; }
.file-btn .file-overlay { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; z-index: 1; font-size: 0; }
.file-btn .file-overlay:disabled { cursor: not-allowed; }

/* 근태 현황 "월별 현황" 달력표(사람 × 날짜). 이름 칸은 가로 스크롤해도 왼쪽에 고정되고, 날짜 칸은 작게 촘촘히.
   칸 색으로 판정을 구분한다(정상 초록·지각/조퇴 노랑·미기록 하늘·결근 빨강·휴가 보라·휴일근무 청록·휴일 회색). */
.mgrid-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 12px 16px 6px; font-size: .82rem; color: var(--muted); }
.mgrid-legend span { display: inline-flex; align-items: center; gap: 4px; }
.mgrid-legend .mg { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 4px; font-style: normal; font-size: .72rem; font-weight: 700; }
.mgrid-wrap { overflow-x: auto; }
.mgrid { border-collapse: separate; border-spacing: 0; font-size: .8rem; min-width: 100%; }
.mgrid th, .mgrid td { border-bottom: 1px solid var(--border); padding: 4px 2px; text-align: center; white-space: nowrap; }
.mgrid thead th { font-weight: 600; color: var(--muted); min-width: 28px; line-height: 1.1; }
.mgrid thead th small { display: block; font-weight: 400; font-size: .68rem; }
.mgrid thead th.sun { color: #d33; } .mgrid thead th.sat { color: #2563eb; }
.mgrid thead th.today { background: var(--primary); color: #fff; border-radius: 6px 6px 0 0; }
.mgrid .mg-name { position: sticky; left: 0; z-index: 1; background: var(--card); text-align: left; padding: 6px 10px; min-width: 150px; box-shadow: 1px 0 0 var(--border); }
.mgrid .mg-sum { font-weight: 600; min-width: 40px; background: var(--bg, #f7f8fa); }
.mgrid .mg-cell { font-weight: 700; font-size: .74rem; height: 30px; }
.mgrid .mg-cell.click { cursor: pointer; } .mgrid .mg-cell.click:hover { outline: 2px solid var(--primary); outline-offset: -2px; }
.mg.present, .mg-cell.present { background: #e6f6ee; color: #0b8a63; }
.mg.late, .mg-cell.late, .mg.early, .mg-cell.early { background: #fff4d6; color: #a05a00; }
.mg.unrecorded, .mg-cell.unrecorded { background: #e7f1fb; color: #135e9f; }
.mg.absent, .mg-cell.absent { background: #fde8e8; color: #b42323; }
.mg.leave, .mg-cell.leave { background: #efe9fb; color: #6b3fb8; }
.mg.holidaywork, .mg-cell.holidaywork { background: #dff4f4; color: #0f766e; }
.mg.off, .mg-cell.off { background: #f1f3f6; color: #9aa3ae; }
.mg-cell.future { background: transparent; }

/* 단말기 목록 → "단말기 그룹" 탭: 왼쪽 그룹 목록(좁게) + 오른쪽 편집(넓게). 좁은 화면에서는 위아래로. */
.dg-layout { display: grid; grid-template-columns: minmax(220px, 300px) 1fr; gap: 14px; align-items: start; }
@media (max-width: 860px) { .dg-layout { grid-template-columns: 1fr; } }
.dg-item { cursor: pointer; padding: 10px 16px; border-top: 1px solid var(--border); }
.dg-item:hover { background: var(--bg, #f7f8fa); }
.dg-item.on { background: #eef4ff; box-shadow: inset 3px 0 0 var(--primary); }
.dg-checks { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 4px 14px; max-height: 260px; overflow: auto; }
.dg-members { max-height: 320px; }

/* 좌우 목록 색 구분(.mp-tinted 로 감싼 MatchPicker 만): **제목줄 바탕색만** — 왼쪽 "전체"=붉은 계열, 오른쪽 "담긴 쪽"=파란 계열.
   목록·필터 바탕은 기본색 그대로(2026-09-21 사용자 요청: 제목만 색을 넣고 나머지는 뺌). 단말기 사용자 등록 → 단말기 그룹 관리. */
.mp-tinted .match-picker > .mp-col:first-child .mp-col-head { background: #fde3e3; color: #a52a2a; }
.mp-tinted .match-picker > .mp-col:last-child .mp-col-head { background: #dfeafd; color: #1d4ed8; }

/* 기간별 상세 근무현황(근태 현황 탭 5, 2026-09-21): 사람별 첫 줄 구분선·합계 줄, 인쇄 시 표만 출력 */
.detail-report .tbl td, .detail-report .tbl th { white-space: nowrap; }
/* 안쪽 스크롤 없이 페이지 스크롤 하나로(사용자 요청) — 가상 스크롤은 페이지 스크롤을 따라간다. 머리글은 상단바 바로 아래에 고정 */
.detail-report { max-height: none; overflow: visible; }
/* 목록 카드의 overflow:hidden 을 풀어야 가상 스크롤·고정 머리글이 페이지 스크롤을 따라간다 */
.list-card.detail-card { overflow: visible; }
.detail-report thead th { position: sticky; top: var(--topbar-h); z-index: 2; background: var(--card, #fff); }
.detail-report tr.dr-first td { border-top: 2px solid var(--border); }
.detail-report tr.dr-sum td { background: var(--surface-2, #f3f4f6); font-weight: 600; }
@media print {
  .sidebar, .topbar, .tabs, .filters, .page-header, .sidebar-collapse-btn, .hint, .btn, .toast-host { display: none !important; }
  .main, .content { margin: 0 !important; padding: 0 !important; }
  .detail-report { overflow: visible !important; max-height: none !important; }
  .detail-report .tbl { font-size: 10px; }
}

/* 근무 예정표(근무 매칭 화면 탭, 2026-09-21): 칸 바탕 = 예정 종류, 아래 테두리 색 = 지난 날 실제 결과 */
.sgrid .sc-cell { font-size: .72rem; text-align: center; white-space: nowrap; padding: 4px 2px; border-bottom: 3px solid transparent; }
.sgrid .sc-cell.work { background: #eef4ff; color: #1d4ed8; }
.sgrid .sc-cell.off { background: #f1f5f9; color: #64748b; }
.sgrid .sc-cell.holiday { background: #fdecec; color: #b91c1c; }
.sgrid .sc-cell.rest { background: #fafafa; }
.sgrid .sc-cell.act-ok { border-bottom-color: #16a34a; }
.sgrid .sc-cell.act-late, .sgrid .sc-cell.act-early, .sgrid .sc-cell.act-unrec { border-bottom-color: #d97706; }
.sgrid .sc-cell.act-absent { border-bottom-color: #dc2626; background: #fff1f1; }
.sgrid .sc-cell.act-leave { border-bottom-color: #7c3aed; }
.sgrid .sc-cell.act-extra { border-bottom-color: #0891b2; }
.sc-leg { display: inline-block; min-width: 26px; padding: 0 3px; margin-right: 4px; font-style: normal; font-size: .72rem; text-align: center; border-radius: 4px; border: 1px solid var(--border); }
.sc-leg.work { background: #eef4ff; color: #1d4ed8; } .sc-leg.off { background: #f1f5f9; color: #64748b; } .sc-leg.holiday { background: #fdecec; color: #b91c1c; } .sc-leg.rest { background: #fafafa; }
.sc-dot { display: inline-block; width: 14px; height: 3px; margin-right: 4px; vertical-align: middle; }
.sc-dot.ok { background: #16a34a; } .sc-dot.late { background: #d97706; } .sc-dot.absent { background: #dc2626; } .sc-dot.leave { background: #7c3aed; } .sc-dot.extra { background: #0891b2; }

/* 근무 예정표: 누를 수 있는 칸, 바뀐 칸(오른쪽 위 주황 삼각형) */
.sgrid .sc-cell.click { cursor: pointer; }
.sgrid .sc-cell.click:hover { outline: 2px solid #93c5fd; outline-offset: -2px; }
.sgrid .sc-cell.chg, .sc-leg.chg { position: relative; }
.sgrid .sc-cell.chg::after, .sc-leg.chg::after { content: ""; position: absolute; top: 0; right: 0; border-top: 7px solid #f97316; border-left: 7px solid transparent; }

/* 근무 예정표 팀별 보기: 팀 머리줄, 날짜별 근무 인원(0명 근무일은 빨강 = 공백) */
.sgrid tr.sc-team td { background: #f1f5f9; font-weight: 700; font-size: .8rem; padding: 4px 8px; text-align: left; }
.sgrid tr.sc-count td { background: #fafafa; font-size: .72rem; text-align: center; border-top: 1px solid var(--border); }
.sgrid tr.sc-count td.mg-name { text-align: left; }
.sgrid tr.sc-count:last-child td { font-weight: 700; background: #f3f4f6; }
.sgrid td.sc-cnt.zero { color: #dc2626; background: #fff1f1; }

/* 근무 매칭 안내문(항목별 줄) · 근무표 짜는 예시(접이식) */
.rot-guide > div { margin: 2px 0; line-height: 1.6; }
.rot-guide ul { margin: 2px 0 2px 18px; padding: 0; }
.rot-examples { padding: 12px 16px; margin-bottom: 14px; }
.rot-examples > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 6px; }
.rot-examples > summary::-webkit-details-marker { display: none; }
.rot-ex-body { margin-top: 10px; }
.rot-ex-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.rot-ex { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; background: #fcfcfd; }
.rot-ex h4 { margin: 0 0 6px; font-size: .92rem; }
.rot-ex ol { margin: 0 0 6px 18px; padding: 0; font-size: .85rem; line-height: 1.6; }
.rot-ex-tbl { border-collapse: collapse; font-size: .75rem; margin-top: 4px; }
.rot-ex-tbl th, .rot-ex-tbl td { border: 1px solid var(--border); padding: 2px 6px; text-align: center; }
.rot-ex-tbl td.w { background: #eef4ff; color: #1d4ed8; }

/* 예정표 드래그 앤 드롭: 끄는 칸 흐리게, 놓을 칸 파란 테두리, 끄는 동안 놓을 수 없는 칸(지난 날짜) 흐리게 */
.sgrid td[data-sc-e="1"] { cursor: grab; }
.sgrid td.sc-dragging { opacity: .4; }
.sgrid td.sc-drop-ok { outline: 3px solid #2563eb !important; outline-offset: -3px; background: #dbeafe !important; }
.sc-dnd-on .sgrid td.sc-cell:not([data-sc-e="1"]) { opacity: .35; }

/* ── 직원 모바일(출장 출퇴근 신청, /my — 2026-10-07) ──
   Blazor 를 쓰지 않는 정적 화면이라 js/my.js 가 만든 요소에 아래 클래스만 붙인다. 휴대폰 한 손 조작 기준(큰 버튼, 최대 폭 520px). */
.my-body { margin: 0; background: var(--bg); }
.my-shell { min-height: 100vh; }
.my-head { display: flex; align-items: center; padding: 12px 16px; background: var(--navy); }
.my-brand { display: flex; align-items: center; gap: 8px; color: #fff; font-weight: 700; text-decoration: none; }
.my-brand img { border-radius: 6px; }
.my-main { padding: 16px; max-width: 520px; margin: 0 auto; }
.my-main .alert { margin-bottom: 12px; }
.my-center { text-align: center; padding: 18px 0; }
.my-title { font-size: 1.2rem; margin: 0 0 10px; }
.my-hello { margin: 4px 2px 14px; } .my-name { font-size: 1.35rem; font-weight: 800; }
.my-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 4px; }
.my-action { display: flex; flex-direction: column; gap: 10px; align-items: stretch; text-align: center; margin-bottom: 12px; }
.my-action-title { font-weight: 700; color: var(--muted); }
.my-action.done { align-items: center; } .my-time { font-size: 1.6rem; font-weight: 800; letter-spacing: .02em; }
/* 입력칸·체크·버튼 사이 간격(카드 안에서 세로로 쌓인다) */
.my-form > *, .my-main .card > .input, .my-main .card > .btn, .my-main .card > .check { margin-top: 10px; }
.my-main textarea.input { resize: vertical; min-height: 64px; }
.my-check { align-items: flex-start; } .my-check input { margin-top: 2px; flex: none; }
.my-loc { font-size: 1.05rem; }
.my-list { display: flex; flex-direction: column; }
.my-row { padding: 10px 0; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px; align-items: flex-start; } .my-row:first-child { border-top: 0; }
.my-reject { color: var(--danger); }
.my-foot { display: flex; justify-content: center; gap: 8px; margin: 18px 0 8px; flex-wrap: wrap; }
.my-inapp { display: block; }

/* 모바일 관리자 — 출장 출퇴근 신청 시트(2026-10-07): 항목 이름/값 목록과 아래 버튼 묶음 */
.mobile-dl { display: grid; grid-template-columns: auto 1fr; gap: 8px 12px; margin: 0 0 12px; } .mobile-dl dt { color: var(--muted); font-size: .9rem; white-space: nowrap; } .mobile-dl dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.sheet-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
