/* @vendit/admin-ui — 정적 페이지용 배포본
 * 생성됨: scripts/build-static-css.mjs — 직접 고치지 마라.
 * 토큰 정본: admin-ui/theme.css (그 위 문서 정본: vcms-dashboards/DESIGN_TOKENS.md)
 * 토큰 84개 + 정적 셸.
 *
 * 쓰는 법:
 *   <link rel="stylesheet" href="https://vendit-ds.pages.dev/v1.css">
 *   <script src="https://vendit-ds.pages.dev/v1.js" defer></script>
 *   <header class="appbar" data-ds-appbar data-title="대시보드 이름"></header>
 */

:root{
  --radius: 0.5rem;

  /* Badge colors (hex — used directly in CSS arbitrary values) */
  --color-badge-green-bg:   #d1fae5;
  --color-badge-green-text: #065f46;
  --color-badge-red-bg:     #fee2e2;
  --color-badge-red-text:   #991b1b;
  --color-badge-gray-bg:    #e2e8f0;
  --color-badge-gray-text:  #1e293b;
  --color-badge-blue-bg:    #dbeafe;
  --color-badge-blue-text:  #1e40af;
  --color-badge-orange-bg:  #ffedd5;
  --color-badge-orange-text: #9a3412;
  --color-badge-amber-bg:   #fef3c7;
  --color-badge-amber-text: #92400e;
}

/* @theme → :root. Tailwind at-rule 은 브라우저가 못 읽는다. */
:root{
  /* ── Brand (VCMS purple) ───────────────────────────────── */
  --color-primary:           #7c3aed;
  --color-primary-hover:     #6d28d9;
  --color-primary-light:     #f5f3ff;
  --color-primary-muted:     #ede9fe;
  --color-primary-foreground: #ffffff;
  /* bg-primary-light 위 텍스트(활성 메뉴 등) — 라이트=violet(은은한 칩에 진한 글씨),
   * 다크=흰색(.dark 에서 override). bg 는 은은하게 유지하고 글자만 눈에 띄게. */
  --color-on-primary-light:  #6d28d9;

  /* ── Semantic surfaces ─────────────────────────────────── */
  --color-background:         #ffffff;
  --color-foreground:         #0f172a;  /* slate-900 */
  --color-card:               #ffffff;
  --color-card-foreground:    #0f172a;
  --color-popover:            #ffffff;
  --color-popover-foreground: #0f172a;

  /* ── Neutral fills ─────────────────────────────────────── */
  --color-secondary:            #f1f5f9;  /* slate-100 */
  --color-secondary-foreground: #1e293b;
  --color-muted:                #f1f5f9;
  --color-muted-foreground:     #64748b;  /* slate-500 */
  --color-accent:               #f1f5f9;
  --color-accent-foreground:    #1e293b;

  /* ── Semantic states ───────────────────────────────────── */
  --color-destructive: #ef4444;
  --color-danger:      #dc2626;
  --color-danger-hover: #b91c1c;
  --color-success:     #16a34a;

  /* ── Edges ─────────────────────────────────────────────── */
  /* Border 정책 (Phase A 도입):
   *   - line       : 기본 카드 / 입력 / 섹션 (gray-200). 약한 경계.
   *   - line-strong: 그리드 / 테이블 / 헤더-본문 사이 (gray-300). 강한 경계.
   *   - line-grid  : status 색 배경 (red/yellow/green-50) 위 그리드 셀 (gray-500).
   *                  OccupancyHeatmap 처럼 색 배경 위에서 일반 strong 으로는 약함.
   *   - gray-400 폐기 — 이전엔 "기본보다 진하게" 용도였으나 의미 모호. */
  --color-border:        #e2e8f0;  /* slate-200 — legacy alias of line */
  --color-line:          #e2e8f0;  /* gray-200 */
  --color-line-strong:   #d1d5db;  /* gray-300 */
  --color-line-grid:     #6b7280;  /* gray-500 */
  --color-input:  #e2e8f0;
  --color-ring:   #7c3aed;

  /* ── Extended semantic (dark-complete vocabulary) ──────────
   * 디자인시스템 마이그레이션(2026-06-01)에서 추가. 하드코딩 색을 토큰으로
   * 흡수하기 위한 어휘 — 각 토큰은 아래 .dark 블록에 다크값을 반드시 가진다.
   * 색값은 임시(WCAG-AA 표준 쌍). /design-tokens 스와치에서 Dean 승인 후 확정. */
  --color-warning:           #d97706;  /* amber-600 — orange/amber status 통합 */
  --color-destructive-light: #fee2e2;  /* 배너/경고 fill */
  --color-warning-light:     #fef3c7;
  --color-success-light:     #d1fae5;
  --color-surface-hover:     #f1f5f9;  /* hover:bg-gray-50/100 대체 */
  --color-surface-disabled:  #f1f5f9;  /* disabled fill */
  --color-line-subtle:       #f3f4f6;  /* gray-100 — 약한 구분선 */
  --color-scrim:             rgb(0 0 0 / 0.4);  /* 모달 오버레이 */
  /* Inverse surface — 항상 어두운 플로팅 바/스낵바 (테마 무관 동일값, .dark 미오버라이드).
   * 임시변경 PendingChangesBar 등 deliberately-dark 컨트롤. 라이트/다크 모두 동일 픽셀. */
  --color-inverse-surface:            #111827;  /* gray-900 — 바 배경 */
  --color-inverse-surface-foreground: #ffffff;  /* 본문 + 저장 버튼 바탕(반전) */
  --color-inverse-surface-muted:      #d1d5db;  /* gray-300 — 취소 텍스트 */
  --color-inverse-surface-line:       #4b5563;  /* gray-600 — 디바이더 / kbd */
  /* Occupancy 데이터 색상 (점유율 히트맵) — chrome 아님, 데이터 인코딩.
   * occupancyTone() 헬퍼만 사용. 코드몹 하드제외. */
  --color-occupancy-0: #fff7ed;  /* 낮음 */
  --color-occupancy-1: #fed7aa;
  --color-occupancy-2: #fdba74;
  --color-occupancy-3: #fb923c;  /* 높음 */
  --color-closed:      #fee2e2;  /* 마감 */

  /* 요금 변동 히트맵 (기간별 요금 매트릭스) — chrome 아닌 데이터 인코딩.
   * rateHeatBg()/rateTextTone() 헬퍼만 사용. 연속 color-mix(|비율|→opacity)라
   * 라이트=밝은 배경+진한 글자, 다크=어두운 배경+밝은 글자로 .dark 가 hue/글자색 별도 공급. */
  --color-rate-up:        #f97316;  /* orange-500 — 상승 히트 hue */
  --color-rate-up-text:   #9a3412;  /* orange-800 — 밝은 상승 배경 위 글자 */
  --color-rate-down:      #0ea5e9;  /* sky-500 — 하락 히트 hue */
  --color-rate-down-text: #075985;  /* sky-800 — 밝은 하락 배경 위 글자 */

  /* ── Environment ───────────────────────────────────────── */
  /* DEV 환경 운영 종료(2026-05-17) — PROD/DEV 모두 브랜드 violet 으로 통일.
   * 향후 staging 환경이 생기면 다시 다른 색으로 분리할 수 있음. */
  --color-env-prod: #8b5cf6;
  --color-env-dev:  #8b5cf6;

  /* ── Font scale (sub-text) ─────────────────────────────────
   * Tailwind 기본 text-xs(12px) 보다 작은 micro-typography 표준.
   * arbitrary text-[9px]/[10px]/[11px] 99곳 산발 사용 → 3 토큰으로 정리.
   * 사용처:
   *   - text-nano    : 9px  — 셀 안 보조 라벨 (캘린더 셀 공휴일명, 작은 메타) */
  --text-nano:    0.5625rem;  /* 9px  */
  --text-micro:   0.625rem;   /* 10px — 카드 안 보조 정보, 단위 표시 */
  --text-caption: 0.6875rem;  /* 11px — 카드 sub 라벨, KPI 설명 */

  /* ── Shell ─────────────────────────────────────────────────
   * 본문 최대 폭. 모든 내부 대시보드가 이 값을 쓴다 — 페이지마다 다르면
   * 탭을 옮길 때마다 좌우 여백이 튄다. vcms-admin Layout 의 max-w-[1600px] 이 기준.
   * 그래프 캔버스처럼 폭이 곧 가독성인 화면만 예외로 넓힌다. */
  --shell-max: 1600px;

  /* ── Border Radius ─────────────────────────────────────── */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;

  /* ── Sticky chrome shadow (다크 분기) ────────────────────────
   * 검정-알파 그림자는 다크 카드 위에서 휘도대비 0 = 안 보임.
   * 라이트=옅은 검정, 다크=진한 검정으로 .dark 가 재공급 (dark: 변형 미사용).
   *   --shadow-sticky-col    : 고정 첫 열(매트릭스) 우측 떠오름
   *   --shadow-sticky-header : 스크롤 시 상단 sticky 헤더 그림자 */
  --shadow-sticky-col:    4px 0 6px -2px rgba(0, 0, 0, 0.08);
  --shadow-sticky-header: 0 10px 12px -10px rgba(0, 0, 0, 0.30);

  /* ── Z-index 레이어 스케일 (값 = 현재 사용값 보존, 스태킹 무변경) ─────
   *  10~50: Tailwind 기본 유틸(z-10..z-50) 그대로 사용 — 콘텐츠 내 sticky/뱃지.
   *  아래 오버레이 계층은 토큰으로 단일화 (z-[var(--z-*)]). */
  --z-sticky:      30;    /* 콘텐츠 내 sticky 바 (탭/네비) — 오버레이 아래 */
  --z-nudge:       50;    /* 발견성 힌트/넛지 (Portal) — 콘텐츠 위, 글로벌 네비(overlay) 아래. #430 */
  --z-overlay:     60;    /* 드로어 / 사이드 오버레이 베이스 */
  --z-floating:    70;    /* 플로팅 액션 툴바 */
  --z-modal:       80;    /* 모달 백드롭 / 바텀시트 */
  --z-popover:     100;   /* 모달 위 팝오버 / 드롭다운 */
  --z-popover-top: 101;   /* 중첩 팝오버 (먼슬 피커) */
  --z-tooltip:     110;   /* 팝오버 위 툴팁 */
  --z-toast:       120;   /* 토스트 — 모달 위에도 항상 보임 */
  --z-max:         9999;  /* 최상단 (포탈 tooltip 등) */
}

.dark{
  --color-primary-light:     #2e1065;  /* violet-950 — 칩 bg */
  --color-primary-muted:     #4c1d95;  /* violet-900 — 아바타 */
  --color-on-primary-light:  #ffffff;  /* 다크: 은은한 violet-950 칩 위 흰 글씨 */

  --color-background:         #0a0f1c;  /* 더 어둡게 — 카드(slate-800)가 떠오르도록 대비 ↑ */
  --color-foreground:         #f1f5f9;  /* slate-100 — 본문 가독성 ↑ (was slate-200) */
  --color-card:               #1e293b;  /* slate-800 */
  --color-card-foreground:    #e2e8f0;
  --color-popover:            #1e293b;
  --color-popover-foreground: #e2e8f0;

  --color-secondary:            #1e293b;
  --color-secondary-foreground: #e2e8f0;
  --color-muted:                #1e293b;
  --color-muted-foreground:     #b4c0d3;  /* 보조텍스트 가독성 ↑ + /50 변형 동반 상승 (was slate-400 #94a3b8) */
  --color-accent:               #334155;
  --color-accent-foreground:    #e2e8f0;

  --color-border:      #3b4a61;  /* 카드 위 보더 가시성 ↑ (was slate-700 #334155) */
  --color-line:        #3b4a61;
  --color-line-strong: #475569;  /* slate-600 */
  --color-line-subtle: #2e3a50;  /* 카드(#1e293b)와 동색이라 다크서 안 보이던 것 → 카드보다 한 단계 밝게 (faint 유지, line #3b4a61 보다 옅음) */
  --color-input:       #334155;

  /* 뱃지 다크 쌍 — 라이트 :root 값은 다크 표면에서 대비 붕괴(녹색 #d1fae5 ≈ 2:1).
   * 900 bg + 300 text 표준 쌍으로 가독성 확보(WCAG-AA). */
  --color-badge-green-bg:  #064e3b;  --color-badge-green-text:  #6ee7b7;
  --color-badge-red-bg:    #7f1d1d;  --color-badge-red-text:    #fca5a5;
  --color-badge-gray-bg:   #334155;  --color-badge-gray-text:   #e2e8f0;
  --color-badge-blue-bg:   #1e3a8a;  --color-badge-blue-text:   #93c5fd;
  --color-badge-orange-bg: #7c2d12;  --color-badge-orange-text: #fdba74;
  --color-badge-amber-bg:  #78350f;  --color-badge-amber-text:  #fcd34d;

  /* 확장 시맨틱 다크값 */
  --color-warning:           #fbbf24;  /* amber-400 */
  --color-destructive-light: #450a0a;  /* red-950 */
  --color-warning-light:     #451a03;
  --color-success-light:     #052e16;
  --color-surface-hover:     #334155;  /* slate-700 */
  --color-surface-disabled:  #334155;  /* slate-700 — card(#1e293b)보다 밝게: disabled solid-fill 버튼 윤곽 가시 (다크에서 fill==card 로 묻히던 회귀 fix) */
  --color-scrim:             rgb(0 0 0 / 0.6);

  --color-occupancy-0: #431407;
  --color-occupancy-1: #7c2d12;
  --color-occupancy-2: #9a3412;
  --color-occupancy-3: #c2410c;
  --color-closed:      #7f1d1d;

  /* 요금 변동 히트 — 다크: hue 더 밝게(어두운 카드 위 color-mix 가독), 글자색은 밝은 톤으로 플립. */
  --color-rate-up:        #fb923c;  /* orange-400 */
  --color-rate-up-text:   #fdba74;  /* orange-300 — 어두운 상승 배경 위 글자 */
  --color-rate-down:      #38bdf8;  /* sky-400 */
  --color-rate-down-text: #7dd3fc;  /* sky-300 — 어두운 하락 배경 위 글자 */

  /* 다크: 검정 농도 ↑ — 어두운 카드 위에서도 떠오름 보이게 */
  --shadow-sticky-col:    6px 0 8px -2px rgba(0, 0, 0, 0.55);
  --shadow-sticky-header: 0 12px 16px -8px rgba(0, 0, 0, 0.60);
}

/* ── 간격 스케일 (정적 전용 추가) ───────────────────────────
 * Tailwind 를 안 쓰는 페이지엔 간격 기준이 없어서 매번 눈대중 px 가 박혔다.
 * 4px 그리드. 이 밖의 값은 쓰지 마라. */
:root{
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:20px; --sp-6:24px; --sp-8:32px; --sp-10:40px; --sp-12:48px;
  /* --shell-max 는 theme.css(정본) 가 준다 */
  --sans:ui-sans-serif,system-ui,-apple-system,"Apple SD Gothic Neo","Pretendard",sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"D2Coding",monospace;
  --shadow-sm:0 1px 2px rgba(0,0,0,.05);
  --shadow-md:0 4px 6px -1px rgba(0,0,0,.08);
}
.dark{
  --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --shadow-md:0 4px 6px -1px rgba(0,0,0,.5);
  /* 네이티브 스크롤바·폼 컨트롤도 다크로. 없으면 긴 팝오버에서 흰 스크롤바가 튄다. */
  color-scheme:dark;
}

*{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;
  scrollbar-gutter:stable;   /* 탭 전환으로 스크롤바가 생겼다 사라지며 가로로 튀는 것 방지 */
}
body{
  margin:0; background:var(--color-background); color:var(--color-foreground);
  font:14px/1.55 var(--sans); -webkit-font-smoothing:antialiased;
}
code,pre,.mono{font-family:var(--mono)}
.num{font-variant-numeric:tabular-nums; letter-spacing:-.01em}
a{color:var(--color-primary); text-decoration:none}
h1,h2,h3{margin:0; text-wrap:balance}
button{font:inherit; color:inherit; cursor:pointer}
:focus-visible{outline:2px solid var(--color-ring); outline-offset:2px; border-radius:var(--radius-sm)}
@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}

/* ── 앱바 — 모든 대시보드 공통. 로고 클릭 = Access 런처 ── */
.appbar{
  position:sticky; top:0; z-index:var(--z-sticky,30);
  background:var(--color-background);
  border-bottom:1px solid transparent;
  transition:box-shadow .2s, border-color .2s;
}
.appbar.scrolled{border-bottom-color:var(--color-line); box-shadow:0 4px 16px -6px rgba(0,0,0,.18)}
.appbar-in{
  max-width:var(--shell-max); margin:0 auto;
  display:flex; align-items:center; gap:var(--sp-4);
  padding:var(--sp-4) var(--sp-6);
}
.appbar .brand{display:flex; align-items:center; gap:9px; flex-shrink:0; color:var(--color-foreground)}
.appbar .logo{flex-shrink:0; display:block}
.appbar h1{
  font-size:16px; font-weight:800; letter-spacing:.03em; white-space:nowrap;
  display:inline-flex; gap:5px; color:var(--color-foreground);
}
.appbar h1 .mark,
.appbar h1 .devmark{color:var(--color-primary)}   /* devmark = 구 이름. 미이관 페이지 호환 */
.appbar .spacer{flex:1 1 auto}
.subbar{
  max-width:var(--shell-max); margin:0 auto;
  padding:0 var(--sp-6) var(--sp-2);
  display:flex; align-items:center; gap:var(--sp-2); flex-wrap:wrap;
}
.subbar .stamp{font-size:12px; color:var(--color-muted-foreground); font-variant-numeric:tabular-nums}
.wrap{max-width:var(--shell-max); margin:0 auto; padding:var(--sp-6) var(--sp-6) 72px}

/* 다시 불러오기 버튼 (subbar) */
.refresh-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; padding:0; border:0; background:none;
  color:var(--color-muted-foreground); border-radius:6px;
  transition:background .12s, color .12s;
}
.refresh-btn:hover{color:var(--color-foreground); background:var(--color-secondary)}
.refresh-btn svg{width:14px; height:14px}
.refresh-btn:disabled{cursor:default}
.refresh-btn.spinning svg{animation:dsspin .8s linear infinite}
@keyframes dsspin{to{transform:rotate(360deg)}}
.refresh-status{font-size:12px; color:var(--color-muted-foreground)}
.refresh-status.ok{color:var(--color-success)}
.refresh-status.err{color:var(--color-danger)}

/* ── 프로필 메뉴 — 아이덴티티 / 화면모드 / 로그아웃 ── */
.pm{position:relative; flex-shrink:0}
.pm-btn{
  width:32px; height:32px; border-radius:9999px; border:0;
  background:var(--color-primary-muted); color:var(--color-on-primary-light);
  font-weight:600; font-size:12px;
  display:inline-flex; align-items:center; justify-content:center; transition:filter .12s;
}
.pm-btn:hover{filter:brightness(.94)}
.pm-menu{
  display:none; position:absolute; right:0; top:calc(100% + 8px); width:256px;
  background:var(--color-card); border:1px solid var(--color-line);
  border-radius:var(--radius-lg); box-shadow:0 10px 30px rgba(0,0,0,.18);
  overflow:hidden; z-index:var(--z-popover,100);
}
.pm.open .pm-menu{display:block}
.pm-id{display:flex; align-items:center; gap:var(--sp-3); padding:14px var(--sp-4)}
.pm-av{
  width:36px; height:36px; border-radius:9999px;
  background:var(--color-primary-muted); color:var(--color-on-primary-light);
  font-weight:600; font-size:14px;
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
}
.pm-who{min-width:0; flex:1}
.pm-nm{font-size:14px; font-weight:600; color:var(--color-foreground); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pm-em{font-size:12px; color:var(--color-muted-foreground); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pm-div{height:1px; background:var(--color-line)}
.pm-row{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-2);
  width:100%; padding:10px var(--sp-4); background:none; border:0; font:inherit;
  font-size:13px; color:var(--color-foreground); text-align:left; text-decoration:none;
}
.pm-row:hover{background:var(--color-secondary)}
.pm-rl{display:inline-flex; align-items:center; gap:9px}
.pm-rv{font-size:12px; font-weight:500; color:var(--color-muted-foreground)}
.pm-ic{width:16px; height:16px; color:var(--color-muted-foreground); flex-shrink:0}
.pm-logout{color:var(--color-danger)}
.pm-logout .pm-ic{color:var(--color-danger)}
.pm-logout:hover{background:var(--color-destructive-light)}

/* ── 프리미티브 (admin-ui/src/shared/ui 대응) ── */
.card{
  background:var(--color-card); border:1px solid var(--color-line);
  border-radius:var(--radius-md); box-shadow:var(--shadow-sm);
  padding:var(--sp-4);
}
.card-pad-lg{padding:var(--sp-5) var(--sp-6)}

.badge{
  display:inline-flex; align-items:center; font-weight:500;
  border-radius:var(--radius-sm); padding:2px var(--sp-2); font-size:12px;
  background:var(--color-badge-gray-bg); color:var(--color-badge-gray-text);
}
.badge-sm{padding:2px 6px; font-size:var(--text-micro,10px)}
.badge-green{background:var(--color-badge-green-bg); color:var(--color-badge-green-text)}
.badge-red{background:var(--color-badge-red-bg); color:var(--color-badge-red-text)}
.badge-blue{background:var(--color-badge-blue-bg); color:var(--color-badge-blue-text)}
.badge-amber{background:var(--color-badge-amber-bg); color:var(--color-badge-amber-text)}
.badge-orange{background:var(--color-badge-orange-bg); color:var(--color-badge-orange-text)}
.badge-primary{background:var(--color-primary-muted); color:var(--color-on-primary-light)}

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  height:36px; padding:0 var(--sp-3); font-size:14px; font-weight:500;
  border-radius:var(--radius-md); border:1px solid transparent;
  background:var(--color-primary); color:var(--color-primary-foreground);
  transition:background .12s;
}
.btn:hover{background:var(--color-primary-hover)}
.btn-sm{height:32px; padding:0 var(--sp-3); font-size:12px}
.btn-outline{
  background:var(--color-card); color:var(--color-foreground);
  border-color:var(--color-border);
}
.btn-outline:hover{background:var(--color-secondary)}
.btn-ghost{background:none; color:var(--color-muted-foreground); border-color:transparent}
.btn-ghost:hover{background:var(--color-secondary); color:var(--color-foreground)}
.btn-danger{background:var(--color-danger); color:#fff}
.btn-danger:hover{background:var(--color-danger-hover)}

.icon-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; padding:0; border-radius:var(--radius-md);
  border:1px solid var(--color-line); background:var(--color-secondary);
  color:var(--color-muted-foreground); transition:background .12s,color .12s;
}
.icon-btn:hover{color:var(--color-foreground)}

.input{
  background:var(--color-background); color:var(--color-foreground);
  border:1px solid var(--color-input); border-radius:var(--radius-md);
  padding:7px var(--sp-3); font-size:14px;
}
.input::placeholder{color:var(--color-muted-foreground)}

/* ── 데이터 테이블 ── */
.ds-table{border-collapse:collapse; width:100%; font-size:13px}
.ds-table th{
  text-align:left; font-size:var(--text-caption,11px); font-weight:700;
  letter-spacing:.05em; text-transform:uppercase;
  color:var(--color-muted-foreground);
  padding:0 var(--sp-3) 7px; border-bottom:1px solid var(--color-line);
  white-space:nowrap;
}
.ds-table td{padding:7px var(--sp-3); border-bottom:1px solid var(--color-line-subtle); vertical-align:top}
.ds-table tr:last-child td{border-bottom:0}
.ds-table td.n{text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap}
.tablewrap{overflow-x:auto}

/* ── KPI 타일 ── */
.kpi-grid{display:grid; gap:var(--sp-3); grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}
.kpi{
  background:var(--color-card); border:1px solid var(--color-line);
  border-top:3px solid var(--color-line); border-radius:var(--radius-md);
  box-shadow:var(--shadow-sm); padding:var(--sp-3) var(--sp-4);
  display:flex; flex-direction:column; gap:2px;
}
.kpi-label{
  font-size:var(--text-caption,11px); font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--color-muted-foreground);
}
.kpi-value{font-size:28px; font-weight:700; line-height:1.15; font-variant-numeric:tabular-nums; letter-spacing:-.02em}
.kpi-value .u{font-size:14px; font-weight:600; color:var(--color-muted-foreground); margin-left:2px}
.kpi-note{font-size:12px; color:var(--color-muted-foreground); margin-top:3px}
.kpi.t-primary{border-top-color:var(--color-primary)}
.kpi.t-danger{border-top-color:var(--color-danger)}
.kpi.t-warning{border-top-color:var(--color-warning)}
.kpi.t-success{border-top-color:var(--color-success)}

.section-head{display:flex; align-items:baseline; gap:var(--sp-3); margin:0 0 var(--sp-3)}
.section-head h2{font-size:13px; font-weight:700}
.section-head .hint{font-size:12px; color:var(--color-muted-foreground)}
