/* ==========================================================================
   MISOSAM Hub v2 — UI components (접두 hub-)
   의존: tokens.css (먼저 로드). 다크는 토큰으로만 분기(html[data-theme="dark"]).
   반응형: ≥1200 사이드바 232 / 900~1199 레일 64(.hub-app.is-rail) /
           <900 드로어(.hub-sidebar.is-open + .hub-scrim) + 하단 탭 56 / <600 표→카드
   ========================================================================== */

/* hidden 속성은 항상 숨김 — .hub-btn{display:inline-flex} 같은 클래스 규칙이 UA 의 [hidden]{display:none} 을 이겨
   el.hidden = true 가 안 먹던 문제(검색 지우기 버튼·드로어·페이저 등) */
[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   1. 레이아웃 셸
   -------------------------------------------------------------------------- */
.hub-body { margin: 0; min-height: 100dvh; background: var(--hub-bg); color: var(--hub-text); }
.hub-body.hub-no-scroll { overflow: hidden; }

.hub-app {
  display: grid;
  grid-template-columns: var(--hub-sidebar-w) minmax(0, 1fr);
  min-height: 100dvh;
}
.hub-app.is-rail { grid-template-columns: var(--hub-rail-w) minmax(0, 1fr); }

/* 스킵 링크 */
.hub-skip {
  position: absolute; left: 8px; top: -200px; z-index: var(--hub-z-skip);
  padding: 8px 14px; border-radius: var(--hub-r-md);
  background: var(--hub-accent); color: var(--hub-accent-ink);
  font-weight: 700; text-decoration: none; box-shadow: var(--hub-shadow-2);
}
.hub-skip:focus { top: 8px; }

/* ---- 사이드바 ---- */
.hub-sidebar {
  position: sticky; top: 0; height: 100dvh;
  display: flex; flex-direction: column;
  background: var(--hub-surface); border-right: 1px solid var(--hub-border);
  z-index: var(--hub-z-sidebar); overflow: hidden;
  padding-top: var(--hub-safe-top);
}
.hub-sidebar__brand {
  display: flex; align-items: center; gap: 10px;
  height: var(--hub-topbar-h); padding: 0 14px; flex: none;
  border-bottom: 1px solid var(--hub-border); text-decoration: none; color: inherit;
}
.hub-sidebar__logo {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--hub-accent); color: var(--hub-accent-ink);
  font-weight: 800; font-size: 15px; letter-spacing: -.02em;
}
.hub-sidebar__name { font-weight: 700; font-size: 14px; line-height: 1.15; white-space: nowrap; }
.hub-sidebar__sub { font-size: var(--hub-fs-xs); color: var(--hub-text-3); line-height: 1.15; white-space: nowrap; }
.hub-sidebar__brand-text { display: flex; flex-direction: column; min-width: 0; }
.hub-sidebar .hub-sidebar__close { margin-left: auto; display: none; }   /* .hub-btn 보다 높은 특이성(≥900 숨김) */

.hub-sidebar__scroll { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 8px; overscroll-behavior: contain; }
.hub-sidebar__group { margin-bottom: 6px; }
.hub-sidebar__group-label {
  padding: 10px 10px 4px; font-size: var(--hub-fs-xs); font-weight: 600;
  color: var(--hub-text-3); letter-spacing: .02em; white-space: nowrap;
}
/* 그룹 헤더 = 접기/펼치기 버튼(shell.js, 사용자별 prefs 'nav.folded') */
.hub-sidebar__group-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 6px; width: 100%;
  border: 0; background: transparent; cursor: pointer; font: inherit; font-size: var(--hub-fs-xs); font-weight: 600;
  text-align: left; border-radius: var(--hub-r-sm); min-height: 28px;
  padding: 6px 10px; margin-top: 4px;
}
.hub-sidebar__group-btn:hover { color: var(--hub-text); background: var(--hub-surface-2); }
.hub-sidebar__group-btn:focus-visible { outline: 0; box-shadow: var(--hub-focus); }
.hub-sidebar__group-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hub-sidebar__group-chev { flex: none; width: 12px; height: 12px; color: var(--hub-text-4); transition: transform var(--hub-dur) var(--hub-ease); }
.hub-sidebar__group.is-folded .hub-sidebar__group-chev { transform: rotate(-90deg); }
.hub-sidebar__group.is-folded .hub-sidebar__list { display: none; }
.hub-app.is-rail .hub-sidebar__group.is-folded .hub-sidebar__list { display: flex; }   /* 레일(아이콘)에선 접힘 무시 */
.hub-sidebar__item {
  display: flex; align-items: center; gap: 10px;
  min-height: 34px; padding: 0 10px; border-radius: var(--hub-r-sm);
  color: var(--hub-text-2); text-decoration: none; font-size: var(--hub-fs-md);
  border: 0; background: transparent; width: 100%; cursor: pointer; text-align: left;
  transition: background var(--hub-dur) var(--hub-ease), color var(--hub-dur) var(--hub-ease);
  position: relative;
}
.hub-sidebar__item:hover { background: var(--hub-surface-2); color: var(--hub-text); }
.hub-sidebar__item svg { flex: none; width: 18px; height: 18px; color: var(--hub-text-3); }
.hub-sidebar__item:hover svg { color: var(--hub-text-2); }
.hub-sidebar__item.is-active, .hub-sidebar__item[aria-current="page"] {
  background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); font-weight: 600;
  box-shadow: inset 3px 0 0 var(--hub-accent);
}
.hub-sidebar__item.is-active svg, .hub-sidebar__item[aria-current="page"] svg { color: var(--hub-accent-soft-ink); }
.hub-sidebar__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-sidebar__item .hub-badge { margin-left: auto; flex: none; }
.hub-sidebar__item--sub { padding-left: 38px; min-height: 30px; font-size: var(--hub-fs-sm); }

.hub-sidebar__foot { flex: none; border-top: 1px solid var(--hub-border); padding: 8px; display: flex; flex-direction: column; gap: 2px; }
.hub-sidebar__user { display: flex; align-items: center; gap: 10px; padding: 6px 10px; min-height: 40px; }
.hub-sidebar__user-name { font-weight: 600; font-size: var(--hub-fs-sm); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-sidebar__user-role { font-size: var(--hub-fs-xs); color: var(--hub-text-3); line-height: 1.2; }
.hub-sidebar__user-text { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.hub-sidebar__footrow { display: flex; gap: 4px; align-items: center; }
.hub-sidebar__footrow .hub-btn { flex: 1; justify-content: flex-start; }

/* 레일(아이콘만) */
.hub-app.is-rail .hub-sidebar__brand { justify-content: center; padding: 0; }
.hub-app.is-rail .hub-sidebar__brand-text,
.hub-app.is-rail .hub-sidebar__group-label,
.hub-app.is-rail .hub-sidebar__label,
.hub-app.is-rail .hub-sidebar__item .hub-badge,
.hub-app.is-rail .hub-sidebar__user-text,
.hub-app.is-rail .hub-sidebar__rail-hide { display: none; }
.hub-app.is-rail .hub-sidebar__group { border-top: 1px solid var(--hub-divider); padding-top: 6px; margin-top: 6px; }
.hub-app.is-rail .hub-sidebar__group:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
.hub-app.is-rail .hub-sidebar__item { justify-content: center; padding: 0; height: 40px; }
.hub-app.is-rail .hub-sidebar__item svg { width: 20px; height: 20px; }
.hub-app.is-rail .hub-sidebar__item--sub { display: none; }
.hub-app.is-rail .hub-sidebar__user { justify-content: center; padding: 6px 0; }
.hub-app.is-rail .hub-sidebar__footrow { flex-direction: column; }
.hub-app.is-rail .hub-sidebar__footrow .hub-btn { width: 100%; justify-content: center; padding: 0; }
.hub-app.is-rail .hub-sidebar__footrow .hub-btn .hub-btn__label { display: none; }

/* 스크림(드로어 뒤 어둡게) */
.hub-scrim {
  position: fixed; inset: 0; z-index: calc(var(--hub-z-drawer) - 1);
  background: var(--hub-scrim); opacity: 0; pointer-events: none;
  transition: opacity var(--hub-dur-slow) var(--hub-ease);
}
.hub-scrim.is-open { opacity: 1; pointer-events: auto; }

/* 일반 드로어(우측 패널 등) */
.hub-drawer {
  position: fixed; top: 0; bottom: 0; right: 0; z-index: var(--hub-z-drawer);
  width: min(420px, 92vw); background: var(--hub-surface); border-left: 1px solid var(--hub-border);
  box-shadow: var(--hub-shadow-3); transform: translateX(100%);
  transition: transform var(--hub-dur-slow) var(--hub-ease);
  display: flex; flex-direction: column; overflow: hidden;
  padding-bottom: var(--hub-safe-bottom);
}
.hub-drawer.is-open { transform: none; }
.hub-drawer--left { right: auto; left: 0; border-left: 0; border-right: 1px solid var(--hub-border); transform: translateX(-100%); }
.hub-drawer--left.is-open { transform: none; }
.hub-drawer__head { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--hub-border); flex: none; }
.hub-drawer__title { margin: 0; font-size: var(--hub-fs-lg); font-weight: 700; flex: 1; min-width: 0; }
.hub-drawer__body { flex: 1; overflow: auto; padding: 16px; }
.hub-drawer__foot { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 16px; border-top: 1px solid var(--hub-border); background: var(--hub-surface-2); flex: none; }

/* ---- 메인 영역 ---- */
.hub-shell-main { display: flex; flex-direction: column; min-width: 0; min-height: 100dvh; }

.hub-topbar {
  position: sticky; top: 0; z-index: var(--hub-z-topbar);
  display: flex; align-items: center; gap: 8px;
  min-height: var(--hub-topbar-h); padding: var(--hub-safe-top) var(--hub-page-pad) 0;
  background: var(--hub-surface); border-bottom: 1px solid var(--hub-border);
}
.hub-topbar .hub-topbar__menu-btn { display: inline-flex; flex: none; }   /* 모든 폭 노출 — <900 드로어, ≥900 사이드바 접기/펼치기 */
.hub-topbar__title {
  margin: 0; font-size: var(--hub-fs-lg); font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.hub-topbar__titlebox { display: flex; flex-direction: column; min-width: 0; justify-content: center; }
.hub-topbar__crumbs {
  display: flex; align-items: center; gap: 4px; flex-wrap: nowrap;
  font-size: var(--hub-fs-xs); color: var(--hub-text-3); white-space: nowrap; overflow: hidden;
  margin: 0; padding: 0; list-style: none;
}
.hub-topbar__crumbs[hidden] { display: none; }
.hub-topbar__crumbs a { color: inherit; text-decoration: none; }
.hub-topbar__crumbs a:hover { color: var(--hub-text); text-decoration: underline; }
.hub-topbar__crumbs li { display: inline-flex; align-items: center; gap: 4px; }
.hub-topbar__crumbs li + li::before { content: "/"; color: var(--hub-text-4); }
.hub-topbar__search { flex: 1 1 240px; max-width: 460px; margin-left: auto; min-width: 0; }
.hub-topbar .hub-topbar__search-btn { display: none; }    /* <600 에서 검색창 대신 아이콘 버튼(shell.js 가 렌더) */
/* 페이지 동작 = 제목 묶음 바로 뒤(shell.js renderTopbar — _PORTING §4-4). 검색창(margin-left:auto)·사용자는 오른쪽 끝 */
.hub-topbar__actions { display: flex; align-items: center; gap: 6px; flex: none; }
.hub-topbar__actions:empty { display: none; }
@media (min-width: 900px) {
  .hub-topbar__actions > .hub-topbar__act.hub-btn--sm { height: var(--hub-control-h); padding: 0 10px; }   /* 32px — 검색창 높이와 맞춤(눈에 띄게) */
}
@media (min-width: 1200px) { .hub-topbar__actions { margin-left: 8px; } }   /* 제목과 16px(탑바 gap 8 + 8) */
.hub-topbar__user { flex: none; position: relative; }

.hub-main {
  flex: 1; min-width: 0; padding: var(--hub-page-pad);
  padding-left: calc(var(--hub-page-pad) + var(--hub-safe-left));
  padding-right: calc(var(--hub-page-pad) + var(--hub-safe-right));
}
.hub-page { width: 100%; min-width: 0; }
.hub-page--narrow { max-width: 960px; margin: 0 auto; }
.hub-page--medium { max-width: 1280px; margin: 0 auto; }
.hub-page__head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px;
  margin-bottom: 12px; flex-wrap: wrap;
}
.hub-page__title { margin: 0; font-size: var(--hub-fs-xl); font-weight: 700; letter-spacing: -.01em; line-height: 1.25; }
.hub-page__desc { margin: 2px 0 0; font-size: var(--hub-fs-sm); color: var(--hub-text-3); }
.hub-page__actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 개체 머리 동작 줄 — 상세 머리 카드의 제목 바로 아래, 왼쪽 정렬(lib/headacts.js · 업무 상세). 탑바에는 두지 않음(_PORTING §4-4) */
.hub-headacts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.hub-headacts > .hub-headacts__end { margin-left: 10px; }   /* 위험 동작: 조금 띄움 — auto 아님(멀리 보내지 않음) */
/* 머리에 이미 동작이 있는 상세(.hub-page__head): 600 이상에서 동작을 제목 묶음 바로 뒤로(space-between 이면 넓은 화면에서 오른쪽 끝에 붙어 멂) */
@media (min-width: 600px) { .hub-page__head--near { justify-content: flex-start; align-items: center; column-gap: 16px; } }
.hub-page__body { display: flex; flex-direction: column; gap: 12px; }
.hub-section { display: flex; flex-direction: column; gap: 8px; }
.hub-section__title { margin: 0; font-size: var(--hub-fs-md); font-weight: 700; color: var(--hub-text-2); display: flex; align-items: center; gap: 6px; }

/* ---- 하단 탭 ---- */
.hub-bottomnav {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--hub-z-bottomnav);
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  height: calc(var(--hub-bottomnav-h) + var(--hub-safe-bottom));
  padding-bottom: var(--hub-safe-bottom);
  background: var(--hub-surface); border-top: 1px solid var(--hub-border);
}
.hub-bottomnav__item {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: var(--hub-touch); padding: 4px 2px;
  color: var(--hub-text-3); text-decoration: none; font-size: 10.5px; font-weight: 500;
  border: 0; background: transparent; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.hub-bottomnav__ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 26px; border-radius: var(--hub-r-pill);
  transition: background var(--hub-dur) var(--hub-ease);
}
.hub-bottomnav__ico svg { width: 20px; height: 20px; }
.hub-bottomnav__item.is-active, .hub-bottomnav__item[aria-current="page"] { color: var(--hub-text); font-weight: 600; }
.hub-bottomnav__item.is-active .hub-bottomnav__ico, .hub-bottomnav__item[aria-current="page"] .hub-bottomnav__ico {
  background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink);
}

/* --------------------------------------------------------------------------
   2. 표면: 카드 · KPI · KV · 타임라인
   -------------------------------------------------------------------------- */
.hub-card {
  background: var(--hub-surface); border: 1px solid var(--hub-border);
  border-radius: var(--hub-r-lg); padding: var(--hub-card-pad);
  min-width: 0;
}
.hub-card--flush { padding: 0; overflow: hidden; }
.hub-card--flush > .hub-card__head { padding: 12px 16px 0; }
.hub-card--flush > .hub-card__head + .hub-card__body { margin-top: 10px; }
.hub-card--flush .hub-table-wrap { border: 0; border-radius: 0; }
.hub-card--elev { box-shadow: var(--hub-shadow-1); }
.hub-card--accent { border-top: 3px solid var(--hub-accent); }
.hub-card--muted { background: var(--hub-surface-2); }
.hub-card--clickable { cursor: pointer; transition: border-color var(--hub-dur), box-shadow var(--hub-dur); text-decoration: none; color: inherit; display: block; }
.hub-card--clickable:hover { border-color: var(--hub-border-strong); box-shadow: var(--hub-shadow-1); }
.hub-card__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.hub-card__title { margin: 0; font-size: var(--hub-fs-md); font-weight: 700; display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.hub-card__title svg { width: 16px; height: 16px; color: var(--hub-text-3); }
.hub-card__sub { font-size: var(--hub-fs-xs); color: var(--hub-text-3); }
.hub-card__actions { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.hub-card__body { min-width: 0; }
.hub-card__foot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--hub-divider); font-size: var(--hub-fs-sm); color: var(--hub-text-3); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hub-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.hub-card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hub-card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hub-card-grid .span-2 { grid-column: span 2; }

/* KPI 타일 */
.hub-stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.hub-stat-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hub-stat-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hub-stat-grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.hub-kpi {
  display: flex; flex-direction: column; gap: 3px; min-width: 0;
  background: var(--hub-surface); border: 1px solid var(--hub-border); border-radius: var(--hub-r-lg);
  padding: 12px 14px; position: relative;
}
.hub-kpi--good { box-shadow: inset 0 3px 0 var(--hub-good); }
.hub-kpi--warn { box-shadow: inset 0 3px 0 var(--hub-warn); }
.hub-kpi--bad { box-shadow: inset 0 3px 0 var(--hub-bad); }
.hub-kpi--info { box-shadow: inset 0 3px 0 var(--hub-info); }
.hub-kpi--accent { box-shadow: inset 0 3px 0 var(--hub-accent); }
.hub-kpi.is-clickable { cursor: pointer; }
.hub-kpi.is-clickable:hover { border-color: var(--hub-border-strong); }
.hub-kpi.is-active { border-color: var(--hub-accent); background: var(--hub-accent-tint); }
.hub-kpi__label { font-size: var(--hub-fs-xs); color: var(--hub-text-3); font-weight: 500; display: flex; align-items: center; gap: 4px; }
.hub-kpi__label svg { width: 14px; height: 14px; }
.hub-kpi__value {
  font-size: var(--hub-fs-2xl); font-weight: 700; letter-spacing: -.015em; line-height: var(--hub-lh-tight);
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hub-kpi__value--sm { font-size: var(--hub-fs-xl); }
.hub-kpi__unit { font-size: var(--hub-fs-sm); font-weight: 500; color: var(--hub-text-3); margin-left: 2px; }
.hub-kpi__delta { display: inline-flex; align-items: center; gap: 2px; font-size: var(--hub-fs-xs); font-weight: 600; color: var(--hub-text-3); }
.hub-kpi__delta.is-up { color: var(--hub-good); }
.hub-kpi__delta.is-down { color: var(--hub-bad); }
.hub-kpi__delta.is-flat { color: var(--hub-text-3); }
.hub-kpi__delta svg { width: 12px; height: 12px; }
.hub-kpi__foot { font-size: var(--hub-fs-xs); color: var(--hub-text-3); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.hub-kpi__spark { margin-top: 4px; height: 28px; }
.hub-kpi__spark svg { width: 100%; height: 100%; display: block; }

/* 키-값 */
.hub-kv { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 14px; margin: 0; font-size: var(--hub-fs-md); line-height: 1.45; }
.hub-kv dt { color: var(--hub-label); font-weight: 500; white-space: nowrap; }
.hub-kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.hub-kv--compact { gap: 3px 10px; font-size: var(--hub-fs-sm); }
.hub-kv--2col { grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr); }
.hub-kv--lined { gap: 0 14px; }
.hub-kv--lined.hub-kv--compact { gap: 0 10px; }
.hub-kv--lined dt, .hub-kv--lined dd { padding: 6px 0; border-bottom: 1px solid var(--hub-divider); }
.hub-kv--lined dt:last-of-type, .hub-kv--lined dd:last-of-type { border-bottom: 0; }

/* 타임라인 */
.hub-timeline { list-style: none; margin: 0; padding: 0 0 0 14px; border-left: 2px solid var(--hub-border); }
.hub-timeline__item { position: relative; padding: 0 0 14px 12px; }
.hub-timeline__item:last-child { padding-bottom: 0; }
.hub-timeline__item::before {
  content: ""; position: absolute; left: -20px; top: 5px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--hub-text-4); box-shadow: 0 0 0 3px var(--hub-surface);
}
.hub-timeline__item--good::before { background: var(--hub-good); }
.hub-timeline__item--warn::before { background: var(--hub-warn); }
.hub-timeline__item--bad::before { background: var(--hub-bad); }
.hub-timeline__item--info::before { background: var(--hub-info); }
.hub-timeline__item--accent::before { background: var(--hub-accent); }
.hub-timeline__time { font-size: var(--hub-fs-xs); color: var(--hub-text-3); }
.hub-timeline__title { font-weight: 600; font-size: var(--hub-fs-md); }
.hub-timeline__body { font-size: var(--hub-fs-sm); color: var(--hub-text-2); margin-top: 2px; }

/* --------------------------------------------------------------------------
   3. 컨트롤: 버튼 · 입력 · 필드 · 스위치 · 체크 · 세그먼트 · 칩 · 뱃지 · 탭 · 툴바
   -------------------------------------------------------------------------- */
.hub-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--hub-control-h); padding: 0 12px;
  border-radius: var(--hub-r-md); border: 1px solid var(--hub-border-strong);
  background: var(--hub-surface); color: var(--hub-text);
  font: inherit; font-size: var(--hub-fs-md); font-weight: 500; line-height: 1;
  cursor: pointer; white-space: nowrap; text-decoration: none; user-select: none;
  -webkit-tap-highlight-color: transparent; vertical-align: middle;
  transition: background var(--hub-dur) var(--hub-ease), border-color var(--hub-dur) var(--hub-ease), color var(--hub-dur) var(--hub-ease);
}
.hub-btn:hover { background: var(--hub-surface-2); border-color: var(--hub-text-4); }
.hub-btn:active { background: var(--hub-surface-3); }
.hub-btn:disabled, .hub-btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; pointer-events: none; }
.hub-btn svg { width: 16px; height: 16px; flex: none; }
.hub-btn--primary { background: var(--hub-accent); border-color: var(--hub-accent); color: var(--hub-accent-ink); font-weight: 600; }
.hub-btn--primary:hover { background: var(--hub-accent-hover); border-color: var(--hub-accent-hover); }
.hub-btn--primary:active { background: var(--hub-accent-active); border-color: var(--hub-accent-active); }
.hub-btn--ghost { background: transparent; border-color: transparent; color: var(--hub-text-2); }
.hub-btn--ghost:hover { background: var(--hub-surface-3); border-color: transparent; color: var(--hub-text); }
.hub-btn--soft { background: var(--hub-accent-soft); border-color: transparent; color: var(--hub-accent-soft-ink); font-weight: 600; }
.hub-btn--soft:hover { background: var(--hub-accent-soft); border-color: var(--hub-accent); }
.hub-btn--danger { background: var(--hub-bad); border-color: var(--hub-bad); color: #fff; font-weight: 600; }
.hub-btn--danger:hover { background: #b91c1c; border-color: #b91c1c; }
.hub-btn--danger-ghost { background: transparent; border-color: transparent; color: var(--hub-bad-ink); }   /* 글자는 -ink(라이트 #991b1b) — --hub-bad #dc2626 은 빨간 행(#fee2e2) 위 3.95:1·회색 바탕 4.47:1·줄무늬 4.49:1 로 AA 미달이었음(프로모션 '회수 필요'·시즌 '묶음 삭제') */
.hub-btn--danger-ghost:hover { background: var(--hub-bad-soft); }
.hub-btn--link { background: transparent; border-color: transparent; color: var(--hub-link); padding: 0 4px; height: auto; }
.hub-btn--link:hover { text-decoration: underline; background: transparent; }
.hub-btn--sm { height: var(--hub-control-h-sm); padding: 0 8px; font-size: var(--hub-fs-sm); border-radius: var(--hub-r-sm); gap: 4px; }
.hub-btn--sm svg { width: 14px; height: 14px; }
.hub-btn--lg { height: var(--hub-control-h-lg); padding: 0 18px; font-size: var(--hub-fs-lg); }
.hub-btn--icon { width: var(--hub-control-h); padding: 0; }
.hub-btn--icon.hub-btn--sm { width: var(--hub-control-h-sm); }
.hub-btn--icon.hub-btn--lg { width: var(--hub-control-h-lg); }
.hub-btn--block { width: 100%; }
.hub-btn--pill { border-radius: var(--hub-r-pill); }
.hub-btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.hub-btn.is-loading::after {
  content: ""; position: absolute; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--hub-text-3); border-right-color: transparent; animation: hub-spin .7s linear infinite;
}
.hub-btn--primary.is-loading::after { border-color: var(--hub-accent-ink); border-right-color: transparent; }
.hub-btn-group { display: inline-flex; vertical-align: middle; }
.hub-btn-group > .hub-btn { border-radius: 0; margin-left: -1px; }
.hub-btn-group > .hub-btn:first-child { border-radius: var(--hub-r-md) 0 0 var(--hub-r-md); margin-left: 0; }
.hub-btn-group > .hub-btn:last-child { border-radius: 0 var(--hub-r-md) var(--hub-r-md) 0; }
.hub-btn-group > .hub-btn.is-active { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); border-color: var(--hub-accent); position: relative; z-index: 1; }

/* 입력 */
.hub-input, .hub-select, .hub-textarea {
  display: block; width: 100%; min-width: 0;
  height: var(--hub-control-h); padding: 0 10px;
  border: 1px solid var(--hub-border-strong); border-radius: var(--hub-r-md);
  background: var(--hub-surface); color: var(--hub-text);
  font: inherit; font-size: var(--hub-fs-md); line-height: normal;
  transition: border-color var(--hub-dur) var(--hub-ease), box-shadow var(--hub-dur) var(--hub-ease);
  -webkit-appearance: none; appearance: none;
}
.hub-input::placeholder, .hub-textarea::placeholder { color: var(--hub-text-4); }
.hub-input:hover, .hub-select:hover, .hub-textarea:hover { border-color: var(--hub-text-4); }
.hub-input:focus, .hub-select:focus, .hub-textarea:focus,
.hub-input:focus-visible, .hub-select:focus-visible, .hub-textarea:focus-visible {
  outline: none; border-color: var(--hub-accent); box-shadow: 0 0 0 3px var(--hub-accent-ring);
}
.hub-input:disabled, .hub-select:disabled, .hub-textarea:disabled { background-color: var(--hub-surface-2); color: var(--hub-text-3); cursor: not-allowed; }   /* background-color 만 — 줄임형은 select 화살표의 no-repeat·위치를 지워 다크에서 화살표가 칸 전체에 반복됐음 */
.hub-input[readonly] { background: var(--hub-surface-2); }
.hub-input.is-invalid, .hub-select.is-invalid, .hub-textarea.is-invalid,
.hub-input[aria-invalid="true"], .hub-select[aria-invalid="true"], .hub-textarea[aria-invalid="true"],
.hub-field.is-invalid .hub-input, .hub-field.is-invalid .hub-select, .hub-field.is-invalid .hub-textarea {
  border-color: var(--hub-bad); box-shadow: 0 0 0 3px var(--hub-bad-ring);
}
.hub-input--sm, .hub-select--sm { height: var(--hub-control-h-sm); padding: 0 8px; font-size: var(--hub-fs-sm); border-radius: var(--hub-r-sm); }
.hub-input--lg, .hub-select--lg { height: var(--hub-control-h-lg); font-size: var(--hub-fs-lg); }
.hub-input--num, .hub-input.is-num { text-align: right; font-variant-numeric: tabular-nums; }
.hub-input[type="number"] { -moz-appearance: textfield; }
.hub-input[type="number"]::-webkit-outer-spin-button, .hub-input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.hub-input[type="date"], .hub-input[type="month"], .hub-input[type="time"] { padding-right: 6px; }
.hub-input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
.hub-textarea { height: auto; min-height: 84px; padding: 8px 10px; line-height: 1.5; resize: vertical; }
.hub-select {
  padding-right: 28px; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 8px center; background-size: 14px;
}
html[data-theme="dark"] .hub-select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b93a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.hub-select[multiple] { height: auto; padding: 4px; background-image: none; }
.hub-select option { background: var(--hub-surface); color: var(--hub-text); }

/* 필드 */
.hub-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.hub-field__label { font-size: var(--hub-fs-sm); font-weight: 600; color: var(--hub-text-2); display: flex; align-items: center; gap: 4px; }
.hub-field__label .req, .hub-field__req { color: var(--hub-bad); font-weight: 700; }
.hub-field__hint { font-size: var(--hub-fs-xs); color: var(--hub-text-3); line-height: 1.5; }
.hub-field__error { font-size: var(--hub-fs-xs); color: var(--hub-bad); font-weight: 500; display: none; }
.hub-field.is-invalid .hub-field__error { display: block; }
.hub-field.is-invalid .hub-field__label { color: var(--hub-bad); }
.hub-field--inline { flex-direction: row; align-items: center; gap: 8px; }
.hub-field--inline .hub-field__label { white-space: nowrap; }
.hub-form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px 16px; }
.hub-form-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hub-form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hub-form-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hub-form-grid .span-2 { grid-column: span 2; }
.hub-form-grid .span-all { grid-column: 1 / -1; }
.hub-form-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.hub-input-group { display: flex; align-items: stretch; min-width: 0; }
.hub-input-group > * { border-radius: 0; margin-left: -1px; min-width: 0; }
.hub-input-group > :first-child { border-radius: var(--hub-r-md) 0 0 var(--hub-r-md); margin-left: 0; }
.hub-input-group > :last-child { border-radius: 0 var(--hub-r-md) var(--hub-r-md) 0; }
.hub-input-group > .hub-input:focus, .hub-input-group > .hub-select:focus { position: relative; z-index: 1; }
.hub-input-group__addon {
  display: inline-flex; align-items: center; padding: 0 10px; flex: none;
  background: var(--hub-surface-2); border: 1px solid var(--hub-border-strong);
  color: var(--hub-text-3); font-size: var(--hub-fs-sm); white-space: nowrap;
}

/* 스위치 */
.hub-switch { position: relative; display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--hub-fs-md); user-select: none; vertical-align: middle; }
.hub-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.hub-switch__track {
  position: relative; flex: none; width: 36px; height: 20px; border-radius: var(--hub-r-pill);
  background: var(--hub-border-strong); transition: background var(--hub-dur) var(--hub-ease);
}
.hub-switch__track::after {
  content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25); transition: transform var(--hub-dur) var(--hub-ease);
}
.hub-switch input:checked + .hub-switch__track { background: var(--hub-accent); }
.hub-switch input:checked + .hub-switch__track::after { transform: translateX(16px); }
.hub-switch input:focus-visible + .hub-switch__track { box-shadow: var(--hub-focus); }
.hub-switch input:disabled + .hub-switch__track { opacity: .5; }
.hub-switch input:disabled ~ .hub-switch__label { color: var(--hub-text-3); }
.hub-switch--sm .hub-switch__track { width: 30px; height: 16px; }
.hub-switch--sm .hub-switch__track::after { width: 12px; height: 12px; }
.hub-switch--sm input:checked + .hub-switch__track::after { transform: translateX(14px); }

/* 체크박스·라디오 */
.hub-checkbox, .hub-radio { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; font-size: var(--hub-fs-md); user-select: none; vertical-align: middle; min-height: 24px; }
.hub-checkbox input, .hub-radio input { width: 16px; height: 16px; margin: 0; flex: none; accent-color: var(--hub-accent); cursor: pointer; }
.hub-checkbox input:focus-visible, .hub-radio input:focus-visible { box-shadow: var(--hub-focus); border-radius: 3px; }
.hub-radio input:focus-visible { border-radius: 50%; }
.hub-checkbox input:disabled, .hub-radio input:disabled { cursor: not-allowed; }
.hub-checkbox input:disabled ~ *, .hub-radio input:disabled ~ * { color: var(--hub-text-3); }
.hub-check-list { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.hub-check-list--col { flex-direction: column; gap: 6px; }

/* 세그먼트 */
.hub-seg {
  display: inline-flex; align-items: center; gap: 2px; padding: 2px;
  background: var(--hub-surface-2); border: 1px solid var(--hub-border); border-radius: var(--hub-r-md);
  vertical-align: middle; max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
.hub-seg::-webkit-scrollbar { display: none; }
.hub-seg__btn, .hub-seg > button, .hub-seg > a {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  height: 26px; padding: 0 10px; border: 0; border-radius: 6px;
  background: transparent; color: var(--hub-text-2); font: inherit; font-size: var(--hub-fs-sm); font-weight: 500;
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background var(--hub-dur) var(--hub-ease), color var(--hub-dur) var(--hub-ease);
}
.hub-seg__btn:hover, .hub-seg > button:hover, .hub-seg > a:hover { color: var(--hub-text); }
.hub-seg .is-active, .hub-seg [aria-pressed="true"], .hub-seg [aria-selected="true"] {
  background: var(--hub-surface); color: var(--hub-text); font-weight: 600; box-shadow: var(--hub-shadow-1);
}
.hub-seg--sm .hub-seg__btn, .hub-seg--sm > button { height: 22px; padding: 0 8px; font-size: var(--hub-fs-xs); }
.hub-seg--block { display: flex; }
.hub-seg--block > * { flex: 1; }

/* 칩 */
.hub-chip {
  display: inline-flex; align-items: center; gap: 4px;
  height: 24px; padding: 0 9px; border-radius: var(--hub-r-pill);
  border: 1px solid var(--hub-border); background: var(--hub-surface);
  font: inherit; font-size: var(--hub-fs-sm); font-weight: 500; line-height: 1; color: var(--hub-text-2);
  white-space: nowrap; vertical-align: middle; text-decoration: none; max-width: 100%;
}
.hub-chip svg { width: 13px; height: 13px; flex: none; }
button.hub-chip, a.hub-chip, .hub-chip--btn { cursor: pointer; transition: background var(--hub-dur), border-color var(--hub-dur), color var(--hub-dur); }
button.hub-chip:hover, a.hub-chip:hover, .hub-chip--btn:hover { background: var(--hub-surface-2); border-color: var(--hub-text-4); color: var(--hub-text); }
.hub-chip.is-active, .hub-chip[aria-pressed="true"] { background: var(--hub-accent-soft); border-color: var(--hub-accent); color: var(--hub-accent-soft-ink); font-weight: 600; }
.hub-chip--good { background: var(--hub-good-soft); color: var(--hub-good-ink); border-color: transparent; }
.hub-chip--warn { background: var(--hub-warn-soft); color: var(--hub-warn-ink); border-color: transparent; }
.hub-chip--bad { background: var(--hub-bad-soft); color: var(--hub-bad-ink); border-color: transparent; }
.hub-chip--info { background: var(--hub-info-soft); color: var(--hub-info-ink); border-color: transparent; }
.hub-chip--neutral { background: var(--hub-neutral-soft); color: var(--hub-neutral-ink); border-color: transparent; }
.hub-chip--accent { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); border-color: transparent; }
.hub-chip--sm { height: 20px; padding: 0 7px; font-size: var(--hub-fs-xs); }
.hub-chip--lg { height: 30px; padding: 0 12px; font-size: var(--hub-fs-md); }
.hub-chip__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.hub-chip__x {
  display: inline-flex; align-items: center; justify-content: center; margin-right: -5px;
  width: 16px; height: 16px; border-radius: 50%; border: 0; background: transparent; color: inherit; cursor: pointer; padding: 0; opacity: .7;
}
.hub-chip__x:hover { opacity: 1; background: rgba(0,0,0,.08); }
.hub-chip__x svg { width: 11px; height: 11px; }
.hub-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.hub-chips--scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.hub-chips--scroll::-webkit-scrollbar { display: none; }

/* 뱃지 */
.hub-badge {
  display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  height: 18px; min-width: 18px; padding: 0 6px; border-radius: var(--hub-r-pill);
  font-size: var(--hub-fs-xs); font-weight: 600; line-height: 1; white-space: nowrap; vertical-align: middle;
  background: var(--hub-neutral-soft); color: var(--hub-neutral-ink);
}
.hub-badge--v1 {
  height: 16px; padding: 0 5px; font-size: 10px; font-weight: 600; letter-spacing: .02em;
  background: var(--hub-surface-3); color: var(--hub-text-3); border: 1px solid var(--hub-border);
}
.hub-badge--ext { height: 16px; padding: 0 5px; font-size: 10px; background: var(--hub-info-soft); color: var(--hub-info-ink); }
.hub-badge--accent { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); }
.hub-badge--solid { background: var(--hub-accent); color: var(--hub-accent-ink); }
.hub-badge--good { background: var(--hub-good-soft); color: var(--hub-good-ink); }
.hub-badge--warn { background: var(--hub-warn-soft); color: var(--hub-warn-ink); }
.hub-badge--bad { background: var(--hub-bad-soft); color: var(--hub-bad-ink); }
.hub-badge--info { background: var(--hub-info-soft); color: var(--hub-info-ink); }
.hub-badge--count { background: var(--hub-bad); color: #fff; font-variant-numeric: tabular-nums; }
.hub-badge--dot { width: 8px; height: 8px; min-width: 0; padding: 0; background: var(--hub-bad); }
.hub-badge--outline { background: transparent; border: 1px solid var(--hub-border-strong); color: var(--hub-text-2); }
.hub-badge--new { background: var(--hub-accent); color: var(--hub-accent-ink); }
.hub-badge svg { width: 11px; height: 11px; }

/* 탭 */
.hub-tabs {
  display: flex; align-items: flex-end; gap: 2px; border-bottom: 1px solid var(--hub-border);
  overflow-x: auto; scrollbar-width: none; margin: 0; padding: 0; list-style: none; min-width: 0;
}
.hub-tabs::-webkit-scrollbar { display: none; }
.hub-tab {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  height: 38px; padding: 0 12px; margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent; background: transparent;
  color: var(--hub-text-3); font: inherit; font-size: var(--hub-fs-md); font-weight: 500;
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: color var(--hub-dur) var(--hub-ease), border-color var(--hub-dur) var(--hub-ease);
}
.hub-tab:hover { color: var(--hub-text); }
.hub-tab svg { width: 15px; height: 15px; }
.hub-tab.is-active, .hub-tab[aria-selected="true"], .hub-tab[aria-current="page"] { color: var(--hub-text); border-bottom-color: var(--hub-accent); font-weight: 600; }
.hub-tab .hub-badge { margin-left: 2px; }
.hub-tab:disabled { opacity: .45; cursor: not-allowed; }
.hub-tabs--pills { border-bottom: 0; gap: 4px; }
.hub-tabs--pills .hub-tab { height: 30px; margin: 0; border: 1px solid transparent; border-radius: var(--hub-r-pill); padding: 0 12px; }
.hub-tabs--pills .hub-tab.is-active, .hub-tabs--pills .hub-tab[aria-selected="true"] { background: var(--hub-accent-soft); border-color: var(--hub-accent); color: var(--hub-accent-soft-ink); }
.hub-tabs--sm .hub-tab { height: 32px; padding: 0 10px; font-size: var(--hub-fs-sm); }
.hub-tabpanel[hidden] { display: none; }
/* 페이지 메뉴(카테고리 메뉴) — 페이지 맨 위에서 화면을 바꾸는 탭(상품 목록|원가 관리, 새 견적서|발급 이력 …).
   흰 카드 바 + 버튼형 항목, 지금 화면 = 노랑 채움. 900~1199 에서 항목 6개+ 는 간격을 줄여 한 줄,
   900 미만은 아이콘 위·글자 아래 타일 격자(가로 스크롤 없음; 항목이 적으면 아이콘 옆 글자 한 줄 — 600~899 는 4개 이하, 600 미만은 2개 이하;
   600 미만 타일은 글자 11px·여백을 줄여 촘촘하게 — 목록이 첫 화면에서 시작하도록).
   카드·모달 안의 하위 탭은 기본 밑줄 탭(.hub-tabs)을 그대로 쓴다 — 단계가 눈에 보이게. 구분선은 .hub-tabs__sep. 인쇄에선 숨김(@media print). */
.hub-tabs--menu {
  flex-wrap: wrap; align-items: center; gap: 4px; padding: 6px;
  border: 1px solid var(--hub-border); border-radius: var(--hub-r-lg);
  background: var(--hub-surface); box-shadow: var(--hub-shadow-1); overflow: visible;
}
.hub-tabs--menu:empty { display: none; }   /* HTML 에 미리 둔 메뉴가 JS 로 채워지기 전 빈 카드로 보이지 않게 */
.hub-tabs--menu .hub-tab {
  position: relative; height: 40px; margin: 0; padding: 0 14px;
  border: 1px solid transparent; border-radius: var(--hub-r-md);
  color: var(--hub-text-2); font-size: var(--hub-fs-md); font-weight: 600;
  transition: background-color var(--hub-dur) var(--hub-ease), color var(--hub-dur) var(--hub-ease), border-color var(--hub-dur) var(--hub-ease);
}
.hub-tabs--menu .hub-tab svg { width: 17px; height: 17px; flex: none; color: var(--hub-text-3); }
.hub-tabs--menu .hub-tab:hover { background: var(--hub-accent-tint); color: var(--hub-text); }
.hub-tabs--menu .hub-tab:hover svg { color: var(--hub-text-2); }
/* 비활성(disabled)은 지금 화면 규칙보다 앞에 — 뒤에 두면 지금 화면+disabled 가 노랑 채움을 잃고 다크에서 짙은 글자(accent-ink)가 배경에 묻힘 */
.hub-tabs--menu .hub-tab:disabled, .hub-tabs--menu .hub-tab[aria-disabled="true"] { background: transparent; }
.hub-tabs--menu .hub-tab:focus-visible { outline: none; box-shadow: var(--hub-focus); }
.hub-tabs--menu .hub-tab.is-active, .hub-tabs--menu .hub-tab[aria-selected="true"], .hub-tabs--menu .hub-tab[aria-current="page"] {
  background: var(--hub-accent); border-color: var(--hub-accent); color: var(--hub-accent-ink); font-weight: 700; box-shadow: var(--hub-shadow-1);
}
.hub-tabs--menu .hub-tab.is-active svg, .hub-tabs--menu .hub-tab[aria-selected="true"] svg, .hub-tabs--menu .hub-tab[aria-current="page"] svg { color: var(--hub-accent-ink); }
/* 지금 화면 항목도 키보드 포커스 테두리가 보이게(같은 특이성의 그림자가 포커스를 덮지 않게 뒤에 둔다) */
.hub-tabs--menu .hub-tab.is-active:focus-visible, .hub-tabs--menu .hub-tab[aria-selected="true"]:focus-visible, .hub-tabs--menu .hub-tab[aria-current="page"]:focus-visible { box-shadow: var(--hub-focus); }
.hub-tabs__sep { flex: none; align-self: center; width: 1px; height: 24px; margin: 0 6px; background: var(--hub-border-strong); }
@media (min-width: 1200px) and (max-width: 1439.98px) {
  /* 사이드바를 편 1280 언저리: 항목이 많으면(6개+) 간격만 조금 줄여 한 줄 유지(인사이트 8개+구분선이 20px 넘쳐 두 줄이 됐음) */
  .hub-tabs--menu:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab) .hub-tab { padding: 0 11px; gap: 5px; }
  .hub-tabs--menu:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab) .hub-tabs__sep { margin: 0 4px; }
}
@media (min-width: 900px) and (max-width: 1199.98px) {
  /* 레일 폭: 항목이 많으면(6개+) 간격·글자를 줄여 한 줄 유지 */
  .hub-tabs--menu:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab) .hub-tab { padding: 0 9px; gap: 5px; font-size: var(--hub-fs-sm); }
  .hub-tabs--menu:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab) .hub-tabs__sep { margin: 0 3px; }
}
@media (max-width: 899.98px) {
  .hub-tabs--menu { display: grid; grid-template-columns: repeat(auto-fit, minmax(76px, 1fr)); align-items: stretch; gap: 4px; padding: 6px; }
  .hub-tabs--menu .hub-tab {
    flex-direction: column; justify-content: center; gap: 4px; height: auto; min-height: 60px; min-width: 0; padding: 8px 4px;
    white-space: normal; text-align: center; line-height: 1.25; font-size: var(--hub-fs-sm); word-break: keep-all; overflow-wrap: anywhere;
  }
  .hub-tabs--menu .hub-tab svg { width: 20px; height: 20px; }
  .hub-tabs--menu .hub-tab .hub-badge { position: absolute; top: 4px; right: 4px; margin: 0; }
  .hub-tabs--menu .hub-tabs__sep { display: none; }
}
@media (min-width: 600px) and (max-width: 899.98px) {
  /* 항목 4개 이하: 자리가 넉넉하니 아이콘 옆 글자 한 줄(칸은 균등) */
  .hub-tabs--menu:not(:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab)) .hub-tab { flex-direction: row; gap: 6px; min-height: var(--hub-touch); padding: 6px 10px; font-size: var(--hub-fs-md); }
  .hub-tabs--menu:not(:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab)) .hub-tab svg { width: 17px; height: 17px; }
  .hub-tabs--menu:not(:has(> .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab ~ .hub-tab)) .hub-tab .hub-badge { position: static; margin-left: 2px; }
}
@media (max-width: 599.98px) {
  /* 휴대폰 타일은 촘촘하게 — 글자 11px(하단 탭과 비슷한 크기)·아이콘 16px·위아래 여백 5px, 바 여백 4px. 타일 격자(모든 항목이 보이고
     가로 스크롤 없음)는 그대로 두고 높이만 줄여 목록이 위에서 시작(375 폭: 7~8개 메뉴 150~162→102px, 5~6개 138~162→102px, 4개 74→54px) */
  .hub-tabs--menu { gap: 4px; padding: 4px; }
  .hub-tabs--menu .hub-tab { min-height: var(--hub-touch); padding: 5px 2px; gap: 2px; font-size: var(--hub-fs-xs); line-height: 1.2; }
  .hub-tabs--menu .hub-tab svg { width: 16px; height: 16px; }
  /* 글자는 한 줄(두 줄로 갈라지면 그 줄 타일이 44→57px 로 커졌음 — '재구매 리마인드'·'상품별 인사이트'·'실질 손익(P&L)'). 칸보다 긴 이름은
     셸(shell.js menuLabelFitSize)이 그 글자만 최소 10px 까지 줄이고(.hub-tab__fit, --hub-tab-fit), 그래도 넘치면 '…' + 타일 title 에 전체 이름 */
  .hub-tabs--menu .hub-tab > span:not(.hub-icon, .hub-badge, .hub-tabs__sep) { max-width: 100%; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .hub-tabs--menu .hub-tab > .hub-tab__fit { font-size: var(--hub-tab-fit, inherit); letter-spacing: -0.02em; }
  /* 휴대폰에서 항목 2개 이하(상품 목록|원가 관리, 새 견적서|발급 이력 …): 칸이 넓으니 아이콘 옆 글자 한 줄 — 타일보다 낮음.
     3개부터는 칸이 100px 남짓이라 글자가 두 줄로 갈라지므로 타일 유지 */
  .hub-tabs--menu:not(:has(> .hub-tab ~ .hub-tab ~ .hub-tab)) .hub-tab { flex-direction: row; gap: 6px; min-height: var(--hub-touch); padding: 6px 10px; font-size: var(--hub-fs-md); }
  .hub-tabs--menu:not(:has(> .hub-tab ~ .hub-tab ~ .hub-tab)) .hub-tab svg { width: 17px; height: 17px; }
  .hub-tabs--menu:not(:has(> .hub-tab ~ .hub-tab ~ .hub-tab)) .hub-tab .hub-badge { position: static; margin-left: 2px; }
  /* 항목 5개: 셸(shell.js menuRowFits)이 5칸에서도 모든 이름이 '…' 없이(375 폭 이상 10.5px·그 아래 10px 이상) 들어간다고 볼 때만
     .is-row5 → 한 줄 5칸(4+1 두 줄 102→54px, 업무 관리(직원)·구매/생산 5개). 긴 이름이 있으면(검색 순위) 4+1 그대로 */
  .hub-tabs--menu.is-row5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* 툴바·필터바·검색 */
.hub-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.hub-toolbar__spacer { flex: 1; }
.hub-toolbar__sep { width: 1px; height: 20px; background: var(--hub-border); flex: none; }
.hub-toolbar__count { font-size: var(--hub-fs-sm); color: var(--hub-text-3); white-space: nowrap; }
.hub-filterbar {
  display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap;
  padding: 10px 12px; background: var(--hub-surface); border: 1px solid var(--hub-border); border-radius: var(--hub-r-lg);
}
.hub-filterbar .hub-field { flex-direction: row; align-items: center; gap: 6px; }
.hub-filterbar .hub-field__label { white-space: nowrap; font-weight: 500; color: var(--hub-text-3); }
.hub-filterbar .hub-input, .hub-filterbar .hub-select { width: auto; min-width: 110px; }
.hub-filterbar .hub-search { flex: 1 1 200px; }
.hub-filterbar .hub-search .hub-input { width: 100%; }
.hub-filterbar__end { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.hub-search { position: relative; display: flex; align-items: center; min-width: 0; }
.hub-search > svg { position: absolute; left: 10px; width: 16px; height: 16px; color: var(--hub-text-4); pointer-events: none; }
.hub-search > .hub-search__icon { position: absolute; left: 10px; display: flex; color: var(--hub-text-4); pointer-events: none; }
.hub-search > .hub-search__icon svg { width: 16px; height: 16px; }
.hub-search .hub-input { padding-left: 32px; }
.hub-search .hub-input--sm { padding-left: 28px; }
.hub-search--sm > svg { width: 14px; height: 14px; left: 8px; }
.hub-search__kbd { position: absolute; right: 8px; pointer-events: none; }
.hub-search__clear { position: absolute; right: 6px; }
.hub-search.has-kbd .hub-input { padding-right: 34px; }
.hub-kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px;
  border: 1px solid var(--hub-border-strong); border-bottom-width: 2px; border-radius: 4px;
  background: var(--hub-surface-2); color: var(--hub-text-3); font-family: var(--hub-font-mono); font-size: 10.5px; line-height: 1;
}

/* --------------------------------------------------------------------------
   4. 데이터: 표 · 페이저 · 빈 상태 · 스켈레톤 · 스피너 · 프로그레스 · 금액 · 아바타
   -------------------------------------------------------------------------- */
.hub-table-wrap {
  position: relative; overflow: auto; min-width: 0;
  max-height: var(--hub-table-max, none);
  background: var(--hub-surface); border: 1px solid var(--hub-border); border-radius: var(--hub-r-lg);
  overscroll-behavior-x: contain;
}
.hub-table-wrap--fill { --hub-table-max: calc(100dvh - var(--hub-topbar-h) - 170px); }
.hub-table-wrap--page { overflow: clip; }                 /* 페이지 스크롤에 thead 고정(가로 스크롤 없음) */
.hub-table-wrap--page .hub-table th { top: var(--hub-topbar-h); }
.hub-table-wrap--plain { border: 0; border-radius: 0; background: transparent; }
.hub-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--hub-fs-md); }
.hub-table th {
  position: sticky; top: 0; z-index: var(--hub-z-sticky);
  height: 36px; padding: 0 10px; text-align: left; white-space: nowrap;
  background: var(--hub-table-head-bg); color: var(--hub-label);
  font-size: var(--hub-fs-sm); font-weight: 600; border-bottom: 1px solid var(--hub-border);
  box-shadow: inset 0 -1px 0 var(--hub-border);
}
.hub-table td {
  height: var(--hub-row-h); padding: 6px 10px; vertical-align: middle;
  border-bottom: 1px solid var(--hub-divider); color: var(--hub-text);
}
.hub-table tbody tr:last-child td { border-bottom: 0; }
/* 줄무늬(table.js 기본 striped:true) — 선택·경고·합계 행 규칙보다 앞에 두어 그쪽이 이기게(동일 특이성은 선언 순서) */
.hub-table--striped tbody tr:nth-child(even) td { background: var(--hub-table-stripe); }
.hub-table tbody tr:hover td, .hub-table--striped tbody tr:hover td { background: var(--hub-table-hover); }
.hub-table tbody tr.is-selected td { background: var(--hub-accent-tint); }
.hub-table tbody tr.is-clickable { cursor: pointer; }
.hub-table tbody tr.is-muted td { color: var(--hub-text-3); }
.hub-table tbody tr.is-danger td { background: var(--hub-bad-soft); }
.hub-table tbody tr.is-warn td { background: var(--hub-warn-soft); }
.hub-table tbody tr.is-total td, .hub-table tfoot td {
  font-weight: 700; background: var(--hub-table-head-bg); border-top: 1px solid var(--hub-border);
}
/* 로딩·빈 상태 행에는 줄무늬·hover 색을 칠하지 않음 */
.hub-table tbody tr.hub-table__skelrow td, .hub-table tbody tr.hub-table__emptyrow td,
.hub-table tbody tr.hub-table__skelrow:hover td, .hub-table tbody tr.hub-table__emptyrow:hover td { background: transparent; }
.hub-table tfoot td { position: sticky; bottom: 0; z-index: var(--hub-z-sticky); }
.hub-table th.num, .hub-table td.num, .hub-table .is-num { text-align: right; font-variant-numeric: tabular-nums; }
.hub-table th.center, .hub-table td.center { text-align: center; }
.hub-table td.nowrap, .hub-table th.nowrap { white-space: nowrap; }
.hub-table td.wrap { white-space: normal; overflow-wrap: anywhere; }
.hub-table th.check, .hub-table td.check { width: 36px; padding: 0 8px; text-align: center; }
.hub-table td.check input, .hub-table th.check input { width: 15px; height: 15px; margin: 0; accent-color: var(--hub-accent); vertical-align: middle; }
.hub-table td.actions, .hub-table th.actions { width: 1%; white-space: nowrap; text-align: right; }
.hub-table .hub-row-actions { display: inline-flex; gap: 2px; opacity: 0; transition: opacity var(--hub-dur); }
.hub-table tbody tr:hover .hub-row-actions, .hub-table tbody tr:focus-within .hub-row-actions { opacity: 1; }
@media (hover: none) { .hub-table .hub-row-actions { opacity: 1; } }
.hub-table td .hub-truncate { display: block; }
.hub-table--dense th { height: 32px; padding: 0 8px; }
.hub-table--dense td { height: var(--hub-row-h-dense); padding: 4px 8px; font-size: var(--hub-fs-sm); }
.hub-table--lined td, .hub-table--lined th { border-right: 1px solid var(--hub-divider); }
.hub-table--lined td:last-child, .hub-table--lined th:last-child { border-right: 0; }
.hub-table--fixed { table-layout: fixed; }
/* 정렬 헤더 */
.hub-table th.is-sortable { padding: 0; }
.hub-table th.is-sortable > button {
  display: flex; align-items: center; gap: 4px; width: 100%; height: 100%; min-height: 36px; padding: 0 10px;
  border: 0; background: transparent; color: inherit; font: inherit; font-weight: 600; text-align: inherit; cursor: pointer;
  border-radius: 0;
}
.hub-table--dense th.is-sortable > button { min-height: 32px; padding: 0 8px; }
.hub-table th.num.is-sortable > button { justify-content: flex-end; }
.hub-table th.is-sortable > button:hover { color: var(--hub-text); background: var(--hub-table-hover); }
.hub-table th.is-sortable > button:focus-visible { box-shadow: inset var(--hub-focus); border-radius: 0; }
.hub-sort { width: 12px; height: 12px; flex: none; opacity: .35; transition: transform var(--hub-dur), opacity var(--hub-dur); }
.hub-table th[aria-sort] .hub-sort, .hub-table th > button[aria-sort] .hub-sort { opacity: 1; color: var(--hub-accent-soft-ink); }
.hub-table th[aria-sort="descending"] .hub-sort, .hub-table th > button[aria-sort="descending"] .hub-sort { transform: rotate(180deg); }
.hub-table th[aria-sort="ascending"] > button, .hub-table th[aria-sort="descending"] > button,
.hub-table th > button[aria-sort="ascending"], .hub-table th > button[aria-sort="descending"] { color: var(--hub-text); }
/* table.js 정렬 헤더: th.is-sortable[aria-sort] > button.hub-table__sortbtn > .hub-table__sortlabel + .hub-table__sorticon(▲▼↕ 텍스트) */
.hub-table__sorticon { font-size: 9px; opacity: .4; margin-left: 2px; line-height: 1; }
.hub-table th[aria-sort="ascending"] .hub-table__sorticon, .hub-table th[aria-sort="descending"] .hub-table__sorticon { opacity: 1; color: var(--hub-accent-soft-ink); }
.hub-table__sortlabel { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hub-ta-left { text-align: left; } .hub-ta-center { text-align: center; } .hub-ta-right { text-align: right; font-variant-numeric: tabular-nums; }
.hub-table th[hidden], .hub-table td[hidden] { display: none !important; }
.hub-table__emptyrow td, .hub-table__skelrow td { height: auto; }
.hub-table__emptyrow td { padding: 0; }
.hub-table__emptyrow:hover td, .hub-table__skelrow:hover td { background: transparent !important; }
.hub-table__skelrow .hub-skeleton { display: inline-block; vertical-align: middle; }
.hub-table__cardtitle { font-weight: 600; font-size: var(--hub-fs-lg); }
.hub-table__cardsub { font-size: var(--hub-fs-sm); color: var(--hub-text-3); }
.hub-table-root { display: flex; flex-direction: column; min-width: 0; }
.hub-table-root > .hub-pager { padding: 8px 4px; }
.hub-table-root > .hub-pager[hidden] { display: none; }
/* 표 안 상태/로딩 행 */
.hub-table .hub-table__state td { height: auto; padding: 0; border: 0; background: transparent; }
.hub-table-wrap.is-loading { pointer-events: none; }
.hub-table-wrap.is-loading .hub-table tbody { opacity: .55; }

/* 페이저 */
.hub-pager {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap;
  padding: 8px 12px; font-size: var(--hub-fs-sm); color: var(--hub-text-3);
}
.hub-pager--top { border-bottom: 1px solid var(--hub-border); }
.hub-pager--bottom { border-top: 1px solid var(--hub-border); }
.hub-pager__info { white-space: nowrap; }
.hub-pager__btns { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.hub-pager__btn {
  display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 28px; padding: 0 6px;
  border: 1px solid transparent; border-radius: var(--hub-r-sm); background: transparent;
  color: var(--hub-text-2); font: inherit; font-size: var(--hub-fs-sm); cursor: pointer; font-variant-numeric: tabular-nums;
}
.hub-pager__btn svg { width: 14px; height: 14px; }
.hub-pager__btn:hover { background: var(--hub-surface-2); }
.hub-pager__btn.is-active, .hub-pager__btn[aria-current="page"] { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); border-color: var(--hub-accent); font-weight: 600; }
.hub-pager__btn:disabled { opacity: .4; cursor: not-allowed; }
.hub-pager__ellipsis, .hub-pager__gap { padding: 0 4px; color: var(--hub-text-4); }
.hub-pager .hub-select { width: auto; height: 28px; padding: 0 24px 0 8px; font-size: var(--hub-fs-sm); }
/* table.js 페이저: .hub-pager__info · .hub-pager__nav(prev/pages/count/next, .hub-btn--ghost --sm) · .hub-pager__tools(select · details.hub-table__cols) */
.hub-pager__nav { display: flex; align-items: center; gap: 2px; margin-left: auto; flex-wrap: wrap; }
.hub-pager__pages { display: inline-flex; align-items: center; gap: 2px; }
.hub-pager .hub-btn.is-active, .hub-pager__page.is-active, .hub-pager__page[aria-current="page"] {
  background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); border-color: var(--hub-accent); font-weight: 600;
}
.hub-pager__page { min-width: 28px; padding: 0 6px; font-variant-numeric: tabular-nums; }
.hub-pager__count { font-size: var(--hub-fs-xs); color: var(--hub-text-3); padding: 0 6px; white-space: nowrap; }
.hub-pager__tools { display: flex; align-items: center; gap: 6px; }
.hub-table__cols { position: relative; }
.hub-table__cols > summary { list-style: none; cursor: pointer; }
.hub-table__cols > summary::-webkit-details-marker { display: none; }
.hub-table__cols[open] > summary { background: var(--hub-surface-3); }
.hub-table__colslist { top: auto; bottom: calc(100% + 4px); left: auto; right: 0; display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; min-width: 170px; max-height: 280px; overflow: auto; }
.hub-table__colslist .hub-checkbox { min-height: 28px; }

/* 빈 상태 */
.hub-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 40px 16px; text-align: center; color: var(--hub-text-3); font-size: var(--hub-fs-md);
}
.hub-empty svg { width: 36px; height: 36px; color: var(--hub-text-4); margin-bottom: 4px; }
.hub-empty__title { font-weight: 600; color: var(--hub-text-2); font-size: var(--hub-fs-md); }
.hub-empty__hint { font-size: var(--hub-fs-sm); color: var(--hub-text-3); max-width: 360px; }
.hub-empty .hub-btn { margin-top: 8px; }
.hub-empty--sm { padding: 20px 12px; }
.hub-empty--sm svg { width: 24px; height: 24px; }

/* 스켈레톤 */
.hub-skeleton {
  display: block; height: 14px; border-radius: 6px; width: 100%;
  background: linear-gradient(90deg, var(--hub-surface-3) 25%, var(--hub-surface-2) 37%, var(--hub-surface-3) 63%);
  background-size: 400% 100%; animation: hub-shimmer 1.4s ease infinite;
}
.hub-skeleton--text { height: 12px; width: 70%; }
.hub-skeleton--title { height: 18px; width: 40%; }
.hub-skeleton--block { height: 120px; border-radius: var(--hub-r-md); }
.hub-skeleton--circle { width: 32px; height: 32px; border-radius: 50%; }
.hub-skeleton--kpi { height: 26px; width: 55%; }
.hub-skeleton--row { height: 36px; border-radius: 0; }
.hub-skeleton-rows { display: flex; flex-direction: column; gap: 8px; padding: 12px; }
.hub-skeleton-rows .hub-skeleton:nth-child(2n) { width: 85%; }
.hub-skeleton-rows .hub-skeleton:nth-child(3n) { width: 60%; }

/* 스피너 */
.hub-spinner {
  display: inline-block; width: 16px; height: 16px; border-radius: 50%; vertical-align: middle;
  border: 2px solid currentColor; border-right-color: transparent; opacity: .8;
  animation: hub-spin .7s linear infinite;
}
.hub-spinner--lg { width: 28px; height: 28px; border-width: 3px; }
.hub-spinner--accent { color: var(--hub-accent); opacity: 1; }
.hub-loading { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 24px; color: var(--hub-text-3); font-size: var(--hub-fs-sm); }
.hub-loading-overlay {
  position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--hub-surface) 70%, transparent); border-radius: inherit;
}

/* 프로그레스 */
.hub-progress { height: 6px; width: 100%; background: var(--hub-surface-3); border-radius: var(--hub-r-pill); overflow: hidden; }
.hub-progress__bar { height: 100%; width: 0; background: var(--hub-accent); border-radius: var(--hub-r-pill); transition: width var(--hub-dur-slow) var(--hub-ease); }
.hub-progress--good .hub-progress__bar { background: var(--hub-good); }
.hub-progress--warn .hub-progress__bar { background: var(--hub-warn); }
.hub-progress--bad .hub-progress__bar { background: var(--hub-bad); }
.hub-progress--info .hub-progress__bar { background: var(--hub-info); }
.hub-progress--sm { height: 4px; }
.hub-progress--lg { height: 10px; }
.hub-progress--striped .hub-progress__bar { background-image: linear-gradient(45deg, rgba(255,255,255,.25) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.25) 50%, rgba(255,255,255,.25) 75%, transparent 75%); background-size: 12px 12px; }
.hub-progress-row { display: flex; align-items: center; gap: 8px; }
.hub-progress-row .hub-progress { flex: 1; }
.hub-progress-row__val { font-size: var(--hub-fs-sm); color: var(--hub-text-2); min-width: 40px; text-align: right; font-variant-numeric: tabular-nums; }

/* 금액·숫자 */
.hub-money, .hub-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.hub-money.is-neg, .hub-num.is-neg { color: var(--hub-bad); }
.hub-money.is-pos, .hub-num.is-pos { color: var(--hub-good); }
.hub-money.is-zero, .hub-num.is-zero { color: var(--hub-text-4); }
.hub-delta { display: inline-flex; align-items: center; gap: 2px; font-size: var(--hub-fs-xs); font-weight: 600; white-space: nowrap; }
.hub-delta.is-up { color: var(--hub-good); }
.hub-delta.is-down { color: var(--hub-bad); }
.hub-delta.is-flat { color: var(--hub-text-3); }

/* 글자 아바타 */
.hub-avatar {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; border-radius: 8px;
  background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink);
  font-weight: 700; font-size: var(--hub-fs-sm); line-height: 1; text-transform: uppercase; overflow: hidden;
}
.hub-avatar img { width: 100%; height: 100%; object-fit: cover; }
.hub-avatar--sm { width: 22px; height: 22px; font-size: 10px; border-radius: 6px; }
.hub-avatar--lg { width: 36px; height: 36px; font-size: var(--hub-fs-lg); border-radius: 10px; }
.hub-avatar--circle { border-radius: 50%; }
.hub-avatar--neutral { background: var(--hub-surface-3); color: var(--hub-text-2); }
.hub-avatar--info { background: var(--hub-info-soft); color: var(--hub-info-ink); }
.hub-avatar--good { background: var(--hub-good-soft); color: var(--hub-good-ink); }

.hub-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 100%; }
.hub-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* 상태 칩(주문 상태 등 공용 색 매핑) */
.hub-status { display: inline-flex; align-items: center; gap: 5px; font-size: var(--hub-fs-sm); white-space: nowrap; }
.hub-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--hub-text-4); flex: none; }
.hub-status--good::before { background: var(--hub-good); }
.hub-status--warn::before { background: var(--hub-warn); }
.hub-status--bad::before { background: var(--hub-bad); }
.hub-status--info::before { background: var(--hub-info); }
.hub-status--accent::before { background: var(--hub-accent); }

/* 알림 박스 */
.hub-alert {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px;
  border-radius: var(--hub-r-md); border: 1px solid var(--hub-border); background: var(--hub-surface-2);
  font-size: var(--hub-fs-md); color: var(--hub-text-2);
}
.hub-alert svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.hub-alert__body { flex: 1; min-width: 0; }
.hub-alert__title { font-weight: 600; color: var(--hub-text); }
.hub-alert--info { background: var(--hub-info-soft); border-color: transparent; color: var(--hub-info-ink); }
.hub-alert--good { background: var(--hub-good-soft); border-color: transparent; color: var(--hub-good-ink); }
.hub-alert--warn { background: var(--hub-warn-soft); border-color: transparent; color: var(--hub-warn-ink); }
.hub-alert--bad { background: var(--hub-bad-soft); border-color: transparent; color: var(--hub-bad-ink); }
.hub-alert--accent { background: var(--hub-accent-soft); border-color: transparent; color: var(--hub-accent-soft-ink); }
.hub-alert--info .hub-alert__title, .hub-alert--good .hub-alert__title, .hub-alert--warn .hub-alert__title, .hub-alert--bad .hub-alert__title, .hub-alert--accent .hub-alert__title { color: inherit; }

/* --------------------------------------------------------------------------
   5. 오버레이: 모달 · 시트 · 토스트 · 메뉴 · 툴팁
   -------------------------------------------------------------------------- */
.hub-modal {
  position: fixed; inset: 0; z-index: var(--hub-z-modal);
  display: flex; align-items: center; justify-content: center; padding: 16px;
  background: var(--hub-scrim); animation: hub-fade var(--hub-dur) var(--hub-ease);
}
.hub-modal[hidden] { display: none; }
.hub-modal__card {
  display: flex; flex-direction: column; width: 100%; max-width: 560px; max-height: calc(100dvh - 32px);
  background: var(--hub-surface); border-radius: var(--hub-r-lg); box-shadow: var(--hub-shadow-3);
  overflow: hidden; animation: hub-pop var(--hub-dur-slow) var(--hub-ease); outline: none;
  border: 1px solid var(--hub-border);
}
.hub-modal__card--sm, .hub-modal--sm .hub-modal__card { max-width: 420px; }
.hub-modal__card--lg, .hub-modal--lg .hub-modal__card { max-width: 860px; }
.hub-modal__card--xl, .hub-modal--xl .hub-modal__card { max-width: 1140px; }
.hub-modal--full { padding: 0; }
.hub-modal__card--full, .hub-modal--full .hub-modal__card { max-width: none; width: 100%; height: 100dvh; max-height: none; border-radius: 0; border: 0; }
.hub-modal__head { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--hub-border); flex: none; }
.hub-modal__title { margin: 0; flex: 1; min-width: 0; font-size: var(--hub-fs-lg); font-weight: 700; display: flex; align-items: center; gap: 6px; }
.hub-modal__close { flex: none; margin-right: -6px; }
.hub-modal__body { flex: 1 1 auto; overflow: auto; padding: 16px; min-height: 0; overscroll-behavior: contain; }
.hub-modal__body--flush { padding: 0; }
.hub-modal__body .hub-card { background: var(--hub-surface-2); }          /* 모달 바탕(surface) 위 카드는 한 단계 밝게 — 다크 층 구분 */
.hub-modal__body .hub-card--muted { background: var(--hub-surface-3); }
.hub-modal__foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--hub-border); background: var(--hub-surface-2); flex: none; flex-wrap: wrap; }
.hub-modal__foot .hub-grow, .hub-modal__foot-left { margin-right: auto; }
.hub-modal__msg { font-size: var(--hub-fs-md); line-height: 1.6; white-space: pre-line; }
.hub-modal--danger .hub-modal__title { color: var(--hub-bad); }

/* 바텀 시트 */
.hub-sheet {
  position: fixed; inset: 0; z-index: var(--hub-z-modal); display: flex; align-items: flex-end; justify-content: center;
  background: var(--hub-scrim); animation: hub-fade var(--hub-dur) var(--hub-ease);
}
.hub-sheet[hidden] { display: none; }
.hub-sheet__card {
  width: 100%; max-width: 640px; max-height: 92dvh; display: flex; flex-direction: column;
  background: var(--hub-surface); border-radius: 16px 16px 0 0; box-shadow: var(--hub-shadow-3);
  padding-bottom: var(--hub-safe-bottom); animation: hub-slide-up var(--hub-dur-slow) var(--hub-ease);
}
.hub-sheet__grip { width: 36px; height: 4px; border-radius: 2px; background: var(--hub-border-strong); margin: 8px auto 2px; flex: none; }
.hub-sheet__head { display: flex; align-items: center; gap: 8px; padding: 8px 16px 10px; border-bottom: 1px solid var(--hub-border); flex: none; }
.hub-sheet__title { margin: 0; flex: 1; font-size: var(--hub-fs-lg); font-weight: 700; }
.hub-sheet__body { flex: 1; overflow: auto; padding: 12px 16px; min-height: 0; }
.hub-sheet__foot { display: flex; gap: 8px; justify-content: flex-end; padding: 10px 16px; border-top: 1px solid var(--hub-border); flex: none; }
.hub-sheet__list { display: flex; flex-direction: column; padding: 6px 8px; }
.hub-sheet__item {
  display: flex; align-items: center; gap: 12px; min-height: var(--hub-touch); padding: 0 10px; border-radius: var(--hub-r-md);
  border: 0; background: transparent; color: var(--hub-text); font: inherit; text-align: left; text-decoration: none; cursor: pointer;
}
.hub-sheet__item:hover { background: var(--hub-surface-2); }
.hub-sheet__item svg { width: 20px; height: 20px; color: var(--hub-text-3); }
.hub-sheet__item.is-active { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); font-weight: 600; }
.hub-sheet__item.is-active svg { color: var(--hub-accent-soft-ink); }

/* 토스트 */
.hub-toast-host {
  position: fixed; right: 16px; bottom: calc(16px + var(--hub-safe-bottom)); z-index: var(--hub-z-toast);
  display: flex; flex-direction: column; gap: 8px; width: min(380px, calc(100vw - 32px)); pointer-events: none;
}
.hub-toast {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; pointer-events: auto;
  background: var(--hub-toast-bg); color: var(--hub-toast-text);
  border-radius: var(--hub-r-md); border-left: 3px solid var(--hub-info); box-shadow: var(--hub-shadow-3);
  font-size: var(--hub-fs-md); line-height: 1.45; animation: hub-toast-in var(--hub-dur-slow) var(--hub-ease);
}
.hub-toast--good { border-left-color: var(--hub-good); }
.hub-toast--bad { border-left-color: var(--hub-bad); }
.hub-toast--warn { border-left-color: var(--hub-warn); }
.hub-toast--info { border-left-color: var(--hub-info); }
.hub-toast__ico { flex: none; width: 16px; height: 16px; margin-top: 1px; }
.hub-toast--good .hub-toast__ico { color: var(--hub-good); }
.hub-toast--bad .hub-toast__ico { color: var(--hub-bad); }
.hub-toast--warn .hub-toast__ico { color: var(--hub-warn); }
.hub-toast--info .hub-toast__ico { color: var(--hub-info); }
.hub-toast__msg { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.hub-toast__action { flex: none; background: transparent; border: 0; color: var(--hub-accent); font: inherit; font-weight: 600; cursor: pointer; padding: 0 4px; }
.hub-toast__close {
  flex: none; width: 22px; height: 22px; margin: -3px -6px -3px 0; border: 0; border-radius: 6px; background: transparent;
  color: inherit; opacity: .7; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0;
}
.hub-toast__close:hover { opacity: 1; background: rgba(255,255,255,.1); }
.hub-toast__close svg { width: 14px; height: 14px; }
.hub-toast.is-leaving { animation: hub-toast-out var(--hub-dur) var(--hub-ease) forwards; }

/* 드롭다운 메뉴 */
.hub-menu-anchor { position: relative; display: inline-block; }
.hub-menu {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: var(--hub-z-menu);
  min-width: 180px; max-width: 320px; padding: 4px; margin: 0; list-style: none;
  background: var(--hub-surface); border: 1px solid var(--hub-border); border-radius: var(--hub-r-md);
  box-shadow: var(--hub-shadow-2); animation: hub-pop var(--hub-dur) var(--hub-ease);
}
.hub-menu[hidden] { display: none; }
.hub-menu--right { left: auto; right: 0; }
.hub-menu--up { top: auto; bottom: calc(100% + 4px); }
.hub-menu--fixed { position: fixed; top: auto; left: auto; }
.hub-menu__item {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 32px; padding: 0 10px;
  border: 0; border-radius: 6px; background: transparent; color: var(--hub-text);
  font: inherit; font-size: var(--hub-fs-md); text-align: left; text-decoration: none; cursor: pointer; white-space: nowrap;
}
.hub-menu__item:hover, .hub-menu__item:focus-visible, .hub-menu__item.is-focus { background: var(--hub-surface-2); box-shadow: none; }
.hub-menu__item svg { width: 16px; height: 16px; color: var(--hub-text-3); flex: none; }
.hub-menu__item.is-active { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); font-weight: 600; }
.hub-menu__item--danger { color: var(--hub-bad); }
.hub-menu__item--danger svg { color: var(--hub-bad); }
.hub-menu__item:disabled { opacity: .45; cursor: not-allowed; }
.hub-menu__item .hub-badge, .hub-menu__item .hub-kbd { margin-left: auto; }
.hub-menu__sep { height: 1px; margin: 4px 2px; background: var(--hub-border); }
.hub-menu__label { padding: 6px 10px 2px; font-size: var(--hub-fs-xs); color: var(--hub-text-3); font-weight: 600; }
.hub-menu__item .hub-menu__label { padding: 0; font-size: inherit; color: inherit; font-weight: inherit; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }  /* shell.js: 항목 텍스트 span */
.hub-menu__head { padding: 8px 10px; border-bottom: 1px solid var(--hub-border); margin: -4px -4px 4px; background: var(--hub-surface-2); border-radius: var(--hub-r-md) var(--hub-r-md) 0 0; }
.hub-menu__head-name { font-weight: 600; font-size: var(--hub-fs-md); }
.hub-menu__head-sub { font-size: var(--hub-fs-xs); color: var(--hub-text-3); }

/* 툴팁 */
.hub-tooltip {
  position: fixed; z-index: var(--hub-z-tooltip); pointer-events: none;
  max-width: 280px; padding: 5px 8px; border-radius: 6px;
  background: var(--hub-tooltip-bg); color: var(--hub-tooltip-text); box-shadow: var(--hub-shadow-2);
  font-size: var(--hub-fs-xs); line-height: 1.45; white-space: normal;
  animation: hub-fade var(--hub-dur) var(--hub-ease);
}
.hub-tooltip[hidden] { display: none; }
.hub-tooltip__title { font-weight: 700; margin-bottom: 2px; }
.hub-tooltip__row { display: flex; justify-content: space-between; gap: 12px; white-space: nowrap; }
.hub-tooltip__row b { font-variant-numeric: tabular-nums; }
.hub-tooltip__sw { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }
[data-hub-tip] { position: relative; }

/* --------------------------------------------------------------------------
   6. 차트 공통(charts.js 가 사용)
   -------------------------------------------------------------------------- */
.hub-chart { position: relative; width: 100%; min-width: 0; }
.hub-chart svg { display: block; width: 100%; height: auto; overflow: visible; }
.hub-chart text { font-family: var(--hub-font); font-size: 10.5px; fill: var(--hub-chart-label); font-variant-numeric: tabular-nums; }
.hub-chart .hub-chart__grid { stroke: var(--hub-chart-grid); stroke-width: 1; }
.hub-chart .hub-chart__axis { stroke: var(--hub-chart-axis); stroke-width: 1; }
.hub-chart .hub-chart__bar { fill: var(--hub-chart-1); transition: opacity var(--hub-dur); }
.hub-chart .hub-chart__bar.is-today, .hub-chart .hub-chart__bar.is-soft { fill: var(--hub-chart-1-soft); }
.hub-chart .hub-chart__bar.is-prev { fill: var(--hub-chart-prev); }
.hub-chart .hub-chart__bar.is-ad { fill: var(--hub-chart-ad); }
.hub-chart .hub-chart__bar:hover, .hub-chart .hub-chart__bar.is-hover { opacity: .8; }
.hub-chart .hub-chart__line { fill: none; stroke: var(--hub-chart-1); stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; }
.hub-chart .hub-chart__area { fill: var(--hub-chart-1); opacity: .12; }
.hub-chart .hub-chart__dot { fill: var(--hub-chart-1); stroke: var(--hub-surface); stroke-width: 1.5; }
.hub-chart .hub-chart__hit { fill: transparent; }
.hub-chart .hub-chart__target { stroke: var(--hub-warn); stroke-dasharray: 4 3; stroke-width: 1.25; }
.hub-chart-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: var(--hub-fs-xs); color: var(--hub-text-3); margin-top: 6px; }
.hub-chart-legend__item { display: inline-flex; align-items: center; gap: 5px; }
.hub-chart-legend__sw { width: 10px; height: 10px; border-radius: 2px; background: var(--hub-chart-1); flex: none; }
.hub-hbars { display: flex; flex-direction: column; gap: 6px; }
.hub-hbars__row { display: grid; grid-template-columns: minmax(80px, 38%) 1fr auto; align-items: center; gap: 8px; font-size: var(--hub-fs-sm); }
.hub-hbars__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--hub-text-2); }
.hub-hbars__track { height: 8px; background: var(--hub-surface-3); border-radius: var(--hub-r-pill); overflow: hidden; }
.hub-hbars__bar { height: 100%; background: var(--hub-chart-1); border-radius: var(--hub-r-pill); }
.hub-hbars__val { font-variant-numeric: tabular-nums; color: var(--hub-text); white-space: nowrap; }
.hub-propbar { display: flex; height: 10px; border-radius: var(--hub-r-pill); overflow: hidden; background: var(--hub-surface-3); }
.hub-propbar__part { height: 100%; min-width: 0; }
.hub-propbar__part:hover { opacity: .85; }
.hub-heat { display: grid; gap: 2px; }
.hub-heat__cell { aspect-ratio: 1; border-radius: 2px; background: var(--hub-surface-3); min-width: 0; }

/* --------------------------------------------------------------------------
   7. 마크다운(.hub-md) — md.render 출력
   -------------------------------------------------------------------------- */
.hub-md { font-size: var(--hub-fs-md); line-height: 1.7; color: var(--hub-text); overflow-wrap: anywhere; }
.hub-md > :first-child { margin-top: 0; }
.hub-md > :last-child { margin-bottom: 0; }
.hub-md h1, .hub-md h2, .hub-md h3, .hub-md h4 { margin: 1.4em 0 .5em; line-height: 1.3; font-weight: 700; letter-spacing: -.01em; }
.hub-md h1 { font-size: var(--hub-fs-xl); padding-bottom: 6px; border-bottom: 1px solid var(--hub-border); }
.hub-md h2 { font-size: 16px; padding-bottom: 4px; border-bottom: 1px solid var(--hub-divider); }
.hub-md h3 { font-size: 14px; }
.hub-md h4 { font-size: var(--hub-fs-md); color: var(--hub-text-2); }
.hub-md p { margin: 0 0 .8em; }
.hub-md ul, .hub-md ol { margin: 0 0 .8em; padding-left: 1.5em; }
.hub-md li { margin: .15em 0; }
.hub-md li > ul, .hub-md li > ol { margin: .2em 0; }
.hub-md strong { font-weight: 700; }
.hub-md em { font-style: italic; }
.hub-md a { color: var(--hub-link); text-decoration: underline; text-underline-offset: 2px; }
.hub-md code { font-family: var(--hub-font-mono); font-size: .92em; padding: 1px 5px; border-radius: 4px; background: var(--hub-surface-3); color: var(--hub-text); }
.hub-md pre { margin: 0 0 .9em; padding: 10px 12px; border-radius: var(--hub-r-md); background: var(--hub-surface-3); border: 1px solid var(--hub-border); overflow: auto; font-size: var(--hub-fs-sm); line-height: 1.55; }
.hub-md pre code { padding: 0; background: transparent; font-size: inherit; }
.hub-md blockquote { margin: 0 0 .9em; padding: 6px 12px; border-left: 3px solid var(--hub-accent); background: var(--hub-accent-tint); color: var(--hub-text-2); border-radius: 0 var(--hub-r-sm) var(--hub-r-sm) 0; }
.hub-md blockquote p { margin: 0; }
.hub-md hr { border: 0; border-top: 1px solid var(--hub-border); margin: 1.2em 0; }
.hub-md img { max-width: 100%; border-radius: var(--hub-r-md); }
.hub-md .hub-table-wrap { margin: 0 0 .9em; }
.hub-md table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--hub-fs-sm); }
.hub-md th { position: sticky; top: 0; background: var(--hub-surface-2); color: var(--hub-text-2); font-weight: 600; text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--hub-border); white-space: nowrap; }
.hub-md td { padding: 6px 10px; border-bottom: 1px solid var(--hub-divider); vertical-align: top; }
.hub-md tr:last-child td { border-bottom: 0; }
.hub-md td.num, .hub-md th.num { text-align: right; font-variant-numeric: tabular-nums; }
.hub-md input[type="checkbox"] { accent-color: var(--hub-accent); margin: 0 6px 0 0; vertical-align: -1px; }
.hub-md .hub-md__kbd { font-family: var(--hub-font-mono); }
.hub-md--compact { font-size: var(--hub-fs-sm); line-height: 1.6; }
.hub-md--compact h1 { font-size: 16px; } .hub-md--compact h2 { font-size: 14px; } .hub-md--compact h3 { font-size: 13px; }

/* --------------------------------------------------------------------------
   8. 유틸리티
   -------------------------------------------------------------------------- */
.hub-visually-hidden, .hub-sr-only {
  position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important;
  overflow: hidden !important; clip: rect(0 0 0 0) !important; clip-path: inset(50%) !important; white-space: nowrap !important; border: 0 !important;
}
.hub-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hub-row--between { justify-content: space-between; }
.hub-row--end { justify-content: flex-end; }
.hub-row--center { justify-content: center; }
.hub-row--start { align-items: flex-start; }
.hub-row--wrap, .hub-wrap { flex-wrap: wrap; }
.hub-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.hub-grow { flex: 1 1 auto; min-width: 0; }
.hub-shrink-0 { flex-shrink: 0; }
.hub-gap-0 { gap: 0; } .hub-gap-1 { gap: var(--hub-s1); } .hub-gap-2 { gap: var(--hub-s2); } .hub-gap-3 { gap: var(--hub-s3); } .hub-gap-4 { gap: var(--hub-s4); } .hub-gap-6 { gap: var(--hub-s6); }
.hub-grid { display: grid; gap: 12px; min-width: 0; }
.hub-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hub-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hub-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hub-grid--auto { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.hub-grid--side { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); }
.hub-mt-0 { margin-top: 0 !important; } .hub-mt-1 { margin-top: var(--hub-s1); } .hub-mt-2 { margin-top: var(--hub-s2); } .hub-mt-3 { margin-top: var(--hub-s3); } .hub-mt-4 { margin-top: var(--hub-s4); } .hub-mt-6 { margin-top: var(--hub-s6); }
.hub-mb-0 { margin-bottom: 0 !important; } .hub-mb-1 { margin-bottom: var(--hub-s1); } .hub-mb-2 { margin-bottom: var(--hub-s2); } .hub-mb-3 { margin-bottom: var(--hub-s3); } .hub-mb-4 { margin-bottom: var(--hub-s4); }
.hub-ml-auto { margin-left: auto; }
.hub-p-0 { padding: 0 !important; } .hub-p-2 { padding: var(--hub-s2); } .hub-p-3 { padding: var(--hub-s3); } .hub-p-4 { padding: var(--hub-s4); }
.hub-muted { color: var(--hub-text-3); }
.hub-faint { color: var(--hub-text-4); }
.hub-text-2 { color: var(--hub-text-2); }
.hub-good { color: var(--hub-good); } .hub-bad { color: var(--hub-bad); } .hub-warn { color: var(--hub-warn); } .hub-info { color: var(--hub-info); }
.hub-accent-text { color: var(--hub-accent-soft-ink); }
.hub-xs { font-size: var(--hub-fs-xs); } .hub-small { font-size: var(--hub-fs-sm); } .hub-lg { font-size: var(--hub-fs-lg); } .hub-xl { font-size: var(--hub-fs-xl); }
.hub-bold { font-weight: 700; } .hub-semibold { font-weight: 600; } .hub-normal { font-weight: 400; }
.hub-mono { font-family: var(--hub-font-mono); font-size: .95em; }
.hub-tabular { font-variant-numeric: tabular-nums; }
.hub-right { text-align: right; } .hub-center { text-align: center; } .hub-left { text-align: left; }
.hub-nowrap { white-space: nowrap; }
.hub-prewrap { white-space: pre-wrap; }
.hub-break { overflow-wrap: anywhere; }
.hub-block { display: block; } .hub-inline { display: inline; } .hub-iflex { display: inline-flex; align-items: center; gap: 4px; }
.hub-hidden, [hidden].hub-force-hidden { display: none !important; }
.hub-divider { height: 1px; background: var(--hub-border); border: 0; margin: 8px 0; }
.hub-divider--v { width: 1px; height: auto; align-self: stretch; margin: 0 4px; }
.hub-link { color: var(--hub-link); text-decoration: none; cursor: pointer; background: none; border: 0; padding: 0; font: inherit; }
.hub-link:hover { text-decoration: underline; }
.hub-link--muted { color: var(--hub-text-3); }
.hub-code, .hub-tag { font-family: var(--hub-font-mono); font-size: .92em; padding: 1px 5px; border-radius: 4px; background: var(--hub-surface-3); }
.hub-relative { position: relative; }
.hub-sticky { position: sticky; top: var(--hub-topbar-h); z-index: var(--hub-z-sticky); }
.hub-scroll-x { overflow-x: auto; min-width: 0; }
.hub-scroll-y { overflow-y: auto; min-height: 0; }
.hub-cursor { cursor: pointer; }
.hub-print-only { display: none !important; }
.hub-w-100 { width: 100%; }
.hub-mw-0 { min-width: 0; }
.hub-sticky-foot { position: sticky; bottom: 0; background: var(--hub-surface); border-top: 1px solid var(--hub-border); padding: 10px var(--hub-page-pad); margin: 0 calc(-1 * var(--hub-page-pad)); z-index: var(--hub-z-sticky); display: flex; gap: 8px; justify-content: flex-end; }
.hub-hide-mobile-only { }  /* 자리 표시(미디어 쿼리에서 정의) */

/* 즐겨찾기 카드(런처·사이드바) */
.hub-fav { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--hub-r-md); color: inherit; text-decoration: none; border: 1px solid var(--hub-border); background: var(--hub-surface); min-width: 0; }
.hub-fav:hover { border-color: var(--hub-border-strong); background: var(--hub-surface-2); }
.hub-fav__text { min-width: 0; display: flex; flex-direction: column; }
.hub-fav__title { font-weight: 600; font-size: var(--hub-fs-md); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-fav__url { font-size: var(--hub-fs-xs); color: var(--hub-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 런처(홈) — pages/home.js: .hub-launcher__grid > a.hub-card.hub-launch(--v1/--ext/--fav) */
.hub-launcher__section { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; }
.hub-launcher__section-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.hub-launcher__title { margin: 0; font-size: var(--hub-fs-lg); font-weight: 700; }
.hub-launcher__groups { display: flex; flex-direction: column; gap: 14px; }
.hub-launcher__group-label { margin: 0 0 6px; font-size: var(--hub-fs-sm); font-weight: 600; color: var(--hub-text-3); }
.hub-launcher__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.hub-launcher__empty { padding: 16px; color: var(--hub-text-3); font-size: var(--hub-fs-sm); text-align: center; border: 1px dashed var(--hub-border-strong); border-radius: var(--hub-r-lg); }
.hub-launcher__chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.hub-launcher__chip-q { font-weight: 600; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.hub-launcher__chip-time { color: var(--hub-text-4); font-size: var(--hub-fs-xs); margin-left: 2px; }
.hub-launch {
  display: flex; align-items: center; gap: 10px; padding: 12px; min-height: 64px; position: relative;
  color: inherit; text-decoration: none; transition: border-color var(--hub-dur), box-shadow var(--hub-dur);
}
.hub-launch:hover { border-color: var(--hub-accent); box-shadow: var(--hub-shadow-1); }
.hub-launch__icon, .hub-launch__ico {
  display: inline-flex; align-items: center; justify-content: center; flex: none; width: 36px; height: 36px; border-radius: 9px;
  background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink);
}
.hub-launch__icon svg, .hub-launch__ico svg { width: 18px; height: 18px; }
.hub-launch__icon .hub-avatar { width: 100%; height: 100%; border-radius: 9px; font-size: var(--hub-fs-lg); }
.hub-launch__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hub-launch__label, .hub-launch__title { font-weight: 600; font-size: var(--hub-fs-md); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-launch__sub, .hub-launch__desc { font-size: var(--hub-fs-xs); color: var(--hub-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-launch__badges { flex: none; display: inline-flex; align-items: center; gap: 4px; color: var(--hub-text-4); }
.hub-launch__badges svg { width: 14px; height: 14px; }
.hub-launch--v1 .hub-launch__icon { background: var(--hub-surface-3); color: var(--hub-text-2); }
.hub-launch--ext .hub-launch__icon { background: var(--hub-info-soft); color: var(--hub-info-ink); }
.hub-launch--fav .hub-launch__icon { background: var(--hub-surface-3); }
.hub-home-notice { display: flex; flex-direction: column; gap: 8px; }
.hub-home-notice__head { display: flex; align-items: center; gap: 6px; }
.hub-home-notice__head svg { width: 16px; height: 16px; color: var(--hub-info); }
.hub-home-notice__title { margin: 0; font-size: var(--hub-fs-md); font-weight: 700; }
.hub-home-notice__body { margin: 0; color: var(--hub-text-2); font-size: var(--hub-fs-sm); }
.hub-home-notice__actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   8b. 모듈 호환 — shell.js / table.js / charts.js / core.js 가 생성하는 하위 클래스
       (계획서의 상위 클래스는 위에, 세부 조각 이름은 모듈 쪽 명명을 따라 여기서 정의)
   -------------------------------------------------------------------------- */
.hub-icon { flex: none; vertical-align: middle; }

/* 사이드바(shell.js): .hub-sidebar__head(brand+pin+close) · nav.hub-sidebar__nav > .hub-sidebar__group > ul.hub-sidebar__list > li > a.hub-sidebar__item */
.hub-sidebar__head { display: flex; align-items: center; flex: none; min-height: var(--hub-topbar-h); padding-right: 6px; border-bottom: 1px solid var(--hub-border); gap: 2px; }
.hub-sidebar__head .hub-sidebar__brand { flex: 1; min-width: 0; border-bottom: 0; }
.hub-brand__dot {
  display: inline-flex; align-items: center; justify-content: center; flex: none; width: 30px; height: 30px; border-radius: 9px;
  background: var(--hub-accent); color: var(--hub-accent-ink); font-weight: 800; font-size: 15px; letter-spacing: -.02em;
}
.hub-brand__dot:empty::before { content: "M"; }
.hub-brand__text { display: flex; flex-direction: column; min-width: 0; }
.hub-brand__name { font-weight: 700; font-size: 14px; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub-brand__sub { font-size: var(--hub-fs-xs); color: var(--hub-text-3); line-height: 1.15; white-space: nowrap; }
.hub-sidebar__nav { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 8px; overscroll-behavior: contain; }
.hub-sidebar__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.hub-sidebar__list > li { min-width: 0; }
.hub-sidebar__icon { flex: none; width: 18px; height: 18px; }
.hub-sidebar__group-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; padding-right: 2px; }
.hub-sidebar__group-head .hub-sidebar__group-label { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.hub-sidebar__group-icon { width: 12px; height: 12px; color: var(--hub-accent-soft-ink); }
.hub-sidebar__star { flex: none; }
.hub-sidebar__star[aria-pressed="true"] svg { color: var(--hub-accent); }
.hub-sidebar__fav-row { position: relative; display: flex; align-items: center; min-width: 0; }
.hub-sidebar__fav-row .hub-sidebar__item { flex: 1; min-width: 0; padding-right: 30px; }
.hub-sidebar__item--fav .hub-avatar { width: 22px; height: 22px; font-size: 10px; border-radius: 6px; flex: none; }
.hub-sidebar__ext { width: 12px !important; height: 12px !important; margin-left: auto; color: var(--hub-text-4); }
.hub-sidebar__fav-del {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 6px; background: transparent;
  color: var(--hub-text-4); cursor: pointer; opacity: 0; transition: opacity var(--hub-dur), background var(--hub-dur);
}
.hub-sidebar__fav-del svg { width: 12px; height: 12px; }
.hub-sidebar__fav-row:hover .hub-sidebar__fav-del, .hub-sidebar__fav-del:focus-visible, .hub-sidebar__fav-row:focus-within .hub-sidebar__fav-del { opacity: 1; }
.hub-sidebar__fav-del:hover { background: var(--hub-bad-soft); color: var(--hub-bad); }
@media (hover: none) { .hub-sidebar__fav-del { opacity: 1; } }
.hub-sidebar__empty { padding: 6px 10px; font-size: var(--hub-fs-xs); color: var(--hub-text-4); }
.hub-sidebar__foot-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.hub-sidebar__foot-actions .hub-btn, .hub-sidebar__foot-btn { justify-content: flex-start; width: 100%; min-width: 0; padding: 0 8px; overflow: hidden; height: 30px; }
.hub-sidebar__foot-actions .hub-sidebar__label { font-size: var(--hub-fs-sm); }
/* 레일 */
.hub-app.is-rail .hub-sidebar__head { flex-direction: column; min-height: 0; padding: 6px 0 4px; gap: 2px; }
.hub-app.is-rail .hub-sidebar__head .hub-sidebar__brand { flex: none; width: 100%; height: 40px; }
.hub-app.is-rail .hub-brand__text { display: none; }
.hub-app.is-rail .hub-sidebar__pin svg { transform: rotate(180deg); }
.hub-app.is-rail .hub-sidebar__group-head { justify-content: center; padding: 0; }
.hub-app.is-rail .hub-sidebar__group-head .hub-sidebar__group-label { display: none; }
.hub-app.is-rail .hub-sidebar__fav-row .hub-sidebar__item { padding-right: 0; }
.hub-app.is-rail .hub-sidebar__fav-del, .hub-app.is-rail .hub-sidebar__ext, .hub-app.is-rail .hub-sidebar__empty { display: none; }
.hub-app.is-rail .hub-sidebar__foot-actions { grid-template-columns: 1fr; }
.hub-app.is-rail .hub-sidebar__foot-actions .hub-btn { justify-content: center; padding: 0; }

/* 탑바(shell.js): menu-btn · .hub-topbar__back · .hub-topbar__title-wrap(crumbs+title) · .hub-topbar__actions(페이지 동작 — 제목 바로 뒤) · form.hub-topbar__search.hub-search · .hub-topbar__right(user) */
.hub-topbar__title-wrap { display: flex; flex-direction: column; min-width: 0; justify-content: center; flex: 0 1 auto; }
.hub-topbar__crumb-list { display: flex; align-items: center; gap: 4px; margin: 0; padding: 0; list-style: none; white-space: nowrap; overflow: hidden; }
.hub-topbar__crumb { display: inline-flex; align-items: center; gap: 4px; }
.hub-topbar__crumb + .hub-topbar__crumb::before { content: "/"; color: var(--hub-text-4); }
.hub-topbar__crumb a { color: inherit; text-decoration: none; }
.hub-topbar__crumb a:hover { color: var(--hub-text); text-decoration: underline; }
/* 경로가 자리보다 길면(600~1023 폭 상세 화면 등 — shell.js fitCrumbs 머리 주석): 가운데 조각(그룹·목록 이름 — 돌아가기 버튼·제목과 겹침)이 먼저
   '한 글자…'까지 줄고(flex-shrink 100000 — 마지막 조각 몫은 0.01px 도 안 됨, 두 글자 조각은 .is-keep 로 그대로), 그다음 마지막 조각(지금 화면 — '찰랑체크'·'상세'·'SR-…')이 '…'.
   9em 넘는 긴 마지막 조각(캠페인 이름 등 — 셸이 .is-long)은 예전처럼 9em 까지 먼저 줄고 그다음 가운데 조각. 마지막 조각이 한 글자도 못 보이거나
   경로가 넘치면 셸이 .is-tight = 마지막 조각만('/' 없이). 전에는 마지막 조각만 줄어 640 폭에서 '찰랑체크' 5/44px·'상세' 3/22px(한 획 조각)만
   남거나 0px 이 되고 '/' 가 삐져나왔음. 자리가 넉넉하면 크기·위치 그대로 — 최소 폭은 원래 폭보다 작고, 줄이는 비율(flex-shrink)은 원래 폭 계산에
   안 들어감(% 상한은 쓰지 말 것: Chrome 이 제목 칸 원래 폭을 잴 때 % 를 그때 자리로 풀어 제목 칸이 좁아지고 검색창이 펼쳐졌음).
   em 값 = 셸 CRUMB_FLOOR_EM·CRUMB_FLOOR_SEC_EM·CRUMB_LAST_KEEP_EM(v2_core_test §18 이 대조). 조각(li)에는 overflow 를 주지 않음 —
   앞의 '/' 글자 획이 상자 왼쪽으로 1px 삐져나와 잘렸음(글자 칸에만 줌) */
.hub-topbar__crumb:first-child:not(:last-child) { flex-shrink: 0; }
.hub-topbar__crumb:not(:first-child):not(:last-child) { flex-shrink: 100000; min-width: 2.6em; }
.hub-topbar__crumb--sec:not(:first-child):not(:last-child) { min-width: 3.6em; }
.hub-topbar__crumb.is-keep:not(:first-child):not(:last-child) { flex-shrink: 0; }   /* 두 글자 가운데 조각('주문'·'고객' — 셸이 붙임): 줄여 봐야 2px 남짓이라 '주…' 만 되므로 그대로 */
.hub-topbar__crumb:last-child { min-width: 0; }
.hub-topbar__crumb.is-long:last-child:not(:first-child) { flex-shrink: 10000000000; min-width: 9em; }
.hub-topbar__crumb:not(:first-child) > :last-child, .hub-topbar__crumb:last-child > :last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-topbar__crumbs.is-tight .hub-topbar__crumb:not(:last-child) { display: none; }
.hub-topbar__crumbs.is-tight .hub-topbar__crumb:last-child { flex-shrink: 1; min-width: 0; }
.hub-topbar__crumbs.is-tight .hub-topbar__crumb:last-child::before { content: none; }
/* 셸이 경로 표시를 바꾼 바로 뒤 폭을 재므로(fitCrumbs·fitSearch) 경로 조각은 전환 없이 바로 바뀌어야 함 — tokens.css '모션 축소'의
   `* { transition-duration: .01ms }` 가 모든 속성을 0.01ms 전환으로 만들어, 잰 값이 바뀌기 전 값이라 경로가 '마지막 조각만'에 잘못 머물렀음
   (검색창 접기는 그대로 두고 셸이 150ms 뒤 경로를 한 번 더 잼 — 검색창 접기 판단이 예전과 같게) */
.hub-topbar__crumb { transition-property: none; }
.hub-topbar__right { display: flex; align-items: center; gap: 6px; margin-left: auto; flex: none; }
.hub-topbar__search + .hub-topbar__right { margin-left: 0; }
/* 탑바 동작 ⋯ 메뉴(shell.js — 휴대폰 <600 에서 동작이 2개 이상일 때만 보임) · 주 동작의 짧은 글자(actions[].short, 휴대폰 전용) */
.hub-topbar__more-wrap { display: none; position: relative; flex: none; }
.hub-topbar__more-menu { left: auto; right: 0; min-width: 200px; }
.hub-topbar__more-menu .hub-menu__item { min-height: var(--hub-touch); }
.hub-btn__short { display: none; }
.hub-topbar__search .hub-input { padding-right: 34px; }
.hub-search .hub-search__btn { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; min-width: 0; min-height: 0; padding: 0; }
.hub-search .hub-search__btn svg { width: 15px; height: 15px; }
.hub-topbar__user-btn {
  display: inline-flex; align-items: center; gap: 6px; height: var(--hub-control-h); padding: 0 6px 0 4px;
  border: 1px solid transparent; border-radius: var(--hub-r-md); background: transparent; color: inherit; font: inherit; cursor: pointer;
}
.hub-topbar__user-btn:hover, .hub-topbar__user-btn[aria-expanded="true"] { background: var(--hub-surface-3); }
.hub-topbar__user-name { font-size: var(--hub-fs-sm); font-weight: 600; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-topbar__user-caret { width: 14px; height: 14px; color: var(--hub-text-3); }
.hub-topbar__user .hub-menu { left: auto; right: 0; min-width: 200px; }

/* 목록으로 돌아가기(lib/backnav.js backButton · shell.setBack) — 가이드 v2/_PORTING.md §4-3
   · 테두리 있는 보조 버튼(ghost 아님 — "버튼이 안 보인다" 대응): 테두리 라이트 text-3(흰 면 5.5:1·바탕 5.0:1)·다크 text-4(4.7:1)
     — 컨트롤 경계 3:1 이상(라이트 text-4 는 2.5:1 로 미달이었음) · 바탕 surface-2 · 굵은 글자 · ← 아이콘
   · 상세 머리 카드의 첫 요소(왼쪽 위) 또는 내용 위 한 줄 .hub-backbar. 글자는 16em 에서 …(전체 이름은 title·aria-label)
   · 탑바 칸 .hub-topbar__back(메뉴 버튼 뒤·제목 앞, 글자 10em) — 휴대폰(<600)은 40×40 아이콘 + 메뉴(☰) 숨김(하단 탭 '더보기'가 메뉴) */
.hub-backbtn {
  flex: none; max-width: 100%; gap: 6px; padding: 0 12px 0 9px;
  background: var(--hub-surface-2); border-color: var(--hub-text-3); color: var(--hub-text); font-weight: 600;
}
.hub-backbtn:hover { background: var(--hub-surface-3); border-color: var(--hub-text-2); color: var(--hub-text); }
html[data-theme="dark"] .hub-backbtn { border-color: var(--hub-text-4); }
html[data-theme="dark"] .hub-backbtn:hover { border-color: var(--hub-text-3); }
.hub-backbtn:active { background: var(--hub-surface-3); }
.hub-backbtn svg { width: 16px; height: 16px; flex: none; }
.hub-backbtn.hub-btn--sm { padding: 0 10px 0 7px; gap: 4px; }
.hub-backbtn.hub-btn--sm svg { width: 14px; height: 14px; }
.hub-backbtn__label { min-width: 0; max-width: 16em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-backbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.hub-backbar > .hub-backbtn { margin-right: 4px; }
.hub-topbar__back { display: flex; align-items: center; flex: none; min-width: 0; }
.hub-topbar__back[hidden] { display: none; }
.hub-topbar__backbtn .hub-backbtn__label { max-width: 10em; }
@media (max-width: 599.98px) {
  .hub-topbar.has-back .hub-topbar__menu-btn { display: none; }
  .hub-topbar .hub-topbar__backbtn { width: 40px; min-width: 40px; height: 40px; min-height: 40px; padding: 0; }
  .hub-topbar .hub-topbar__backbtn .hub-backbtn__label { display: none; }
  .hub-topbar .hub-topbar__backbtn svg { width: 18px; height: 18px; }
  .hub-backbtn { min-height: 40px; }
}
.hub-menu__head { display: flex; align-items: center; gap: 8px; }
.hub-menu__who { min-width: 0; }
.hub-menu__name { font-weight: 600; font-size: var(--hub-fs-md); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hub-menu__role { font-size: var(--hub-fs-xs); color: var(--hub-text-3); }

/* 하단 탭(shell.js): a.hub-bottomnav__item > svg.hub-bottomnav__icon + span.hub-bottomnav__label */
.hub-bottomnav__icon { width: 22px; height: 22px; padding: 3px 12px; border-radius: var(--hub-r-pill); box-sizing: content-box; transition: background var(--hub-dur); }
.hub-bottomnav__item.is-active .hub-bottomnav__icon, .hub-bottomnav__item[aria-current="page"] .hub-bottomnav__icon { background: var(--hub-accent-soft); color: var(--hub-accent-soft-ink); }
.hub-bottomnav__label { font-size: 10.5px; line-height: 1.2; }

/* 폼(shell.js 비밀번호 모달): form.hub-form.hub-form--stack > .hub-field … .hub-form__actions */
.hub-form { display: flex; flex-direction: column; gap: 12px; }
.hub-form--stack { gap: 12px; }
.hub-form__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
small.hub-field__hint { display: block; }

/* 로그인 상태 유지 기기 모달(shell.js openDevicesModal) */
.hub-dev-intro { margin: 0; font-size: var(--hub-fs-sm); line-height: 1.6; }
.hub-dev-list { display: flex; flex-direction: column; gap: 8px; }
.hub-dev { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--hub-border); border-radius: var(--hub-r-md); background: var(--hub-surface); }
.hub-dev.is-current { border-color: var(--hub-accent); background: var(--hub-accent-tint, var(--hub-surface)); }
.hub-dev__ic { width: 32px; height: 32px; flex: none; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; background: var(--hub-surface-3); color: var(--hub-text-2); }
.hub-dev__ic svg { width: 18px; height: 18px; }
.hub-dev__body { flex: 1; min-width: 0; }
.hub-dev__name { font-weight: 600; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.hub-dev__meta { font-size: var(--hub-fs-xs); color: var(--hub-text-3); margin-top: 2px; overflow-wrap: anywhere; }
.hub-dev-empty { padding: 12px; border: 1px dashed var(--hub-border-strong); border-radius: var(--hub-r-md); text-align: center; }
.hub-dev-empty p { margin: 4px 0; }

/* 모달(core.js): .hub-modal__card--md(기본) · .hub-modal__text(confirm 본문) */
.hub-modal__card--md { max-width: 560px; }
.hub-modal__text { font-size: var(--hub-fs-md); line-height: 1.6; }

/* 마크다운(core.js md.render): 작업 목록 */
.hub-md__task { list-style: none; margin-left: -1.3em; }
.hub-md__task input { accent-color: var(--hub-accent); margin: 0 6px 0 0; vertical-align: -1px; }

/* 차트(charts.js) — 레이아웃 조각(색·툴팁은 charts.js 가 자체 주입) */
.hub-chart__svg { display: block; width: 100%; height: auto; }
.hub-chart__scroll { overflow-x: auto; overscroll-behavior-x: contain; }
.hub-chart__empty { padding: 16px; }
.hub-chart__cell:hover, .hub-chart__cell.is-hover { opacity: .85; }
.hub-hbar__top { display: flex; justify-content: space-between; gap: 8px; font-size: var(--hub-fs-sm); }
.hub-propbar__seg { height: 100%; min-width: 0; }
.hub-propbar__seg:hover { opacity: .85; }

/* --------------------------------------------------------------------------
   8c. 구분 색 — 섹션(크롬 전용) · 목록 카드 상태 줄 · 지브라
   · 섹션: shell.js 가 사이드바 그룹·메뉴 항목·하단 탭·경로 점에 data-sec="<그룹 key>",
     #hubApp 에 현재 페이지의 섹션 data-sec 를 붙인다(syncActive 가 경로 변경 때 갱신).
     컴포넌트는 var(--sec) / var(--sec-soft) 만 쓴다(값은 tokens.css --hub-sec-*).
     섹션 색은 아이콘·점·막대·틴트에만 — 글자색은 텍스트 토큰 유지, 상태 표시에 쓰지 않음.
   · 목록 카드(.hub-lcard): 왼쪽 4px 상태 줄(--hub-good/warn/info/bad/border-strong) + 안에 상태 배지(글자) 필수.
   · 지브라(.hub-zebra): 카드·행 묶음을 표 줄무늬와 같은 토큰(--hub-table-stripe/-hover)으로 교대.
   -------------------------------------------------------------------------- */
:root { --sec: var(--hub-sec-settings); --sec-soft: var(--hub-sec-settings-soft); }
[data-sec="home"], .hub-launcher__group[data-group="home"] { --sec: var(--hub-sec-home); --sec-soft: var(--hub-sec-home-soft); }
[data-sec="orders"], .hub-launcher__group[data-group="orders"] { --sec: var(--hub-sec-orders); --sec-soft: var(--hub-sec-orders-soft); }
[data-sec="docs"], .hub-launcher__group[data-group="docs"] { --sec: var(--hub-sec-docs); --sec-soft: var(--hub-sec-docs-soft); }
[data-sec="products"], .hub-launcher__group[data-group="products"] { --sec: var(--hub-sec-products); --sec-soft: var(--hub-sec-products-soft); }
[data-sec="supply"], .hub-launcher__group[data-group="supply"] { --sec: var(--hub-sec-supply); --sec-soft: var(--hub-sec-supply-soft); }
[data-sec="insights"], .hub-launcher__group[data-group="insights"] { --sec: var(--hub-sec-insights); --sec-soft: var(--hub-sec-insights-soft); }
[data-sec="content"], .hub-launcher__group[data-group="content"] { --sec: var(--hub-sec-content); --sec-soft: var(--hub-sec-content-soft); }
[data-sec="support"], .hub-launcher__group[data-group="support"] { --sec: var(--hub-sec-support); --sec-soft: var(--hub-sec-support-soft); }
[data-sec="settings"], .hub-launcher__group[data-group="settings"] { --sec: var(--hub-sec-settings); --sec-soft: var(--hub-sec-settings-soft); }

/* 사이드바·드로어(같은 요소): 그룹 머리 점 · 섹션색 아이콘(비활성은 살짝 옅게) · 활성 = 섹션 틴트 + 왼쪽 3px 막대 */
.hub-sidebar__group[data-sec] .hub-sidebar__group-text::before {
  content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 6px; vertical-align: 1px;
  border-radius: 50%; background: var(--sec);
}
.hub-sidebar__item[data-sec] .hub-sidebar__icon { opacity: var(--hub-sec-icon-opacity, .85); transition: opacity var(--hub-dur) var(--hub-ease); }
.hub-sidebar__item[data-sec] .hub-sidebar__icon svg { color: var(--sec); }
.hub-sidebar__item[data-sec]:hover .hub-sidebar__icon,
.hub-sidebar__item[data-sec].is-active .hub-sidebar__icon,
.hub-sidebar__item[data-sec][aria-current="page"] .hub-sidebar__icon { opacity: 1; }
.hub-sidebar__item[data-sec].is-active, .hub-sidebar__item[data-sec][aria-current="page"] {
  background: var(--sec-soft); color: var(--hub-text); box-shadow: inset 3px 0 0 var(--sec);
}
/* 활성 막대(inset 그림자)가 포커스 링을 덮지 않게 둘을 합침 */
.hub-sidebar__item.is-active:focus-visible, .hub-sidebar__item[aria-current="page"]:focus-visible { box-shadow: inset 3px 0 0 var(--hub-accent), var(--hub-focus); }
.hub-sidebar__item[data-sec].is-active:focus-visible, .hub-sidebar__item[data-sec][aria-current="page"]:focus-visible { box-shadow: inset 3px 0 0 var(--sec), var(--hub-focus); }

/* 하단 탭(<900): 섹션색 아이콘, 활성 알약은 섹션 틴트(라벨은 텍스트 토큰) */
.hub-bottomnav__item[data-sec] .hub-bottomnav__icon { color: var(--sec); }
.hub-bottomnav__item[data-sec].is-active .hub-bottomnav__icon,
.hub-bottomnav__item[data-sec][aria-current="page"] .hub-bottomnav__icon { background: var(--sec-soft); color: var(--sec); }

/* 탑바: 섹션 경로 앞 작은 점 · 제목 묶음 왼쪽 3px 섹션 막대(페이지 머리 표시 — <600 에서 경로가 숨어도 보임) */
.hub-topbar__crumb-dot { flex: none; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--sec); }
.hub-app[data-sec] .hub-topbar__title-wrap { padding-left: 10px; box-shadow: inset 3px 0 0 var(--sec); }

/* 홈 런처: 그룹 라벨 점 · 모듈 타일 섹션 틴트(v1 미이식 카드는 회색 유지) · hover 테두리 */
.hub-launcher__group:is([data-sec], [data-group]) > .hub-launcher__group-label::before {
  content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 6px; vertical-align: 1px;
  border-radius: 50%; background: var(--sec);
}
.hub-launcher__group:is([data-sec], [data-group]) .hub-launch:not(.hub-launch--v1) .hub-launch__icon { background: var(--sec-soft); color: var(--sec); }
.hub-launcher__group:is([data-sec], [data-group]) .hub-launch:hover { border-color: var(--sec); }

/* 목록 카드 — <div|a|button class="hub-lcard hub-lcard--warn"> … <span class="hub-badge hub-badge--warn">부분입고</span>
   상태 줄(색)은 항상 글자 배지·칩과 함께. 클릭 카드는 a/button/[role=button] 또는 .is-clickable. */
.hub-lcard {
  --lcard-stripe: transparent;
  display: block; position: relative; min-width: 0; max-width: 100%;
  padding: 12px 14px 12px 16px;
  background-color: var(--hub-surface); border: 1px solid var(--hub-border); border-radius: var(--hub-r-lg);
  box-shadow: inset 4px 0 0 var(--lcard-stripe);
  color: inherit; text-decoration: none; text-align: left; overflow-wrap: anywhere;
  transition: background-color var(--hub-dur) var(--hub-ease), border-color var(--hub-dur) var(--hub-ease);
}
button.hub-lcard { width: 100%; font: inherit; }
.hub-lcard--good { --lcard-stripe: var(--hub-good); }
.hub-lcard--warn { --lcard-stripe: var(--hub-warn); }
.hub-lcard--info { --lcard-stripe: var(--hub-info); }
.hub-lcard--bad { --lcard-stripe: var(--hub-bad); }
.hub-lcard--neutral { --lcard-stripe: var(--hub-border-strong); }

/* 지브라 — 자식은 자기 배경을 정하지 말 것(.hub-lcard 는 지브라에 양보). 홀수 = surface, 짝수 = 표 줄무늬 */
:where(.hub-zebra) > * { background-color: var(--hub-surface); }
.hub-zebra > :nth-child(even) { background-color: var(--hub-table-stripe); }
.hub-zebra > :is(a, button, [role="button"], .is-clickable, .hub-lcard--clickable):hover { background-color: var(--hub-table-hover); }
.hub-zebra > .is-selected { background-image: linear-gradient(var(--hub-accent-tint), var(--hub-accent-tint)); }

/* 목록 카드 상태(지브라보다 뒤 — hover·선택이 줄무늬를 이김) */
.hub-lcard:is(a, button, [role="button"], .is-clickable, .hub-lcard--clickable) { cursor: pointer; }
.hub-lcard:is(a, button, [role="button"], .is-clickable, .hub-lcard--clickable):hover { background-color: var(--hub-table-hover); border-color: var(--hub-border-strong); }
.hub-lcard.is-selected, .hub-lcard.is-current {
  border-color: var(--hub-accent);
  background-image: linear-gradient(var(--hub-accent-tint), var(--hub-accent-tint));
}
.hub-lcard:focus-visible { box-shadow: inset 4px 0 0 var(--lcard-stripe), var(--hub-focus); }
@media (max-width: 599.98px) {
  .hub-lcard { padding: 10px 12px 10px 14px; }
}

/* --------------------------------------------------------------------------
   8d. 모바일 목록(간단히·자세히) — lib/mlist.js · table.js(mobile) 공용 부품. 가이드 v2/_PORTING.md '모바일 목록'
   · 행 .hub-mrow > .hub-mrow__check · .hub-mrow__thumb · .hub-mrow__main(.hub-mrow__title(.hub-mtitle) + .hub-mrow__sub) · .hub-mrow__end · .hub-mrow__act
   · 목록 컨테이너 .hub-mlist(행 사이 구분선, .hub-zebra 와 함께 쓰면 줄무늬) · 자세히 줄 .hub-mlines > .hub-mline(__k 라벨 · __v 값)
   · 제목 .hub-mtitle(--clamp: --mt-lines 줄로 자름, .is-truncated 일 때만 [전체▾] .hub-mtitle__more, .is-expanded = 펼침)
   · 보기 토글 .hub-mtoggle(휴대폰에서만 보임) · 표 위 휴대폰 바 .hub-table__mbar(정렬 select + 토글)
   · 하단 고정 바는 bottom: var(--hub-bottom-ui) (하단 탭 + 안전 영역 위)
   -------------------------------------------------------------------------- */
:root { --hub-bottom-ui: var(--hub-safe-bottom); }
.hub-mlist { display: flex; flex-direction: column; min-width: 0; }
.hub-mlist > .hub-mrow + .hub-mrow { border-top: 1px solid var(--hub-divider); }
.hub-mrow {
  display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 56px;
  padding: 8px 12px; color: inherit; text-decoration: none; text-align: left; font: inherit;
  -webkit-tap-highlight-color: transparent;
}
:where(button.hub-mrow) { width: 100%; border: 0; background-color: transparent; }
.hub-mrow.is-clickable { cursor: pointer; }
.hub-mrow.is-clickable:hover { background-color: var(--hub-table-hover); }
.hub-mrow.is-clickable:active { background-color: var(--hub-table-hover); }
.hub-mrow:focus-visible { outline: none; box-shadow: inset var(--hub-focus); }
.hub-mrow--good { box-shadow: inset 3px 0 0 var(--hub-good); }
.hub-mrow--warn { box-shadow: inset 3px 0 0 var(--hub-warn); }
.hub-mrow--info { box-shadow: inset 3px 0 0 var(--hub-info); }
.hub-mrow--bad { box-shadow: inset 3px 0 0 var(--hub-bad); }
.hub-mrow--neutral { box-shadow: inset 3px 0 0 var(--hub-border-strong); }
.hub-mrow.is-selected { background-image: linear-gradient(var(--hub-accent-tint), var(--hub-accent-tint)); }
/* 자세히 머리: 제목만 있는 행이 56px 최소 높이로 빈 칸을 남기지 않게(사진·체크·액션이 있으면 그 높이가 됨) */
.hub-mrow--detail { align-items: flex-start; min-height: 0; }

.hub-mrow__check {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; min-height: 40px; margin: 0 -8px 0 -10px; cursor: pointer;
}
.hub-mrow__check input { width: 18px; height: 18px; margin: 0; accent-color: var(--hub-accent); }
.hub-mrow__thumb {
  flex: none; position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border-radius: var(--hub-r-md); overflow: hidden;
  background: var(--hub-surface-2); border: 1px solid var(--hub-divider); color: var(--hub-text-4);
}
.hub-mrow__thumb--sm { width: 36px; height: 36px; }
.hub-mrow__thumb--lg { width: 64px; height: 64px; }
.hub-mrow .hub-mrow__thumb > img, .hub-mrow__thumb > img {
  display: block; width: 100%; height: 100%; max-width: none; max-height: none; object-fit: cover;
  margin: 0; border: 0; border-radius: 0; background: transparent;
}
.hub-mrow .hub-mrow__thumb > :not(img) {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
  margin: 0; border: 0; border-radius: 0; background: transparent;
}
.hub-mrow__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hub-mrow__title { font-size: calc(var(--hub-fs-md) + 1px); font-weight: 600; line-height: 1.35; color: var(--hub-text); }
.hub-mrow--detail .hub-mrow__title { font-size: var(--hub-fs-lg); }
/* 보조 줄: 조각(.hub-mrow__part) 하나가 줄바꿈 단위 — 조각 안에서는 줄을 바꾸지 않음(한글이 '소|진'처럼 끊기지 않게),
   한 조각이 줄보다 길면 그 조각만 '…'. 줄 수를 넘는 나머지 조각은 잘리고 마지막 줄 끝에 '…' */
.hub-mrow__sub { min-width: 0; font-size: var(--hub-fs-sm); line-height: 1.45; color: var(--hub-text-3); word-break: keep-all; }
.hub-mrow__sub--clamp { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--ms-lines, 1); overflow: hidden; }
/* 자르는 줄(간단히)에서만 조각 = 줄바꿈 단위. 자르지 않는 줄(자세히·mobileSubLines:0)은 조각 안에서도 띄어쓰기 단위로 줄바꿈 */
.hub-mrow__sub--clamp > .hub-mrow__part { display: inline-block; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
.hub-mrow__sub:not(.hub-mrow__sub--clamp) { overflow-wrap: anywhere; }
.hub-mrow__part + .hub-mrow__part::before { content: "·"; margin: 0 5px; color: var(--hub-text-4); }
/* 칩 둘이 나란하면 점 대신 간격만([제외] [×2]) */
.hub-mrow__part--chip + .hub-mrow__part--chip { margin-left: 4px; }
.hub-mrow__part--chip + .hub-mrow__part--chip::before { content: none; }
.hub-mrow__sub :is(.hub-chip, .hub-badge) { height: 18px; padding: 0 6px; font-size: var(--hub-fs-xs); vertical-align: 1px; }
/* 둘째 줄: sub(왼쪽, 넘치면 …) + 주 값(오른쪽 — 행마다 같은 자리라 세로로 훑기 쉬움) */
.hub-mrow__line2 { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.hub-mrow__line2 > .hub-mrow__sub { flex: 1 1 auto; }
.hub-mrow__end {
  flex: none; display: inline-flex; align-items: baseline; justify-content: flex-end; gap: 6px;
  margin-left: auto; max-width: 62%; min-width: 0; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* 칸(최대 62%)이 모자라면 보조 값이 먼저 줄어듦(…) — 주 값은 혼자 칸보다 길 때만 잘림(시즌 상품 '소진 46.7일 재고 1,234' 가 '소진 46.7… 재고 …' 로
   주 값까지 잘렸음) */
.hub-mrow__end-main { flex: 0 0 auto; max-width: 100%; min-width: 0; font-size: calc(var(--hub-fs-md) + 1px); font-weight: 700; color: var(--hub-text); overflow: hidden; text-overflow: ellipsis; }
.hub-mrow__end-sub { min-width: 0; font-size: var(--hub-fs-sm); color: var(--hub-text-3); overflow: hidden; text-overflow: ellipsis; }
.hub-mrow__end :is(.hub-chip, .hub-badge) { height: 20px; }
.hub-mrow__act { flex: none; display: inline-flex; align-items: center; gap: 2px; margin-right: -6px; }
.hub-mrow__act .hub-btn { min-height: 40px; min-width: 40px; }
.hub-mrow__act .hub-row-actions { opacity: 1; }
.hub-mrow__skel-end { flex: none; width: 56px; height: 14px; }

/* 제목: 자르기 + [전체▾](잘렸을 때만) + 펼침. 길게 누르기 중 글자 선택·말풍선 메뉴가 뜨지 않게(자를 때만) */
.hub-mtitle { display: flex; align-items: flex-start; gap: 2px; min-width: 0; }
/* 한글은 단어(띄어쓰기) 단위로 줄바꿈 — 띄어쓰기 없는 긴 덩어리(상품코드·URL·중국어)만 아무 데서나 */
.hub-mtitle__text { flex: 0 1 auto; min-width: 0; word-break: keep-all; overflow-wrap: anywhere; }
@media (pointer: coarse) { .hub-mtitle--clamp > .hub-mtitle__text { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; } }
.hub-mtitle--clamp:not(.is-expanded) > .hub-mtitle__text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--mt-lines, 1); overflow: hidden; }
.hub-mtitle__more {
  flex: none; position: relative; display: none; align-items: center; justify-content: center;
  width: 22px; height: 20px; margin-top: 0; padding: 0; border: 0; border-radius: var(--hub-r-sm);
  background: var(--hub-surface-3); color: var(--hub-text-2); cursor: pointer; font: inherit;
}
/* 보이는 크기는 작게, 누르는 영역은 42×40px. 위로는 8px 만(행 위쪽 여백 = 8px) — 위로 더 넓히면 표 첫 행에서 그 부분이
   표 틀(.hub-table-wrap, overflow) 밖으로 나가 잘려 38px 이 됐음. 모자란 만큼 아래로(12px) */
.hub-mtitle__more::after { content: ""; position: absolute; inset: -8px -10px -12px; }
.hub-mtitle__more:focus-visible { outline: none; box-shadow: var(--hub-focus); }
.hub-mtitle__more svg { transition: transform var(--hub-dur) var(--hub-ease); }
.hub-mtitle.is-truncated > .hub-mtitle__more, .hub-mtitle.is-expanded > .hub-mtitle__more { display: inline-flex; }
.hub-mtitle.is-expanded > .hub-mtitle__more svg { transform: rotate(180deg); }

/* 자세히 줄: '라벨 : 값' */
.hub-mlines { display: flex; flex-direction: column; gap: 3px; padding: 0 12px 10px; min-width: 0; }
.hub-mline { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; min-width: 0; font-size: var(--hub-fs-md); }
.hub-mline__k { flex: none; min-width: 72px; color: var(--hub-text-3); font-size: var(--hub-fs-sm); font-weight: 500; }
.hub-mline__v { min-width: 0; text-align: right; word-break: keep-all; overflow-wrap: anywhere; }
.hub-mline--num .hub-mline__v { font-variant-numeric: tabular-nums; }

/* createTable 휴대폰 목록: 행 하나 = 셀 하나(.hub-mtd > .hub-mrow) — 카드 모드 셀 규칙(라벨:값 flex)을 끔 */
.hub-table.hub-table--mlist tbody tr.hub-mtr { padding: 0; }
.hub-table.hub-table--mlist td.hub-mtd { display: block; height: auto; min-height: 0; padding: 0; border: 0; text-align: left; }
.hub-table.hub-table--mlist td.hub-mtd::before { content: none; }
.hub-table--mlist .hub-mrow__main .hub-skeleton { display: block; }
.hub-table--mlist tbody tr.hub-mtr.is-clickable:active { background: var(--hub-table-hover); }

/* 표 위 휴대폰 바(정렬 + 보기 토글) — 항상 한 줄: 정렬 select 가 남는 폭만큼 줄고(넘치면 …), 방향 버튼은 아이콘,
   바(컨테이너)가 좁으면 토글 글자를 숨겨 아이콘만(이름은 버튼 aria-label). .has-sort = 정렬 select 있음(table.js) */
.hub-table__mbar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: nowrap;
  padding: 6px 10px; border-bottom: 1px solid var(--hub-divider); min-width: 0;
  container: hubmbar / inline-size;
}
.hub-table__msortbox { display: flex; align-items: center; gap: 4px; flex: 1 1 0; min-width: 0; }
.hub-table__mbar .hub-table__msort {
  flex: 1 1 auto; width: auto; min-width: 0; max-width: 240px; min-height: 40px;
  padding-left: 8px; padding-right: 26px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hub-table__mbar .hub-table__mdir { flex: none; min-height: 40px; min-width: 40px; }
.hub-mtoggle { display: none; flex: none; margin-left: auto; }
.hub-mtoggle.hub-seg > .hub-mtoggle__btn { min-height: 40px; height: 40px; padding: 0 10px; font-size: var(--hub-fs-sm); }
.hub-mtoggle__btn svg { flex: none; }
.hub-mtoggle--icon .hub-mtoggle__label { display: none; }
.hub-mtoggle.hub-seg.hub-mtoggle--icon > .hub-mtoggle__btn { width: 40px; min-width: 40px; padding: 0; }
@container hubmbar (max-width: 329.98px) {
  .hub-table__mbar.has-sort .hub-mtoggle__label { display: none; }
  .hub-table__mbar.has-sort .hub-mtoggle.hub-seg > .hub-mtoggle__btn { width: 40px; min-width: 40px; padding: 0; }
}
@media (max-width: 599.98px) { .hub-mtoggle { display: inline-flex; } }

/* --------------------------------------------------------------------------
   9. 애니메이션
   -------------------------------------------------------------------------- */
@keyframes hub-spin { to { transform: rotate(360deg); } }
@keyframes hub-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@keyframes hub-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes hub-pop { from { opacity: 0; transform: translateY(6px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes hub-slide-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes hub-toast-in { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes hub-toast-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(8px); } }
@keyframes hub-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.hub-pulse { animation: hub-pulse 1.2s ease infinite; }

/* --------------------------------------------------------------------------
   10. 반응형
   -------------------------------------------------------------------------- */
/* 900 ~ 1199: 레일은 .hub-app.is-rail 로 shell.js 가 제어(기본 rail 저장값) */
@media (max-width: 1199.98px) {
  .hub-stat-grid--5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hub-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hub-card-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hub-form-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* < 900: 사이드바 → 드로어, 하단 탭, 터치 44px */
@media (max-width: 899.98px) {
  .hub-app, .hub-app.is-rail { grid-template-columns: minmax(0, 1fr); }
  .hub-sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; height: 100dvh; width: var(--hub-drawer-w);
    z-index: var(--hub-z-drawer); transform: translateX(-100%);
    box-shadow: none; transition: transform var(--hub-dur-slow) var(--hub-ease);
    border-right: 1px solid var(--hub-border); padding-bottom: var(--hub-safe-bottom);
  }
  .hub-sidebar.is-open { transform: none; box-shadow: var(--hub-shadow-3); }
  .hub-sidebar.hub-drawer { left: 0; right: auto; width: var(--hub-drawer-w); border-left: 0; transform: translateX(-100%); }  /* shell.js 가 .hub-drawer 를 덧붙임 */
  .hub-sidebar.hub-drawer.is-open { transform: none; }
  .hub-sidebar .hub-sidebar__close { display: inline-flex; }
  .hub-sidebar__head { padding-right: 8px; }
  /* 레일 규칙 무효화(드로어는 항상 펼침) */
  .hub-app.is-rail .hub-sidebar__brand { justify-content: flex-start; padding: 0 14px; }
  .hub-app.is-rail .hub-sidebar__brand-text, .hub-app.is-rail .hub-sidebar__group-label, .hub-app.is-rail .hub-sidebar__label,
  .hub-app.is-rail .hub-sidebar__item .hub-badge, .hub-app.is-rail .hub-sidebar__user-text, .hub-app.is-rail .hub-sidebar__item--sub { display: flex; }
  .hub-app.is-rail .hub-sidebar__group { border-top: 0; padding-top: 0; margin-top: 0; }
  .hub-app.is-rail .hub-sidebar__item { justify-content: flex-start; padding: 0 10px; height: auto; }
  .hub-app.is-rail .hub-sidebar__item svg { width: 18px; height: 18px; }
  .hub-app.is-rail .hub-sidebar__footrow { flex-direction: row; }
  .hub-app.is-rail .hub-sidebar__footrow .hub-btn { justify-content: flex-start; padding: 0 12px; }
  .hub-app.is-rail .hub-sidebar__footrow .hub-btn .hub-btn__label { display: inline; }
  .hub-sidebar__pin { display: none !important; }

  .hub-topbar .hub-topbar__menu-btn { display: inline-flex; }
  .hub-topbar__search { flex-basis: 160px; }
  .hub-bottomnav { display: grid; }
  .hub-main { padding-bottom: calc(var(--hub-bottomnav-h) + var(--hub-safe-bottom) + var(--hub-page-pad)); }
  .hub-toast-host { left: 16px; right: 16px; width: auto; bottom: calc(var(--hub-bottomnav-h) + var(--hub-safe-bottom) + 12px); }
  .hub-sticky-foot { bottom: calc(var(--hub-bottomnav-h) + var(--hub-safe-bottom)); }
  .hub-drawer { width: min(420px, 100vw); }

  /* 터치 타깃 */
  .hub-sidebar__group-btn { min-height: var(--hub-touch); }
  .hub-btn, .hub-input, .hub-select, .hub-tab, .hub-menu__item, .hub-sidebar__item, .hub-pager__btn,
  .hub-seg__btn, .hub-seg > button, .hub-sheet__item, .hub-bottomnav__item, .hub-fav, .hub-switch, .hub-checkbox, .hub-radio { min-height: var(--hub-touch); }
  .hub-btn--icon { min-width: var(--hub-touch); }
  .hub-btn--sm { min-height: var(--hub-touch); min-width: var(--hub-touch); padding: 0 12px; }
  .hub-topbar__user-btn { min-height: var(--hub-touch); }   /* 375 실측: 32px 였음 — 터치 타깃 44 */
  .hub-btn--icon.hub-btn--sm { min-width: var(--hub-touch); padding: 0; }
  .hub-input--sm, .hub-select--sm { min-height: var(--hub-touch); }
  /* 예외: 표 행 안의 아이콘 버튼(카드 모드 행 액션)·칩은 36px — 밀도 유지 */
  .hub-table .hub-row-actions .hub-btn { min-height: 36px; min-width: 36px; }
  .hub-chip--btn, button.hub-chip, a.hub-chip { min-height: 36px; padding: 0 12px; }
  .hub-chip__x { width: 24px; height: 24px; }
  .hub-textarea { min-height: 96px; }
  .hub-table th.is-sortable > button { min-height: var(--hub-touch); }
  .hub-tabs--pills .hub-tab { min-height: var(--hub-touch); }
  .hub-tabs--sm .hub-tab { min-height: var(--hub-touch); }
  .hub-toast__close, .hub-modal__close, .hub-sidebar__close { min-height: var(--hub-touch); min-width: var(--hub-touch); }
  .hub-toast__close { margin: -12px -14px -12px 0; }
  .hub-link, .hub-btn--link { min-height: 0; }
  .hub-seg { padding: 3px; }
  .hub-seg__btn, .hub-seg > button { border-radius: 6px; }
  .hub-pager .hub-select { min-height: var(--hub-touch); }
  .hub-pager__btn { min-width: 40px; }   /* 예전 쪽 버튼(28px 폭) — 터치 40px+ (.hub-pager__page 등 hub-btn--sm 은 위 규칙으로 44px) */
  .hub-grid--side { grid-template-columns: minmax(0, 1fr); }
  .hub-kv--2col { grid-template-columns: max-content minmax(0, 1fr); }
  .hub-hide-tablet { display: none !important; }
}

/* < 600: 모바일 — 표→카드, 모달→시트, 밀도 완화 */
@media (max-width: 599.98px) {
  :root { --hub-page-pad: 12px; }
  .hub-topbar { gap: 4px; }
  .hub-topbar__crumbs { display: none; }
  .hub-topbar__title { font-size: var(--hub-fs-lg); }
  .hub-topbar__titlebox, .hub-topbar__title-wrap { flex: 1; }
  /* 검색창은 아이콘 크기(40×44 — 터치 타깃)로 접힘 — 입력을 탭(:focus-within)하거나 .is-searching 이면 탑바를 덮는 전체 폭 입력으로 펼침(JS 불필요) */
  .hub-topbar__search { flex: 0 0 40px; width: 40px; min-width: 0; max-width: none; margin-left: auto; }
  .hub-topbar__search > svg, .hub-topbar__search > .hub-search__icon { left: 12px; }
  .hub-topbar__search .hub-input { padding: 0; color: transparent; background: transparent; border-color: transparent; cursor: pointer; caret-color: transparent; }
  .hub-topbar__search .hub-input::placeholder { color: transparent; }
  .hub-topbar__search .hub-search__btn, .hub-topbar__search .hub-search__kbd { display: none; }
  .hub-topbar__search:focus-within, .hub-topbar.is-searching .hub-topbar__search {
    position: absolute; left: 8px; right: 8px; top: calc(var(--hub-safe-top) + 6px); bottom: 6px; width: auto; flex: none; z-index: 1; margin: 0;
    background: var(--hub-surface); border-radius: var(--hub-r-md);
  }
  .hub-topbar__search:focus-within .hub-input, .hub-topbar.is-searching .hub-topbar__search .hub-input {
    height: 100%; width: 100%; padding: 0 34px 0 32px; color: inherit; background: var(--hub-surface); border-color: var(--hub-accent); cursor: text; caret-color: auto;
  }
  .hub-topbar__search:focus-within .hub-input::placeholder, .hub-topbar.is-searching .hub-topbar__search .hub-input::placeholder { color: var(--hub-text-4); }
  .hub-topbar__search:focus-within .hub-search__btn, .hub-topbar.is-searching .hub-topbar__search .hub-search__btn { display: inline-flex; }
  .hub-topbar .hub-topbar__search-btn { display: none; }
  .hub-topbar__actions .hub-btn:not(.hub-btn--icon) .hub-btn__label { display: none; }
  /* 동작이 2개 이상이면(shell.js .has-more): 주 동작 1개만 탑바에, 나머지는 ⋯ 메뉴로 — 제목이 '검…'으로 눌리지 않게 */
  .hub-topbar__actions.has-more > .hub-topbar__act--extra { display: none; }
  .hub-topbar__actions.has-more > .hub-topbar__more-wrap { display: inline-flex; }
  /* 동작 칸이 제목 바로 뒤라 ⋯ 오른쪽에 검색·사용자가 있음 — 메뉴는 탑바(sticky = 기준 상자) 오른쪽 끝에 붙임(300px 이하에서 왼쪽 밖으로 잘리지 않게) */
  .hub-topbar__actions.has-more > .hub-topbar__more-wrap { position: static; }
  .hub-topbar__more-menu { right: var(--hub-page-pad); max-width: calc(100vw - 2 * var(--hub-page-pad)); }
  .hub-headacts > .hub-headacts__end { margin-left: 0; }   /* 머리 동작 줄이 줄바꿈되면 [삭제]만 들여써져 보임 — 휴대폰은 간격(gap)만 */
  .hub-topbar__actions .hub-btn__short { display: inline; }
  .hub-topbar__user .hub-btn, .hub-topbar__user-btn { padding: 0 4px; }
  .hub-topbar__user-btn { min-width: 40px; justify-content: center; }
  .hub-topbar__user-name, .hub-topbar__user-caret { display: none; }   /* 아바타만(이름·▾ 는 메뉴 안에) — 제목 자리 확보 */
  /* 탑바 아이콘 버튼은 폭 40(높이 44) — 제목('이전 검토 찾기' 7자 등)이 잘리지 않게 자리 확보 */
  .hub-topbar .hub-topbar__menu-btn { min-width: 40px; width: 40px; }
  .hub-topbar__actions .hub-btn { min-width: 40px; }
  .hub-topbar__actions > .hub-topbar__act:not(.hub-topbar__act--text):not(:has(.hub-btn__short)), .hub-topbar__more { width: 40px; padding: 0; }
  .hub-topbar__actions > .hub-topbar__act:has(.hub-btn__short) { padding: 0 10px; }
  .hub-topbar__actions > .hub-btn.hub-topbar__act--text:not(.hub-btn--icon) .hub-btn__label { display: inline; }   /* 아이콘 없는 동작은 글자를 숨기면 빈 버튼이 됨 */
  .hub-topbar__right, .hub-topbar__actions { gap: 4px; }
  .hub-app[data-sec] .hub-topbar__title-wrap { padding-left: 8px; }
  .hub-page__head { align-items: flex-start; flex-direction: column; gap: 8px; }
  .hub-page__actions { width: 100%; }
  .hub-page__actions .hub-btn { flex: 1 1 auto; }
  .hub-stat-grid, .hub-stat-grid--3, .hub-stat-grid--4, .hub-stat-grid--5 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .hub-kpi { padding: 10px 12px; }
  .hub-kpi__value { font-size: var(--hub-fs-xl); }
  .hub-grid--2, .hub-grid--3, .hub-grid--4, .hub-grid--auto, .hub-card-grid, .hub-card-grid--2, .hub-card-grid--3,
  .hub-form-grid, .hub-form-grid--2, .hub-form-grid--3, .hub-form-grid--4 { grid-template-columns: minmax(0, 1fr); }
  .hub-form-grid .span-2, .hub-card-grid .span-2 { grid-column: auto; }
  .hub-kv { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .hub-kv dt { margin-top: 6px; font-size: var(--hub-fs-xs); }
  .hub-kv dt:first-child { margin-top: 0; }
  .hub-kv--lined dt { border-bottom: 0; padding-bottom: 0; }
  .hub-filterbar { padding: 8px 10px; gap: 8px; }
  .hub-filterbar .hub-field { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .hub-filterbar .hub-input, .hub-filterbar .hub-select { width: 100%; min-width: 0; flex: 1; }
  .hub-filterbar .hub-search { flex-basis: 100%; }
  .hub-filterbar__end { margin-left: 0; width: 100%; }
  .hub-filterbar__end .hub-btn { flex: 1; }
  .hub-toolbar .hub-toolbar__sep { display: none; }
  .hub-launch { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hub-hide-mobile { display: none !important; }
  .hub-only-mobile { display: initial; }

  /* 모달 → 바텀 시트 */
  .hub-modal { align-items: flex-end; padding: 0; }
  .hub-modal__card, .hub-modal__card--sm, .hub-modal__card--lg, .hub-modal__card--xl {
    max-width: none; max-height: 92dvh; border-radius: 16px 16px 0 0; border: 0;
    padding-bottom: var(--hub-safe-bottom); animation: hub-slide-up var(--hub-dur-slow) var(--hub-ease);
  }
  .hub-modal__card--full, .hub-modal--full .hub-modal__card { max-height: none; height: 100dvh; border-radius: 0; }
  .hub-modal__foot { position: sticky; bottom: 0; }
  .hub-modal__foot .hub-btn { flex: 1 1 auto; }
  .hub-modal__foot .hub-modal__foot-left, .hub-modal__foot .hub-grow { flex: 0 0 100%; margin-right: 0; order: 2; }

  /* 표 → 카드 (hub-table--keep 은 표 유지 + 가로 스크롤) */
  .hub-table:not(.hub-table--keep) { font-size: var(--hub-fs-md); }
  .hub-table:not(.hub-table--keep) thead { display: none; }
  .hub-table:not(.hub-table--keep), .hub-table:not(.hub-table--keep) tbody,
  .hub-table:not(.hub-table--keep) tr, .hub-table:not(.hub-table--keep) td { display: block; width: 100%; }
  .hub-table:not(.hub-table--keep) tfoot { display: block; }
  .hub-table:not(.hub-table--keep) tfoot tr { display: block; }
  .hub-table:not(.hub-table--keep) tbody tr { padding: 10px 12px; border-bottom: 1px solid var(--hub-border); }
  .hub-table:not(.hub-table--keep) tbody tr:last-child { border-bottom: 0; }
  .hub-table:not(.hub-table--keep) tbody tr:hover td { background: transparent; }
  .hub-table:not(.hub-table--keep) tbody tr:hover { background: var(--hub-surface-2); }
  .hub-table:not(.hub-table--keep) tbody tr.is-selected { background: var(--hub-accent-tint); }
  .hub-table:not(.hub-table--keep) tbody tr.is-selected td { background: transparent; }
  .hub-table:not(.hub-table--keep).hub-table--striped tbody tr:nth-child(even) td { background: transparent; }
  .hub-table:not(.hub-table--keep).hub-table--striped tbody tr:nth-child(even):not(.is-selected):not(.is-warn):not(.is-danger):not(.is-total):not(.hub-table__skelrow):not(.hub-table__emptyrow) { background: var(--hub-table-stripe); }
  .hub-table:not(.hub-table--keep) tbody tr.is-warn { background: var(--hub-warn-soft); }
  .hub-table:not(.hub-table--keep) tbody tr.is-danger { background: var(--hub-bad-soft); }
  /* 빨간 행 위 보조 글자: text-3 는 bad-soft(#fee2e2) 위 4.47:1 로 AA 미달 → text-2(6.19:1) */
  .hub-table:not(.hub-table--keep) tbody tr.is-danger :is(.hub-mrow__sub, .hub-mrow__end-sub, .hub-mline__k, td.hub-card-subtitle, td.is-card-subtitle),
  .hub-table:not(.hub-table--keep) tbody tr.is-danger td[data-th]::before { color: var(--hub-text-2); }
  .hub-table:not(.hub-table--keep) tbody tr.is-total { background: var(--hub-table-head-bg); }
  .hub-table:not(.hub-table--keep) tbody tr.is-warn td, .hub-table:not(.hub-table--keep) tbody tr.is-danger td,
  .hub-table:not(.hub-table--keep) tbody tr.is-total td { background: transparent; }
  .hub-table:not(.hub-table--keep).hub-table--striped tbody tr.is-clickable:hover { background: var(--hub-table-hover); }
  .hub-table:not(.hub-table--keep) td {
    height: auto; min-height: 0; padding: 3px 0; border: 0;
    display: flex; justify-content: space-between; align-items: baseline; gap: 12px; text-align: right;
  }
  .hub-table:not(.hub-table--keep) td[data-th]::before {
    content: attr(data-th); flex: none; color: var(--hub-text-3); font-size: var(--hub-fs-sm); font-weight: 500; text-align: left;
    min-width: 72px;
  }
  .hub-table:not(.hub-table--keep) td:not([data-th]) { justify-content: flex-start; text-align: left; }
  .hub-table:not(.hub-table--keep) td[data-th=""]::before { content: none; }
  .hub-table:not(.hub-table--keep) td.num { text-align: right; }
  .hub-table:not(.hub-table--keep) td.hub-card-title, .hub-table:not(.hub-table--keep) td.is-card-title {
    display: block; text-align: left; font-weight: 600; font-size: var(--hub-fs-lg); padding-bottom: 4px;
  }
  .hub-table:not(.hub-table--keep) td.hub-card-title::before, .hub-table:not(.hub-table--keep) td.is-card-title::before { content: none; }
  .hub-table:not(.hub-table--keep) td.hub-card-subtitle, .hub-table:not(.hub-table--keep) td.is-card-subtitle { display: block; text-align: left; color: var(--hub-text-3); font-size: var(--hub-fs-sm); padding-top: 0; }
  .hub-table:not(.hub-table--keep) td.hub-card-subtitle::before, .hub-table:not(.hub-table--keep) td.is-card-subtitle::before { content: none; }
  .hub-table:not(.hub-table--keep) td.hub-table__cardhead { display: block; text-align: left; padding: 0 0 4px; }
  .hub-table:not(.hub-table--keep) td.hub-table__cardhead::before { content: none; }
  .hub-table:not(.hub-table--keep) tr.hub-table__emptyrow, .hub-table:not(.hub-table--keep) tr.hub-table__skelrow { padding: 0; }
  .hub-table:not(.hub-table--keep) tr.hub-table__emptyrow td { display: block; padding: 0; }
  .hub-table:not(.hub-table--keep) td.check { display: none; }
  .hub-table:not(.hub-table--keep) td.actions { justify-content: flex-end; padding-top: 6px; }
  .hub-table:not(.hub-table--keep) td.actions::before { content: none; }
  .hub-table:not(.hub-table--keep) td.is-hide-mobile, .hub-table:not(.hub-table--keep) td.hub-hide-mobile { display: none; }
  .hub-table:not(.hub-table--keep) td .hub-truncate { display: inline-block; max-width: 60vw; vertical-align: bottom; }
  .hub-table:not(.hub-table--keep) tbody tr.is-total td, .hub-table:not(.hub-table--keep) tfoot td { position: static; background: transparent; border-top: 0; }
  .hub-table:not(.hub-table--keep) tbody tr.is-total, .hub-table:not(.hub-table--keep) tfoot { background: var(--hub-surface-2); padding: 8px 12px; }
  .hub-table:not(.hub-table--keep) .hub-table__state td { display: block; padding: 0; }
  .hub-table:not(.hub-table--keep) .hub-row-actions { opacity: 1; }
  .hub-table-wrap.hub-table-wrap--fill { --hub-table-max: none; }
  /* 페이저 한 줄: ‹ 이전 · 3 / 35 · 다음 › [50개씩] — 쪽 번호 버튼·'총 N건' 안내는 숨김(1쪽뿐이면 '총 N건' 만).
     .has-nav(table.js fillPager) 또는 :has() 로 판정 — 손으로 만든 페이저도 같은 클래스면 자동 */
  .hub-pager { justify-content: center; flex-wrap: wrap; gap: 4px 8px; padding: 6px 8px; }
  .hub-pager__info { width: auto; text-align: center; }
  .hub-pager.has-nav > .hub-pager__info, .hub-pager:has(> .hub-pager__nav) > .hub-pager__info,
  .hub-pager:has(> .hub-pager__btns) > .hub-pager__info { display: none; }
  .hub-pager__pages { display: none; }
  .hub-pager__btns, .hub-pager__nav { margin: 0; justify-content: center; flex-wrap: nowrap; gap: 0; }
  .hub-pager__count { padding: 0; font-size: var(--hub-fs-md); font-weight: 600; color: var(--hub-text-2); }
  .hub-pager__nav > .hub-pager__count::before, .hub-pager__nav > .hub-pager__count::after { content: "·"; margin: 0 6px; font-weight: 400; color: var(--hub-text-4); }
  .hub-pager__tools { width: auto; justify-content: center; }
}
/* .hub-table--cards 는 "카드 제목 셀이 있음" 표시(table.js) — 카드 전환 자체는 <600 자동 규칙이 담당.
   폭과 무관하게 강제 카드 모드가 필요하면 .hub-table--cards-always */
.hub-table--cards-always thead { display: none; }
.hub-table--cards-always, .hub-table--cards-always tbody, .hub-table--cards-always tr, .hub-table--cards-always td { display: block; width: 100%; }
.hub-table--cards-always tbody tr { padding: 10px 12px; border-bottom: 1px solid var(--hub-border); }
.hub-table--cards-always tbody tr:last-child { border-bottom: 0; }
.hub-table--cards-always td { height: auto; padding: 3px 0; border: 0; display: flex; justify-content: space-between; gap: 12px; text-align: right; }
.hub-table--cards-always td[data-th]::before { content: attr(data-th); color: var(--hub-text-3); font-size: var(--hub-fs-sm); text-align: left; min-width: 72px; }
.hub-table--cards-always td.hub-card-title, .hub-table--cards-always td.hub-table__cardhead { display: block; text-align: left; font-weight: 600; font-size: var(--hub-fs-lg); }
.hub-table--cards-always td.hub-card-title::before, .hub-table--cards-always td.hub-table__cardhead::before { content: none; }
.hub-table--cards-always tbody tr:hover td { background: transparent; }
.hub-table--cards-always td[hidden] { display: none; }

/* 자기 안에서만 가로 스크롤(긴 툴바·칩·탭 줄 — 페이지 전체가 옆으로 밀리지 않게) */
.hub-scroll-x { max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.hub-scroll-x::-webkit-scrollbar { display: none; }
.hub-toolbar--scroll { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.hub-toolbar--scroll::-webkit-scrollbar { display: none; }
.hub-toolbar--scroll > * { flex: none; }

/* < 900: 하단 고정 바 기준선(하단 탭 + 안전 영역) */
@media (max-width: 899.98px) {
  :root { --hub-bottom-ui: calc(var(--hub-bottomnav-h) + var(--hub-safe-bottom)); }
}

/* iOS·iPadOS 는 16px 미만 입력칸에 포커스하면 화면을 확대함 — 휴대폰(<600)과 터치 기기(pointer: coarse — iPad 등, 폭 무관).
   마우스 기기(600 이상)는 그대로. 리치 편집칸([contenteditable])은 페이지 CSS(.pur-memo-body 13px 등)보다 우선하도록 :root 로 특이성 올림.
   페이지가 휴대폰에서 입력칸을 16px 보다 작게 덮어쓰면 안 됨(큰 글자 입력칸 — 스캔 입력 등 — 은 그대로 둠) */
@media (max-width: 599.98px), (pointer: coarse) {
  .hub-input, .hub-input--sm, .hub-input--lg, .hub-select, .hub-select--sm, .hub-textarea, .hub-pager .hub-select,
  :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="button"], [type="submit"], [type="reset"], [type="image"]), select, textarea) { font-size: 16px; }
  :root [contenteditable="true"], :root [contenteditable=""], :root [contenteditable="plaintext-only"] { font-size: 16px; }
}
/* < 600: 휴대폰 위생(전역) — 탭 타깃 40px+·큰 모달 전체 높이·가로 넘침 방어 */
@media (max-width: 599.98px) {
  /* 탭 타깃 40px 이상(칩 버튼·표 행 아이콘 버튼 — <900 의 36px 예외를 휴대폰에선 올림) */
  .hub-chip--btn, button.hub-chip, a.hub-chip { min-height: 40px; }
  .hub-table .hub-row-actions .hub-btn { min-height: 40px; min-width: 40px; }
  /* 기간·보기 세그먼트(1년/2년·이번 달) — 짧은 글자도 폭 40px 이상. min-width 를 주면 flex 의 '글자 폭 아래로는 안 줄어듦'(auto)이
     사라져 버튼이 글자보다 좁아지며 겹치므로 줄지 않게(flex-shrink 0) — 칸이 모자라면 .hub-seg 안에서 가로 스크롤(전과 같음) */
  .hub-seg__btn, .hub-seg > button, .hub-seg > a { min-width: 40px; flex-shrink: 0; }
  /* 꽉 채우는 세그먼트(--block, 칸을 나눠 가짐)는 줄어들 수 있게 두되 글자 폭 아래로는 안 줄어듦 */
  .hub-seg--block > :is(.hub-seg__btn, button, a) { flex-shrink: 1; min-width: max-content; }
  /* 단독 링크(카드 머리·바닥·툴바·버튼 줄 안 · .hub-link--tap)와 링크 모양 버튼은 높이 40px 로(문장 속·목록 행 안의 링크는 그대로) */
  .hub-btn--link:not(:is(.hub-mrow, .hub-mtitle, .hub-md, p) *) { min-height: 40px; }
  :is(.hub-card__head, .hub-card__actions, .hub-card__foot, .hub-toolbar, .hub-filterbar, .hub-filterbar__end, .hub-page__actions, .hub-form-actions, .hub-empty, .hub-section) > .hub-link,
  .hub-link.hub-link--tap { display: inline-flex; align-items: center; min-height: 40px; }
  /* 그 밖의 링크(문장 속 등)는 모양·줄 높이는 그대로 두고 누르는 영역만 위아래로 넓힘(목록 행 안은 제외 — 행 탭을 가로채지 않게) */
  :where(.hub-link):not(:is(.hub-mrow, .hub-mtitle, .hub-link--tap) *):not(.hub-link--tap) { position: relative; }
  :where(.hub-link):not(:is(.hub-mrow, .hub-mtitle, .hub-link--tap) *):not(.hub-link--tap)::after {
    content: ""; position: absolute; left: 50%; top: 50%; width: max(calc(100% + 4px), 40px); height: 40px; transform: translate(-50%, -50%);
  }
  /* 접기·펼치기(details > summary) — 줄 높이 40px, 글자는 세로 가운데 */
  :where(summary) { min-height: 40px; align-content: center; }
  /* 큰 모달(lg·xl)은 시트 대신 전체 높이 — 머리(닫기)는 늘 위에, 본문만 스크롤 */
  .hub-modal__card--lg, .hub-modal__card--xl, .hub-modal--lg .hub-modal__card, .hub-modal--xl .hub-modal__card {
    height: 100dvh; max-height: 100dvh; border-radius: 0; padding-top: var(--hub-safe-top);
  }
  .hub-modal__head { position: sticky; top: 0; z-index: 1; background: var(--hub-surface); }
  /* 숫자는 고정폭(자릿수 정렬) */
  .hub-table td.num, .hub-mrow__end, .hub-kpi__value, .hub-pager__info { font-variant-numeric: tabular-nums; }
  /* 페이지가 옆으로 밀리지 않게(마지막 방어선 — 넓은 표는 hub-table--keep 래퍼 안에서 가로 스크롤) */
  .hub-main { overflow-x: clip; }
  /* 페이저: 혹시 넘치면 그 안에서 가로 스크롤(한 줄 규칙은 위 <600 블록) */
  .hub-pager__nav, .hub-pager__btns { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .hub-pager__nav::-webkit-scrollbar, .hub-pager__btns::-webkit-scrollbar { display: none; }
}

@media (min-width: 600px) { .hub-only-mobile { display: none !important; } }
@media (min-width: 900px) { .hub-only-tablet-down { display: none !important; } .hub-scrim.is-open { display: none; } }

/* --------------------------------------------------------------------------
   11. 인쇄
   -------------------------------------------------------------------------- */
@media print {
  @page { margin: 12mm 14mm; }
  html, body, .hub-body { background: #fff !important; color: #000 !important; }
  .hub-sidebar, .hub-topbar, .hub-bottomnav, .hub-scrim, .hub-toast-host, .hub-skip, .hub-drawer, .hub-menu, .hub-tooltip,
  .hub-print-hide, .hub-page__actions, .hub-headacts, .hub-filterbar, .hub-pager, .hub-sticky-foot, .hub-row-actions, .hub-tabs--menu, .hub-backbtn { display: none !important; }
  .hub-print-only { display: initial !important; }
  .hub-app, .hub-app.is-rail { display: block; min-height: 0; }
  .hub-shell-main { min-height: 0; }
  .hub-main { padding: 0 !important; }
  .hub-card, .hub-kpi, .hub-table-wrap, .hub-lcard { break-inside: avoid; box-shadow: none !important; border-color: #999 !important; }
  .hub-lcard--good, .hub-lcard--warn, .hub-lcard--info, .hub-lcard--bad, .hub-lcard--neutral { border-left: 4px solid var(--lcard-stripe) !important; }   /* 그림자를 끄는 대신 상태 줄을 테두리로 */
  .hub-table-wrap { overflow: visible !important; max-height: none !important; }
  .hub-table th, .hub-table tfoot td { position: static !important; background: #f0f0f0 !important; color: #000 !important; }
  .hub-table td, .hub-table th { border-color: #999 !important; }
  .hub-table tr { break-inside: avoid; }
  .hub-table thead { display: table-header-group; }
  a { color: inherit !important; text-decoration: none !important; }
  .hub-modal, .hub-sheet { position: static !important; background: transparent !important; padding: 0 !important; }
  .hub-modal__card { max-height: none !important; box-shadow: none !important; }
  .hub-modal__foot { display: none !important; }
}
