/*
 * Shared UI primitives.
 *
 * This file is the migration layer that consolidates repeated page styles.
 * Visual values still come from app.css tokens; do not introduce new hex colors here.
 * Page-specific layout may remain elsewhere, but generic cards/buttons/badges/fields/
 * tables/tabs/empty states/toolbars should converge on these primitives.
 */

/* ── shell utilities: replace static inline styles in base.html ── */
.nav-primary{ padding-top:8px; padding-bottom:10px; }

/* ── 사이드바 13그룹 2단 아코디언 (파트 A1) ──
   토큰만 사용(하드코딩 hex 금지 — 없는 토큰은 선언 통째로 사라진다: css_eats_undefined_tokens_silently).
   접힘은 JS 없는 <details>/<summary>. 마커 전역 제거는 app.css 의 summary 규칙이 처리한다. */
.navtop{ display:block; padding:8px 16px; color:var(--fg2); font-size:13px; font-weight:700;
  border-left:2px solid transparent; }
.navtop:hover{ background:var(--soft); color:var(--accent); }
.navtop.on{ background:var(--accent-soft); color:var(--accent-fg); border-left-color:var(--accent); }
.navgrp{ border:0; }
.navgrp-h{ display:flex; align-items:center; gap:6px; padding:8px 14px 8px 16px;
  color:var(--muted); font-size:12.5px; font-weight:600; cursor:pointer; letter-spacing:.01em; }
.navgrp-h:hover{ background:var(--soft); color:var(--fg2); }
.navgrp[open] > .navgrp-h{ color:var(--fg); }
.navgrp-h .navnote{ font-size:10.5px; font-weight:400; color:var(--faint); }
.navgrp-h .navcx{ margin-left:auto; width:0; height:0; flex:0 0 auto;
  border-left:4px solid currentColor; border-top:4px solid transparent; border-bottom:4px solid transparent;
  opacity:.5; transition:transform .15s; }
.navgrp[open] > .navgrp-h .navcx{ transform:rotate(90deg); opacity:.7; }
.navkids{ margin:1px 0 4px 22px; border-left:1px solid var(--border); padding:2px 0; }
.navkids a{ display:block; padding:6px 12px; color:var(--muted); font-size:12.5px; font-weight:600;
  border-left:2px solid transparent; margin-left:-1px; }
.navkids a:hover{ background:var(--soft); color:var(--accent); }
.navkids a.on{ background:var(--accent-soft); color:var(--accent-fg); border-left-color:var(--accent); }
.navsoon{ display:block; padding:6px 12px; color:var(--faint); font-size:12.5px; font-weight:500;
  cursor:default; }
.navtag{ float:right; font-size:9.5px; font-weight:700; font-style:normal; border-radius:2px;
  padding:1px 6px; margin-top:1px; }
.navtag.soon{ color:var(--faint); background:var(--soft); }
.navkids .navbadge{ float:right; }

/* ── 등록폼틀 primitive (파트 A2) ──
   섹션 앵커바 + 필드행 카운터. 토큰만(하드코딩 hex 금지). 필드행 자체(.grid/.fv/.st/.src-badge)
   는 등록 화면의 기존 표 CSS 를 그대로 쓴다 — 여기서 다시 정의하지 않는다. */
.regform-anchorbar{ position:sticky; top:0; z-index:5; display:flex; flex-wrap:wrap; gap:4px;
  align-items:center; margin:0 0 12px; padding:8px 10px; background:var(--panel);
  border:1px solid var(--border); border-radius:var(--radius-sm); }
.regform-anchorbar .rfa-h{ font-size:11px; font-weight:700; letter-spacing:.04em; color:var(--faint);
  padding:2px 8px 2px 2px; }
.regform-anchorbar .rfa-link{ display:inline-flex; align-items:center; gap:5px; font-size:12px;
  color:var(--muted); padding:4px 9px; border-radius:999px; white-space:nowrap; }
.regform-anchorbar .rfa-link:hover{ background:var(--soft); color:var(--accent); }
.regform-anchorbar .rfa-link.active{ background:var(--accent-soft); color:var(--accent-fg); font-weight:700; }
.regform-anchorbar .rfa-n{ font-size:10.5px; font-weight:700; color:var(--faint); }
.regform-anchorbar .rfa-link.active .rfa-n{ color:var(--accent); }
.regform-counter{ display:inline-block; margin-left:8px; font-size:11px; font-weight:600;
  color:var(--faint); }
.regform-counter.over{ color:var(--rej); font-weight:700; }
.grid tr[id^="regsec-"]{ scroll-margin-top:64px; }
.grid tr.regform-err td{ background:var(--rej-bg); }

.nav-footer{ margin-top:auto; border-top:1px solid var(--border-soft); padding-top:6px; }
.nav-footer-action{
  display:block; width:100%; text-align:left; padding:8px 16px;
  background:none; border:0; color:var(--fg2); font-family:inherit;
  font-size:12px; cursor:pointer;
}
.nav-footer-link{ font-size:12px; }
.nav-footer-link.muted{ color:var(--faint); }
.job-badge-stack{
  position:fixed; right:16px; bottom:16px; z-index:300;
  display:flex; flex-direction:column; gap:6px; align-items:flex-end;
}

/* ── card ── */
.card{
  background:var(--panel); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow);
}
.card.compact{ border-radius:var(--radius-sm); }
.card.flat{ box-shadow:none; }
.card-body{ padding:16px 18px; }
.card-title{ color:var(--fg); font-size:13px; font-weight:700; }
.card-subtitle{ color:var(--muted); font-size:11px; }

/* ── button ── */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  min-height:34px; padding:7px 13px; border:1px solid var(--border);
  border-radius:var(--radius-sm); background:var(--panel); color:var(--fg2);
  font:600 12px/1.3 inherit; text-decoration:none; cursor:pointer;
}
.btn:hover{ border-color:var(--accent); color:var(--accent); }
.btn.primary{ background:var(--brand); border-color:var(--brand); color:#fff; }
.btn.secondary{ background:var(--panel); color:var(--fg2); }
.btn.danger{ background:var(--panel); border-color:var(--rej); color:var(--rej); }
.btn.sm{ min-height:29px; padding:5px 10px; font-size:11.5px; }
.btn:disabled,.btn[aria-disabled="true"]{ cursor:not-allowed; opacity:.55; }

/* Product workbench uses the same button primitive at the denser 36px operating-console size.
   During migration the legacy `.p2-toolbtn` name is an alias of this primitive. Once all markup
   is migrated, the alias can disappear without changing the visual contract. */
.btn.control,
.p2-toolbtn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  min-height:36px; height:36px; padding:0 13px;
  border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--panel); color:var(--fg2); font-family:inherit;
  font-size:12.5px; font-weight:700; text-decoration:none;
  white-space:nowrap; cursor:pointer;
}
.btn.control:hover,
.p2-toolbtn:hover{ border-color:var(--accent); color:var(--accent); }
.btn.control.primary,
.p2-toolbtn.primary{ background:var(--accent); border-color:var(--accent); color:#fff; }
.btn.control.primary:hover,
.p2-toolbtn.primary:hover{ background:var(--accent-700); color:#fff; }
.btn.control svg,
.p2-toolbtn svg{ width:14px; height:14px; opacity:.65; }
.btn.control.primary svg,
.p2-toolbtn.primary svg{ opacity:1; }
/* 정렬처럼 **단일선택 토글**로 쓰는 control 버튼(`aria-pressed`). 눌린 칸은 accent 윤곽 +
   soft 채움. ⛔`.primary`(꽉 찬 accent)를 쓰지 마라 — 그건 「상품 등록」 같은 주 동작 전용이라
   정렬 칸이 페이지에서 제일 센 버튼이 돼 버린다. 토큰은 셋 다 app.css 에 실재한다(다크 포함).*/
.btn.control[aria-pressed="true"],
.p2-toolbtn[aria-pressed="true"]{
  border-color:var(--accent); color:var(--accent-fg); background:var(--accent-soft);
}

select.btn.control,
select.p2-toolbtn{
  appearance:none; padding-right:30px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 15px) 15px,calc(100% - 10px) 15px;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat;
}

/* ── badge / status ── */
.badge{
  display:inline-flex; align-items:center; gap:4px; padding:3px 9px;
  border:1px solid var(--border); border-radius:999px;
  background:var(--subtle); color:var(--muted); font-size:11px; font-weight:700;
}
.badge.ok{ background:var(--ok-bg); border-color:var(--ok); color:var(--ok); }
.badge.warn{ background:var(--warn-bg); border-color:var(--warn); color:var(--warn); }
.badge.bad{ background:var(--rej-bg); border-color:var(--rej); color:var(--rej); }
.badge.none{ background:var(--soft); border-color:var(--border); color:var(--faint); }

/* Selectable filter chips are badges with interaction, not a separate component family.
   `.p2-chip` is temporarily kept as a compatibility alias so JS/markup do not have to move in
   the same commit as the visual contract. */
.badge.filter,
.p2-chip,
.ads-filter-chip{
  display:inline-flex; align-items:center; gap:6px;
  min-height:28px; padding:5px 12px 5px 10px;
  border:1px solid var(--border); border-radius:999px;
  background:var(--panel); color:var(--faint);
  font-size:12px; font-weight:700; line-height:1.25;
}
.badge.filter{ cursor:pointer; }
.badge.filter:hover,
.p2-scenario-chip:hover{ border-color:var(--accent); color:var(--accent); }
.badge.filter.on,
.p2-scenario-chip.on{ background:var(--accent); border-color:var(--accent); color:#fff; }
.badge.filter .n,
.p2-chip .n,
.ads-filter-chip .n{ font-size:10.5px; opacity:.72; font-variant-numeric:tabular-nums; }
.p2-chip svg{ width:14px; height:14px; opacity:.85; flex:0 0 auto; }

/* ── fields ── */
.field{
  width:100%; min-height:36px; padding:7px 10px;
  border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--panel); color:var(--fg2); font:400 13px/1.4 inherit;
}
.field:hover{ border-color:var(--accent); }
.field:disabled{ background:var(--soft); color:var(--faint); cursor:not-allowed; }
.field-label{ display:block; margin-bottom:5px; color:var(--muted); font-size:11.5px; font-weight:600; }

/* Search is a field pattern: icon + borderless input inside one shared surface.
   Legacy `.p2-search` is an alias until product markup is migrated. */
.search-field,
.p2-search{
  flex:1; min-width:220px; min-height:36px; height:36px; padding:0 12px;
  display:flex; align-items:center; gap:8px;
  border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--subtle); color:var(--muted);
}
.search-field:focus-within,
.p2-search:focus-within{ border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
.search-field svg,
.p2-search svg{ width:14px; height:14px; flex:0 0 auto; opacity:.6; }
.search-field input,
.p2-search input{
  flex:1; min-width:0; border:0; outline:0; background:transparent;
  color:var(--fg); font:inherit; font-size:12.5px;
}
.search-field input::placeholder,
.p2-search input::placeholder{ color:var(--muted); }

/* ── table ── */
.table-wrap{ overflow:auto; border:1px solid var(--border); border-radius:var(--radius-sm); background:var(--panel); }
.table{ width:100%; border-collapse:collapse; background:var(--panel); }
.table th{
  padding:8px 10px; border-bottom:1px solid var(--border); border-right:1px solid var(--border);
  background:var(--thead-bg); color:var(--fg); font-size:11.5px; font-weight:700; text-align:left;
}
.table td{ padding:8px 10px; border-bottom:1px solid var(--border); border-right:1px solid var(--border); color:var(--fg2); vertical-align:middle; }
.table th:last-child, .table td:last-child{ border-right:0; }
.table tbody tr:last-child td{ border-bottom:0; }
.table.dense th,.table.dense td{ padding-top:7px; padding-bottom:7px; }
.table.sticky thead th{ position:sticky; top:0; z-index:1; }

/* Operating-console table: shared dense/sticky grid used by product browse and reusable elsewhere.
   Legacy p2 names are aliases during migration; product-only column semantics remain in app.css. */
.table-wrap.console,
.p2-gridwrap{
  overflow:hidden; background:var(--panel); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow);
}
.table-scroll.console,
.p2-scrollx{ overflow:auto; min-height:320px; }
table.table.console,
table.p2-grid{
  width:100%; border-collapse:collapse; background:var(--panel);
  font-size:12.5px; white-space:nowrap;
}
table.table.console th,
.p2-grid th{
  padding:9px 10px; vertical-align:middle; text-align:left;
  background:var(--thead-bg); color:var(--fg); font-size:11.5px; font-weight:700;
  border-bottom:1px solid var(--border); border-right:1px solid var(--border);
  position:sticky; top:0; z-index:5; box-shadow:inset 0 -1px 0 var(--border);
}
table.table.console td,
.p2-grid td{
  padding:8px 10px; vertical-align:middle; color:var(--fg2);
  border-bottom:1px solid var(--border); border-right:1px solid var(--border);
}
table.table.console tbody tr:hover td,
.p2-grid tbody tr:hover td{ background:var(--soft); }
table.table.console .num,
.p2-grid th.num,
.p2-grid td.num{ text-align:right; font-variant-numeric:tabular-nums; }
table.table.console .chk,
.p2-grid th.chk,
.p2-grid td.chk{ width:34px; text-align:center; }

/* ── tabs ── */
.tabs{ display:flex; gap:4px; border-bottom:1px solid var(--border-soft); }
.tab{
  display:inline-flex; align-items:center; min-height:34px; padding:7px 10px;
  border-bottom:2px solid transparent; color:var(--muted); font-size:12px; font-weight:600;
}
.tab:hover{ color:var(--accent); }
.tab.on{ border-bottom-color:var(--accent); color:var(--accent-fg); }

/* ── empty state ── */
.empty{ padding:34px 16px; text-align:center; color:var(--muted); font-size:12.5px; line-height:1.6; }
.empty strong{ color:var(--fg2); }

/* ── KPI ── */
.kpi-label{ color:var(--muted); font-size:11.5px; font-weight:600; }
.kpi-value{ color:var(--fg); font-size:24px; font-weight:700; line-height:1.15; }
.kpi-meta{ color:var(--muted); font-size:11px; }

/* ── toolbar ── */
.toolbar{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.toolbar .toolbar-spacer{ margin-left:auto; }
.toolbar-card,
.p2-toolbar,
.ads-toolbar{
  background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:12px 14px 13px; margin-bottom:14px;
}
.toolbar-row,
.p2-searchrow,
.ads-toolbar-row{ display:flex; align-items:center; gap:10px; }
.toolbar-spacer,
.p2-toolbar-spacer{ margin-left:auto; }
.ads-toolbar-row{ margin-bottom:12px; min-width:0; }
.ads-toolbar-row .search{ flex:1; min-width:180px; }
.ads-filter-chip .dot{ width:7px; height:7px; border-radius:999px; flex:0 0 auto; }


/* ── order controls compatibility aliases ──
   Keep current order-screen visuals while moving ownership to the shared system. */
.search-input.order,
.osearch{
  flex:1; max-width:420px; height:42px;
  padding:9px 14px 9px 34px;
  font-size:13.5px; font-family:inherit;
  border:1px solid var(--border); border-radius:2px;
  background:var(--panel) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%2399a' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.7' y2='16.7'/%3E%3C/svg%3E") no-repeat 11px center;
}
.search-input.order:focus,
.osearch:focus{ outline:none; border-color:var(--accent); }
.filter-chip.order,
.oacct{
  border:1px solid var(--border); background:var(--panel); border-radius:2px;
  font-size:12px; font-weight:700; color:var(--muted);
  padding:7px 14px; cursor:pointer; font-family:inherit;
}
.filter-chip.order:hover,
.oacct:hover{ border-color:var(--accent); color:var(--accent); }
.filter-chip.order.on,
.oacct.on{ background:var(--accent); border-color:var(--accent); color:#fff; }
.filter-chip.order .count,
.oacct .c{ opacity:.7; margin-left:5px; font-weight:600; }
.btn.ghost-compact,
.btn-x{
  border:1px solid var(--border); background:var(--panel); border-radius:2px;
  font-size:12.5px; font-weight:700; color:var(--muted);
  padding:7px 14px; cursor:pointer; font-family:inherit;
}
.btn.ghost-compact:hover,
.btn-x:hover{ border-color:var(--accent); color:var(--accent); }

/* ── returns layout modifiers ── */
.kpis.four{ grid-template-columns:repeat(4,minmax(0,1fr)); margin-bottom:14px; }
.rtabs.split{ display:flex; align-items:center; }
.rtabs.split .tab-action{ margin-left:auto; }
.sec-body.flush{ padding:0; }
.table-scroll-x{ overflow-x:auto; }
.form-gap-sm{ margin-top:4px; }
.is-hidden{ display:none; }
.empty.returns-empty{ padding:30px; }
.warnbar .warnbar-label{ flex:0 0 auto; }


/* ── ads console compatibility aliases ── */
.btn.console,
.ads-mockup .toolbtn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  min-height:36px; height:36px; padding:0 13px;
  border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--panel); color:var(--fg2); font-family:inherit;
  font-size:12.5px; font-weight:700; text-decoration:none; white-space:nowrap; cursor:pointer;
}
.btn.console.primary,
.ads-mockup .toolbtn.pri{ background:var(--brand); border-color:var(--brand); color:var(--panel); }
.btn.console[aria-disabled="true"],
.ads-mockup .toolbtn[aria-disabled="true"]{ background:var(--soft); border-color:var(--border); color:var(--faint); cursor:not-allowed; }

.table-wrap.ads-console,
.ads-grid-card,
.ads-mockup .gridwrap{
  background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); overflow:hidden;
}
.table-scroll.ads-console,
.ads-scroll-x,
.ads-mockup .scrollx{ overflow-x:auto; }
table.table.ads-console,
.ads-data-grid,
.ads-mockup table.grid{ width:100%; border-collapse:collapse; font-size:12.5px; }
table.table.ads-console thead th,
.ads-data-grid thead th,
.ads-mockup .grid thead th{
  position:sticky; top:0; z-index:5; background:var(--thead-bg);
  border-bottom:1px solid var(--border); border-right:1px solid var(--border);
  padding:0; vertical-align:top; text-align:left;
}
table.table.ads-console tbody td,
.ads-data-grid tbody td,
.ads-mockup .grid tbody td{
  padding:8px 10px; border-bottom:1px solid var(--border);
  border-right:1px solid var(--border); white-space:nowrap; color:var(--fg2);
}
table.table.ads-console tbody tr:hover td,
.ads-data-grid tbody tr:hover td,
.ads-mockup .grid tbody tr:hover td{ background:var(--soft); }
table.table.ads-console .num,
.ads-data-grid .num,
.ads-mockup .grid .num{ text-align:right; font-variant-numeric:tabular-nums; }


/* ── finance console compatibility aliases ── */
.money-page .money-toolbar,
.money-page .toolbar.money-toolbar{
  background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:12px 14px 13px; margin-bottom:14px;
}
.money-page .searchrow{ display:flex; align-items:center; gap:10px; }
.money-page .money-search{
  flex:1; min-width:220px; display:flex; align-items:center; gap:8px;
  height:36px; padding:0 12px; border:1px solid var(--border);
  border-radius:var(--radius-sm); background:var(--subtle); color:var(--muted);
}
.money-page .money-search svg{ opacity:.6; }
.money-page .money-search span{ font-size:12.5px; }
.money-page .toolbtn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  height:36px; padding:0 13px; border:1px solid var(--border);
  border-radius:var(--radius-sm); background:var(--panel); color:var(--fg2);
  font-size:12.5px; font-weight:700; white-space:nowrap; font-family:inherit;
}
.money-page .toolbtn svg{ opacity:.6; }
.money-page .gridwrap{
  background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); overflow:hidden;
}
.money-page table.grid{ border-collapse:collapse; font-size:12.5px; width:100%; }
.money-page .grid thead th{
  background:var(--thead-bg); border-bottom:1px solid var(--border);
  border-right:1px solid var(--border); padding:9px 11px; text-align:left;
  font-size:11.5px; font-weight:700; color:var(--fg); white-space:nowrap;
}
.money-page .grid thead th.num{ text-align:right; }
.money-page .grid tbody td{
  padding:8px 11px; border-bottom:1px solid var(--border);
  border-right:1px solid var(--border); color:var(--fg2); white-space:nowrap;
}
.money-page .grid tbody tr:hover td{ background:var(--soft); }
.money-page .grid .num{ text-align:right; font-variant-numeric:tabular-nums; }


/* ── settings compatibility aliases ── */
.card.settings-card,
.settings-page .card{
  background:var(--panel); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); overflow:hidden; margin-bottom:14px;
}
.btn.settings,
.settings-page .toolbtn{
  display:inline-flex; align-items:center; gap:6px; min-height:32px; height:32px; padding:0 12px;
  border:1px solid var(--border); border-radius:2px; background:var(--panel);
  color:var(--fg2); font-size:12.5px; font-weight:700; white-space:nowrap; font-family:inherit;
}
.btn.settings svg,
.settings-page .toolbtn svg{ opacity:.6; }
.btn.settings.primary,
.settings-page .toolbtn.pri{ background:var(--brand); border-color:var(--brand); color:#fff; }


/* ── settings table/status compatibility aliases ── */
.settings-page table.grid{ width:100%; border-collapse:collapse; font-size:12.5px; background:var(--panel); }
.settings-page .grid thead th{ padding:9px 11px; text-align:left; white-space:nowrap; background:var(--thead-bg); color:var(--fg); font-size:11.5px; font-weight:700; border-bottom:1px solid var(--border); border-right:1px solid var(--border); }
.settings-page .grid tbody td{ padding:8px 11px; white-space:nowrap; color:var(--fg2); border-bottom:1px solid var(--border); border-right:1px solid var(--border); }
.settings-page .fc-h .badge.rej{ background:var(--rej-bg); color:var(--rej); }
.settings-page .fc-h .badge.warn{ background:var(--warn-bg); color:var(--warn); }
.settings-page .fc-h .badge.ok{ background:var(--ok-bg); color:var(--ok); }
.settings-page .fc-h .badge.unknown{ background:var(--subtle); color:var(--faint); }

/* ── notice / text utilities ── */
.topbar-action{ margin-left:8px; }
.notice{
  padding:12px 16px; border:1px solid var(--border); border-radius:var(--radius);
  margin-bottom:16px; background:var(--panel); color:var(--fg2);
  font-size:13px; font-weight:700;
}
.notice.ok{ background:var(--ok-bg); border-color:var(--ok); color:var(--ok); }
.notice.warn{ background:var(--warn-bg); border-color:var(--warn); color:var(--warn); }
.text-muted-sm{ color:var(--muted); font-size:12px; }
.text-danger-strong{ color:var(--rej); font-weight:700; }
.mt-14{ margin-top:14px; }

/* ── auth shell ── */
.auth-page{
  min-height:100vh; display:flex; align-items:center; justify-content:center;
  background:var(--bg); color:var(--fg);
}
.auth-card{
  width:340px; padding:32px 30px; background:var(--panel); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow);
}
.auth-brand{ display:flex; align-items:center; gap:8px; color:var(--fg); font-size:18px; font-weight:700; letter-spacing:-.02em; }
.auth-icon{ font-size:20px; }
.auth-sub{ margin:6px 0 22px; color:var(--muted); font-size:12.5px; }
.auth-label{ display:block; margin-bottom:6px; color:var(--muted); font-size:12px; font-weight:700; }
.auth-field{ min-height:42px; height:42px; padding:0 13px; font-size:14px; }
.auth-field:focus{ outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
.auth-submit{ width:100%; min-height:42px; height:42px; margin-top:16px; font-size:14px; font-weight:700; }
.auth-error{ margin-bottom:16px; padding:9px 12px; border-radius:var(--radius-sm); background:var(--rej-bg); color:var(--rej); font-size:12.5px; font-weight:600; }
.auth-username-proxy{ position:absolute; width:1px; height:1px; padding:0; border:0; opacity:0; pointer-events:none; }


/* ── 조회틀 부족조각 (멀티채널 콘솔 파트 B · Task 1) ──
   조회틀은 위쪽 정본(.toolbar-card·.search-field·.tabs·.badge.filter·.table.console·.empty)을
   그대로 쓴다. 그 정본에 **없던 3개**만 여기서 확장한다 — 새 도메인 alias 를 만들지 않는다.
   토큰은 전부 app.css 에 실재한다(미선언 var 금지 가드 통과). */

/* ① 행 상태 = **행 전체 옅은 음영** + 좌측 색띠 (사방넷 틀A A-7). 배지만으론 100행을 훑을 때
   안 보인다 — "배지는 안 보이고 색은 보인다". 정상(판매중)은 rowstate 를 안 달아 음영이 없다(흰색).
   ⚠️ border-collapse 표에선 tr 배경/그림자가 불안정 → td 에 건다. hover(--soft)는 아래 규칙이 이긴다.
   ⚠️ 음영은 아주 옅게(6~9%) — 2줄 복합칼럼 글자가 묻히지 않게. 색약속은 사장님이 사방넷에서
      익힌 그대로다: 녹색=일시중지 · 붉은=오류/삭제 · 앰버=주의(위너이탈) · 회색=미연결. */
.table tr[data-rowstate="ok"]   td{ background:color-mix(in srgb, var(--ok)    8%, var(--panel)); }
.table tr[data-rowstate="warn"] td{ background:color-mix(in srgb, var(--warn)  9%, var(--panel)); }
.table tr[data-rowstate="bad"]  td{ background:color-mix(in srgb, var(--rej)   8%, var(--panel)); }
.table tr[data-rowstate="none"] td{ background:color-mix(in srgb, var(--faint) 6%, var(--panel)); }
.table tr[data-rowstate="ok"]   td:first-child{ box-shadow:inset 3px 0 0 var(--ok); }
.table tr[data-rowstate="warn"] td:first-child{ box-shadow:inset 3px 0 0 var(--warn); }
.table tr[data-rowstate="bad"]  td:first-child{ box-shadow:inset 3px 0 0 var(--rej); }
.table tr[data-rowstate="none"] td:first-child{ box-shadow:inset 3px 0 0 var(--faint); }

/* ② 빈상태 2종. 「검색 전(hint)」과 「결과 없음(none)」은 다른 말이라 톤·아이콘을 가른다. */
.empty[data-kind]{ display:flex; flex-direction:column; align-items:center; gap:6px; }
.empty[data-kind] .ico{ font-size:22px; line-height:1; opacity:.5; }
.empty[data-kind="hint"]{ color:var(--muted); }
.empty[data-kind="none"]{ color:var(--faint); }

/* ③ 기준일 드롭다운. .search-field 톤(subtle 바탕·36px)을 재사용한 select 래퍼. */
.lookup-asof{
  display:inline-flex; align-items:center; gap:6px;
  min-height:36px; height:36px; padding:0 10px;
  border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--subtle); color:var(--muted); font-size:12px; font-weight:700;
}
.lookup-asof select{
  border:0; outline:0; background:transparent; color:var(--fg2);
  font:inherit; font-size:12px; cursor:pointer;
}

/* ④ A-5 복합 칼럼 — 한 칸에 2줄(상품명 / SPID·계정 …). 가로 스크롤 대신 세로로 접는다. */
.table td.cell-stack{ line-height:1.35; }
.table td.cell-stack .cs-1{ color:var(--fg); font-weight:600; }
.table td.cell-stack .cs-2{ margin-top:2px; color:var(--muted); font-size:11px; }

/* ⑤ A-5 2줄 헤더 — 헤더 칸도 관련 라벨을 겹쳐 쓴다(품번코드/자체상품코드/모델명 식). */
.table th .th-sub{ display:block; margin-top:1px; color:var(--faint); font-size:10px; font-weight:600; }

/* ⑥ 결과표 헤더 = **다크네이비 + 흰 텍스트** (사방넷 틀A A-5).
   ★사방넷은 두 색을 가른다 — 필터 패널 라벨셀=회색(--thead-bg), 결과 격자 헤더=다크네이비.
   조회틀 결과표(.table.console)에만 건다: 전역 --thead-bg 는 finance·settings·ads·orders 등
   11개 표가 공유하므로(그 헤더 전부를 뒤집는 건 이 화면 밖 미검증 화면까지 바꾼다) 안 건드린다.
   .table.console 는 조회틀 primitive(_lookup_table) 전용이라 몰상품·몰지원 조회화면만 네이비가 된다. */
table.table.console thead th{ background:var(--lookup-thead); color:var(--on-accent); }
table.table.console thead th .th-sub{ color:color-mix(in srgb, var(--on-accent) 60%, transparent); }

/* ⑦ 거대 검색 패널 (사방넷 틀A A-1·A-2·A-3) — 좌우 2단 라벨셀 격자.
   왼쪽=값(무엇을 찾나) · 오른쪽=플래그/정렬(어떻게 보나). 라벨셀=회색(--thead-bg), 값셀=흰색.
   gap:1px + 배경 --border 트릭으로 전 셀 1px 격자(nth-child 없이 어느 열수에도 안 깨진다).
   4열(라벨|값|라벨|값) → 좁아지면 2열 → 더 좁으면 1열. 소스순서(좌라벨·좌값·우라벨·우값)가
   그대로 재배열돼 라벨/값 짝이 유지된다. */
.lkp-panel{ display:grid; grid-template-columns:max-content minmax(0,1fr) max-content minmax(0,1fr);
  gap:1px; background:var(--border); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); margin-bottom:14px; overflow:hidden; }
.lkp-panel > .lc,.lkp-panel > .vc{ display:flex; align-items:center; gap:7px; flex-wrap:wrap;
  padding:7px 11px; min-height:40px; }
.lkp-panel > .lc{ background:var(--thead-bg); color:var(--fg); font-size:12px; font-weight:700; white-space:nowrap; }
.lkp-panel > .vc{ background:var(--panel); color:var(--fg2); }
.lkp-panel > .vc.wide{ grid-column:span 3; }                 /* 검색항목처럼 값이 넓은 행 */
@media(max-width:1040px){ .lkp-panel{ grid-template-columns:max-content minmax(0,1fr); }
  .lkp-panel > .vc.wide{ grid-column:span 1; } }
@media(max-width:560px){ .lkp-panel{ grid-template-columns:1fr; } .lkp-panel > .lc{ min-height:0; } }
/* 패널 안 컨트롤 (select·input) */
.lkp-sel,.lkp-in{ height:30px; border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--panel); color:var(--fg2); font:inherit; font-size:12px; padding:0 8px; }
.lkp-in{ min-width:170px; }
.lkp-sel{ cursor:pointer; }
.lkp-sel:disabled,.lkp-in:disabled{ background:var(--soft); color:var(--faint); cursor:not-allowed; }
.lkp-sep{ color:var(--faint); }                              /* from ~ to 구분 */
.lkp-searchitem{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
/* 퀵칩(일자) — v1 은 틀만(적용 예정)이라 비활성 표시 */
.lkp-chip{ height:26px; padding:0 9px; border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--panel); color:var(--muted); font-size:11px; font-weight:700; cursor:pointer; }
.lkp-chip:hover{ border-color:var(--accent); color:var(--accent); }
.lkp-chip[disabled]{ background:var(--soft); color:var(--faint); cursor:not-allowed; border-color:var(--border); }
/* 선택검색 체크박스 무더기(A-1) */
.lkp-checks{ display:flex; gap:14px; flex-wrap:wrap; }
.lkp-checks label{ display:inline-flex; align-items:center; gap:5px; font-size:12px; color:var(--fg2); font-weight:600; }
.lkp-checks input:disabled ~ *,.lkp-checks label:has(input:disabled){ color:var(--faint); }
.lkp-hint{ font-size:10.5px; color:var(--faint); font-weight:600; }  /* "(적용 예정)" 정직 표시 */

/* ⑧ 자료수 N건 + 일괄 액션바 (사방넷 틀A A-4) — 표 바로 위·표 밖. 행버튼이 아니라 상단 일괄.
   버튼은 정본 .btn 을 재사용. 아직 안 붙은 동작은 [disabled] 로 비활성(작동하는 척 금지). */
.lkp-actionbar{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0 0 8px; }
.lkp-count{ font-size:12.5px; font-weight:700; color:var(--fg2); }
.lkp-count b{ color:var(--accent); font-variant-numeric:tabular-nums; }
.lkp-actionbar .acts{ margin-left:auto; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.lkp-actionbar .acts .btn{ height:30px; padding:0 11px; font-size:12px; }
