/* [DEV_MAP] admin/assets/app.css - 공용 컴포넌트 - v1.0 (2026-09-03)
   [목적] 버튼·표·배지·칩·카드·폼의 공통 모양
   [핵심] 색은 전부 tokens.css 의 var() 를 쓴다. 여기에 hex 를 쓰지 않는다
   [연관] tokens.css(먼저 로드) · mobile.css(뒤에 로드) · _header.php
   [주의] 🔴 로드 순서가 바뀌면 var() 가 비어 색이 사라진다 */

*, *::before, *::after { box-sizing: border-box; }
/* 🔴 hidden 속성이 항상 이기게 한다.
   브라우저 기본은 [hidden]{display:none} 인데, 우리가 .badge{display:inline-block} 처럼
   display 를 주면 명시도가 같아 나중에 선언한 우리 규칙이 이겨 요소가 그대로 보인다.
   실제로 "미저장 0건" 배지가 hidden 인데도 화면에 남았다. */
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg-body); color: var(--text);
  font: var(--fs-3)/1.55 var(--font);
  -webkit-text-size-adjust: 100%;
}
a { color: var(--primary); text-decoration: none; }
/* 🔴 밑줄 hover 도 포인터 있는 기기로 한정한다. 터치에서는 마지막에 닿은
   링크에 밑줄이 남아 그 항목이 선택된 것처럼 보인다. 배경색과 같은 부류다. */
@media (hover: hover) and (pointer: fine) { a:hover { text-decoration: underline; } }
h1, h2, h3 { margin: 0 0 var(--s3); font-weight: 600; line-height: 1.3; }
h1 { font-size: var(--fs-5); }
h2 { font-size: var(--fs-4); }

/* --- 레이아웃 셸 --- */
.shell { display: flex; min-height: 100vh; }
.side {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: var(--surface); border-right: 1px solid var(--border-strong);
  display: flex; flex-direction: column;
}
.side__brand {
  height: var(--topbar-h); display: flex; align-items: center; gap: var(--s2);
  padding: 0 var(--s4); border-bottom: 1px solid var(--border);
  font-weight: 600; font-size: var(--fs-3);
}
.side__nav { padding: var(--s3) var(--s2); display: flex; flex-direction: column; gap: 2px; }
.side__link {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s3); border-radius: var(--r-sm);
  color: var(--text-sub); font-size: var(--fs-3);
}
/* 🔴 hover 를 포인터가 있는 기기로 한정한다. 터치에서는 손이 닿은 항목에
   hover 가 붙어 그대로 남아, 현재 화면이 아닌 항목이 강조된 것처럼 보인다.
   실측: 모바일 캡처의 회색이 --surface-2 값이었고 활성색 --accent-bg 가 아니었다. */
@media (hover: hover) and (pointer: fine) {
  .side__link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
}
.side__link.is-on { background: var(--primary-weak); color: var(--primary-hover); font-weight: 600; }
.side__link svg { width: 17px; height: 17px; flex: 0 0 17px; }
.side__group { padding: var(--s4) var(--s3) var(--s1); color: var(--text-muted); font-size: var(--fs-1); }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.top {
  height: var(--topbar-h); display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--s5); background: var(--surface); border-bottom: 1px solid var(--border-strong);
}
.top__who { color: var(--text-sub); font-size: var(--fs-2); display: flex; align-items: center; gap: var(--s3); }
.top__date {
  color: var(--text-sub); font-size: var(--fs-2);
  padding: var(--s1) var(--s2); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2); white-space: nowrap;
}
/* 🔴 미저장 배지. 0 이면 hidden 으로 감춘다. 색은 warning — 오류가 아니라 주의다 */
.top__unsaved { text-decoration: none; white-space: nowrap; }
.top__unsaved:hover { text-decoration: none; }
.content { padding: var(--s5); flex: 1; }

/* --- 카드 --- */
.card {
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--r-md); padding: var(--s5); box-shadow: var(--shadow-edge);
}
.card + .card { margin-top: var(--s4); }
.card__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s4); }

/* --- 버튼 --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: var(--s2) var(--s4); min-height: 34px;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--text);
  font: 500 var(--fs-3)/1 var(--font); cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--surface-2); text-decoration: none; }
  .btn--primary:hover { background: var(--primary-hover); }
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.btn--danger { background: var(--danger); border-color: var(--danger); color: var(--on-primary); }
.btn--block { width: 100%; }

/* --- 폼 --- */
.field { margin-bottom: var(--s4); }
.field__label { display: block; margin-bottom: var(--s2); font-size: var(--fs-2); color: var(--text-sub); }
.input {
  width: 100%; padding: var(--s2) var(--s3); min-height: 38px;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--text); font: var(--fs-3)/1.4 var(--font);
}
.input:focus { outline: 2px solid var(--focus-ring); outline-offset: 1px; border-color: var(--primary); }
.input--num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* --- 표 --- */
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-2); }
.table th, .table td { padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border-strong); text-align: left; }
.table th { background: var(--surface-2); color: var(--text-sub); font-weight: 600; white-space: nowrap; }
.table td.num, .table th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
@media (hover: hover) and (pointer: fine) {
  .table tbody tr:hover { background: var(--surface-2); }
}
/* 🔴 카드와 표는 최소 --shadow-edge 를 갖는다. 경계선만으로는 배경과 갈라지지 않는다 */
.table__wrap { overflow-x: auto; background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--r-md); box-shadow: var(--shadow-edge); }
.table__wrap .table { margin: 0; }

/* --- 배지·칩 --- */
.badge {
  display: inline-block; padding: 2px var(--s2); border-radius: var(--r-sm);
  font-size: var(--fs-1); font-weight: 600; line-height: 1.6;
}
.badge--ok     { background: var(--success-weak);     color: var(--success); }
.badge--warn   { background: var(--warning-weak); color: var(--warning); }
.badge--danger { background: var(--danger-weak); color: var(--danger); }
.badge--mute   { background: var(--border);    color: var(--text-muted); }
.chip {
  display: inline-flex; align-items: center; gap: var(--s1);
  padding: var(--s1) var(--s2); border: 1px solid var(--border-strong);
  border-radius: 999px; font-size: var(--fs-1); color: var(--text-sub);
}

/* 금액 부호. 🔴 색만으로 구분하지 않는다 — 부호를 함께 낸다 */
.amt--plus  { color: var(--plus); }
.amt--minus { color: var(--minus); }

/* --- 알림 --- */
.alert { padding: var(--s3) var(--s4); border-radius: var(--r-sm); font-size: var(--fs-2); margin-bottom: var(--s4); }
.alert--danger { background: var(--danger-weak); color: var(--danger); }
.alert--warn   { background: var(--warning-weak);   color: var(--warning); }

/* --- 토스트 --- */
.toast-wrap { position: fixed; right: var(--s5); bottom: var(--s5); display: flex; flex-direction: column; gap: var(--s2); z-index: 70; }
.toast {
  background: var(--text); color: var(--on-primary); padding: var(--s3) var(--s4);
  border-radius: var(--r-sm); font-size: var(--fs-2); box-shadow: var(--shadow-modal); max-width: 22rem;
}
.toast--danger { background: var(--danger); }

/* --- 모달 --- */
.modal-back {
  position: fixed; inset: 0; background: rgba(31,36,48,.45);
  display: flex; align-items: center; justify-content: center; padding: var(--s4); z-index: 60;
}
.modal { background: var(--surface); border-radius: var(--r-md); box-shadow: var(--shadow-modal); max-width: 28rem; width: 100%; padding: var(--s5); }
.modal__foot { display: flex; justify-content: flex-end; gap: var(--s2); margin-top: var(--s5); }

/* --- 로그인 --- */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: var(--s4); }
.login-box { width: 100%; max-width: 21rem; }
.login-box h1 { text-align: center; margin-bottom: var(--s5); }

.muted { color: var(--text-muted); }
.mono  { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- 모바일 드로어 ---------------------------------------------
   기본(데스크톱)에서는 햄버거와 스크림이 없다. mobile.css 가 켠다.
   🔴 열림 상태는 body.is-drawer 하나로만 관리한다. 두 곳에서 켜고 끄면
      한쪽만 닫혀 스크롤 락이 풀리지 않는다. */
.hamburger { display: none; }
.scrim { display: none; }
