/* ==========================================================================
   全站设计系统 · static/css/ui.css（单文件 · 自包含）
   --------------------------------------------------------------------------
   本文件已内联全部 Design Token（原 tokens.css），不再依赖任何外部变量文件。
   所有类均为新增 .ui-* 命名空间，不会与既有 .card / .btn / .m-* 冲突。

   加载顺序：bootstrap / style.min.css / m.css（主题层） → 本文件 → glass.css → 页面内联 <style>
   因本文件自带 :root，只要本文件加载成功，全站配色与组件即完整，不存在“变量未定义”。

   组件清单：
     .ui-card          统一卡片（含 head / body / title）
     .ui-stat-card     统计卡（--accent 控制强调色，带图标底 + 数值 + 标签）
     .ui-empty         空状态（图标 + 标题 + 描述 + CTA）
     .ui-badge         状态徽章（ok/warn/danger/info/muted/vip）
     .is-loading       按钮加载态（内联 spinner，保留原文本）
     .ui-skeleton      骨架屏
     .ui-toolbar       筛选工具栏（.ui-chip 选中态 0.15s 过渡）
     .ui-marquee       滚动公告（PC / 移动端共用，替代两套装实现）
     .ui-info-list     图标条目列表
     :focus-visible    抢回被主题 outline:none !important 禁用的键盘焦点环
   ========================================================================== */

/* ==========================================================================
   Design Token · 全站设计变量（内联，原 tokens.css）
   --------------------------------------------------------------------------
   配色规范：
     · 青绿 --brand-500 → --brand-green   = 产品唯一主色，三端通用
     · 紫色 --vip-500   → --vip-600       = 会员 / 付费 / 等级专属语义色
       「看到紫 = 权益」，除会员卡、等级徽章、充值入口外一律不得使用
   ========================================================================== */
:root {
  /* ---------- 品牌主色（青绿） ---------- */
  --brand-500: #00bde9;
  --brand-600: #0098b8;
  --brand-700: #007a94;
  --brand-green: #7ed957;
  --brand-green-d: #4faa2c;
  --brand-gradient: linear-gradient(135deg, #00bde9 0%, #7ed957 100%);
  --brand-gradient-soft: linear-gradient(135deg, rgba(0, 189, 233, .12) 0%, rgba(126, 217, 87, .12) 100%);
  --brand-ring: rgba(0, 189, 233, .35);
  --brand-a08: rgba(0, 189, 233, .08);
  --brand-a12: rgba(0, 189, 233, .12);
  --brand-a18: rgba(0, 189, 233, .18);
  --brand-a28: rgba(0, 189, 233, .28);

  /* ---------- 会员 / 付费专属（紫） ---------- */
  --vip-500: #667eea;
  --vip-600: #764ba2;
  --vip-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  --vip-a18: rgba(102, 126, 234, .18);
  --vip-a35: rgba(102, 126, 234, .35);

  /* ---------- 语义功能色 ---------- */
  --c-ok: #16a34a;
  --c-ok-bg: #e8f5e9;
  --c-warn: #f59e0b;
  --c-warn-bg: #fff8e1;
  --c-danger: #ef4444;
  --c-danger-bg: #fdecea;
  --c-info: #0284c7;
  --c-info-bg: #e3f2fd;
  --c-muted: #8e8e93;
  --c-muted-bg: #f0f2f5;

  /* ---------- 文字 ---------- */
  --text-1: #1f2937;
  --text-2: #6b7280;
  --text-3: #9ca3af;
  --text-inv: #ffffff;

  /* ---------- 面与描边 ---------- */
  --surface: #ffffff;
  --surface-2: #f6f9fc;
  --surface-3: #eef3f8;
  --line: #e6ecf3;
  --line-2: #d7e0ea;

  /* ---------- 圆角 ---------- */
  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-pill: 999px;

  /* ---------- 阴影 ---------- */
  --sh-1: 0 2px 12px rgba(15, 23, 42, .06);
  --sh-2: 0 6px 24px rgba(15, 23, 42, .09);
  --sh-3: 0 12px 36px rgba(15, 23, 42, .14);
  --sh-brand: 0 6px 18px rgba(0, 189, 233, .28);
  --sh-vip: 0 6px 24px rgba(102, 126, 234, .35);

  /* ---------- 间距 ---------- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* ---------- 字号 ---------- */
  --fs-xs: 12px;
  --fs-sm: 13px;
  --fs-md: 14px;
  --fs-lg: 16px;
  --fs-xl: 20px;
  --fs-2xl: 26px;

  /* ---------- 动效 ---------- */
  --dur-fast: .15s;
  --dur: .25s;
  --dur-slow: .4s;
  --ease-out: cubic-bezier(.22, .61, .36, 1);

  /* ---------- 对齐 Bootstrap / Light Year 主题变量 ----------
     让 .btn-primary / .text-primary / .badge / 链接等组件自动统一到品牌色。
     必须在 style.min.css 之后加载才会生效。 */
  --bs-primary: var(--brand-500);
  --bs-primary-rgb: 0, 189, 233;
  --bs-link-color: var(--brand-600);
  --bs-link-hover-color: var(--brand-500);
  --bs-body-bg: #eef7fd;
  --bs-body-color: var(--text-1);
}

/* ---------- 键盘焦点环 ----------
   style.min.css 用 !important 全局禁用了 outline，只能在后加载的样式里抢回。
   限定 :focus-visible —— 鼠标点击不显示，键盘 Tab 才显示。 */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
  outline: 2px solid var(--brand-500, #00bde9) !important;
  outline-offset: 2px;
}

/* ---------- 卡片 ---------- */
.ui-card {
  background: var(--surface, #ffffff);
  border: 1px solid var(--line, #dbe3ec);
  border-radius: var(--r-lg, 16px);
  box-shadow: var(--sh-1, 0 4px 16px rgba(15, 23, 42, .08));
  overflow: hidden;
}
.ui-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2, 8px);
  padding: var(--sp-4, 16px) var(--sp-4, 16px) var(--sp-2, 8px);
}
.ui-card__title {
  margin: 0;
  font-size: var(--fs-lg, 16px);
  font-weight: 600;
  color: var(--text-1, #1f2937);
  display: flex;
  align-items: center;
  gap: var(--sp-2, 8px);
}
.ui-card__title i { color: var(--brand-500, #00bde9); font-size: 19px; }
.ui-card__body { padding: 0 var(--sp-4, 16px) var(--sp-4, 16px); }

/* ---------- 统计卡 ---------- */
.ui-stat-card {
  --accent: var(--brand-500, #00bde9);
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3, 12px);
  padding: var(--sp-4, 16px);
  border-radius: var(--r-lg, 16px);
  background: var(--surface, #ffffff);
  border: 1px solid var(--line, #dbe3ec);
  box-shadow: var(--sh-1, 0 4px 16px rgba(15, 23, 42, .08));
  overflow: hidden;
  transition: transform var(--dur-fast, .15s) var(--ease-out, ease),
              box-shadow var(--dur-fast, .15s) var(--ease-out, ease);
}
.ui-stat-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-2, 0 6px 24px rgba(15, 23, 42, .09));
}
/* 右上角柔光，强化 --accent 而不铺满整卡 */
.ui-stat-card::after {
  content: '';
  position: absolute;
  top: -40%;
  right: -18%;
  width: 130px;
  height: 130px;
  border-radius: 50%;
  background: var(--accent);
  opacity: .10;
  pointer-events: none;
}
.ui-stat-card__icon {
  position: relative;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--r-md, 12px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  font-size: 22px;
}
.ui-stat-card__icon::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: .12;
}
.ui-stat-card__icon i { position: relative; }
.ui-stat-card__main { position: relative; min-width: 0; }
.ui-stat-card__value {
  font-size: var(--fs-2xl);
  font-weight: 700;
  line-height: 1.2;
  color: var(--text-1, #1f2937);
  font-variant-numeric: tabular-nums;
}
.ui-stat-card__label {
  margin-top: 2px;
  font-size: var(--fs-sm, 13px);
  color: var(--text-2, #6b7280);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 强调色预设 */
.ui-stat-card--brand  { --accent: var(--brand-500, #00bde9); }
.ui-stat-card--green  { --accent: var(--brand-green-d, #4faa2c); }
.ui-stat-card--info   { --accent: var(--c-info); }
.ui-stat-card--warn   { --accent: var(--c-warn); }
.ui-stat-card--danger { --accent: var(--c-danger); }
.ui-stat-card--vip    { --accent: var(--vip-500, #667eea); }
.ui-stat-card--muted  { --accent: var(--c-muted); }
/* 整卡渐变（用于顶部欢迎卡 / 会员卡） */
.ui-stat-card--solid {
  border: none;
  color: var(--text-inv, #ffffff);
  background: var(--brand-gradient, linear-gradient(135deg, #00bde9 0%, #7ed957 100%));
  box-shadow: var(--sh-brand);
}
.ui-stat-card--solid .ui-stat-card__value,
.ui-stat-card--solid .ui-stat-card__label { color: var(--text-inv, #ffffff); }
.ui-stat-card--solid .ui-stat-card__icon { color: var(--text-inv, #ffffff); }
.ui-stat-card--solid .ui-stat-card__icon::before { background: #fff; opacity: .22; }
.ui-stat-card--solid::after { background: #fff; opacity: .12; }
.ui-stat-card--vip-solid {
  border: none;
  color: var(--text-inv, #ffffff);
  background: var(--vip-gradient, linear-gradient(135deg, #667eea 0%, #764ba2 100%));
  box-shadow: var(--sh-vip);
}
.ui-stat-card--vip-solid .ui-stat-card__value,
.ui-stat-card--vip-solid .ui-stat-card__label { color: var(--text-inv, #ffffff); }
.ui-stat-card--vip-solid .ui-stat-card__icon { color: var(--text-inv, #ffffff); }
.ui-stat-card--vip-solid .ui-stat-card__icon::before { background: #fff; opacity: .22; }

/* ---------- 空状态 ---------- */
.ui-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2, 8px);
  padding: var(--sp-8, 32px) var(--sp-4, 16px);
  text-align: center;
  color: var(--text-2, #6b7280);
}
.ui-empty__icon {
  width: 56px;
  height: 56px;
  border-radius: var(--r-pill, 999px);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-a08, rgba(0, 189, 233, .08));
  color: var(--brand-600, #0098b8);
  font-size: 28px;
}
.ui-empty__title { color: var(--text-1, #1f2937); font-weight: 600; font-size: var(--fs-md, 14px); }
.ui-empty__desc { font-size: var(--fs-sm, 13px); margin: 0; }
.ui-empty__actions {
  margin-top: var(--sp-2, 8px);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2, 8px);
  justify-content: center;
}

/* ---------- 状态徽章 ---------- */
.ui-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 10px;
  border-radius: var(--r-pill, 999px);
  font-size: var(--fs-xs, 12px);
  font-weight: 600;
  line-height: 1.7;
  white-space: nowrap;
}
.ui-badge--ok     { background: var(--c-ok-bg);     color: var(--c-ok); }
.ui-badge--warn   { background: var(--c-warn-bg);   color: #8a6d00; }
.ui-badge--danger { background: var(--c-danger-bg); color: #c62828; }
.ui-badge--info   { background: var(--c-info-bg);   color: #1565c0; }
.ui-badge--muted  { background: var(--c-muted-bg);  color: #546e7a; }
.ui-badge--vip    { background: var(--vip-gradient, linear-gradient(135deg, #667eea 0%, #764ba2 100%)); color: #fff; max-width: 100%; white-space: normal; overflow-wrap: anywhere; }

/* ---------- 按钮加载态 ---------- */
.is-loading { pointer-events: none; opacity: .8; }
.is-loading::before {
  content: '';
  display: inline-block;
  width: 13px;
  height: 13px;
  margin-right: 6px;
  vertical-align: -2px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: uiSpin .6s linear infinite;
}
@keyframes uiSpin { to { transform: rotate(360deg); } }

/* ---------- 骨架屏 ---------- */
.ui-skeleton {
  position: relative;
  display: inline-block;
  min-width: 2.5em;
  min-height: 1em;
  border-radius: var(--r-xs);
  background: #e6edf5;
  color: transparent !important;
  overflow: hidden;
  vertical-align: middle;
  user-select: none;
}
.ui-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .8), transparent);
  animation: uiShine 1.3s ease-in-out infinite;
}
@keyframes uiShine {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* ---------- 筛选工具栏 ---------- */
.ui-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2, 8px);
}
.ui-toolbar__group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  background: var(--surface-3, #eef3f8);
  border-radius: var(--r-md, 12px);
}
.ui-chip {
  border: none;
  background: transparent;
  padding: 6px 12px;
  border-radius: var(--r-sm, 8px);
  font-size: var(--fs-sm, 13px);
  font-weight: 500;
  color: var(--text-2, #6b7280);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.ui-chip i { font-size: 15px; vertical-align: -2px; margin-right: 2px; }
.ui-chip:hover { color: var(--text-1, #1f2937); }
.ui-chip.is-active {
  background: var(--surface, #ffffff);
  color: var(--brand-600, #0098b8);
  font-weight: 600;
  box-shadow: var(--sh-1, 0 2px 12px rgba(15, 23, 42, .06));
}
.ui-toolbar__spacer { flex: 1 1 auto; }

/* ---------- 滚动公告（PC / 移动端共用） ---------- */
.ui-marquee {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--sp-4, 16px);
  background: var(--brand-gradient, linear-gradient(135deg, #00bde9 0%, #7ed957 100%));
  color: #fff;
  font-size: var(--fs-md, 14px);
  overflow: hidden;
}
.ui-marquee--sm { height: 34px; font-size: var(--fs-sm, 13px); padding: 0 var(--sp-3, 12px); }
.ui-marquee__link {
  display: flex;
  align-items: center;
  gap: var(--sp-2, 8px);
  width: 100%;
  color: inherit;
  text-decoration: none;
}
.ui-marquee__link:hover { color: #fff; text-decoration: none; }
.ui-marquee__icon { flex: none; font-size: 18px; }
.ui-marquee__track { flex: 1; overflow: hidden; white-space: nowrap; }
.ui-marquee__text {
  display: inline-block;
  white-space: nowrap;
  padding-left: 100%;
  animation: uiMarquee 20s linear infinite;
}
.ui-marquee__link:hover .ui-marquee__text { animation-play-state: paused; }
@keyframes uiMarquee {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-100%); }
}

/* ---------- 图标条目列表 ---------- */
.ui-info-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3, 12px);
}
.ui-info-list li { display: flex; align-items: flex-start; gap: var(--sp-3, 12px); }
.ui-info-list__icon {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: var(--r-sm, 8px);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-a08, rgba(0, 189, 233, .08));
  color: var(--brand-600, #0098b8);
  font-size: 16px;
}
.ui-info-list__title { font-weight: 600; color: var(--text-1, #1f2937); font-size: var(--fs-md, 14px); }
.ui-info-list__desc { color: var(--text-2, #6b7280); font-size: var(--fs-sm, 13px); line-height: 1.7; }

/* ---------- 表单提交遮罩（配合 UI.formMask） ---------- */
.ui-form-mask {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2, 8px);
  background: rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  color: var(--brand-600, #0098b8);
  font-size: var(--fs-sm, 13px);
  font-weight: 600;
  border-radius: inherit;
}
.ui-form-mask__spin {
  width: 16px;
  height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: uiSpin .6s linear infinite;
}

/* ---------- 静默刷新提示（配合 UI.refreshHint） ---------- */
.ui-refresh-hint {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 15;
  padding: 2px 8px;
  border-radius: var(--r-pill, 999px);
  background: var(--brand-a12, rgba(0, 189, 233, .12));
  color: var(--brand-600, #0098b8);
  font-size: 11px;
  font-weight: 600;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
  pointer-events: none;
}
.ui-refresh-hint.is-on { opacity: 1; transform: none; }

/* ---------- 通用 Toast（配合 UI.toast） ---------- */
.ui-toast {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, -12px);
  z-index: 10000;
  max-width: 80%;
  padding: 10px 22px;
  border-radius: var(--r-pill, 999px);
  background: rgba(17, 24, 39, .88);
  color: #fff;
  font-size: var(--fs-md, 14px);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.ui-toast.show { opacity: 1; transform: translate(-50%, 0); }
.ui-toast--error { background: rgba(220, 38, 38, .92); }

/* ---------- 入场动画 ---------- */
.ui-fade-up { animation: uiFadeUp var(--dur-slow) var(--ease-out) both; }
@keyframes uiFadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- 降低动效偏好 ---------- */
@media (prefers-reduced-motion: reduce) {
  .ui-marquee__text { animation: none; }
  .ui-skeleton::after { animation: none; }
  .ui-fade-up { animation: none; }
  .is-loading::before { animation-duration: 1.6s; }
  .ui-stat-card:hover { transform: none; }
}
