/* ============================================================
 * SmartCS 组件类（纯 CSS，零 JS 依赖）
 * 依赖 tokens.css / base.css
 * ============================================================ */

/* ==================== 图标（配合 index.html 雪碧图 <use>） ==================== */
.icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.icon--sm { width: 16px; height: 16px; }
.icon--lg { width: 20px; height: 20px; }

/* ==================== 路由切换内容区入场（app.js 挂载后添加 .page-enter） ==================== */
.page-enter {
  animation: page-enter var(--dur-page) var(--ease-out) both;
}
@keyframes page-enter {
  from { opacity: 0; transform: translateY(12px); }
}

/* ==================== 按钮 ==================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 32px;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* active 态轻微缩放（所有变体统一） */
.btn:active:not(:disabled) { transform: scale(0.97); }

.btn--primary {
  background: var(--color-accent);
  color: var(--color-accent-text);
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover:not(:disabled) { background: var(--color-accent-hover); }
.btn--primary:active:not(:disabled) { background: var(--color-accent-active); }

.btn--secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border);
  box-shadow: var(--shadow-sm);
}
.btn--secondary:hover:not(:disabled) { background: var(--color-surface-2); }
.btn--secondary:active:not(:disabled) { background: var(--color-border); }

.btn--ghost {
  background: transparent;
  color: var(--color-text-2);
}
.btn--ghost:hover:not(:disabled) {
  background: var(--color-surface-2);
  color: var(--color-text);
}
.btn--ghost:active:not(:disabled) { background: var(--color-border); }

.btn--danger {
  background: var(--color-danger);
  color: var(--color-accent-text);
}
.btn--danger:hover:not(:disabled) { background: var(--color-danger-soft); color: var(--color-danger); }
.btn--danger:active:not(:disabled) { background: var(--color-danger); color: var(--color-accent-text); }

/* 尺寸变体 */
.btn--sm { height: 26px; padding: 0 var(--space-2); font-size: var(--text-xs); border-radius: var(--radius-sm); }
.btn--lg { height: 38px; padding: 0 var(--space-5); font-size: var(--text-base); }

/* 图标按钮 */
.btn--icon { width: 32px; padding: 0; }
.btn--icon.btn--sm { width: 26px; }

/* 加载态：转圈 */
.btn.is-loading { pointer-events: none; opacity: 0.7; }
.btn.is-loading .btn__spinner {
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--radius-full);
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ==================== 表单控件 ==================== */
.input,
.textarea,
.select {
  width: 100%;
  padding: 0 var(--space-3);
  height: 34px;
  font-size: var(--text-base);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.textarea {
  height: auto;
  min-height: 72px;
  padding: var(--space-2) var(--space-3);
  resize: vertical;
  line-height: var(--leading-normal);
}

.input::placeholder,
.textarea::placeholder { color: var(--color-text-3); }

.input:hover:not(:disabled),
.textarea:hover:not(:disabled),
.select:hover:not(:disabled) { border-color: var(--color-border-strong); }

/* 统一焦点环：accent 边框 + 2px accent-soft 外发光（--shadow-focus） */
.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
}

.input:disabled,
.textarea:disabled,
.select:disabled {
  background: var(--color-surface-2);
  color: var(--color-text-3);
  cursor: not-allowed;
}

.field { display: flex; flex-direction: column; gap: var(--space-1); }
.field__label { font-size: var(--text-sm); font-weight: 500; color: var(--color-text-2); }
.field__hint  { font-size: var(--text-xs); color: var(--color-text-3); }

/* ==================== 卡片 ==================== */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.card__title { font-size: var(--text-base); font-weight: 600; }
.card__body  { padding: var(--space-4); }
.card--flush .card__body { padding: 0; }

/* hover 提升：需要交互反馈的卡片加 .card--hoverable */
.card--hoverable {
  transition: box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.card--hoverable:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

/* ==================== 表格 ==================== */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.table th {
  text-align: left;
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--color-text-3);
  background: var(--color-surface-2);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text);
  vertical-align: middle;
}

.table tbody tr { transition: background var(--dur-fast) var(--ease-out); }
.table tbody tr:hover { background: var(--color-surface-2); }
.table tbody tr:last-child td { border-bottom: none; }

/* 斑马纹变体：偶数行铺页面底色，hover 仍统一为 surface-2 */
.table--zebra tbody tr:nth-child(even) { background: var(--color-bg); }
.table--zebra tbody tr:nth-child(even):hover { background: var(--color-surface-2); }

/* 行选中态 */
.table tbody tr.is-selected { background: var(--color-accent-soft); }
.table tbody tr.is-selected:hover { background: var(--color-accent-soft); }

/* 表格横向滚动容器（窄屏下表格不挤压，改为横向滚动） */
.table-scroll { overflow-x: auto; }
.table-scroll .table { min-width: 720px; }

/* ==================== Badge ==================== */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 1px var(--space-2);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 18px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}

.badge--pending { background: var(--color-surface-2); color: var(--color-text-2); }
.badge--info    { background: var(--color-info-soft);    color: var(--color-info); }
.badge--success { background: var(--color-success-soft); color: var(--color-success); }
.badge--warning { background: var(--color-warning-soft); color: var(--color-warning); }
.badge--danger  { background: var(--color-danger-soft);  color: var(--color-danger); }

/* 小圆点 */
.badge__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
}

/* ==================== Modal ==================== */
.modal-mask {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: var(--color-mask);
  animation: fade-in var(--dur-base) var(--ease-out);
}

.modal {
  width: min(480px, calc(100vw - var(--space-8)));
  max-height: calc(100vh - var(--space-8));
  overflow-y: auto;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: pop-in var(--dur-base) var(--ease-out);
}

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.modal__title { font-size: var(--text-md); font-weight: 600; }
.modal__body  { padding: var(--space-5); color: var(--color-text-2); font-size: var(--text-sm); }
.modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
}

/* 出场动画：JS 在移除 DOM 前给 mask 加 .is-leaving（scale + fade） */
.modal-mask.is-leaving {
  animation: fade-out var(--dur-base) var(--ease-out) both;
  pointer-events: none;
}
.modal-mask.is-leaving .modal {
  animation: pop-out var(--dur-base) var(--ease-out) both;
}

@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes pop-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
}
@keyframes pop-out {
  to { opacity: 0; transform: translateY(8px) scale(0.98); }
}

/* ==================== Toast ==================== */
.toast-wrap {
  position: fixed;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 240px;
  max-width: 360px;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  animation: toast-in var(--dur-slow) var(--ease-out);
}

.toast--success { border-left-color: var(--color-success); }
.toast--warning { border-left-color: var(--color-warning); }
.toast--danger  { border-left-color: var(--color-danger); }

.toast.is-leaving {
  animation: toast-out var(--dur-base) var(--ease-out) both;
  pointer-events: none;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(16px); }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateX(12px); }
}

/* ==================== EmptyState ==================== */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-16) var(--space-6);
  text-align: center;
  color: var(--color-text-3);
}

/* 图标槽位：小图标（48px 圆角底） */
.empty-state__icon {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  color: var(--color-text-3);
}

/* 图标槽位：线条插图（大尺寸、无底色，引用雪碧图 #illus-*） */
.empty-state__icon--lg {
  width: auto;
  height: auto;
  padding: var(--space-2);
  background: transparent;
  color: var(--color-border-strong);
}
.empty-state__icon--lg svg { opacity: 0.9; }

.empty-state__title { font-size: var(--text-md); font-weight: 600; color: var(--color-text-2); }
.empty-state__desc  { font-size: var(--text-sm); max-width: 360px; }

/* ==================== Skeleton ==================== */
.skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
}

/* 微光扫过（shimmer）：斜向高光带自左向右循环 */
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    transparent 20%,
    var(--color-surface) 50%,
    transparent 80%);
  transform: translateX(-100%);
  animation: shimmer 1.4s var(--ease-out) infinite;
}

.skeleton--text { height: 14px; margin: var(--space-1) 0; }
.skeleton--row  { height: 44px; border-radius: var(--radius-md); }
.skeleton--circle { width: 32px; height: 32px; border-radius: var(--radius-full); }
.skeleton--block { height: 120px; border-radius: var(--radius-md); }

@keyframes shimmer {
  to { transform: translateX(100%); }
}

/* ==================== 侧栏导航 ==================== */
.sidebar {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  box-shadow: var(--shadow-edge-r);
  transition: width var(--dur-base) var(--ease-out);
  overflow: hidden;
}

.sidebar.is-collapsed { width: var(--sidebar-width-collapsed); }

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--topbar-height);
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-weight: 600;
  font-size: var(--text-base);
  white-space: nowrap;
}

.sidebar__nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-2);
  overflow-y: auto;
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-3);
  height: 34px;
  border-radius: var(--radius-md);
  color: var(--color-text-2);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.nav-item:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
  text-decoration: none;
}

.nav-item:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

.nav-item.is-active {
  background: var(--color-accent-soft);
  color: var(--color-accent);
}

/* 激活项左侧 3px accent 指示条（贴侧栏左缘） */
.nav-item.is-active::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-2));
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 16px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
}

.nav-item__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.nav-item__label { flex: 1; overflow: hidden; text-overflow: ellipsis; }

.sidebar.is-collapsed .nav-item__label,
.sidebar.is-collapsed .sidebar__brand-text { display: none; }

/* 移动端侧栏遮罩（≤960px 侧栏变为抽屉时使用） */
.sidebar-mask {
  position: fixed;
  inset: 0;
  z-index: 105;
  background: var(--color-mask-light);
  animation: fade-in var(--dur-base) var(--ease-out);
}

/* ==================== 顶栏 ==================== */
.topbar {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--topbar-height);
  padding: 0 var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-edge-b);
  flex-shrink: 0;
}

.topbar__title { font-size: var(--text-md); font-weight: 600; }
.topbar__crumb { font-size: var(--text-sm); color: var(--color-text-3); }

/* 顶栏用户徽标（管理员登录态） */
.topbar__user {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.topbar__user.hidden { display: none; }
.topbar__user-name {
  font-size: var(--text-sm);
  color: var(--color-text-2);
  padding: 2px 10px;
  background: var(--color-accent-soft);
  color: var(--color-accent);
  border-radius: var(--radius-full);
  font-weight: 500;
}

/* 汉堡按钮：仅窄屏显示（与 app.js 的移动端侧栏开关联动） */
.topbar__toggle { display: none; flex-shrink: 0; }

/* ==================== 抽屉 Drawer ==================== */
.drawer-mask {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--color-mask-light);
  animation: fade-in var(--dur-base) var(--ease-out);
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 95;
  width: min(420px, 90vw);
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-left: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  animation: drawer-in var(--dur-slow) var(--ease-out);
}

.drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.drawer__title { font-size: var(--text-md); font-weight: 600; }
.drawer__body  { flex: 1; overflow-y: auto; padding: var(--space-5); }
.drawer__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
}

/* 出场动画：JS 在移除 DOM 前给 mask / drawer 加 .is-leaving */
.drawer-mask.is-leaving {
  animation: fade-out var(--dur-base) var(--ease-out) both;
  pointer-events: none;
}
.drawer.is-leaving {
  animation: drawer-out var(--dur-base) var(--ease-out) both;
  pointer-events: none;
}

@keyframes drawer-in {
  from { transform: translateX(100%); }
}
@keyframes drawer-out {
  to { transform: translateX(100%); }
}

/* ==================== 进度条 ==================== */
.progress {
  width: 100%;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-surface-2);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  transition: width var(--dur-base) var(--ease-out);
}

.progress__bar--success { background: var(--color-success); }

/* ==================== Chips ==================== */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  cursor: pointer;
  user-select: none;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.chip:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.chip:active:not(:disabled) { transform: scale(0.97); }

.chip:focus-visible {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
}

.chip:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.chip.is-selected {
  background: var(--color-accent-soft);
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ============================================================
 * 响应式断点
 * ≤960px：侧栏转为抽屉式覆盖层（汉堡按钮切换），顶栏收窄
 * ≤640px：Modal / Drawer / Toast / EmptyState 全宽自适应
 * ============================================================ */
@media (max-width: 960px) {
  .topbar { padding: 0 var(--space-3); gap: var(--space-2); }
  .topbar__toggle { display: inline-flex; }
  .topbar__crumb { display: none; }

  /* 侧栏：脱离文档流，默认左移出屏，is-open 时滑入 */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 110;
    width: var(--sidebar-width);
    transform: translateX(-100%);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .sidebar.is-open {
    width: var(--sidebar-width);
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }

  /* 抽屉展开时忽略桌面端的折叠态，完整显示文字 */
  .sidebar.is-open .nav-item__label,
  .sidebar.is-open .sidebar__brand-text { display: block; }

  /* 桌面端的折叠按钮在移动端无意义，隐藏 */
  #btn-collapse { display: none; }

  /* 表格窄屏横向滚动兜底（未包 .table-scroll 的表格） */
  .card--flush { overflow-x: auto; }
}

@media (max-width: 640px) {
  .modal-mask { padding: var(--space-3); }
  .modal { width: 100%; max-height: calc(100vh - var(--space-6)); }
  .modal__header { padding: var(--space-3) var(--space-4); }
  .modal__body { padding: var(--space-4); }
  .modal__footer { padding: var(--space-3) var(--space-4); }

  .drawer { width: 100vw; }
  .drawer__header { padding: var(--space-3) var(--space-4); }
  .drawer__body { padding: var(--space-4); }
  .drawer__footer { padding: var(--space-3) var(--space-4); }

  .toast-wrap {
    left: var(--space-4);
    right: var(--space-4);
  }
  .toast { min-width: 0; max-width: none; width: 100%; }

  .empty-state { padding: var(--space-10) var(--space-4); }
}
