/* ==========================================================================
   공통 컴포넌트 — 패널, 통계 카드, 아바타, 진척도 바, 배지, 탭, 표, 빈 상태,
   가로 스크롤 영역, 유틸리티, 로그인·오류 화면
   app.css(토큰) · app-layout.css 다음에 불러온다 (components/app_css.html).
   ========================================================================== */

/* ---------- 카드 / 패널 ---------- */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.panel-header {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 1rem 1.25rem; border-bottom: 1px solid var(--border);
}
.panel-title { font-size: 1rem; font-weight: 700; margin: 0; }
.panel-body { padding: 1.25rem; }
.panel-footer { padding: 0.75rem 1.25rem; border-top: 1px solid var(--border); background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius); }

.stat-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 1.1rem 1.25rem; box-shadow: var(--shadow-sm); height: 100%;
}
.stat-card .stat-label { color: var(--text-muted); font-size: 0.8125rem; font-weight: 500; display: flex; align-items: center; gap: 0.4rem; word-break: keep-all; overflow-wrap: anywhere; }
.stat-card .stat-value { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.02em; margin-top: 0.25rem; line-height: 1.2; }
.stat-card .stat-sub { color: var(--text-subtle); font-size: 0.8rem; margin-top: 0.15rem; }
.stat-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 8px; font-size: 0.95rem;
  background: var(--accent-soft); color: var(--accent);
}

/* ---------- 아바타 ---------- */
.avatar {
  --avatar-size: 32px;
  --avatar-color: #6366f1;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: var(--avatar-size); height: var(--avatar-size); border-radius: 50%;
  background: var(--avatar-color); color: #fff;
  font-size: calc(var(--avatar-size) * 0.38); font-weight: 600; letter-spacing: -0.03em;
  line-height: 1; user-select: none;
}
.avatar-empty { background: var(--surface-2); color: var(--text-subtle); border: 1px dashed var(--border-strong); }
.avatar-stack { display: inline-flex; }
.avatar-stack .avatar { box-shadow: 0 0 0 2px var(--surface); }
.avatar-stack .avatar + .avatar { margin-left: -8px; }

/* ---------- 진척도 바 ---------- */
.pbar { display: flex; align-items: center; gap: 0.6rem; }
.pbar-track { flex: 1; height: 8px; background: #eaecf0; border-radius: 99px; overflow: hidden; min-width: 60px; }
.pbar-fill { height: 100%; border-radius: 99px; transition: width 0.3s ease; }
.pbar-sm .pbar-track { height: 6px; }
.pbar-lg .pbar-track { height: 12px; }
.pbar-value { font-size: 0.8125rem; font-weight: 600; min-width: 2.6em; text-align: right; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pbar-low .pbar-fill { background: #94a3b8; }
.pbar-mid .pbar-fill { background: #3b82f6; }
.pbar-high .pbar-fill { background: #6366f1; }
.pbar-done .pbar-fill { background: var(--status-done); }

/* ---------- 배지 ---------- */
.badge-soft {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.2rem 0.55rem; border-radius: 99px; font-size: 0.75rem; font-weight: 600; white-space: nowrap;
  background: var(--surface-2); color: var(--text-muted); border: 1px solid transparent;
}
.badge-soft::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-soft.no-dot::before { display: none; }

.status-todo { color: var(--status-todo-text); background: var(--status-todo-soft); }
.status-in-progress { color: var(--status-in-progress-text); background: var(--status-in-progress-soft); }
.status-review { color: var(--status-review-text); background: var(--status-review-soft); }
.status-done { color: var(--status-done-text); background: var(--status-done-soft); }

.pstatus-planning { color: var(--pstatus-planning-text); background: #f5f3ff; }
.pstatus-active { color: var(--pstatus-active-text); background: #eff6ff; }
.pstatus-on-hold { color: var(--pstatus-on-hold-text); background: #fffbeb; }
.pstatus-completed { color: var(--pstatus-completed-text); background: #ecfdf5; }

.priority-low { color: var(--priority-low); }
.priority-medium { color: var(--priority-medium); }
.priority-high { color: var(--priority-high); }
.priority-urgent { color: var(--priority-urgent); }
.badge-soft.priority-low { color: var(--priority-low-text); background: #f8fafc; }
.badge-soft.priority-medium { color: var(--priority-medium-text); background: #eff6ff; }
.badge-soft.priority-high { color: var(--priority-high-text); background: #fffbeb; }
.badge-soft.priority-urgent { color: var(--priority-urgent-text); background: #fef2f2; }

.badge-overdue { color: var(--danger-text); background: #fef2f2; }

/* ---------- 업무 첨부파일·댓글 개수 ({% task_counts task %}) ----------
   relative: 안쪽 .visually-hidden 이 페이지 가로 스크롤을 만들지 않게 */
.task-counts {
  position: relative; display: inline-flex; align-items: center; gap: 0.45rem;
  flex-shrink: 0; white-space: nowrap; vertical-align: middle;
}
.task-count {
  display: inline-flex; align-items: center; gap: 0.15rem;
  font-size: 0.75rem; font-weight: 600; color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.task-count .bi { font-size: 0.8rem; }

/* ---------- 프로젝트 탭 (개요 / 칸반 / 간트 / 달력 / 타임라인 / 회의록) ---------- */
.project-tabs {
  display: flex; gap: 0.25rem; border-bottom: 1px solid var(--border);
  margin-bottom: 1.25rem; overflow-x: auto;
}
.project-tabs a {
  display: inline-flex; align-items: center; gap: 0.45rem; white-space: nowrap;
  padding: 0.65rem 0.9rem; color: var(--text-muted); text-decoration: none; font-weight: 600; font-size: 0.9rem;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.project-tabs a:hover { color: var(--text); }
.project-tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }
/* 좁은 화면(< 640px — 달력의 좁은 화면 기준과 같다): 탭 6개(개요·칸반·간트·달력·타임라인·회의록)가
   잘리지 않게 아이콘 없이 한 줄에 (375px 에서 343px 안, 320px 에서 288px 안). 아이콘을 단 기본 탭은
   약 562px 이 필요해 576~595px(본문 544~563px)에서 넘쳤다 — 640px(본문 608px)부터 기본 탭.
   test_calendar_e2e_mobile 이 320·375·576·600·639·640·768px 에서 확인. 그래도 넘치면 탭 줄만
   가로로 스크롤된다 (현재 탭이 보이게 각 화면 JS 가 민다). */
@media (max-width: 639.98px) {
  .project-tabs { gap: 0; }
  .project-tabs a { gap: 0.3rem; padding: 0.6rem 0.45rem; font-size: 0.875rem; }
  .project-tabs a > .bi { display: none; }
}
@media (max-width: 359.98px) {
  .project-tabs a { padding: 0.6rem 0.28rem; font-size: 0.8125rem; letter-spacing: -0.01em; }
}
.color-dot { display: inline-block; width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }

/* ---------- 표 ---------- */
.table-app { margin: 0; --bs-table-bg: transparent; }
.table-app thead th {
  font-size: 0.75rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em;
  background: var(--surface-2); border-bottom: 1px solid var(--border); padding: 0.65rem 1rem; white-space: nowrap;
}
.table-app td { padding: 0.8rem 1rem; vertical-align: middle; border-color: var(--border); }
.table-app tbody tr:hover { background: var(--surface-2); }
.table-app tbody tr:last-child td { border-bottom: 0; }

/* ---------- 빈 상태 ---------- */
.empty-state {
  text-align: center; padding: 3rem 1rem; color: var(--text-muted);
  background: var(--surface); border: 1px dashed var(--border-strong); border-radius: var(--radius);
}
.empty-state > i { font-size: 2.25rem; color: var(--text-subtle); display: block; margin-bottom: 0.75rem; }
.empty-state p { margin-bottom: 1rem; }

/* ---------- 가로 스크롤 영역 ----------
   overflow-x:auto 컨테이너는 position:relative 여야 안쪽 .visually-hidden(position:absolute)이
   스크롤 영역 밖으로 빠져 페이지 전체 가로 스크롤을 만들지 않는다. */
.table-responsive, .scroll-x { position: relative; }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- 기타 ---------- */
.keep-all { word-break: keep-all; overflow-wrap: anywhere; }
.stat-sub, .empty-state p, .panel-title { word-break: keep-all; overflow-wrap: anywhere; }
.text-muted-2 { color: var(--text-muted) !important; }
.text-subtle { color: var(--text-subtle) !important; }
.fw-semibold { font-weight: 600 !important; }
.tabular { font-variant-numeric: tabular-nums; }
.link-plain { color: inherit; text-decoration: none; }
.link-plain:hover { color: var(--accent); }
/* 옅은 단추의 키보드 초점: Bootstrap 기본(옅은 회색 번짐)은 흰 패널 위에서 거의 보이지 않는다 */
.btn-light:focus-visible,
.btn-outline-secondary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.min-w-0 { min-width: 0; }
.text-truncate-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- 로그인 ---------- */
.auth-page {
  min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1.5rem;
  background: radial-gradient(1200px 600px at 10% -10%, #e0e7ff 0%, transparent 60%),
              radial-gradient(900px 500px at 110% 110%, #ede9fe 0%, transparent 60%), var(--bg);
}
.auth-card { width: 100%; max-width: 400px; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-lg); padding: 2rem; }
.auth-card .brand-mark { width: 44px; height: 44px; font-size: 1.35rem; border-radius: 12px; }
/* 비밀번호 로그인과 NAS 계정 로그인 버튼 사이 "또는" 구분선 */
.auth-divider { display: flex; align-items: center; gap: .75rem; margin: 1.25rem 0; color: var(--text-muted); font-size: .8125rem; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; border-top: 1px solid var(--border); }

/* ---------- 오류 페이지 (403/404) ---------- */
.error-state { max-width: 560px; margin: 2rem auto; }

/* ---------- 견적 상태·유형 배지 ({{ quote.status|qstatus_class }}) ---------- */
.qstatus-draft { color: var(--q-draft-text); background: var(--q-draft-soft); }
.qstatus-review { color: var(--q-review-text); background: var(--q-review-soft); }
.qstatus-sent { color: var(--q-sent-text); background: var(--q-sent-soft); }
.qstatus-negotiation { color: var(--q-negotiation-text); background: var(--q-negotiation-soft); }
.qstatus-won { color: var(--q-won-text); background: var(--q-won-soft); }
.qstatus-lost { color: var(--q-lost-text); background: var(--q-lost-soft); }
.qtype { display: inline-flex; align-items: center; gap: .3rem; font-size: .75rem; font-weight: 600; color: var(--text-muted); }
.qtype::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--qtype-color, var(--text-subtle)); }
.qtype-sw { --qtype-color: var(--qtype-sw); }
.qtype-hw { --qtype-color: var(--qtype-hw); }
.qtype-mixed { --qtype-color: var(--qtype-mixed); }
.qtype-maintenance { --qtype-color: var(--qtype-maintenance); }
.qtype-goods { --qtype-color: var(--qtype-goods); }
.qtype-mfg { --qtype-color: var(--qtype-mfg); }
.money { font-variant-numeric: tabular-nums; white-space: nowrap; }
