/* ═══════════════════════════════════════════════
   PJI Dashboard — Custom CSS (Web-first Responsive)
   Converted from template.html mockup
═══════════════════════════════════════════════ */

/* ── Google Font ──────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600;700&family=DM+Mono:wght@400;500&family=IBM+Plex+Sans+KR:wght@400;500;600;700&family=IBM+Plex+Mono:wght@500;600;700&display=swap');

/* ── Design Tokens ───────────────────────────── */
:root {
  --green:       #006838;
  --green-dark:  #004d29;
  --green-light: #e6f2ec;
  --green-mid:   #c2dfd0;
  --green-fade:  #f0f8f4;
  --white:       #ffffff;
  --gray-50:     #f8f9fa;
  --gray-100:    #f1f3f4;
  --gray-200:    #e8eaed;
  --gray-300:    #dadce0;
  --gray-400:    #bdc1c6;
  --gray-500:    #80868b;
  --gray-600:    #5f6368;
  --gray-700:    #3c4043;
  --gray-900:    #202124;
  --red:         #c5221f;
  --amber:       #f9a825;
  --blue:        #1a73e8;
  --text:        #1a1c1e;
  --border:      #e2e6ea;
  --shadow-sm:   0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06);
  --shadow-md:   0 4px 12px rgba(0,0,0,.10), 0 2px 4px rgba(0,0,0,.06);
  --shadow-lg:   0 8px 24px rgba(0,0,0,.12);
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --sidebar-w: 260px;
  --header-h: 56px;
  --transition: .18s cubic-bezier(.4,0,.2,1);

  /* 그린 면 위에 올라가는 글자색. 다크에서는 그린이 밝아지므로 어두운 글자로 뒤집는다. */
  --on-green:    #ffffff;
  /* 헤더는 브랜드 그린을 그대로 쓰지 않는다. 다크에서 채도 높은 띠는 눈이 부시다. */
  --header-bg:   #006838;
  --rail-w:      66px;
}

/* ── Reset ───────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'DM Sans', sans-serif !important;
  background: var(--gray-50) !important;
  color: var(--text) !important;
  font-size: 14px !important;
  line-height: 1.5 !important;
  -webkit-font-smoothing: antialiased !important;
}

/* ── Layout Shell ─────────────────────────────── */
.db-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  height: var(--header-h);
  background: var(--header-bg);
  display: flex; align-items: center; gap: 16px;
  padding: 0 20px;
  box-shadow: 0 2px 8px rgba(0,104,56,.25);
}
/* ── 차트별 로딩 스피너 (Wave dots) ─────────── */
.sales-chart-loading .chart-card,
.sales-chart-loading .kpi-grid,
.sales-chart-loading .kpi-mini-grid,
.sales-chart-loading .achieve-grid,
.sales-chart-loading .table-card,
.product-chart-loading .chart-card,
.product-chart-loading .table-card,
.product-chart-loading #category-chart-container,
.customer-chart-loading .chart-card,
.customer-chart-loading .kpi-row,
.customer-chart-loading .cluster-summary-row,
.compare-chart-loading .chart-card,
.compare-chart-loading .cmp-kpi-row,
.region-cmp-chart-loading .chart-card,
.region-cmp-chart-loading .cmp-kpi-row,
.map-chart-loading .chart-card {
  position: relative;
}
.sales-chart-loading .chart-card::after,
.sales-chart-loading .kpi-grid::after,
.sales-chart-loading .kpi-mini-grid::after,
.sales-chart-loading .achieve-grid::after,
.sales-chart-loading .table-card::after,
.product-chart-loading .chart-card::after,
.product-chart-loading .table-card::after,
.product-chart-loading #category-chart-container::after,
.customer-chart-loading .chart-card::after,
.customer-chart-loading .kpi-row::after,
.customer-chart-loading .cluster-summary-row::after,
.compare-chart-loading .chart-card::after,
.compare-chart-loading .cmp-kpi-row::after,
.region-cmp-chart-loading .chart-card::after,
.region-cmp-chart-loading .cmp-kpi-row::after,
.map-chart-loading .chart-card::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(255,255,255,0.6);
  border-radius: inherit;
  z-index: 10;
}
.chart-wave-loader {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 11;
  pointer-events: none;
}

/* ── 피자 로딩 오버레이 ──────────────────────── */
@keyframes pizza-rotate {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
#pizza-spin-img,
#pizza-spin-img-product,
#pizza-spin-img-customer {
  width: 90px; height: 90px;
  animation: pizza-rotate 1s linear infinite;
  filter: drop-shadow(0 4px 12px rgba(0,0,0,0.4));
}

.db-header .header-logo {
  display: flex; align-items: center; gap: 10px;
}
.db-header .logo-icon {
  width: 64px; height: 64px; border-radius: 8px;
  background: transparent;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
}
.db-header .logo-text {
  font-size: 17px; font-weight: 700; color: #fff; letter-spacing: -.3px;
}
.db-header .logo-sub {
  font-size: 10px; font-weight: 400; color: rgba(255,255,255,.65);
  display: block; line-height: 1;
}
.header-spacer { flex: 1; }
.header-pill {
  background: rgba(255,255,255,.15); color: #fff;
  font-size: 11px; font-weight: 600; letter-spacing: .5px;
  padding: 4px 10px; border-radius: 20px;
}
.header-date {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--gray-100); border-radius: 4px;
  padding: 3px 8px; font-size: 11px; color: var(--gray-600);
}
.header-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: rgba(255,255,255,.25);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: #fff; font-weight: 700;
  cursor: pointer;
}
.header-logout {
  background: rgba(255,255,255,.15); color: #fff;
  border: 1px solid rgba(255,255,255,.3);
  font-size: 11px; font-weight: 500;
  padding: 4px 10px; border-radius: 6px;
  cursor: pointer; transition: background var(--transition);
}
.header-logout:hover { background: rgba(255,255,255,.25); }

.db-app-body {
  margin-top: var(--header-h);
  display: flex;
  min-height: calc(100vh - var(--header-h));
}

/* ── Sidebar ──────────────────────────────────── */
.db-sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--white);
  border-right: 1px solid var(--border);
  padding: 20px 16px;
  position: sticky; top: var(--header-h);
  height: calc(100vh - var(--header-h));
  overflow-y: auto;
  overflow-x: hidden;
}
.db-sidebar::-webkit-scrollbar { width: 4px; }
.db-sidebar::-webkit-scrollbar-track { background: transparent; }
.db-sidebar::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: 2px; }

.sidebar-section { margin-bottom: 20px; }
.sidebar-title {
  font-size: 10px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; color: var(--gray-500);
  margin-bottom: 10px; padding: 0 4px;
}
.filter-group { margin-bottom: 14px; }
.filter-label {
  font-size: 11px; font-weight: 600; color: var(--gray-600);
  display: flex; align-items: center; gap: 5px;
  margin-bottom: 6px; padding: 0 2px;
}
.filter-label .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--green); display: inline-block; flex-shrink: 0;
}
.sidebar-divider {
  height: 1px; background: var(--border); margin: 4px 0 16px;
}

/* ── dcc.Dropdown 커스텀 스타일 ────────────────── */
.custom-dropdown .Select-control,
.custom-dropdown .VirtualizedSelectFocusedOption,
.custom-dropdown .Select--single > .Select-control {
  border: 1.5px solid var(--border) !important;
  border-radius: var(--r-sm) !important;
  font-family: 'DM Sans', sans-serif !important;
  font-size: 13px !important;
  color: var(--text) !important;
  background: var(--white) !important;
  min-height: 36px !important;
  box-shadow: none !important;
  transition: border-color var(--transition) !important;
}
.custom-dropdown .Select-control:hover,
.custom-dropdown .is-focused .Select-control {
  border-color: var(--green) !important;
  box-shadow: 0 0 0 3px rgba(0,104,56,.12) !important;
}
.custom-dropdown .Select-placeholder,
.custom-dropdown .Select-value-label {
  font-size: 13px !important;
  color: var(--text) !important;
  line-height: 34px !important;
}
.custom-dropdown .Select-menu-outer {
  border: 1.5px solid var(--border) !important;
  border-radius: var(--r-sm) !important;
  box-shadow: var(--shadow-md) !important;
  font-size: 13px !important;
  z-index: 200 !important;
}
.custom-dropdown .Select-option.is-selected {
  background: var(--green-light) !important;
  color: var(--green) !important;
}
.custom-dropdown .Select-option.is-focused {
  background: var(--green-fade) !important;
  color: var(--green) !important;
}
.custom-dropdown .Select-arrow { border-top-color: var(--gray-500) !important; }
.custom-dropdown .Select-arrow-zone:hover .Select-arrow {
  border-top-color: var(--green) !important;
}

/* ── Period / Comp Toggle Buttons ─────────────── */
.period-btns {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
}
.comp-btns { display: flex; gap: 4px; }

.period-btn, .comp-btn {
  padding: 6px 4px;
  border: 1.5px solid var(--border); border-radius: 6px;
  background: var(--white);
  font-family: 'DM Sans', sans-serif;
  font-size: 11px; font-weight: 500; color: var(--gray-600);
  cursor: pointer; text-align: center;
  transition: all var(--transition);
}
.period-btn:hover, .comp-btn:hover {
  border-color: var(--green); color: var(--green); background: var(--green-fade);
}
.period-btn.active {
  border-color: var(--green); background: var(--green); color: var(--on-green);
}
.comp-btn { flex: 1; font-weight: 600; }
.comp-btn.active.yoy { border-color: #1a73e8; background: #1a73e8; color: #fff; }
.comp-btn.active.mom { border-color: #f9ab00; background: #f9ab00; color: #fff; }
.comp-btn.active.wow { border-color: #34a853; background: #34a853; color: #fff; }
.comp-btn:disabled { opacity: 0.35; cursor: not-allowed; pointer-events: none; }

/* 쓰이지 않는 필터 묶음 — 데이터 탭에서는 비교 기준이 놀고 있다.
   버튼의 :disabled 는 이미 흐려지지만 머리글과 드롭다운은 그대로라
   묶음째 흐려 줘야 '지금은 안 쓰는 자리' 로 읽힌다. */
.filter-group.is-off .filter-label,
.filter-group.is-off .comp-period-label { opacity: .4; }
.filter-group.is-off .custom-dropdown {
  opacity: .45; pointer-events: none;
}

/* 데이터 탭에서는 비교 기간을 쓰지 않으니 상태 줄에서도 뺀다 */
.status-bar-db.no-comp .status-comp { display: none; }
.comp-period-label {
  font-size: 11px; color: var(--gray-500);
  margin-top: 5px; text-align: center; line-height: 1.4;
}

/* ── Date Range Rows ──────────────────────────── */
.date-range-row { display: flex; flex-direction: column; gap: 6px; }
.date-row-inner { display: flex; align-items: center; gap: 6px; }
.date-mini-label {
  font-size: 10px; font-weight: 600; color: var(--gray-500);
  min-width: 22px; flex-shrink: 0;
}

/* dcc.DatePickerSingle 스타일 오버라이드 */
.db-date-picker .SingleDatePickerInput,
.db-date-picker .DateInput {
  border: none !important; background: transparent !important;
}
.db-date-picker .DateInput_input {
  flex: 1; padding: 6px 8px !important;
  border: 1.5px solid var(--border) !important;
  border-radius: var(--r-sm) !important;
  font-family: 'DM Sans', sans-serif !important;
  font-size: 12px !important; color: var(--text) !important;
  background: var(--white) !important; width: 100% !important;
  line-height: 1.4 !important;
}
.db-date-picker .DateInput_input:focus {
  border-color: var(--green) !important;
  box-shadow: 0 0 0 3px rgba(0,104,56,.12) !important;
  outline: none !important;
}
.db-date-picker .SingleDatePicker,
.db-date-picker .SingleDatePickerInput {
  width: 100% !important;
}

/* ── Search Buttons ───────────────────────────── */
.btn-search {
  width: 100%; padding: 10px;
  background: var(--green); color: var(--on-green);
  border: none; border-radius: var(--r-sm);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 700;
  cursor: pointer; letter-spacing: .3px;
  display: flex; align-items: center; justify-content: center; gap: 7px;
  transition: background var(--transition), transform .1s;
  box-shadow: 0 2px 8px rgba(0,104,56,.3);
}
.btn-search:hover { background: var(--green-dark); }
.btn-search:active { transform: translateY(1px); }
.btn-reset {
  width: 100%; padding: 10px;
  background: var(--gray-100); color: var(--gray-600);
  border: none; border-radius: var(--r-sm);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 500;
  cursor: pointer; transition: background var(--transition);
}
.btn-reset:hover { background: var(--gray-200); }

/* ── Main Content ─────────────────────────────── */
.db-main {
  flex: 1; padding: 24px 24px 40px;
  min-width: 0; overflow-x: clip;
}

/* ── Status Bar ───────────────────────────────── */
.status-bar-db {
  display: flex; align-items: center; gap: 8px;
  background: var(--green-fade); border: 1px solid var(--green-mid);
  border-radius: var(--r-sm);
  padding: 8px 14px; margin-bottom: 20px;
  font-size: 12px; color: var(--green-dark);
}
.status-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--green); flex-shrink: 0;
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .4; }
}

/* ── Tab Navigation ───────────────────────────── */
.db-tab-nav {
  display: flex; gap: 0; margin-bottom: 24px;
  border-bottom: 2px solid var(--border);
  position: sticky;
  top: var(--header-h);
  z-index: 50;
  background: var(--bg);
}
.db-tab-btn {
  padding: 10px 22px; border: none; background: transparent;
  font-family: 'DM Sans', sans-serif;
  font-size: 14px; font-weight: 500; color: var(--gray-500);
  cursor: pointer; position: relative;
  transition: color var(--transition);
  white-space: nowrap;
}
.db-tab-btn::after {
  content: ''; position: absolute; bottom: -2px; left: 0; right: 0;
  height: 2px; background: var(--green);
  transform: scaleX(0); transition: transform var(--transition);
}
.db-tab-btn:hover { color: var(--green); }
.db-tab-btn.active { color: var(--green); font-weight: 700; }
.db-tab-btn.active::after { transform: scaleX(1); }

/* ── KPI Cards ────────────────────────────────── */
.kpi-grid {
  display: grid;
  /* 고정 4열이면 카드 폭이 227px 밖에 안 나와, 값(30px)과 YOY 배지(15px)가
     한 줄에 못 들어가고 배지가 아래로 밀렸다. 최소 폭을 정해 두면 화면에 따라
     열 수가 자동으로 정해지면서 두 숫자가 항상 나란히 놓인다.
     300px = 값 128 + 배지 115(+109.24% 기준) + 간격 10 + 좌우 패딩 36 + 여유. */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px; margin-bottom: 20px;
}
.kpi-card {
  background: var(--white); border-radius: var(--r-md);
  padding: 16px 18px; border: 1px solid var(--border);
  box-shadow: var(--shadow-sm); position: relative; overflow: hidden;
  transition: box-shadow var(--transition), transform var(--transition);
  cursor: default;
}
.kpi-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.kpi-card::before {
  content: ''; position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  background: var(--accent-color, var(--green));
}
.kpi-card .kpi-label {
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 600; letter-spacing: -.2px;
  color: var(--gray-600); margin-bottom: 8px;
}
/* 값 + 증감률을 한 줄에. baseline 정렬이라 숫자 크기가 달라도 밑선이 맞는다 */
.kpi-card .kpi-value-row {
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 4px 10px; margin-bottom: 6px;
}
.kpi-card .kpi-num {
  font-family: 'IBM Plex Mono', 'DM Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 30px; font-weight: 700; color: var(--text);
  letter-spacing: -1.2px; line-height: 1.05;
}
.kpi-card .kpi-num.sm { font-size: 22px; letter-spacing: -.8px; }
.kpi-card .kpi-num .unit {
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 500; color: var(--gray-500);
  letter-spacing: 0; margin-left: 1px;
}
/* 한 카드에 값 여러 개 (매장 평균 / 매장 수) */
.kpi-card .kpi-multi-row {
  display: flex; align-items: flex-end; flex-wrap: wrap;
  gap: 6px 18px; margin-bottom: 6px;
}
.kpi-card .kpi-multi-item { display: flex; flex-direction: column; gap: 2px; }
.kpi-card .kpi-sub {
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 11px; font-weight: 500; color: var(--gray-500);
}
.comp-badge {
  font-family: 'IBM Plex Mono', 'DM Mono', monospace;
  font-variant-numeric: tabular-nums;
  padding: 2px 8px; border-radius: 5px;
  font-size: 15px; font-weight: 700; white-space: nowrap;
}
.comp-badge.up { background: #e6f4ea; color: #1e8e3e; }
.comp-badge.down { background: #fce8e6; color: #c5221f; }
.comp-label {
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 11px; color: var(--gray-400);
}

/* 좁은 화면에서는 카드 폭이 170px 안팎이라 값을 조금 줄인다 */
@media (max-width: 520px) {
  .kpi-card .kpi-num     { font-size: 24px; letter-spacing: -.9px; }
  .kpi-card .kpi-num.sm  { font-size: 19px; }
  .comp-badge            { font-size: 13px; padding: 2px 6px; }
  .kpi-card .kpi-multi-row { gap: 6px 12px; }
}

/* ── Customer KPI — 3열 2행 그리드 ─────────────── */
.kpi-grid-c {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto;
  gap: 14px;
  margin-bottom: 20px;
}

/* ── Customer KPI 필터 배지 (매장 선택 시 표시) ──── */
.kpi-filter-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #e8f5e9;
  border: 1px solid #a5d6a7;
  color: #2e7d32;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 14px;
  border-radius: 8px;
  margin-bottom: 8px;
}

/* ── Customer KPI Cards (리치 버전) ─────────────── */
.kpi-card-c {
  background: var(--white);
  border-radius: var(--r-md);
  padding: 16px 18px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  position: relative;
  transition: box-shadow .18s, transform .18s;
  cursor: default;
  overflow: hidden;
}
.kpi-card-c::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--accent, var(--green));
}
.kpi-card-c:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
/* 헤더 */
.kpi-c-header {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}
.kpi-c-icon {
  font-size: 16px;
  width: 28px; height: 28px;
  border-radius: 7px;
  background: var(--accent-bg, #f5f5f5);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.kpi-c-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .4px;
  color: var(--gray-500);
  text-transform: uppercase;
}
/* 메인 수치 */
.kpi-c-main {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.kpi-c-main-val {
  font-size: 26px;
  font-weight: 700;
  font-family: 'DM Mono', monospace;
  color: var(--text);
  letter-spacing: -1px;
  line-height: 1.1;
}
.kpi-c-main-unit {
  font-size: 12px;
  font-weight: 500;
  color: var(--gray-500);
  letter-spacing: 0;
}
/* 보조 행 */
.kpi-c-sub-area {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 8px;
}
.kpi-c-sub-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  color: var(--gray-500);
  line-height: 1.4;
}
.kpi-c-sub-label { color: var(--gray-400); }
.kpi-c-sub-val   { font-weight: 600; color: var(--text); }
/* 뱃지 행 (VIP 등급 분포용) */
.kpi-c-badge-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 6px;
}
.kpi-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 3px 8px;
  border-radius: 6px;
  min-width: 44px;
  flex: 1;
}
.kpi-badge .badge-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
}
.kpi-badge .badge-val {
  font-size: 13px;
  font-weight: 700;
  font-family: 'DM Mono', monospace;
  margin-top: 1px;
}

/* ── Achievement Cards ────────────────────────── */
.achieve-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 14px; margin-bottom: 20px;
}
.achieve-card {
  background: var(--white); border-radius: var(--r-md);
  padding: 16px 18px; border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}
.achieve-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 12px;
}
.achieve-type {
  font-size: 12px; font-weight: 700; color: var(--green);
  background: var(--green-light); padding: 3px 8px;
  border-radius: 4px; letter-spacing: .5px;
}
.achieve-period-label { font-size: 11px; color: var(--gray-500); }
.achieve-pct {
  font-size: 24px; font-weight: 700;
  font-family: 'DM Mono', monospace; letter-spacing: -1px;
}
.achieve-pct.over { color: var(--green); }
.achieve-pct.under { color: var(--red); }
.progress-track {
  width: 100%; height: 6px; background: var(--gray-200);
  border-radius: 3px; overflow: hidden; position: relative;
  margin: 8px 0;
}
.progress-fill { height: 100%; border-radius: 3px; transition: width .6s cubic-bezier(.4,0,.2,1); }
.progress-fill.over { background: var(--green); }
.progress-fill.under { background: var(--amber); }
.achieve-sub { font-size: 11px; color: var(--gray-500); }
.achieve-sub span { font-weight: 600; color: var(--gray-700); }

/* ── KPI Mini (12종) ──────────────────────────── */
.kpi-mini-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 10px; margin-bottom: 20px;
}
.kpi-mini {
  background: var(--white); border-radius: var(--r-sm);
  border: 1px solid var(--border); padding: 12px 14px;
  box-shadow: var(--shadow-sm);
}
.kpi-mini .km-label {
  font-size: 10px; font-weight: 700; color: var(--gray-500);
  text-transform: uppercase; letter-spacing: .4px; margin-bottom: 4px;
}
.kpi-mini .km-val {
  font-size: 18px; font-weight: 700;
  font-family: 'DM Mono', monospace; color: var(--text); letter-spacing: -.5px;
}
.kpi-mini .km-unit { font-size: 10px; color: var(--gray-400); margin-left: 2px; }
.kpi-mini .km-bar { margin-top: 6px; }
.kpi-mini .km-bar-track { height: 3px; background: var(--gray-200); border-radius: 2px; }
.kpi-mini .km-bar-fill { height: 100%; border-radius: 2px; }
.kpi-mini.good .km-val { color: var(--green); }
.kpi-mini.good .km-bar-fill { background: var(--green); }
.kpi-mini.warn .km-val { color: var(--amber); }
.kpi-mini.warn .km-bar-fill { background: var(--amber); }
.kpi-mini.bad .km-val { color: var(--red); }
.kpi-mini.bad .km-bar-fill { background: var(--red); }

/* ── Section Label ────────────────────────────── */
.section-label {
  font-size: 11px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; color: var(--gray-400);
  display: flex; align-items: center; gap: 8px;
  margin-top: 28px;      /* ← 이전 차트와 구분 여백 */
  margin-bottom: 12px;
}
.section-label:first-child { margin-top: 0; }  /* KPI 위 첫 섹션은 여백 없음 */
.section-label::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}

/* ── Pareto Controls ──────────────────────────── */
.pareto-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px 14px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.pareto-controls .axis-label {
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  color: var(--gray-600);
  letter-spacing: 0;
  text-transform: none;
}
.pareto-slider-wrap {
  flex: 1;
  min-width: 200px;
  max-width: 420px;
}
/* 파레토 요약 뱃지 */
.pareto-summary-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--green-light);
  border: 1px solid var(--green-mid);
  color: var(--green-dark);
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 12px;
  white-space: nowrap;
}

/* ── Chart Cards ──────────────────────────────── */
.chart-row { display: grid; gap: 14px; margin-bottom: 20px; }
.chart-row.cols-2 { grid-template-columns: 1fr 1fr; }
.chart-row.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.chart-row.cols-1-2 { grid-template-columns: 1fr 2fr; }
.chart-row.cols-2-1 { grid-template-columns: 2fr 1fr; }
.chart-row.cols-1  { grid-template-columns: 1fr; }

.chart-card {
  background: var(--white); border-radius: var(--r-md);
  border: 1px solid var(--border); box-shadow: var(--shadow-sm);
  overflow: hidden;
  position: relative;
}
.chart-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px 0; gap: 10px;
}
.chart-title {
  font-size: 13px; font-weight: 700; color: var(--text);
  display: flex; align-items: center; gap: 7px;
}
/* 산점도 제목 — chart-card 직접 자식으로 올라와 padding 적용 */
.scatter-chart-title {
  padding: 14px 18px 0;
}
.ct-icon {
  width: 22px; height: 22px; border-radius: 5px;
  background: var(--green-light);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px;
}

/* ── 산점도 축 선택 컨트롤 ────────────────────────── */
.scatter-controls {
  display: flex;
  flex-wrap: wrap;           /* 좁은 화면에서 줄바꿈 */
  gap: 10px;
  padding: 10px 18px 14px;
  border-bottom: 1px solid var(--border);
  align-items: flex-end;     /* 레이블+드롭다운 수직 정렬 */
}
.axis-selector {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 140px;           /* 최소 140px, 여유 있으면 늘어남 */
  min-width: 140px;
  max-width: 260px;
}
.axis-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--gray-500);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  user-select: none;
}
/* Dash Dropdown 내부 폰트·높이 조정 */
.scatter-axis-dd .Select-control,
.scatter-axis-dd .Select-menu-outer {
  font-size: 12px !important;
}
.scatter-axis-dd .Select-control {
  min-height: 32px !important;
  height: 32px !important;
  border-color: var(--border) !important;
  border-radius: 6px !important;
}

/* ── 군집 분류 기준 정보 버튼 & 패널 ───────────────── */
/* 제목 행 래퍼: 상대 위치로 패널 기준점 제공 */
.scatter-title-wrap {
  position: relative;
  padding: 14px 18px 0;
}
/* 정보 버튼 컨테이너 (버튼 주변 여백) */
.info-btn-wrap {
  display: inline-flex;
  align-items: center;
  margin-left: 8px;
}
/* 하늘색 원형 느낌표 버튼 */
.info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #b3e5fc;        /* 하늘색 배경 */
  color: #0277bd;             /* 진한 파란 텍스트 */
  border: none;
  font-size: 11px;
  font-weight: 900;
  font-family: 'DM Sans', sans-serif;
  cursor: pointer;
  line-height: 1;
  transition: background 0.15s, transform 0.1s;
  flex-shrink: 0;
}
.info-btn:hover {
  background: #81d4fa;
  transform: scale(1.12);
}
.info-btn:active { transform: scale(0.95); }

/* 팝업 패널 */
.info-panel {
  position: relative;
  margin: 10px 0 6px;
  padding: 16px 18px;
  background: var(--white);
  border: 1px solid #b3e5fc;
  border-left: 4px solid #0288d1;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  z-index: 100;
  animation: fadeSlideDown 0.18s ease;
}
@keyframes fadeSlideDown {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.info-panel-title {
  font-size: 13px;
  font-weight: 800;
  color: #0277bd;
  margin-bottom: 6px;
}
.info-panel-desc {
  font-size: 12px;
  color: var(--gray-600);
  line-height: 1.6;
  margin: 0 0 12px;
}
.info-panel-subtitle {
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  margin: 10px 0 6px;
}
/* 점수 기준 테이블 */
.info-panel-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  margin-bottom: 6px;
}
.info-panel-table th {
  background: #e1f5fe;
  color: #01579b;
  font-weight: 700;
  padding: 5px 10px;
  text-align: left;
  border-bottom: 1px solid #b3e5fc;
}
.info-panel-table td {
  padding: 5px 10px;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}
.info-panel-table tr:last-child td { border-bottom: none; }
.info-panel-table tr:nth-child(even) td { background: var(--surface); }
/* 주석 */
.info-panel-note {
  font-size: 11px;
  color: var(--gray-500);
  margin: 8px 0 4px;
  line-height: 1.5;
}
/* 군집별 특성 행 */
.info-segment-row {
  display: flex;
  align-items: flex-start;
  font-size: 12px;
  padding: 3px 0;
  line-height: 1.5;
}

/* ── 군집 요약 카드 행 ─────────────────────────────── */
.cluster-summary-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 18px 16px;
  border-top: 1px solid var(--border);
}
.cluster-card {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
}
.cluster-card-name {
  font-weight: 700;
  color: var(--text);
}
.cluster-card-sep {
  color: var(--gray-400);
  margin: 0 2px;
}
.cluster-card-count {
  color: var(--gray-600);
}
.cluster-card-pct {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 10px;
  font-weight: 700;
  font-size: 11px;
  margin-left: 4px;
}

.chart-actions { display: flex; gap: 4px; }
.chart-action-btn {
  padding: 3px 8px; border: 1px solid var(--border);
  border-radius: 4px; background: transparent;
  font-family: 'DM Sans', sans-serif;
  font-size: 10px; font-weight: 600; color: var(--gray-600);
  cursor: pointer; transition: all var(--transition);
}
.chart-action-btn:hover, .chart-action-btn.active {
  background: var(--green); border-color: var(--green); color: var(--on-green);
}
.chart-body { padding: 14px 18px 18px; }

/* Plotly 차트 래퍼 */
.chart-body .js-plotly-plot,
.chart-body .plot-container {
  width: 100% !important;
}
.chart-body .js-plotly-plot .plotly { border: none !important; }

/* ── Table Cards ──────────────────────────────── */
.table-card {
  background: var(--white); border-radius: var(--r-md);
  border: 1px solid var(--border); box-shadow: var(--shadow-sm);
  margin-bottom: 20px; overflow: hidden;
}
.table-header {
  padding: 14px 18px;
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 1px solid var(--border);
}
.data-table { width: 100%; border-collapse: collapse; }
.data-table th {
  padding: 9px 14px; text-align: left;
  font-size: 10px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--gray-500);
  background: var(--gray-50); border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table td {
  padding: 9px 14px; font-size: 13px; color: var(--text);
  border-bottom: 1px solid var(--gray-100);
}
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: var(--green-fade); }
.data-table td.num { font-family: 'DM Mono', monospace; text-align: right; }
.data-table td.rank {
  width: 32px; font-weight: 700; color: var(--gray-400);
  font-family: 'DM Mono', monospace;
}
.data-table td.rank.top { color: var(--green); }
.bar-cell { display: flex; align-items: center; gap: 8px; }
.inline-bar {
  flex: 1; height: 4px; background: var(--gray-200);
  border-radius: 2px; overflow: hidden; min-width: 60px;
}
.inline-fill { height: 100%; background: var(--green); border-radius: 2px; }
.badge-pct {
  font-size: 11px; font-weight: 700;
  padding: 2px 6px; border-radius: 4px;
}
.badge-pct.up { background: #e6f4ea; color: #1e8e3e; }
.badge-pct.dn { background: #fce8e6; color: #c5221f; }

/* ── 지역 평균 비교 탭 ───────────────────────── */
.rcmp-region-info {
  font-size: 12px; color: var(--gray-600);
  padding: 6px 10px; background: var(--gray-50);
  border: 1px solid var(--gray-200); border-radius: 6px;
  line-height: 1.5;
}

/* ── 지역 드릴다운 ────────────────────────────── */
.region-drill-btn {
  background: none; border: none; padding: 0;
  color: var(--green); font-weight: 600; font-size: 13px;
  cursor: pointer; text-decoration: underline dotted;
  text-underline-offset: 2px;
}
.region-drill-btn:hover { color: var(--green-dark); }
.region-drill-panel {
  background: var(--gray-50); border: 1px solid var(--gray-200);
  border-radius: 10px; padding: 16px 18px;
  margin-bottom: 16px;
  animation: fadeInDown 0.2s ease;
}
@keyframes fadeInDown {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Product Grid ─────────────────────────────── */
.product-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 14px; margin-bottom: 20px;
}
.pie-legend {
  display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px;
}
.pie-legend-item { display: flex; align-items: center; gap: 5px; font-size: 11px; }
.pie-legend-dot { width: 8px; height: 8px; border-radius: 2px; }

/* ── Customer Tab ─────────────────────────────── */
.retention-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}

/* ── DatePicker Portal 스타일 (with_portal=True) ─ */
/* Portal은 body에 직접 마운트 → z-index만 확보 */
.ReactModalPortal,
.DatePickerPortal {
  z-index: 9999 !important;
}
.ReactModal__Overlay {
  z-index: 9999 !important;
  background: rgba(0,0,0,.35) !important;
}
.ReactModal__Content {
  border-radius: var(--r-md) !important;
  box-shadow: var(--shadow-lg) !important;
  border: 1px solid var(--border) !important;
  padding: 0 !important;
}
/* 인라인 달력 z-index 보험 (portal 미사용 시) */
.SingleDatePicker_picker {
  z-index: 9999 !important;
}

/* ── Mobile Filter Toggle Bar (900px 미만에서만 표시) ── */
.mobile-filter-bar {
  display: none;         /* 데스크탑에서 숨김 */
  margin-bottom: 12px;
}
.mobile-filter-bar-btn {
  width: 100%;
  padding: 10px 16px;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--r-sm);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 500; color: var(--text);
  cursor: pointer; text-align: left;
  display: flex; align-items: center; gap: 8px;
  transition: border-color var(--transition), box-shadow var(--transition);
  box-shadow: var(--shadow-sm);
}
.mobile-filter-bar-btn:hover {
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(0,104,56,.10);
}

/* ── Responsive Breakpoints ───────────────────── */
/* 1400px 이상: KPI Mini 6열 */
@media (min-width: 1400px) {
  .kpi-mini-grid { grid-template-columns: repeat(6, 1fr); }
}
/* 1100px ~ 1399px: KPI Mini 4열 */
@media (max-width: 1399px) and (min-width: 1101px) {
  .kpi-mini-grid { grid-template-columns: repeat(4, 1fr); }
}
/* 1100px 이하: 2열 KPI, 차트 단열 */
@media (max-width: 1100px) {
  .kpi-grid-c { grid-template-columns: repeat(2, 1fr); }
  .chart-row.cols-2   { grid-template-columns: 1fr; }
  .chart-row.cols-1-2 { grid-template-columns: 1fr; }
  .chart-row.cols-2-1 { grid-template-columns: 1fr; }
  .chart-row.cols-3   { grid-template-columns: 1fr 1fr; }
  .kpi-mini-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ─────────────────────────────────────────────────
   900px 미만 — 사이드바 → 상단 콜랩스 패널
─────────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* 바디를 세로 방향으로 전환 */
  .db-app-body {
    flex-direction: column;
  }

  /* 사이드바: 좌측 고정 → 상단 패널로 변환 */
  .db-sidebar {
    width: 100%;
    height: auto;
    max-height: 0;
    overflow: hidden;
    position: relative;
    top: auto; left: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 0 16px;
    transition: max-height .35s cubic-bezier(.4,0,.2,1),
                padding    .35s cubic-bezier(.4,0,.2,1);
    background: var(--white);
    box-shadow: none;
    z-index: 50;
  }
  /* 열린 상태 */
  .db-sidebar.mobile-open {
    max-height: 1000px;
    padding: 16px;
    border-bottom: 1px solid var(--border);
    box-shadow: 0 4px 12px rgba(0,0,0,.08);
  }

  /* 내부 섹션: 가로 flex 래핑 */
  .db-sidebar .sidebar-section {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 8px;
  }
  .db-sidebar .filter-group {
    flex: 1 1 160px;
    min-width: 140px;
    margin-bottom: 0;
  }
  /* period 버튼 열수 조정 */
  .db-sidebar .period-btns {
    grid-template-columns: repeat(6, 1fr);
  }
  .db-sidebar .sidebar-divider { display: none; }

  /* 조회/초기화 버튼 가로 배치 */
  .db-sidebar .btn-search,
  .db-sidebar .btn-reset {
    display: inline-flex; width: auto; flex: 1;
    padding: 8px 20px;
  }
  .db-sidebar > div:last-child {
    display: flex; gap: 8px; margin-top: 4px;
  }

  /* 메인 콘텐츠 */
  .db-main { padding: 16px; }

  /* 모바일 토글 버튼 표시 */
  .mobile-filter-bar { display: block; }

  /* KPI 그리드 축소 */
  .kpi-mini-grid { grid-template-columns: repeat(2, 1fr); }
}

/* 600px 미만: 소형 모바일 */
@media (max-width: 600px) {
  .kpi-grid-c { grid-template-columns: 1fr; }
  .achieve-grid { grid-template-columns: 1fr; }
  .kpi-mini-grid { grid-template-columns: repeat(2, 1fr); }
  .product-grid { grid-template-columns: 1fr; }
  .retention-grid { grid-template-columns: 1fr; }
  .chart-row.cols-3 { grid-template-columns: 1fr; }
  .db-tab-btn { padding: 10px 14px; font-size: 13px; }
  .db-sidebar .period-btns { grid-template-columns: repeat(3, 1fr); }
}

/* ══════════════════════════════════════════════
   Compare Tab (비교 탭)
══════════════════════════════════════════════ */

/* 조회 조건 바 */
.cmp-filter-bar {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: 16px; padding: 18px 20px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  margin-bottom: 20px;
  position: relative;
  z-index: 100;
  overflow: visible;
}
.cmp-filter-item {
  display: flex; flex-direction: column; gap: 4px;
  min-width: 160px;
}
.cmp-filter-item--wide { min-width: 300px; flex: 1; }
.cmp-filter-item--btn  { justify-content: flex-end; min-width: auto; }
.cmp-filter-label {
  font-size: 11px; font-weight: 600;
  color: var(--gray-600); text-transform: uppercase; letter-spacing: .4px;
}
.cmp-date-row { display: flex; align-items: center; gap: 6px; }
.cmp-date-sep { font-size: 13px; color: var(--gray-500); }
.cmp-date-picker .SingleDatePickerInput,
.cmp-date-picker .DateInput {
  border: none !important; background: transparent !important;
}
.cmp-date-picker .DateInput_input {
  border: 1px solid var(--border) !important;
  border-radius: var(--r-sm) !important;
  background: var(--white) !important;
  font-size: 12px !important;
  padding: 6px 8px !important;
  font-family: 'DM Sans', sans-serif !important;
  color: var(--text) !important;
  line-height: 1.4 !important;
}
.cmp-dropdown .Select-control,
.cmp-dropdown-multi .Select-control {
  border-color: var(--border) !important;
  border-radius: var(--r-sm) !important;
  min-height: 34px !important;
}
.cmp-dropdown .Select-menu-outer,
.cmp-dropdown-multi .Select-menu-outer {
  z-index: 9999 !important;
  position: absolute !important;
}
/* Dash dcc.Dropdown 메뉴 z-index (React-Select v1) */
.cmp-filter-bar .VirtualizedSelectFocusedOption,
.cmp-filter-bar .VirtualizedSelectOption { z-index: 9999 !important; }
.cmp-filter-bar .Select.is-open { z-index: 9999 !important; }
.cmp-search-btn {
  padding: 8px 24px;
  background: var(--green); color: var(--on-green);
  border: none; border-radius: var(--r-sm);
  font-family: 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: background var(--transition), box-shadow var(--transition);
  white-space: nowrap;
}
.cmp-search-btn:hover {
  background: var(--green-dark);
  box-shadow: 0 2px 8px rgba(0,104,56,.25);
}

/* KPI 카드 */
.cmp-kpi-row { margin-bottom: 20px; }
.cmp-kpi-cards {
  display: flex; flex-wrap: wrap; gap: 14px;
}
.cmp-kpi-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  padding: 16px 18px;
  min-width: 220px; flex: 1;
}
.cmp-card-header {
  display: flex; align-items: center;
  justify-content: space-between; gap: 8px;
  margin-bottom: 12px;
}
.cmp-store-name {
  font-size: 14px; font-weight: 700; color: var(--gray-700);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmp-store-badge {
  font-size: 10px; font-weight: 600;
  padding: 2px 8px; border-radius: 20px;
  white-space: nowrap;
}
.cmp-card-body { display: flex; flex-direction: column; gap: 8px; }
.cmp-kpi-row-item {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 0; border-bottom: 1px solid var(--gray-100);
}
.cmp-kpi-row-item:last-child { border-bottom: none; }
.cmp-kpi-label {
  font-size: 11px; color: var(--gray-500); flex: 0 0 80px;
}
.cmp-kpi-val {
  font-size: 13px; font-weight: 600; color: var(--gray-700); flex: 1;
}
.cmp-diff-badge {
  font-size: 11px; font-weight: 700;
  padding: 1px 6px; border-radius: 4px;
  white-space: nowrap;
}
.cmp-diff-badge.cmp-badge-up   { background: #e6f4ea; color: #1e8e3e; }
.cmp-diff-badge.cmp-badge-down { background: #fce8e6; color: #c5221f; }
.cmp-diff-badge.cmp-badge-flat { background: var(--gray-100); color: var(--gray-500); }

.cmp-empty-msg {
  padding: 32px; text-align: center;
  color: var(--gray-500); font-size: 13px;
  background: var(--gray-50); border-radius: var(--r-md);
  border: 1px dashed var(--border);
}

@media (max-width: 900px) {
  /* 세로로 세우면서 align-items 를 그대로 두면 flex-end 가 살아 있어
     항목들이 오른쪽 끝에만 맞고 왼쪽이 들쭉날쭉해진다
     (375px 실측: 왼쪽 모서리가 65 / 184 / 31 / 272 로 제각각).
     세로 배치에서는 폭을 채우는 게 맞다. */
  .cmp-filter-bar {
    flex-direction: column; align-items: stretch;
    gap: 12px; padding: 14px;
  }
  .cmp-filter-item,
  .cmp-filter-item--wide,
  .cmp-filter-item--btn { min-width: 0; width: 100%; }
  .cmp-filter-item--btn { justify-content: flex-start; }

  /* 손가락으로 누르는 화면이므로 44px 아래로 내려가지 않게 */
  .cmp-search-btn { width: 100%; min-height: 44px; font-size: 14px; }
  /* 위쪽 .cmp-dropdown 규칙이 min-height 를 !important 로 34px 에 묶어 둬서
     같은 강도로 눌러야 손가락 크기(44px)가 나온다. */
  .cmp-dropdown .Select-control,
  .cmp-dropdown-multi .Select-control { min-height: 44px !important; }
  .cmp-date-picker .DateInput_input { min-height: 40px; font-size: 13px; }
  .cmp-date-row { gap: 8px; }
  .cmp-date-row .cmp-date-picker { flex: 1 1 0; min-width: 0; }
  .cmp-date-row .cmp-date-picker .SingleDatePickerInput,
  .cmp-date-row .cmp-date-picker .DateInput,
  .cmp-date-row .cmp-date-picker .DateInput_input { width: 100%; }

  .cmp-kpi-card { min-width: 100%; }
}


/* ── AI 종합 분석 카드 ─────────────────────────── */
/* ── AI 종합 분석 카드 ─────────────────────────────────
   한글 가독성 규칙 두 가지가 핵심이다.
   · word-break: keep-all — 어절 중간에서 줄이 끊기지 않게 한다.
     기본값(break-word)은 "매출이"를 "매출" / "이" 로 쪼개 읽기 흐름을 끊는다.
   · 목록은 불릿을 띄우고 본문에 hanging indent 를 준다.
     기본 list-style 은 둘째 줄이 불릿 아래로 들어가 좌측 정렬이 흐트러진다. */
.ai-insight-body {
  padding: 6px 6px 4px;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 13.5px; line-height: 1.85; color: var(--text);
  min-height: 60px;
  text-align: left;
  word-break: keep-all;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}
.ai-insight-hint {
  padding: 26px 4px; text-align: center; font-size: 13px;
  color: var(--gray-500); white-space: pre-line; line-height: 1.7;
}
.ai-insight-error {
  margin: 14px auto; padding: 14px 18px; max-width: 620px;
  text-align: left; font-size: 12.5px; line-height: 1.7;
  color: var(--red); white-space: pre-line;
  border: 1px solid var(--border); border-radius: 6px;
}

/* 한 줄이 너무 길면 다음 줄 첫 글자를 찾는 눈의 이동 거리가 커진다.
   본문 폭을 제한해 시선 이동을 짧게 유지한다. */
.ai-insight-md { 
  padding: 20px;
}

.ai-insight-md h2 {
  font-size: 12.5px; font-weight: 700; letter-spacing: .01em;
  color: var(--green);
  margin: 22px 0 9px; padding-bottom: 5px;
  border-bottom: 1px solid var(--border);
}
.ai-insight-md h2:first-child { margin-top: 2px; }

.ai-insight-md p { margin: 0 0 11px; }
.ai-insight-md p:last-child { margin-bottom: 0; }

.ai-insight-md ul { margin: 0 0 11px; padding-left: 0; list-style: none; }
.ai-insight-md li {
  position: relative;
  padding-left: 16px;      /* 불릿 자리 — 둘째 줄부터 여기에 맞춰 들여쓰인다 */
  margin-bottom: 8px;
}
.ai-insight-md li:last-child { margin-bottom: 0; }
.ai-insight-md li::before {
  content: ""; position: absolute; left: 3px; top: .78em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--green); opacity: .5;
}
.ai-insight-md li > p { margin: 0; }        /* dcc.Markdown 이 항목을 <p> 로 감쌀 때 */

.ai-insight-md strong { color: var(--green-dark); font-weight: 700; }
.ai-insight-md em { font-style: normal; color: var(--gray-600); }

/* 헤더 — 제목과 버튼을 한 줄에 두고 메타는 아래 줄로 내린다.
   메타(일자·저장본 시각·모델·데이터 출처)가 길어 같은 줄에 두면
   버튼 폭이 눌려 "분석 생 / 성" 처럼 글자가 세로로 쪼개진다. */
#ai-insight-section .chart-header { align-items: flex-start; gap: 14px; }
#ai-insight-meta {
  display: block; margin-top: 5px; line-height: 1.55;
  color: var(--gray-500); word-break: keep-all;
}
#ai-insight-btn { white-space: nowrap; flex-shrink: 0; }

@media (max-width: 640px) {
  .ai-insight-body { font-size: 13px; line-height: 1.75; padding: 4px 2px; }
  .ai-insight-md h2 { margin-top: 18px; }
}

/* ═══════════════════════════════════════════════════════════════
   다크 모드 토큰
   ───────────────────────────────────────────────────────────────
   개별 규칙을 다크용으로 다시 쓰지 않는다. 위쪽 CSS 가 이미 대부분
   var(--...) 로 색을 잡고 있으므로, 토큰 값만 갈아 끼우면 통째로 뒤집힌다.

   --white 는 이름과 달리 "카드 면" 으로 쓰이고 있어 다크에서는 어두운 면이
   된다. 이름을 바꾸면 1,400줄을 전부 손봐야 해 값만 바꿨다.

   브랜드 그린 #006838 은 어두운 배경에서 대비 1.6:1 로 거의 묻힌다.
   명도를 올린 #57b585 를 따로 두고, 그 위 글자는 --on-green 으로 뒤집는다.
   ═══════════════════════════════════════════════════════════════ */
:root[data-theme="dark"] {
  --green:       #57b585;
  --green-dark:  #7ecfa4;
  --green-light: #16261e;
  --green-mid:   #2a4735;
  --green-fade:  #121d18;
  --white:       #171e1a;   /* 카드·패널 면 */
  --gray-50:     #0f1412;   /* 본문 바탕 */
  --gray-100:    #1b231f;
  --gray-200:    #222b26;
  --gray-300:    #2f3a34;
  --gray-400:    #4a564f;
  --gray-500:    #8b978f;
  --gray-600:    #9caaa2;
  --gray-700:    #c3cec8;
  --gray-900:    #e7ede9;
  --red:         #f08a87;
  --amber:       #e0a343;
  --blue:        #7bb0f5;
  --text:        #e7ede9;
  --border:      #26302b;
  --on-green:    #0f1412;
  --header-bg:   #10241a;
  --shadow-sm:   0 1px 3px rgba(0,0,0,.55), 0 1px 2px rgba(0,0,0,.45);
  --shadow-md:   0 4px 12px rgba(0,0,0,.55), 0 2px 4px rgba(0,0,0,.45);
  --shadow-lg:   0 8px 24px rgba(0,0,0,.65);
}
:root[data-theme="dark"] .db-header { box-shadow: 0 1px 0 var(--border); }

/* 로딩 오버레이가 흰 막이라 다크에서 화면이 하얗게 번쩍인다. */
:root[data-theme="dark"] .sales-chart-loading .chart-card::after,
:root[data-theme="dark"] .sales-chart-loading .kpi-grid::after,
:root[data-theme="dark"] .sales-chart-loading .table-card::after,
:root[data-theme="dark"] .product-chart-loading .chart-card::after,
:root[data-theme="dark"] .product-chart-loading .table-card::after,
:root[data-theme="dark"] .compare-chart-loading .chart-card::after,
:root[data-theme="dark"] .region-cmp-chart-loading .chart-card::after,
:root[data-theme="dark"] .map-chart-loading .chart-card::after {
  background: rgba(15,20,18,.62);
}

/* Dash Dropdown 은 자체 스타일이 흰 배경으로 박혀 있어 토큰이 닿지 않는다. */
:root[data-theme="dark"] .Select-control,
:root[data-theme="dark"] .Select-menu-outer,
:root[data-theme="dark"] .VirtualizedSelectOption,
:root[data-theme="dark"] .DateInput_input,
:root[data-theme="dark"] .DayPicker,
:root[data-theme="dark"] .CalendarMonth,
:root[data-theme="dark"] .CalendarMonthGrid,
:root[data-theme="dark"] .DayPicker_weekHeader {
  background: var(--white) !important;
  color: var(--text) !important;
}
:root[data-theme="dark"] .Select-value-label,
:root[data-theme="dark"] .Select-placeholder,
:root[data-theme="dark"] .CalendarDay__default {
  color: var(--text) !important;
}
:root[data-theme="dark"] .CalendarDay__default {
  background: var(--white) !important;
  border-color: var(--border) !important;
}
:root[data-theme="dark"] .VirtualizedSelectFocusedOption {
  background: var(--green-light) !important;
}

/* ═══════════════════════════════════════════════════════════════
   헤더 아이콘 버튼 (☰ 메뉴 접기 · 🌙 테마)
   ═══════════════════════════════════════════════════════════════ */
.header-icon-btn {
  background: rgba(255,255,255,.14); border: none; color: #fff;
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  font-size: 14px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--transition);
}
.header-icon-btn:hover { background: rgba(255,255,255,.26); }
.header-icon-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* ═══════════════════════════════════════════════════════════════
   상단 필터 바
   ───────────────────────────────────────────────────────────────
   사이드바 시절의 마크업을 그대로 쓴다 (filter-group / sidebar-section).
   콜백 9개 모듈이 그 안의 id 를 참조하므로 구조는 두고 배치만 뒤집는다.
   ═══════════════════════════════════════════════════════════════ */
.fb-wrap {
  position: sticky; top: var(--header-h); z-index: 60;
  margin-top: var(--header-h);
  background: var(--gray-50);
  border-bottom: 1px solid var(--border);
  padding: 12px 20px 10px;
  display: flex; flex-direction: column; gap: 10px;
}

/* 가로 배치 — 섹션과 그룹을 한 줄로 편다 */
.fb-wrap .filterbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 14px;
  padding: 10px 14px;
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--r-md);
}

/* 접기 — 높이 애니메이션은 쓰지 않는다.
   필터가 좁은 폭에서 두 줄로 접히면 높이가 가변이라 max-height 는 값이
   모자라 툭 끊기고, grid 0fr↔1fr 는 이 안의 Dropdown 팝업과 겹친다.
   여는 순간이 빠른 편이 낫다. */
.fb-wrap.collapsed .filterbar { display: none; }
.fb-wrap .filterbar .sidebar-section {
  display: flex; align-items: flex-end; gap: 12px; margin: 0;
}
.fb-wrap .filterbar .sidebar-title { display: none; }   /* 각 필드에 라벨이 이미 있다 */
.fb-wrap .filterbar .filter-group { margin: 0; min-width: 0; }
.fb-wrap .filterbar .filter-label {
  margin-bottom: 4px; font-size: 10.5px; white-space: nowrap;
}
.fb-wrap .filterbar .sidebar-divider {
  width: 1px; height: 34px; align-self: flex-end; margin: 0 2px 4px;
  background: var(--border); border: 0;
}
.fb-wrap .filterbar .custom-dropdown { min-width: 132px; }
.fb-wrap .filterbar .period-btns,
.fb-wrap .filterbar .comp-btns { flex-wrap: nowrap; }
.fb-wrap .filterbar .comp-period-label { display: none; }
.fb-wrap .filterbar .date-range-row { display: flex; gap: 8px; align-items: flex-end; }

.fb-actions { margin-left: auto; display: flex; gap: 8px; align-items: flex-end; }
.fb-wrap .filterbar .btn-search,
.fb-wrap .filterbar .btn-reset { width: auto; padding: 8px 18px; margin: 0; }

/* 상태바 줄 — 접혀도 남아 현재 조건을 보여 준다 */
.fb-statusrow { display: flex; align-items: stretch; gap: 10px; }
.fb-statusrow .status-bar-db { flex: 1; margin: 0; }
.fb-toggle {
  flex-shrink: 0; cursor: pointer; white-space: nowrap;
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 0 14px;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 12px; font-weight: 600; color: var(--gray-600);
  transition: color var(--transition), border-color var(--transition);
}
.fb-toggle:hover { color: var(--green); border-color: var(--green); }
.fb-toggle:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

/* ═══════════════════════════════════════════════════════════════
   내비 레일 + 확장 오버레이
   ───────────────────────────────────────────────────────────────
   오버레이는 본문을 밀지 않고 겹친다. 밀면 열고 닫을 때마다 Plotly 가
   리사이즈돼 차트가 출렁인다.
   ═══════════════════════════════════════════════════════════════ */
.db-app-body { margin-top: 0; display: flex; min-height: 0; }

.db-rail-wrap { position: relative; flex-shrink: 0; }

.db-rail {
  width: var(--rail-w); background: var(--white);
  /* --fb-h 는 00-theme.js 가 필터 바 실제 높이로 채운다. 접거나 창이 좁아져
     두 줄이 되면 값이 바뀌므로 상수로 박아 둘 수 없다. */
  border-right: 1px solid var(--border);
  position: sticky; top: calc(var(--header-h) + var(--fb-h, 96px));
  height: calc(100vh - var(--header-h) - var(--fb-h, 96px));
  display: flex; flex-direction: column; padding: 8px 0 12px;
  overflow-y: auto; overflow-x: hidden;
}
.db-rail::-webkit-scrollbar { width: 0; }

/* .rail-list — 슬라이딩 오버레이를 걷어내며 래퍼가 사라졌다.
   .db-rail 자체가 flex column 이라 따로 둘 이유가 없다. */
.rail-group {
  font-size: 9px; font-weight: 700; letter-spacing: .1em;
  color: var(--gray-500); text-align: center; padding: 10px 0 5px;
}
.rail-item {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: none; border: none; cursor: pointer; position: relative;
  padding: 8px 3px; margin: 0 7px 2px; border-radius: var(--r-sm);
  color: var(--gray-600); font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  transition: background var(--transition), color var(--transition);
}
.rail-item:hover { background: var(--gray-100); color: var(--green); }
.rail-item .rail-ic { font-size: 16px; line-height: 1; }
.rail-item .rail-tx {
  font-size: 9px; font-weight: 600; letter-spacing: -.02em;
  text-align: center; line-height: 1.25;
}
.rail-item.active { background: var(--green-light); color: var(--green); font-weight: 700; }
.rail-item.active::before {
  content: ''; position: absolute; left: -7px; top: 50%;
  transform: translateY(-50%); width: 3px; height: 22px;
  border-radius: 0 3px 3px 0; background: var(--green);
}
.rail-item:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }

/* 헤더 ☰ — 레일을 통째로 숨겨 본문을 66px 넓힌다 */
#app-root.rail-hidden .db-rail-wrap { display: none; }

/* 본문 */
.db-main { padding: 18px 22px 40px; }
.status-bar-db { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════
   좁은 화면
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 1100px) {
  .fb-wrap .filterbar { gap: 10px; }
  .fb-wrap .filterbar .custom-dropdown { min-width: 116px; }
}
@media (max-width: 820px) {
  /* ═══════════════════════════════════════════════════════════
     모바일 (안 A) — 하단 탭바 + 필터 바텀시트
     ───────────────────────────────────────────────────────────
     데스크톱과 같은 DOM 을 배치만 바꿔 쓴다. 모바일용 메뉴·필터를 따로
     그리면 버튼 id 가 겹쳐 탭 전환·조회 콜백이 꼬인다.
     ═══════════════════════════════════════════════════════════ */

  /* ── 헤더 ── 56px 안에 로고 64px + 2줄 타이틀 + 서브텍스트가 겹쳤다.
     로고를 줄이고 부제·날짜·LIVE 를 걷어낸다. */
  .db-header { gap: 6px; padding: 0 8px; overflow: hidden; }
  .db-header .logo-icon { width: 36px; height: 24px; flex-shrink: 0; }
  .db-header .header-logo { min-width: 0; }
  .db-header .header-icon-btn { width: 28px; height: 28px; font-size: 13px; }
  .db-header .header-avatar { width: 26px; height: 26px; }
  #header-username { display: none; }
  .db-header .logo-text { font-size: 15px; }
  .db-header .logo-sub,
  .header-pill,
  .header-date { display: none; }
  .header-logout { padding: 6px 10px; font-size: 11px; }
  #btn-rail-toggle { display: none; }   /* 레일이 하단으로 내려가 숨길 대상이 없다 */

  /* ── 상단 조건 줄 ── keep-all 이 없어 '전체 매장' 이 두 줄로 쪼개졌다 */
  .fb-wrap { padding: 8px 10px; gap: 8px; }
  .status-bar-db {
    display: block; word-break: keep-all; overflow-wrap: anywhere;
    font-size: 11.5px; line-height: 1.55; padding: 8px 11px;
  }
  .status-bar-db .status-dot { display: inline-block; vertical-align: middle; margin-right: 5px; }
  .status-bar-db span[style] { margin-left: 0 !important; display: block; }
  .fb-statusrow { gap: 8px; }
  .fb-toggle { padding: 0 12px; font-size: 11.5px; min-height: 40px; }

  /* ── 필터 = 바텀시트 ──
     가로 한 줄에 8개를 욱여넣는 대신 아래에서 올라오는 시트로 분리한다.
     접힘(collapsed) 이 곧 시트 닫힘이라 상태 하나로 데스크톱과 공유된다. */
  /* 딤은 실제 요소다 — 눌러서 시트를 닫을 수 있어야 하기 때문이다.
     ::before 로 두면 클릭을 받지 못한다. */
  .fb-wrap:not(.collapsed) .fb-backdrop {
    display: block; position: fixed; inset: 0; z-index: 88;
    background: rgba(26, 28, 30, .45); cursor: pointer;
  }
  /* 토글 버튼이 딤 위에 남아 있어야 그것으로도 닫을 수 있다 */
  .fb-wrap .fb-statusrow { position: relative; z-index: 92; }
  .fb-wrap .filterbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    flex-direction: column; align-items: stretch; flex-wrap: nowrap;
    gap: 14px; padding: 18px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    border-radius: 20px 20px 0 0; border-width: 1px 0 0;
    max-height: 78vh; overflow-y: auto;
    box-shadow: 0 -8px 28px rgba(0, 0, 0, .22);
  }
  /* 시트 손잡이 */
  .fb-wrap .filterbar::before {
    content: ""; display: block; width: 38px; height: 4px; border-radius: 3px;
    background: var(--gray-300); margin: -4px auto 2px; flex-shrink: 0;
  }
  .fb-wrap .filterbar .sidebar-section {
    flex-direction: column; align-items: stretch; gap: 14px;
  }
  .fb-wrap .filterbar .sidebar-divider { display: none; }
  .fb-wrap .filterbar .filter-group { width: 100%; }
  .fb-wrap .filterbar .filter-label { font-size: 12px; margin-bottom: 6px; }
  .fb-wrap .filterbar .custom-dropdown { width: 100%; min-width: 0; }

  /* 터치 타깃 44px — 손가락으로 누르는 화면의 최소치 */
  .fb-wrap .filterbar .Select-control,
  .fb-wrap .filterbar .DateInput_input { min-height: 44px; font-size: 14px; }
  .fb-wrap .filterbar .db-date-picker .DateInput { width: 100%; }
  .fb-wrap .filterbar .date-range-row { flex-direction: column; gap: 10px; align-items: stretch; }
  .fb-wrap .filterbar .date-row-inner { display: flex; align-items: center; gap: 10px; }

  /* 집계 단위 6개는 3열 두 줄로 접어야 한 화면에 들어간다 */
  .fb-wrap .filterbar .period-btns {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px;
  }
  .fb-wrap .filterbar .comp-btns {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px;
  }
  .fb-wrap .filterbar .period-btn,
  .fb-wrap .filterbar .comp-btn {
    min-height: 44px; font-size: 13px; padding: 0;
    display: flex; align-items: center; justify-content: center;
  }

  .fb-wrap .filterbar .fb-actions { margin: 4px 0 0; gap: 10px; }
  .fb-wrap .filterbar .btn-search { flex: 1; min-height: 48px; font-size: 14px; }
  .fb-wrap .filterbar .btn-reset { flex: 0 0 104px; min-height: 48px; font-size: 14px; }

  /* ── 레일 = 하단 탭바 ──
     820px 미만에서 레일을 static 으로 두니 세로로 1,700px 을 차지하고
     본문이 그 아래에서 시작했다. 가로로 눕혀 화면 아래에 고정한다. */
  .db-rail-wrap { position: static; }
  .db-rail {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 80;
    width: auto; height: auto;
    flex-direction: row; align-items: stretch;
    padding: 0 0 env(safe-area-inset-bottom, 0px);
    border-right: none; border-top: 1px solid var(--border);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .05);
    flex-wrap: wrap;
  }
  .db-rail .rail-group { display: none; }        /* 그룹 라벨은 세로 배치용 */
  .db-rail .rail-item {
    flex: 1 1 0; min-width: 0; margin: 0; border-radius: 0; padding: 9px 2px 8px;
    min-height: 56px; justify-content: center;
  }
  #app-root.nav-more .db-rail .rail-item { flex: 1 1 20%; }
  .db-rail .rail-item .rail-ic { font-size: 18px; }
  .db-rail .rail-item .rail-tx { font-size: 10px; }
  .db-rail .rail-item.active { background: transparent; }
  .db-rail .rail-item.active::before {
    left: 0; right: 0; top: 0; bottom: auto; transform: none;
    width: auto; height: 2px; border-radius: 0;
  }
  /* 하단바에 안 들어가는 메뉴는 더보기로 접는다 */
  .db-rail .rail-item[data-mobile="more"] { display: none; }
  #app-root.nav-more .db-rail .rail-item[data-mobile="more"] { display: flex; }
  #app-root.nav-more .db-rail .rail-more { background: var(--green-light); color: var(--green); }
  .db-rail .rail-more { display: flex; }

  /* 본문은 탭바 높이만큼 아래를 비워 둔다 */
  .db-main { padding: 14px 10px 88px; }
  #app-root.nav-more .db-main { padding-bottom: 148px; }

  /* ── 내용 ── */
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .kpi-card { padding: 10px 12px; min-width: 0; }
  .kpi-card .kpi-num { font-size: 21px; }
  .kpi-card .kpi-value-row { flex-wrap: wrap; gap: 4px; }
  .kpi-card .comp-badge { font-size: 12px; }
  .kpi-multi-row { gap: 10px; }
  .chart-row.cols-3, .chart-row.cols-2 { grid-template-columns: 1fr; }
  .section-label { font-size: 10.5px; }
  /* 표는 좁은 폭에서 칸을 억지로 줄이다 '서' '울' 처럼 한 글자씩 세로로
     쪼갠다. 줄이지 말고 가로로 밀어 보게 한다 — 이쪽이 훨씬 읽힌다. */
  .table-card, .chart-card { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .data-table { min-width: 620px; }
  .data-table th, .data-table td {
    white-space: nowrap; word-break: keep-all; padding: 8px 10px;
  }
  .dash-table-container .dash-spreadsheet-container { max-width: 100%; }
  .data-table, .dash-table-container table { font-size: 11.5px; }
}

/* 사이드바 시절 집계 단위는 3열 그리드로 두 줄이었다(일주월 / 분기년요일).
   가로 바에서는 한 줄로 펴야 필터 바 높이가 절반으로 준다. */
.fb-wrap .filterbar .period-btns {
  display: flex; flex-wrap: nowrap; gap: 4px;
}
.fb-wrap .filterbar .period-btn,
.fb-wrap .filterbar .comp-btn { padding: 7px 11px; white-space: nowrap; }

/* 한 줄에 담기 — 1440px 에서 조회 버튼이 둘째 줄로 밀리면 그만큼 세로를 더 쓴다.
   드롭다운은 자라지 않게 고정 폭을 주고, 버튼 패딩을 조인다. */
.fb-wrap .filterbar .filter-group { flex: 0 0 auto; }
.fb-wrap .filterbar .custom-dropdown { width: 128px; min-width: 0; }
.fb-wrap .filterbar .period-btn,
.fb-wrap .filterbar .comp-btn { padding: 7px 9px; font-size: 11px; }
.fb-wrap .filterbar .date-mini-label { font-size: 10px; color: var(--gray-500); }
.fb-wrap .filterbar .db-date-picker .DateInput { width: 118px; }
.fb-wrap .filterbar .btn-search,
.fb-wrap .filterbar .btn-reset { padding: 8px 16px; font-size: 12px; }

/* 레일 펼치기 버튼 — 아이콘 폭에 맞춰 작게 */
/* 증감 배지·강조 칩은 연한 틴트가 하드코딩돼 있어 토큰이 닿지 않는다.
   다크에서 그대로 두면 어두운 카드 위에 형광 분홍·연두 칩이 떠 버린다.
   같은 색상 계열을 어둡게 눌러 대비만 유지한다. */
:root[data-theme="dark"] .comp-badge.up,
:root[data-theme="dark"] .badge-pct.up,
:root[data-theme="dark"] .cmp-diff-badge.cmp-badge-up {
  background: #17301f; color: #6fcf97;
}
:root[data-theme="dark"] .comp-badge.down,
:root[data-theme="dark"] .badge-pct.dn,
:root[data-theme="dark"] .cmp-diff-badge.cmp-badge-down {
  background: #331d1c; color: #f08a87;
}

/* ═══════════════════════════════════════════════════════════════
   데이터 탭 — dash_table.DataTable
   ───────────────────────────────────────────────────────────────
   DataTable 은 색을 인라인으로 박아 넣어 토큰이 닿지 않는 부분이 남는다.
   페이지 이동·필터·내보내기 버튼이 그렇다. 여기서 따로 맞춘다.
   ═══════════════════════════════════════════════════════════════ */
.data-tab-hint {
  padding: 40px 4px; text-align: center; font-size: 13px;
  color: var(--gray-500);
}
.dash-table-container { margin-top: 4px; }
.dash-table-container .dash-spreadsheet-container { border-radius: var(--r-sm); }
.dash-table-container .previous-next-container,
.dash-table-container .dash-table-tooltip { color: var(--gray-600); font-size: 12px; }
.dash-table-container .previous-next-container .page-number,
.dash-table-container .previous-next-container input {
  background: var(--white); color: var(--text);
  border: 1px solid var(--border); border-radius: 5px;
}
.dash-table-container button.export,
.dash-table-container .previous-next-container button {
  background: var(--white); color: var(--gray-600);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 4px 12px; font-size: 12px; font-weight: 600; cursor: pointer;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
}
.dash-table-container button.export:hover,
.dash-table-container .previous-next-container button:hover {
  color: var(--green); border-color: var(--green);
}
.dash-table-container input.dash-filter--case,
.dash-table-container .dash-filter input {
  background: var(--gray-50) !important; color: var(--text) !important;
}
/* 숫자 열은 자릿수가 맞아야 크기 비교가 눈으로 된다 */
.dash-table-container .dash-cell.column-4,
.dash-table-container .dash-cell.column-5,
.dash-table-container .dash-cell.column-6,
.dash-table-container .dash-cell.column-7 {
  font-variant-numeric: tabular-nums;
}
:root[data-theme="dark"] .dash-table-container .dash-spreadsheet-inner input {
  background: var(--white) !important; color: var(--text) !important;
}

/* YOY 배지 — DataTable 은 셀에 컴포넌트를 못 넣어 markdown+html 로 그린다.
   마크다운은 내용을 <p> 로 감싸므로 여백을 걷어내야 배지가 셀 가운데 앉는다. */
.dash-table-container .dash-cell .dash-cell-value p { margin: 0; }
.dash-table-container .dash-cell .badge-pct { display: inline-block; white-space: nowrap; }
:root[data-theme="dark"] .dash-table-container .badge-pct.up { background: #17301f; color: #6fcf97; }
:root[data-theme="dark"] .dash-table-container .badge-pct.dn { background: #331d1c; color: #f08a87; }

/* ═══════════════════════════════════════════════════════════════
   모바일 마무리 — 순서 때문에 뒤쪽 선언에 지던 것들
   ───────────────────────────────────────────────────────────────
   위쪽 @media 블록 뒤에 데스크톱용 .fb-wrap .filterbar 규칙이 더 있어,
   같은 특정도라면 나중 것이 이긴다. 여기서 한 번 더 못 박는다.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 820px) {
  /* 시트가 하단 탭바 위에 놓여야 한다.
     .fb-wrap 이 sticky + z-index 를 가져 새 쌓임 맥락을 만들기 때문에,
     그 안의 시트에 z-index 를 아무리 올려도 바깥의 탭바를 못 이긴다.
     맥락 자체를 탭바 위로 올린다. */
  .fb-wrap { z-index: 95; }

  /* 시트 안에서는 모든 입력이 한 열 전폭 */
  .fb-wrap .filterbar .filter-group { flex: 1 1 auto; width: 100%; }
  .fb-wrap .filterbar .custom-dropdown { width: 100%; min-width: 0; }
  .fb-wrap .filterbar .date-range-row,
  .fb-wrap .filterbar .date-row-inner { width: 100%; }
  .fb-wrap .filterbar .db-date-picker,
  .fb-wrap .filterbar .db-date-picker .DateInput,
  .fb-wrap .filterbar .db-date-picker .DateInput_input { width: 100%; }

  /* 집계 단위 6개·Comp 3개는 그리드로 접어야 한 화면에 들어간다 */
  .fb-wrap .filterbar .period-btns {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px; flex-wrap: wrap;
  }
  .fb-wrap .filterbar .comp-btns {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px;
  }
  .fb-wrap .filterbar .period-btn,
  .fb-wrap .filterbar .comp-btn {
    min-height: 44px; font-size: 13px; padding: 0;
    display: flex; align-items: center; justify-content: center;
  }
  .fb-wrap .filterbar .btn-search,
  .fb-wrap .filterbar .btn-reset { min-height: 48px; font-size: 14px; padding: 0; }
}

/* '더보기' 는 모바일 하단 탭바 전용이다. 데스크톱 레일에는 전체 메뉴가
   이미 다 보이므로 나올 이유가 없다 (모바일 블록에서 다시 켠다). */
/* 버튼 자신의 클래스. app-root 에 붙는 상태 클래스(nav-more)와 이름이
   겹치면 이 규칙이 #app-root 를 통째로 숨겨 화면이 사라진다. */
.rail-more { display: none; }

/* 딤은 모바일에서 시트가 열렸을 때만 나온다. 데스크톱에는 시트가 없다. */
.fb-backdrop { display: none; }

/* ═══════════════════════════════════════════════════════════════
   열린 탭 스트립
   ───────────────────────────────────────────────────────────────
   메뉴를 고르면 여기에 탭이 붙는다. 활성 표시는 초록 밑줄 —
   예전 가로 탭(.db-tab-btn)이 쓰던 표시를 그대로 이어 쓴다.

   음수 마진으로 .db-main 의 좌우 패딩을 상쇄해 스트립만 폭을 꽉 채운다.
   경계선이 본문 폭에서 끊기면 탭이 떠 있는 것처럼 보인다.
   ═══════════════════════════════════════════════════════════════ */
.tab-strip-wrap {
  position: relative;
  display: flex; align-items: stretch;
  margin: -18px -22px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--gray-50);
}
.tab-strip {
  display: flex; align-items: stretch; gap: 2px;
  padding: 0 0 0 22px;
  /* minmax(0,...) 없이는 flex 아이템이 내용 폭을 최소값으로 삼아
     스크롤되지 않고 목록 버튼을 화면 밖으로 밀어낸다 */
  flex: 1 1 0; min-width: 0;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: thin;
}
.tab-strip::-webkit-scrollbar { height: 3px; }
.tab-strip::-webkit-scrollbar-track { background: transparent; }
.tab-strip::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: 2px; }
.tab-strip:empty { display: none; }

.db-tab {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 8px 10px 12px; cursor: pointer;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 500; color: var(--gray-500);
  white-space: nowrap; flex-shrink: 0;
  border-bottom: 2px solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.db-tab:hover { color: var(--green); }
.db-tab.active { color: var(--green); font-weight: 700; border-bottom-color: var(--green); }
.db-tab .tab-name { pointer-events: none; }

.tab-close {
  border: none; background: none; cursor: pointer; padding: 0;
  width: 18px; height: 18px; border-radius: 4px; flex-shrink: 0;
  font-size: 15px; line-height: 1; color: var(--gray-400);
  display: flex; align-items: center; justify-content: center;
  transition: background var(--transition), color var(--transition);
}
.tab-close:hover { background: var(--gray-200); color: var(--gray-700); }
.db-tab.active .tab-close { color: var(--gray-600); }

/* ── 탭 목록 (가려진 탭까지 한눈에) ───────────────────────── */
.tab-menu-btn {
  flex-shrink: 0; border: none; cursor: pointer;
  width: 34px; margin-right: 22px; padding: 0;
  background: var(--gray-50); color: var(--gray-500);
  font-size: 15px; line-height: 1;
  border-left: 1px solid var(--border);
  transition: color var(--transition), background var(--transition);
}
.tab-menu-btn:hover { color: var(--green); background: var(--gray-100); }
.tab-strip-wrap.menu-open .tab-menu-btn { color: var(--green); background: var(--gray-100); }

.tab-menu {
  display: none;
  position: absolute; top: 100%; right: 22px; z-index: 60;
  min-width: 200px; padding: 5px;
  /* 카드 면은 --white 다 (다크에서는 어두운 면으로 뒤집힌다) */
  background: var(--white); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 6px 20px rgba(0, 0, 0, .12);
}
.tab-strip-wrap.menu-open .tab-menu { display: block; }

.tab-menu-item {
  display: block; width: 100%; text-align: left;
  border: none; background: none; cursor: pointer;
  padding: 8px 10px; border-radius: 5px;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif;
  font-size: 13px; color: var(--gray-700); white-space: nowrap;
}
.tab-menu-item:hover { background: var(--gray-100); }
.tab-menu-item.active { color: var(--green); font-weight: 700; }
.tab-menu-sep { height: 1px; margin: 5px 4px; background: var(--border); }
.tab-menu-item.quiet { color: var(--gray-500); font-size: 12.5px; }
.tab-menu-item:disabled { color: var(--gray-300); cursor: default; background: none; }

@media (max-width: 820px) {
  /* 모바일은 .db-main 패딩이 달라 상쇄값도 달라야 한다 */
  .tab-strip-wrap { margin: -14px -10px 12px; }
  .tab-strip { padding: 0 0 0 10px; }
  .tab-menu-btn { margin-right: 10px; width: 38px; }
  .tab-menu { right: 10px; }
  .db-tab { font-size: 12.5px; padding: 9px 6px 9px 10px; }
  .tab-close { width: 22px; height: 22px; }
}


/* ═══════════════════════════════════════════════════════════════
   관리 화면 (계정·팀)
   ───────────────────────────────────────────────────────────────
   목록과 편집을 좌우로 나란히 둔다. 위아래로 두면 38명짜리 표가 화면을
   채워 행을 골라도 편집 칸이 스크롤 밖에 있었다.
   ═══════════════════════════════════════════════════════════════ */
.admin-head-left { display: flex; align-items: center; min-width: 0; }

.admin-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 18px 0;
}
.admin-search {
  flex: 1 1 260px; min-width: 0; height: 34px; padding: 0 12px;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif; font-size: 13px;
  color: var(--text); background: var(--white);
  border: 1px solid var(--border); border-radius: var(--r-sm);
}
.admin-search:focus { outline: none; border-color: var(--green); }

/* 상태 칩 — RadioItems 의 기본 동그라미는 숨기고 칩처럼 보이게 */
.admin-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.admin-chips label {
  display: inline-flex; align-items: center; cursor: pointer;
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--white);
  font-size: 12.5px; color: var(--gray-600);
}
.admin-chips input { position: absolute; opacity: 0; width: 0; height: 0; }
.admin-chips label:hover { border-color: var(--green); color: var(--green); }
.admin-chips label:has(input:checked) {
  background: var(--green); border-color: var(--green);
  color: var(--on-green, #fff); font-weight: 700;
}

.admin-split {
  display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 16px; padding: 12px 18px 18px; align-items: start;
}
.admin-list { min-width: 0; }

/* 편집 칸은 붙여 둔다 — 목록을 내리며 여러 계정을 손볼 때 위로 돌아가지 않게 */
.admin-pane {
  min-width: 0; position: sticky; top: 8px;
  padding: 14px; border-radius: var(--r-md);
  background: var(--gray-50); border: 1px solid var(--border);
}
.admin-pane-head {
  display: flex; align-items: center; gap: 8px; min-height: 26px;
  margin-bottom: 4px;
}
.admin-pane-title { font-size: 13px; font-weight: 700; color: var(--text); }
.admin-picked {
  padding: 2px 10px; border-radius: 999px;
  background: var(--green-light); color: var(--green-dark);
  font-size: 12.5px; font-weight: 700;
}
.admin-picked:empty { display: none; }

.admin-empty {
  padding: 26px 8px; text-align: center;
  font-size: 12.5px; color: var(--gray-500);
}

.admin-form { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }
.admin-row { display: flex; flex-wrap: wrap; gap: 14px; }
/* flex-direction: column 안에서 flex-basis 는 '높이' 로 읽힌다. 세로로 쌓이는
   편집 칸에 1 1 200px 을 주면 칸마다 200px 높이로 벌어진다 — 가로로 나란히
   놓는 .admin-row 안에서만 늘어나게 한다. */
.admin-field { min-width: 0; }
.admin-row > .admin-field { flex: 1 1 200px; }
.admin-field .filter-label { margin-bottom: 5px; }
.admin-hint { margin-top: 5px; font-size: 11.5px; color: var(--gray-500); }

.admin-input {
  width: 100%; box-sizing: border-box; height: 34px; padding: 0 10px;
  font-family: 'IBM Plex Sans KR', 'DM Sans', sans-serif; font-size: 13px;
  color: var(--text); background: var(--white);
  border: 1px solid var(--border); border-radius: var(--r-sm);
}
.admin-input:focus { outline: none; border-color: var(--green); }

/* 지금 고친 조합으로 몇 개를 보게 되는지 — 저장 전에 알려 준다 */
.admin-scope {
  padding: 8px 10px; border-radius: var(--r-sm);
  background: var(--green-fade); color: var(--green-dark);
  font-size: 12.5px; font-weight: 600;
}
.admin-scope:empty { display: none; }

.admin-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.admin-actions .btn-search, .admin-actions .btn-reset { flex: 1 1 auto; }

.admin-msg {
  padding: 9px 12px; border-radius: var(--r-sm);
  background: var(--white); border: 1px solid var(--border);
  font-size: 12.5px; color: var(--text); white-space: pre-wrap;
}
.admin-msg:empty { display: none; }

/* 임시 비밀번호 — 한 번만 보이므로 눈에 띄게, 받아 적기 쉽게 */
.admin-pw {
  padding: 10px 12px; border-radius: var(--r-sm);
  background: var(--amber-fade, #fff8e6); border: 1px solid var(--amber, #e0a343);
}
.admin-pw:empty { display: none; }
.admin-pw-note { font-size: 11.5px; color: var(--gray-600); }
.admin-pw-row { display: flex; align-items: center; gap: 8px; margin: 6px 0; }
.admin-pw-value {
  flex: 1 1 auto; padding: 6px 10px; border-radius: var(--r-sm);
  background: var(--white); border: 1px solid var(--border);
  font-family: 'DM Mono', Consolas, monospace; font-size: 14px;
  font-weight: 700; letter-spacing: .5px; color: var(--text);
  word-break: break-all;
}
.admin-pw-copy {
  flex: 0 0 auto; height: 30px; padding: 0 12px; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--white); color: var(--gray-700); font-size: 12.5px;
}
.admin-pw-copy:hover { border-color: var(--green); color: var(--green); }

/* 새로 만들기 — 평소엔 접어 둔다 */
.admin-details {
  margin-top: 14px; border: 1px solid var(--border);
  border-radius: var(--r-md); background: var(--white);
}
.admin-summary {
  cursor: pointer; padding: 12px 18px; list-style: none;
  font-size: 13px; font-weight: 700; color: var(--gray-700);
}
.admin-summary::-webkit-details-marker { display: none; }
.admin-summary:hover { color: var(--green); }
.admin-details[open] .admin-summary { border-bottom: 1px solid var(--border); }
.admin-details-body { display: flex; flex-direction: column; gap: 12px; padding: 14px 18px 18px; }

@media (max-width: 1100px) {
  .admin-split { grid-template-columns: minmax(0, 1fr); }
  .admin-pane { position: static; }
}
@media (max-width: 820px) {
  .admin-field { flex: 1 1 100%; }
  .admin-toolbar, .admin-split { padding-left: 12px; padding-right: 12px; }
}
