@charset "UTF-8";
/* ==========================================================================
   components.css —— 可复用组件层
   --------------------------------------------------------------------------
   本文件提供与业务无关的通用组件：按钮、表单、头像、徽章、卡片、导航、
   侧边栏、分段控件、标签页、统计卡、表格、弹窗、提示、列表、折叠面板、
   加载态、人机验证、排名、进度、时间线等。
   所有颜色/间距/圆角/阴影/时长均取自 tokens.css 的令牌，因此自动支持深色模式。
   本文件不 @import，只依赖 tokens.css 定义的变量（由 HTML 的 link 顺序保证）。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 按钮
   -------------------------------------------------------------------------- */
.btn{
  /* 每个按钮自带一套可覆盖的局部变量，修饰类只需改变量即可换肤 */
  --btn-bg:var(--c-surface);
  --btn-fg:var(--c-text);
  --btn-bd:var(--c-border);
  --btn-bg-hover:var(--c-surface-3);
  --btn-sh:var(--sh-xs);

  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-2);
  padding:9px 16px;
  min-height:38px;
  border:1px solid var(--btn-bd);
  border-radius:var(--r-md);
  background:var(--btn-bg);
  color:var(--btn-fg);
  font-size:var(--fs-base);
  font-weight:var(--fw-semi);
  line-height:1.2;
  white-space:nowrap;
  text-align:center;
  box-shadow:var(--btn-sh);
  transition:background-color var(--dur-2) var(--ease),
             color var(--dur-2) var(--ease),
             border-color var(--dur-2) var(--ease),
             box-shadow var(--dur-2) var(--ease),
             transform var(--dur-1) var(--ease);
}
.btn:hover{background:var(--btn-bg-hover)}
.btn:active{transform:translateY(1px) scale(.995)}
.btn:focus-visible{outline:2px solid var(--c-primary);outline-offset:2px}
.btn:disabled,
.btn[aria-disabled="true"]{
  opacity:.55;
  cursor:not-allowed;
  box-shadow:none;
  transform:none;
}
.btn:disabled:hover{background:var(--btn-bg)}

/* 1.1 主按钮：品牌渐变 + 彩色投影 */
.btn-primary{
  --btn-bg:var(--g-primary);
  --btn-fg:#fff;
  --btn-bd:transparent;
  --btn-bg-hover:linear-gradient(135deg,var(--c-sky-500),var(--c-sky-700));
  --btn-sh:var(--sh-primary);
}
.btn-primary:hover{box-shadow:0 14px 28px -12px rgba(14,165,233,.85)}
.btn-primary:disabled:hover{box-shadow:none}

/* 1.2 幽灵按钮：透明底，描边随主题 */
.btn-ghost{
  --btn-bg:transparent;
  --btn-fg:var(--c-primary-700);
  --btn-bd:var(--c-primary-200);
  --btn-bg-hover:var(--c-primary-50);
  --btn-sh:none;
}
.btn-ghost:hover{border-color:var(--c-primary);color:var(--c-primary-700)}

/* 1.3 语义按钮 */
.btn-danger{
  --btn-bg:var(--c-danger-strong);--btn-fg:#fff;--btn-bd:transparent;
  --btn-bg-hover:#b91c1c;--btn-sh:var(--sh-danger);
}
.btn-warn{
  --btn-bg:var(--c-warn);--btn-fg:#3b2503;--btn-bd:transparent;
  --btn-bg-hover:var(--c-warn-strong);--btn-sh:0 10px 22px -10px rgba(245,158,11,.7);
}
.btn-ok{
  --btn-bg:var(--c-success-strong);--btn-fg:#fff;--btn-bd:transparent;
  --btn-bg-hover:#047857;--btn-sh:0 10px 22px -10px rgba(16,185,129,.7);
}

/* 1.4 尺寸与布局修饰 */
.btn-sm{
  padding:5px 11px;
  min-height:30px;
  font-size:var(--fs-xs);
  border-radius:var(--r-sm);
  gap:var(--sp-1);
}
.btn-lg{
  padding:13px 24px;
  min-height:46px;
  font-size:var(--fs-md);
  border-radius:var(--r-lg);
}
.btn-block{display:flex;width:100%}

/* 1.5 纯图标按钮：正方形，内容居中 */
.btn-icon{
  padding:0;
  width:38px;
  height:38px;
  min-height:38px;
  flex:0 0 auto;
  border-radius:var(--r-md);
  font-size:var(--fs-md);
}
.btn-icon.btn-sm{width:30px;height:30px;min-height:30px;font-size:var(--fs-sm)}
.btn-icon.btn-lg{width:46px;height:46px;min-height:46px;font-size:var(--fs-lg)}

/* 1.6 按钮内加载点：由 HTML 提供 <span class="btn-spinner"> */
.btn-spinner{
  width:14px;height:14px;flex-shrink:0;
  border:2px solid currentColor;
  border-top-color:transparent;
  border-radius:50%;
  opacity:.9;
  animation:spin .7s linear infinite;
}
.btn-sm .btn-spinner{width:12px;height:12px;border-width:1.5px}
.btn-lg .btn-spinner{width:16px;height:16px}
.btn.is-loading{pointer-events:none;opacity:.85}
@keyframes spin{to{transform:rotate(360deg)}}

/* --------------------------------------------------------------------------
   2. 表单
   -------------------------------------------------------------------------- */
.field{margin-bottom:var(--sp-4);min-width:0}

/* 2.1 原生控件统一外观 */
.field input,
.field select,
.field textarea{
  display:block;
  width:100%;
  padding:10px 13px;
  min-height:40px;
  border:1px solid var(--c-border);
  border-radius:var(--r-field);
  background:var(--c-surface);
  color:var(--c-text);
  font-size:var(--fs-base);
  line-height:1.4;
  transition:border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease),background-color var(--dur-2) var(--ease);
}
.field select{
  /* 自绘箭头：避免图标字体，也避免浏览器默认箭头不一致 */
  appearance:none;
  -webkit-appearance:none;
  padding-right:34px;
  background-image:
    linear-gradient(45deg,transparent 50%,var(--c-muted) 50%),
    linear-gradient(135deg,var(--c-muted) 50%,transparent 50%);
  background-size:5px 5px,5px 5px;
  background-repeat:no-repeat;
  background-position:calc(100% - 17px) calc(50% + 1px),calc(100% - 12px) calc(50% + 1px);
  cursor:pointer;
}
.field textarea{min-height:96px;resize:vertical;line-height:var(--lh-base)}
.field input:hover,.field select:hover,.field textarea:hover{border-color:var(--c-border-strong)}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--c-primary);
  box-shadow:var(--sh-focus-ring);
  background:var(--c-surface);
}
.field input::placeholder,.field textarea::placeholder{color:var(--c-muted-2)}
.field input:disabled,.field select:disabled,.field textarea:disabled{
  background:var(--c-surface-2);
  color:var(--c-muted);
  cursor:not-allowed;
  border-style:dashed;
}
.field input[readonly]{background:var(--c-surface-2)}
/* 日期控件在深色下的图标反色 */
@media (prefers-color-scheme: dark){
  .field input[type="date"],.field input[type="time"]{color-scheme:dark}
}
input[type="checkbox"],input[type="radio"]{
  accent-color:var(--c-primary-600);
  width:16px;height:16px;
  vertical-align:-3px;
  cursor:pointer;
}

/* 2.2 标签与说明文字 */
.field>label,
.field>legend{
  display:block;
  margin-bottom:var(--sp-2);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  color:var(--c-text-2);
}
.field label .req,
.field>label .req{color:var(--c-danger);margin-left:2px}
.hint{
  display:block;
  margin-top:var(--sp-2);
  font-size:var(--fs-xs);
  line-height:var(--lh-base);
  color:var(--c-muted);
}
.field-error{
  display:block;
  margin-top:var(--sp-2);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  color:var(--c-danger);
}
.field-error::before{content:"! ";font-weight:var(--fw-black)}
/* 出错时的输入框描边 */
.field.has-error input,
.field.has-error select,
.field.has-error textarea{
  border-color:var(--c-danger);
  box-shadow:0 0 0 3px var(--c-danger-100);
}

/* 2.3 多列栅格 */
.row2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 var(--sp-4)}
.row3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 var(--sp-3)}
/* .row2/.row3 里若不放 .field，则退化为普通网格间距 */
.row2>*,.row3>*{min-width:0}
.row2:not(:has(.field)){gap:var(--sp-3)}
.row3:not(:has(.field)){gap:var(--sp-3)}

/* 2.4 复选框行 */
.checkbox{
  display:inline-flex;
  align-items:flex-start;
  gap:var(--sp-2);
  padding:var(--sp-1) 0;
  font-size:var(--fs-sm);
  color:var(--c-text-2);
  cursor:pointer;
  user-select:none;
  line-height:var(--lh-snug);
}
.checkbox input[type="checkbox"]{margin-top:2px;flex-shrink:0}
.checkbox:hover{color:var(--c-text)}

/* 2.5 开关：结构为 .switch > input + .slider */
.switch{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:var(--sp-3);
  cursor:pointer;
  font-size:var(--fs-sm);
  color:var(--c-text-2);
  user-select:none;
}
.switch>input{
  position:absolute;
  width:1px;height:1px;
  opacity:0;
  pointer-events:none;
}
.switch .slider{
  position:relative;
  width:44px;height:24px;
  flex-shrink:0;
  border-radius:var(--r-pill);
  background:var(--c-border-strong);
  box-shadow:inset 0 1px 2px rgba(15,23,42,.15);
  transition:background-color var(--dur-3) var(--ease);
}
.switch .slider::after{
  content:"";
  position:absolute;
  top:3px;left:3px;
  width:18px;height:18px;
  border-radius:50%;
  background:#fff;
  box-shadow:0 1px 3px rgba(15,23,42,.35);
  transition:transform var(--dur-3) var(--ease-spring);
}
.switch input:checked+.slider{background:var(--g-primary)}
.switch input:checked+.slider::after{transform:translateX(20px)}
.switch input:focus-visible+.slider{outline:2px solid var(--c-primary);outline-offset:2px}
.switch input:disabled+.slider{opacity:.5;cursor:not-allowed}
.switch input:disabled~*{opacity:.6}

/* 2.6 字段分组 */
.fieldset{
  border:1px solid var(--c-border);
  border-radius:var(--r-card);
  background:var(--c-surface);
  padding:var(--sp-4);
  margin-bottom:var(--sp-4);
  min-width:0;
}
.fieldset>legend,
.fieldset>.fieldset-title{
  padding:0 var(--sp-2);
  margin-left:calc(var(--sp-2) * -1);
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  color:var(--c-primary-700);
}
.fieldset .field:last-child{margin-bottom:0}

/* --------------------------------------------------------------------------
   3. 头像
   -------------------------------------------------------------------------- */
.avatar,
.avatar-letter,
.avatar-official{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  flex:0 0 auto;
  border-radius:var(--r-avatar);
  overflow:hidden;
  font-weight:var(--fw-black);
  line-height:1;
  user-select:none;
  /* 统一基准尺寸：26px，由修饰类放大 */
  width:26px;height:26px;
  font-size:var(--fs-2xs);
  background:var(--g-primary);
  color:#fff;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.28);
}
.avatar img{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  border-radius:inherit;
}
/* 字母 / 汉字回退：渐变底 + 白字 + 字距收紧 */
.avatar-letter{
  background:var(--g-primary);
  color:#fff;
  letter-spacing:0;
  text-shadow:0 1px 2px rgba(2,44,74,.35);
}
/* 备用色板：由 HTML 追加 .avatar-letter-b / .avatar-letter-c 时启用 */
.avatar-letter.avatar-letter-b{background:linear-gradient(135deg,#60a5fa,#2563eb)}
.avatar-letter.avatar-letter-c{background:linear-gradient(135deg,#34d399,#059669)}
/* 官方「逃走中」头像：深蓝渐变 + 居中白字，小尺寸也要清晰可读 */
.avatar-official{
  background:var(--g-official);
  color:#fff;
  font-weight:var(--fw-black);
  letter-spacing:.5px;
  text-shadow:0 1px 3px rgba(0,0,0,.45);
  box-shadow:inset 0 0 0 1px rgba(125,211,252,.45),0 2px 8px -3px rgba(3,105,161,.7);
}
.avatar-official::after{
  /* 斜向高光，强化"官方认证"的金属感 */
  content:"";
  position:absolute;inset:0;
  background:linear-gradient(140deg,rgba(255,255,255,.35) 0 28%,transparent 60%);
  pointer-events:none;
}

/* 3.1 尺寸体系（同步缩放字号，保证小尺寸可读） */
.avatar-sm,.avatar-sm.avatar-letter,.avatar-sm.avatar-official{width:32px;height:32px;font-size:13px}
.avatar-md,.avatar-md.avatar-letter,.avatar-md.avatar-official{width:44px;height:44px;font-size:17px}
.avatar-lg,.avatar-lg.avatar-letter,.avatar-lg.avatar-official{width:64px;height:64px;font-size:24px}
.avatar-xl,.avatar-xl.avatar-letter,.avatar-xl.avatar-official{width:92px;height:92px;font-size:34px}
.avatar-sm.avatar-official{letter-spacing:0}
.avatar-xs,.avatar-xs.avatar-letter,.avatar-xs.avatar-official{width:22px;height:22px;font-size:10px}

/* 3.2 选中态描边环 */
.avatar-ring{
  box-shadow:0 0 0 2px var(--c-surface),0 0 0 5px var(--c-primary),var(--sh-md);
}
.avatar-ring.avatar-official{box-shadow:0 0 0 2px var(--c-surface),0 0 0 5px var(--c-primary-600),var(--sh-md)}

/* 3.3 可点击更换头像：hover/聚焦显示遮罩与文字 */
.avatar-picker{
  position:relative;
  display:inline-flex;
  border-radius:var(--r-avatar);
  cursor:pointer;
  line-height:0;
}
.avatar-picker-mask{
  position:absolute;
  inset:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:2px;
  border-radius:inherit;
  background:rgba(2,44,74,.62);
  backdrop-filter:blur(2px);
  color:#fff;
  font-size:var(--fs-2xs);
  font-weight:var(--fw-bold);
  letter-spacing:.5px;
  line-height:1.2;
  opacity:0;
  transition:opacity var(--dur-3) var(--ease);
  text-align:center;
}
/* 纯 CSS 相机图形，替代图标字体 */
.avatar-picker-mask::before{
  content:"";
  width:14px;height:11px;
  border:1.5px solid currentColor;
  border-radius:3px;
  background:
    radial-gradient(circle at 50% 50%,currentColor 0 2.2px,transparent 2.4px);
  box-shadow:0 -3px 0 -1px currentColor inset;
}
.avatar-picker:hover .avatar-picker-mask,
.avatar-picker:focus-within .avatar-picker-mask,
.avatar-picker:focus .avatar-picker-mask{opacity:1}
.avatar-picker:active{transform:scale(.97)}

/* --------------------------------------------------------------------------
   4. 徽章 / 标签 / 芯片 / 胶囊
   -------------------------------------------------------------------------- */
.badge{
  display:inline-flex;
  align-items:center;
  gap:4px;
  padding:3px 9px;
  border-radius:var(--r-pill);
  background:var(--c-primary-100);
  color:var(--c-primary-700);
  font-size:var(--fs-2xs);
  font-weight:var(--fw-bold);
  line-height:1.5;
  white-space:nowrap;
  border:1px solid transparent;
}
.badge-super{
  background:var(--g-official);
  color:#fff;
  box-shadow:0 4px 12px -5px rgba(3,105,161,.85);
}
.badge-admin{background:var(--g-primary);color:#fff}
.badge-user{background:var(--c-surface-3);color:var(--c-muted)}
.badge-danger{background:var(--c-danger-100);color:var(--c-danger-strong)}
.badge-warn{background:var(--c-warn-100);color:var(--c-warn-strong)}
.badge-ok{background:var(--c-success-100);color:var(--c-success-strong)}
.badge-muted{background:var(--c-surface-3);color:var(--c-muted)}

/* 标签：与徽章同族，但更中性，用于分类 */
.tag{
  display:inline-flex;
  align-items:center;
  gap:4px;
  padding:3px 9px;
  border:1px solid var(--c-border);
  border-radius:var(--r-sm);
  background:var(--c-surface-2);
  color:var(--c-muted);
  font-size:var(--fs-2xs);
  font-weight:var(--fw-semi);
  white-space:nowrap;
}
.tag-ok{background:var(--c-success-100);color:var(--c-success-strong);border-color:transparent}
.tag-danger{background:var(--c-danger-100);color:var(--c-danger-strong);border-color:transparent}
.tag-warn{background:var(--c-warn-100);color:var(--c-warn-strong);border-color:transparent}

/* 芯片：可点击的筛选元素 */
.chip{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  padding:5px 12px;
  border:1px solid var(--c-border);
  border-radius:var(--r-pill);
  background:var(--c-surface);
  color:var(--c-text-2);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  white-space:nowrap;
  cursor:pointer;
  transition:background-color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease);
}
.chip:hover{background:var(--c-primary-50);border-color:var(--c-primary-200);color:var(--c-primary-700)}
.chip.active{background:var(--c-primary-100);border-color:var(--c-primary);color:var(--c-primary-700)}

/* 胶囊：纯展示的圆角容器 */
.pill{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  padding:4px 12px;
  border-radius:var(--r-pill);
  background:var(--c-surface-2);
  color:var(--c-text-2);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  border:1px solid var(--c-border);
}
.pill strong{color:var(--c-primary-600);font-weight:var(--fw-black)}

/* --------------------------------------------------------------------------
   5. 卡片与容器
   -------------------------------------------------------------------------- */
.card{
  position:relative;
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-card);
  padding:var(--sp-5);
  box-shadow:var(--sh-sm);
  transition:box-shadow var(--dur-3) var(--ease),border-color var(--dur-3) var(--ease),transform var(--dur-3) var(--ease);
}
.card:hover{box-shadow:var(--sh-md);border-color:var(--c-primary-200)}
.card-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-3);
  flex-wrap:wrap;
  padding-bottom:var(--sp-3);
  margin-bottom:var(--sp-4);
  border-bottom:1px solid var(--c-border);
}
.card-title{
  font-size:var(--fs-md);
  font-weight:var(--fw-bold);
  line-height:var(--lh-snug);
  color:var(--c-text);
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  min-width:0;
}
.card-title .badge{margin-left:var(--sp-1)}
.card-body{font-size:var(--fs-base);color:var(--c-text-2);line-height:var(--lh-base)}
.card-body+.card-body{margin-top:var(--sp-3)}
.card-actions{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:var(--sp-2);
  flex-wrap:wrap;
  margin-top:var(--sp-4);
  padding-top:var(--sp-3);
  border-top:1px solid var(--c-border);
}
.card>h3:first-child{margin-bottom:var(--sp-3)}

/* 面板：无阴影的扁平容器，用于嵌套 */
.panel{
  background:var(--c-surface-2);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  padding:var(--sp-4);
}
.panel+.panel{margin-top:var(--sp-3)}

/* 分隔线：可带居中文字 */
.divider{
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  margin:var(--sp-5) 0;
  border:0;
  height:1px;
  background:var(--c-border);
}
.divider::before,.divider::after{content:"";flex:1}
.divider.has-text{
  height:auto;
  background:none;
  color:var(--c-muted-2);
  font-size:var(--fs-xs);
  text-align:center;
}

/* --------------------------------------------------------------------------
   6. 空状态：纯 CSS 画的"空盒子"插画
   -------------------------------------------------------------------------- */
.empty{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--sp-2);
  padding:var(--sp-10) var(--sp-5);
  border:1px dashed var(--c-border);
  border-radius:var(--r-card);
  background:var(--c-surface-2);
  color:var(--c-muted);
  font-size:var(--fs-sm);
  text-align:center;
}
.empty-icon{
  position:relative;
  width:64px;height:52px;
  margin-bottom:var(--sp-2);
  border:2px solid var(--c-border-strong);
  border-radius:var(--r-lg);
  background:var(--c-surface);
  box-shadow:var(--sh-xs);
  flex:0 0 auto;
}
/* 盒盖 */
.empty-icon::before{
  content:"";
  position:absolute;
  top:-10px;left:50%;
  transform:translateX(-50%) rotate(-3deg);
  width:64px;height:8px;
  border:2px solid var(--c-border-strong);
  border-radius:var(--r-sm);
  background:var(--c-surface);
}
/* 内部"空空如也"的斜线 */
.empty-icon::after{
  content:"";
  position:absolute;
  inset:12px 10px 10px;
  border-radius:var(--r-sm);
  background:
    linear-gradient(to top right,transparent calc(50% - 1px),var(--c-border-strong) calc(50% - 1px) calc(50% + 1px),transparent calc(50% + 1px)),
    linear-gradient(to bottom right,transparent calc(50% - 1px),var(--c-border-strong) calc(50% - 1px) calc(50% + 1px),transparent calc(50% + 1px));
  opacity:.65;
}
.empty strong{color:var(--c-text-2);font-size:var(--fs-base);font-weight:var(--fw-bold)}
.empty .btn{margin-top:var(--sp-2)}

/* --------------------------------------------------------------------------
   7. 顶部导航
   -------------------------------------------------------------------------- */
.topbar{
  position:sticky;
  top:0;
  z-index:var(--z-nav);
  background:var(--c-nav-bg);
  border-bottom:1px solid var(--c-nav-border);
  backdrop-filter:blur(14px) saturate(160%);
  -webkit-backdrop-filter:blur(14px) saturate(160%);
  box-shadow:0 1px 0 rgba(15,23,42,.03),0 8px 24px -20px rgba(2,132,199,.5);
}
.topbar-inner{
  display:flex;
  align-items:center;
  gap:var(--sp-5);
  max-width:var(--page-max);
  margin:0 auto;
  padding:0 var(--sp-5);
  height:var(--nav-h);
}

/* 7.1 品牌 */
.brand{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex-shrink:0;
  font-weight:var(--fw-black);
  font-size:var(--fs-md);
  color:var(--c-primary-700);
  letter-spacing:-.01em;
  transition:opacity var(--dur-2) var(--ease);
}
.brand:hover{opacity:.85}
.brand-logo{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:42px;height:42px;
  flex-shrink:0;
  border-radius:var(--r-lg);
  background:var(--g-official);
  color:#fff;
  font-size:13px;
  font-weight:var(--fw-black);
  letter-spacing:.5px;
  text-align:center;
  line-height:1.05;
  box-shadow:0 10px 22px -10px rgba(3,105,161,.9),inset 0 0 0 1px rgba(125,211,252,.4);
}
.brand-logo-sm{
  width:30px;height:30px;
  border-radius:var(--r-sm);
  font-size:10px;
  letter-spacing:0;
  box-shadow:0 6px 14px -8px rgba(3,105,161,.9),inset 0 0 0 1px rgba(125,211,252,.4);
}
.brand-logo{transition:transform var(--dur-3) var(--ease-out),box-shadow var(--dur-3) var(--ease)}
.brand:hover .brand-logo{transform:translateY(-1px)}
.brand-name{
  font-size:var(--fs-md);
  font-weight:var(--fw-black);
  color:var(--c-primary-700);
  white-space:nowrap;
}
.brand-sub{
  display:block;
  font-size:var(--fs-2xs);
  font-weight:var(--fw-medium);
  color:var(--c-muted);
  letter-spacing:.5px;
}

/* 7.2 主链接：active 用下划线动效而非色块 */
.nav-links{
  display:flex;
  align-items:center;
  gap:var(--sp-1);
  flex:1 1 auto;
  min-width:0;
}
.nav-link{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  padding:8px 13px;
  border-radius:var(--r-sm);
  color:var(--c-muted);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  white-space:nowrap;
  cursor:pointer;
  transition:color var(--dur-2) var(--ease),background-color var(--dur-2) var(--ease);
}
.nav-link::after{
  content:"";
  position:absolute;
  left:13px;right:13px;bottom:2px;
  height:2px;
  border-radius:var(--r-pill);
  background:var(--g-primary);
  transform:scaleX(0);
  transform-origin:center;
  transition:transform var(--dur-3) var(--ease-out);
}
.nav-link:hover{color:var(--c-primary-700);background:var(--c-primary-50)}
.nav-link:hover::after{transform:scaleX(.55)}
.nav-link.active{color:var(--c-primary-700);font-weight:var(--fw-bold)}
.nav-link.active::after{transform:scaleX(1)}
.nav-link:focus-visible{outline:2px solid var(--c-primary);outline-offset:1px}

/* 未读小红点：带脉冲扩散 */
.nav-dot{
  position:relative;
  display:inline-block;
  width:8px;height:8px;
  flex-shrink:0;
  border-radius:50%;
  background:var(--c-danger);
  box-shadow:0 0 0 2px var(--c-surface);
}
.nav-dot::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:50%;
  background:var(--c-danger);
  animation:dot-pulse 2s var(--ease) infinite;
}
@keyframes dot-pulse{
  0%{transform:scale(1);opacity:.65}
  70%{transform:scale(2.6);opacity:0}
  100%{transform:scale(2.6);opacity:0}
}

/* 7.3 右侧操作区与用户芯片 */
.nav-actions{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  margin-left:auto;
  flex-shrink:0;
}
.user-chip{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  max-width:190px;
  padding:4px 13px 4px 4px;
  border:1px solid var(--c-border);
  border-radius:var(--r-pill);
  background:var(--c-surface-2);
  color:var(--c-primary-700);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  cursor:pointer;
  transition:background-color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease);
}
.user-chip:hover{background:var(--c-primary-50);border-color:var(--c-primary-200);box-shadow:var(--sh-sm)}
.user-chip .avatar{width:28px;height:28px;font-size:11px}
.user-chip-name{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  min-width:0;
}
.user-chip-meta{display:block;font-size:var(--fs-2xs);color:var(--c-muted);font-weight:var(--fw-normal)}

/* --------------------------------------------------------------------------
   8. 侧边导航
   -------------------------------------------------------------------------- */
.sidebar{
  display:flex;
  flex-direction:column;
  gap:var(--sp-2);
  width:var(--sidebar-w);
  flex:0 0 auto;
  padding:var(--sp-3);
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-card);
  box-shadow:var(--sh-sm);
}
.sidebar-group{min-width:0}
.sidebar-group+.sidebar-group{margin-top:var(--sp-2)}
.sidebar-group-title{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  padding:6px 10px;
  font-size:var(--fs-2xs);
  font-weight:var(--fw-black);
  letter-spacing:.08em;
  color:var(--c-muted-2);
  text-transform:uppercase;
}
.sidebar-group-items{display:flex;flex-direction:column;gap:2px}
.sidebar-item{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  width:100%;
  padding:8px 11px;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  background:none;
  color:var(--c-muted);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  text-align:left;
  cursor:pointer;
  transition:background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease);
}
.sidebar-item:hover{background:var(--c-primary-50);color:var(--c-primary-700)}
.sidebar-item.active{
  background:var(--g-primary);
  color:#fff;
  border-color:transparent;
  box-shadow:var(--sh-primary);
}
.sidebar-item.active .count-badge{background:rgba(255,255,255,.28);color:#fff}
.sidebar-item:focus-visible{outline:2px solid var(--c-primary);outline-offset:1px}

/* 计数角标 */
.count-badge{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:18px;
  height:17px;
  margin-left:auto;
  padding:0 6px;
  border-radius:var(--r-pill);
  background:var(--c-danger-100);
  color:var(--c-danger-strong);
  font-size:10px;
  font-weight:var(--fw-black);
  line-height:1;
  flex-shrink:0;
}

/* --------------------------------------------------------------------------
   9. 分段控件与标签页
   -------------------------------------------------------------------------- */
.segmented{
  display:inline-flex;
  align-items:center;
  gap:3px;
  padding:3px;
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  background:var(--c-surface-2);
}
.segmented-item{
  flex:1 1 auto;
  padding:7px 14px;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  background:none;
  color:var(--c-muted);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  white-space:nowrap;
  cursor:pointer;
  transition:background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease);
}
.segmented-item:hover{color:var(--c-primary-700)}
.segmented-item.active{
  background:var(--c-surface);
  color:var(--c-primary-700);
  font-weight:var(--fw-bold);
  box-shadow:var(--sh-sm);
}
.segmented-item:focus-visible{outline:2px solid var(--c-primary);outline-offset:1px}

.tabs{
  display:flex;
  align-items:center;
  gap:var(--sp-1);
  border-bottom:1px solid var(--c-border);
  margin-bottom:var(--sp-5);
  overflow-x:auto;
  scrollbar-width:none;
}
.tabs::-webkit-scrollbar{display:none}
.tab{
  position:relative;
  padding:10px 14px;
  border:0;
  background:none;
  color:var(--c-muted);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  white-space:nowrap;
  cursor:pointer;
  transition:color var(--dur-2) var(--ease);
}
.tab::after{
  content:"";
  position:absolute;
  left:var(--sp-3);right:var(--sp-3);bottom:-1px;
  height:2px;
  border-radius:var(--r-pill) var(--r-pill) 0 0;
  background:var(--g-primary);
  transform:scaleX(0);
  transition:transform var(--dur-3) var(--ease-out);
}
.tab:hover{color:var(--c-primary-700)}
.tab.active{color:var(--c-primary-700);font-weight:var(--fw-bold)}
.tab.active::after{transform:scaleX(1)}
.tab:focus-visible{outline:2px solid var(--c-primary);outline-offset:-2px}

/* 面板：默认隐藏，.active 显示（前后端共用同一契约） */
.tab-panel{display:none}
.tab-panel.active{display:block;animation:panel-in var(--dur-3) var(--ease-out) both}
@keyframes panel-in{
  from{opacity:0;transform:translateY(6px)}
  to{opacity:1;transform:none}
}

/* --------------------------------------------------------------------------
   10. 统计仪表盘
   -------------------------------------------------------------------------- */
.stat-grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  gap:var(--sp-3);
}
.stat-card{
  position:relative;
  display:flex;
  flex-direction:column;
  gap:var(--sp-1);
  padding:var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-5);
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-xs);
  overflow:hidden;
  transition:transform var(--dur-3) var(--ease-out),box-shadow var(--dur-3) var(--ease),border-color var(--dur-3) var(--ease);
}
/* 左侧品牌色竖条，让仪表盘有节奏 */
.stat-card::before{
  content:"";
  position:absolute;
  top:var(--sp-3);bottom:var(--sp-3);left:0;
  width:3px;
  border-radius:0 var(--r-pill) var(--r-pill) 0;
  background:var(--g-primary);
  opacity:.85;
}
.stat-icon{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:34px;height:34px;
  margin-bottom:var(--sp-1);
  border-radius:var(--r-md);
  background:var(--c-primary-100);
  color:var(--c-primary-700);
  font-size:var(--fs-md);
  font-weight:var(--fw-black);
}
.stat-label{
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  color:var(--c-muted);
  line-height:var(--lh-snug);
}
.stat-value{
  font-size:clamp(1.2rem,1.05rem + .6vw,1.6rem);
  font-weight:var(--fw-black);
  line-height:1.1;
  color:var(--c-text);
  font-variant-numeric:tabular-nums;
  letter-spacing:-.02em;
}
.stat-delta{
  display:inline-flex;
  align-items:center;
  gap:3px;
  align-self:flex-start;
  padding:2px 7px;
  border-radius:var(--r-pill);
  font-size:var(--fs-2xs);
  font-weight:var(--fw-bold);
  background:var(--c-surface-3);
  color:var(--c-muted);
}
.stat-delta.up{background:var(--c-success-100);color:var(--c-success-strong)}
.stat-delta.down{background:var(--c-danger-100);color:var(--c-danger-strong)}
.stat-delta.flat{background:var(--c-surface-3);color:var(--c-muted)}
.stat-delta.up::before{content:"▲";font-size:8px}
.stat-delta.down::before{content:"▼";font-size:8px}

.stat-card.clickable{cursor:pointer}
.stat-card.clickable:hover,
.stat-card.clickable:focus-visible{
  transform:translateY(-2px);
  border-color:var(--c-primary-200);
  box-shadow:var(--sh-md);
}
.stat-card.clickable:active{transform:translateY(0)}
.stat-card.clickable::after{
  content:"";
  position:absolute;
  inset:0;
  background:radial-gradient(120px 60px at 100% 0,var(--c-primary-50),transparent 70%);
  opacity:0;
  transition:opacity var(--dur-3) var(--ease);
  pointer-events:none;
}
.stat-card.clickable:hover::after{opacity:1}

/* --------------------------------------------------------------------------
   11. 表格
   -------------------------------------------------------------------------- */
.table-wrap{
  width:100%;
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  border:1px solid var(--c-border);
  border-radius:var(--r-card);
  background:var(--c-surface);
  box-shadow:var(--sh-xs);
}
.table-wrap .table{border:0;border-radius:0;box-shadow:none}
.table{
  width:100%;
  min-width:520px;
  border-collapse:separate;
  border-spacing:0;
  font-size:var(--fs-sm);
  color:var(--c-text-2);
}
.table th{
  position:sticky;
  top:0;
  z-index:1;
  padding:11px 15px;
  background:var(--c-surface-2);
  color:var(--c-primary-700);
  font-size:var(--fs-xs);
  font-weight:var(--fw-black);
  letter-spacing:.02em;
  text-align:left;
  white-space:nowrap;
  border-bottom:1px solid var(--c-border);
}
.table td{
  padding:11px 15px;
  border-top:1px solid var(--c-border);
  vertical-align:middle;
  line-height:var(--lh-snug);
}
.table tbody tr{transition:background-color var(--dur-2) var(--ease)}
.table tbody tr:nth-child(even){background:var(--c-surface-2)}
.table tbody tr:hover{background:var(--c-primary-50)}
.table tbody tr:first-child td{border-top:0}
.table td .nowrap,.table th .nowrap{white-space:nowrap}
.table-actions{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex-wrap:wrap;
  white-space:nowrap;
}
.table-actions .btn{min-height:28px;padding:4px 10px;font-size:var(--fs-xs)}
/* 可排序表头 */
.table th.sortable{cursor:pointer;user-select:none}
.table th.sortable:hover{color:var(--c-primary-600)}

/* --------------------------------------------------------------------------
   12. 弹窗
   -------------------------------------------------------------------------- */
.no-scroll{overflow:hidden !important}
.modal-mask{
  position:fixed;
  inset:0;
  z-index:var(--z-mask);
  display:flex;
  align-items:center;
  justify-content:center;
  padding:var(--sp-5);
  background:var(--c-mask);
  backdrop-filter:blur(4px);
  -webkit-backdrop-filter:blur(4px);
  animation:mask-in var(--dur-3) var(--ease) both;
  overflow-y:auto;
}
@keyframes mask-in{from{opacity:0}to{opacity:1}}
.modal{
  position:relative;
  width:100%;
  max-width:540px;
  max-height:min(88vh,860px);
  overflow-y:auto;
  padding:var(--sp-6);
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-modal);
  box-shadow:var(--sh-xl);
  animation:modal-in var(--dur-4) var(--ease-out) both;
}
@keyframes modal-in{
  from{opacity:0;transform:translateY(14px) scale(.975)}
  to{opacity:1;transform:none}
}
/* 顶部渐变装饰线 */
.modal::before{
  content:"";
  position:absolute;
  top:0;left:var(--sp-6);right:var(--sp-6);
  height:2px;
  border-radius:0 0 var(--r-pill) var(--r-pill);
  background:var(--g-primary);
  opacity:.9;
}
.modal-sm{max-width:400px}
.modal-lg{max-width:680px}
.modal-wide{max-width:760px}

.modal-head{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:var(--sp-3);
  margin-bottom:var(--sp-4);
  padding-bottom:var(--sp-3);
  border-bottom:1px solid var(--c-border);
}
.modal-title{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  font-size:var(--fs-lg);
  font-weight:var(--fw-black);
  line-height:var(--lh-snug);
  letter-spacing:-.01em;
  min-width:0;
}
.modal h3{font-size:var(--fs-lg);font-weight:var(--fw-black);margin-bottom:var(--sp-3);line-height:var(--lh-snug)}
.modal-close{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:32px;height:32px;
  flex:0 0 auto;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  background:var(--c-surface-2);
  color:var(--c-muted);
  font-size:var(--fs-md);
  line-height:1;
  cursor:pointer;
  transition:background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease),transform var(--dur-2) var(--ease);
}
.modal-close:hover{background:var(--c-danger-100);color:var(--c-danger-strong);transform:rotate(90deg)}
.modal-body{
  font-size:var(--fs-base);
  color:var(--c-text-2);
  line-height:var(--lh-base);
  min-width:0;
}
.modal-body .field:last-child{margin-bottom:0}
.modal-actions{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:var(--sp-2);
  flex-wrap:wrap;
  margin-top:var(--sp-5);
  padding-top:var(--sp-4);
  border-top:1px solid var(--c-border);
}
.modal-actions .btn{min-width:86px}

/* --------------------------------------------------------------------------
   13. 提示：toast / alert
   -------------------------------------------------------------------------- */
.toast-wrap{
  position:fixed;
  top:var(--sp-5);
  right:var(--sp-5);
  z-index:var(--z-toast);
  display:flex;
  flex-direction:column;
  align-items:flex-end;
  gap:var(--sp-2);
  pointer-events:none;
  max-width:min(360px,calc(100vw - 32px));
}
.toast{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  padding:11px 18px;
  border-radius:var(--r-lg);
  background:var(--c-surface-inv);
  color:var(--c-bg);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  line-height:var(--lh-snug);
  box-shadow:var(--sh-lg);
  pointer-events:auto;
  animation:toast-in var(--dur-4) var(--ease-out) both;
}
/* 左侧色条，让语义一眼可辨 */
.toast::before{
  content:"";
  width:3px;
  align-self:stretch;
  flex:0 0 auto;
  border-radius:var(--r-pill);
  background:currentColor;
  opacity:.7;
}
@keyframes toast-in{
  from{opacity:0;transform:translateY(-10px) scale(.97)}
  to{opacity:1;transform:none}
}
.toast-ok{background:var(--c-success-strong);color:#fff}
.toast-err{background:var(--c-danger-strong);color:#fff}
.toast-warn{background:var(--c-warn-strong);color:#fff}
/* 兼容历史脚本输出的 .toast.ok / .toast.err */
.toast.ok{background:var(--c-success-strong);color:#fff}
.toast.err{background:var(--c-danger-strong);color:#fff}
.toast.warn{background:var(--c-warn-strong);color:#fff}

.alert{
  display:flex;
  align-items:flex-start;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--c-border);
  border-left:3px solid var(--c-muted-2);
  border-radius:var(--r-lg);
  background:var(--c-surface-2);
  color:var(--c-text-2);
  font-size:var(--fs-sm);
  line-height:var(--lh-base);
}
.alert+.alert{margin-top:var(--sp-3)}
.alert strong{font-weight:var(--fw-bold)}
.alert a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.alert-info{background:var(--c-info-100);border-color:transparent;border-left-color:var(--c-info-strong);color:var(--c-primary-700)}
.alert-warn{background:var(--c-warn-100);border-color:transparent;border-left-color:var(--c-warn-strong);color:var(--c-warn-strong)}
.alert-danger{background:var(--c-danger-100);border-color:transparent;border-left-color:var(--c-danger-strong);color:var(--c-danger-strong)}
.alert-ok{background:var(--c-success-100);border-color:transparent;border-left-color:var(--c-success-strong);color:var(--c-success-strong)}

/* --------------------------------------------------------------------------
   14. 列表
   -------------------------------------------------------------------------- */
.list{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}
.list-item{
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  transition:border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease),background-color var(--dur-2) var(--ease);
}
.list-item:hover{border-color:var(--c-primary-200);box-shadow:var(--sh-sm)}
.list-item-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px}
.list-item-title{
  font-size:var(--fs-base);
  font-weight:var(--fw-semi);
  color:var(--c-text);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.list-item-desc{
  font-size:var(--fs-xs);
  color:var(--c-muted);
  line-height:var(--lh-base);
  overflow-wrap:anywhere;
}
.list-item-meta{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:var(--sp-1);
  font-size:var(--fs-2xs);
  color:var(--c-muted-2);
  font-variant-numeric:tabular-nums;
}
.list-item-actions{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex-shrink:0;
  flex-wrap:wrap;
}

/* --------------------------------------------------------------------------
   15. 折叠面板
   -------------------------------------------------------------------------- */
.accordion{
  border:1px solid var(--c-border);
  border-radius:var(--r-card);
  background:var(--c-surface);
  overflow:hidden;
  transition:border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease);
}
.accordion+.accordion{margin-top:var(--sp-2)}
.accordion:hover{border-color:var(--c-primary-200)}
.accordion-head{
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  width:100%;
  padding:var(--sp-4) var(--sp-5);
  background:none;
  color:var(--c-text);
  font-size:var(--fs-md);
  font-weight:var(--fw-bold);
  text-align:left;
  cursor:pointer;
  user-select:none;
  transition:background-color var(--dur-2) var(--ease);
}
.accordion-head:hover{background:var(--c-primary-50)}
.accordion-head:focus-visible{outline:2px solid var(--c-primary);outline-offset:-2px}
.accordion-arrow{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:24px;height:24px;
  margin-left:auto;
  flex:0 0 auto;
  border-radius:var(--r-sm);
  background:var(--c-primary-50);
  color:var(--c-primary-600);
  font-size:11px;
  font-weight:var(--fw-black);
  transition:transform var(--dur-3) var(--ease-out),background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease);
}
.accordion-arrow::before{content:"▸"}
.accordion-head:hover .accordion-arrow{background:var(--c-primary-100)}
.accordion.open .accordion-arrow{transform:rotate(90deg);background:var(--c-primary-600);color:#fff}
.accordion-body{
  display:none;
  padding:0 var(--sp-5) var(--sp-5);
  font-size:var(--fs-sm);
  color:var(--c-text-2);
  line-height:var(--lh-base);
  border-top:1px solid var(--c-border);
  padding-top:var(--sp-4);
}
.accordion.open .accordion-body{display:block;animation:panel-in var(--dur-3) var(--ease-out) both}

/* --------------------------------------------------------------------------
   16. 加载态
   -------------------------------------------------------------------------- */
.skeleton{
  position:relative;
  display:block;
  min-height:14px;
  border-radius:var(--r-sm);
  background:var(--c-surface-3);
  overflow:hidden;
}
.skeleton::after{
  content:"";
  position:absolute;
  inset:0;
  transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,var(--c-glass-strong),transparent);
  animation:shimmer 1.4s var(--ease) infinite;
}
@keyframes shimmer{to{transform:translateX(100%)}}
.skeleton-text{height:12px;margin-bottom:var(--sp-2)}
.skeleton-text:last-child{width:64%}
.skeleton-title{height:18px;width:42%;margin-bottom:var(--sp-3)}
.skeleton-avatar{width:44px;height:44px;border-radius:var(--r-avatar);flex:0 0 auto}
.skeleton-card{height:110px;border-radius:var(--r-card)}

.spinner{
  display:inline-block;
  width:20px;height:20px;
  border:2px solid var(--c-primary-100);
  border-top-color:var(--c-primary);
  border-radius:50%;
  animation:spin .7s linear infinite;
}
.spinner-sm{width:14px;height:14px;border-width:2px}
.spinner-lg{width:32px;height:32px;border-width:3px}

.loading-mask{
  position:absolute;
  inset:0;
  z-index:5;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--sp-3);
  background:var(--c-glass);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
  border-radius:inherit;
  color:var(--c-muted);
  font-size:var(--fs-sm);
  animation:mask-in var(--dur-2) var(--ease) both;
}
.loading-mask::before{
  content:"";
  width:26px;height:26px;
  border:2.5px solid var(--c-primary-100);
  border-top-color:var(--c-primary);
  border-radius:50%;
  animation:spin .7s linear infinite;
}
/* 覆盖整个视口的全屏加载 */
.loading-mask.is-fixed{position:fixed;z-index:var(--z-toast)}

/* --------------------------------------------------------------------------
   17. 人机验证
   -------------------------------------------------------------------------- */
.captcha-box{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex-wrap:wrap;
}
.captcha-canvas,
.captcha-img{
  display:block;
  height:44px;
  width:auto;
  min-width:104px;
  border:1px solid var(--c-border);
  border-radius:var(--r-md);
  background:var(--c-surface-2);
  cursor:pointer;
  flex:0 0 auto;
  transition:border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease);
}
.captcha-canvas:hover,.captcha-img:hover{border-color:var(--c-primary-200);box-shadow:var(--sh-sm)}
.captcha-input{
  flex:1 1 120px;
  min-width:0;
  padding:10px 13px;
  min-height:44px;
  border:1px solid var(--c-border);
  border-radius:var(--r-md);
  background:var(--c-surface);
  color:var(--c-text);
  font-size:var(--fs-base);
  letter-spacing:.28em;
  text-transform:uppercase;
  transition:border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease);
}
.captcha-input:focus{border-color:var(--c-primary);box-shadow:var(--sh-focus-ring)}
.captcha-refresh{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:44px;height:44px;
  flex:0 0 auto;
  border:1px solid var(--c-border);
  border-radius:var(--r-md);
  background:var(--c-surface-2);
  color:var(--c-primary-600);
  font-size:var(--fs-md);
  cursor:pointer;
  transition:background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease),transform var(--dur-3) var(--ease);
}
.captcha-refresh:hover{background:var(--c-primary-100);color:var(--c-primary-700);transform:rotate(-90deg)}
.captcha-refresh:active{transform:rotate(-180deg) scale(.94)}

/* 17.1 拖动验证 */
.slider-verify{
  position:relative;
  width:100%;
  max-width:340px;
  padding:var(--sp-2);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  background:var(--c-surface-2);
  user-select:none;
  touch-action:none;
}
.slider-track{
  position:relative;
  height:44px;
  border-radius:var(--r-md);
  background:var(--c-surface-3);
  border:1px solid var(--c-border);
  overflow:hidden;
}
.slider-fill{
  position:absolute;
  top:0;left:0;bottom:0;
  width:0;
  background:linear-gradient(90deg,var(--c-primary-100),var(--c-primary-200));
  transition:width var(--dur-1) linear,background-color var(--dur-3) var(--ease);
}
.slider-verify.verified .slider-fill{background:linear-gradient(90deg,var(--c-success-100),var(--c-success))}
.slider-handle{
  position:absolute;
  top:50%;left:2px;
  transform:translateY(-50%);
  display:flex;
  align-items:center;
  justify-content:center;
  width:40px;height:40px;
  border-radius:var(--r-md);
  background:var(--c-surface);
  border:1px solid var(--c-primary-200);
  box-shadow:var(--sh-sm);
  color:var(--c-primary-600);
  font-size:var(--fs-md);
  cursor:grab;
  transition:box-shadow var(--dur-2) var(--ease),background-color var(--dur-2) var(--ease);
}
/* 纯 CSS 双向箭头图形 */
.slider-handle::before{
  content:"";
  width:12px;height:10px;
  background:
    linear-gradient(to right,currentColor 0 4px,transparent 4px) 0 0/4px 10px no-repeat,
    linear-gradient(to left,currentColor 0 4px,transparent 4px) 100% 0/4px 10px no-repeat,
    linear-gradient(to right,currentColor 0 6px,transparent 6px) 3px 4px/6px 2px no-repeat;
}
.slider-handle:active{cursor:grabbing;box-shadow:var(--sh-md)}
.slider-verify.verified .slider-handle{border-color:var(--c-success);color:var(--c-success-strong)}
.slider-hint{
  position:absolute;
  top:0;left:0;right:0;bottom:0;
  display:flex;
  align-items:center;
  justify-content:center;
  padding-left:52px;
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  color:var(--c-muted);
  pointer-events:none;
  letter-spacing:.02em;
}
.slider-verify.verified .slider-hint{color:var(--c-success-strong)}

/* 17.2 拼图验证 */
.slider-puzzle{
  position:relative;
  width:100%;
  max-width:340px;
  aspect-ratio:17/10;
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  overflow:hidden;
  background:
    repeating-linear-gradient(45deg,var(--c-surface-2) 0 12px,var(--c-surface-3) 12px 24px);
}
.slider-piece{
  position:absolute;
  top:0;left:0;
  width:56px;height:56px;
  border:2px solid var(--c-primary);
  border-radius:var(--r-xs);
  background:var(--g-primary);
  box-shadow:var(--sh-md);
  cursor:grab;
  z-index:2;
  transition:box-shadow var(--dur-2) var(--ease);
}
.slider-piece:active{cursor:grabbing;box-shadow:var(--sh-lg)}
.slider-hole{
  position:absolute;
  top:0;
  width:56px;height:56px;
  border:2px dashed var(--c-primary-200);
  border-radius:var(--r-xs);
  background:rgba(14,165,233,.12);
  z-index:1;
}

/* --------------------------------------------------------------------------
   18. 排名
   -------------------------------------------------------------------------- */
.rank-item{
  position:relative;
  display:flex;
  align-items:center;
  gap:var(--sp-4);
  padding:var(--sp-3) var(--sp-5);
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-xs);
  transition:transform var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease);
}
.rank-item:hover{border-color:var(--c-primary-200);box-shadow:var(--sh-md);transform:translateY(-1px)}
.rank-no{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:30px;height:30px;
  flex:0 0 auto;
  border-radius:var(--r-sm);
  background:var(--c-surface-3);
  color:var(--c-muted);
  font-size:var(--fs-sm);
  font-weight:var(--fw-black);
  font-variant-numeric:tabular-nums;
}
.rank-name{
  flex:1 1 auto;
  min-width:0;
  font-size:var(--fs-base);
  font-weight:var(--fw-semi);
  color:var(--c-text);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
/* 注意：DOM 里 .rank-coin 的内容本身已带"CM币"字样，这里不再追加伪元素，
   只做数字部分的字重与等宽数字对齐 */
.rank-coin{
  display:inline-flex;
  align-items:baseline;
  gap:3px;
  flex:0 0 auto;
  font-size:var(--fs-md);
  font-weight:var(--fw-black);
  color:var(--c-primary-600);
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
/* 前三名：金银铜 */
.rank-item.top1,
.rank-item.top2,
.rank-item.top3{
  border-color:transparent;
  box-shadow:var(--sh-md);
}
.rank-item.top1{background:linear-gradient(100deg,var(--c-warn-100),var(--c-surface) 62%)}
.rank-item.top2{background:linear-gradient(100deg,var(--c-surface-3),var(--c-surface) 62%)}
.rank-item.top3{background:linear-gradient(100deg,#ffedd5,var(--c-surface) 62%)}
.rank-item.top1 .rank-no{background:var(--g-gold);color:#fff;box-shadow:0 6px 14px -6px rgba(245,158,11,.9)}
.rank-item.top2 .rank-no{background:linear-gradient(135deg,#cbd5e1,#94a3b8);color:#fff}
.rank-item.top3 .rank-no{background:linear-gradient(135deg,#fdba74,#fb923c);color:#fff}
.rank-item.top1::before{
  content:"";
  position:absolute;
  left:0;top:var(--sp-2);bottom:var(--sp-2);
  width:3px;
  border-radius:0 var(--r-pill) var(--r-pill) 0;
  background:var(--g-gold);
}
/* 我自己：品牌色高亮 */
.rank-item.me{
  border-color:var(--c-primary);
  background:linear-gradient(100deg,var(--c-primary-50),var(--c-surface) 70%);
  box-shadow:0 0 0 2px var(--c-primary-100);
}
.rank-item.me .rank-name{font-weight:var(--fw-bold);color:var(--c-primary-700)}
.rank-item.me::after{
  content:"我";
  position:absolute;
  top:-7px;right:var(--sp-4);
  padding:1px 7px;
  border-radius:var(--r-pill);
  background:var(--g-primary);
  color:#fff;
  font-size:10px;
  font-weight:var(--fw-black);
  letter-spacing:.5px;
}

/* --------------------------------------------------------------------------
   19. 进度条
   -------------------------------------------------------------------------- */
.progress{
  position:relative;
  width:100%;
  height:8px;
  border-radius:var(--r-pill);
  background:var(--c-surface-3);
  overflow:hidden;
}
.progress-bar{
  display:block;
  height:100%;
  width:0;
  border-radius:inherit;
  background:var(--g-primary);
  transition:width var(--dur-5) var(--ease-out);
}
.progress-bar.ok{background:linear-gradient(90deg,var(--c-success),var(--c-success-strong))}
.progress-bar.warn{background:linear-gradient(90deg,var(--c-warn),var(--c-warn-strong))}
.progress-bar.danger{background:linear-gradient(90deg,#f87171,var(--c-danger-strong))}
/* 细/粗变体 */
.progress-sm{height:5px}
.progress-lg{height:12px}

/* --------------------------------------------------------------------------
   20. 时间线
   -------------------------------------------------------------------------- */
.timeline{
  position:relative;
  display:flex;
  flex-direction:column;
  gap:var(--sp-5);
  padding-left:var(--sp-6);
  margin:var(--sp-4) 0;
}
.timeline::before{
  content:"";
  position:absolute;
  top:var(--sp-2);bottom:var(--sp-2);left:6px;
  width:2px;
  border-radius:var(--r-pill);
  background:linear-gradient(180deg,var(--c-primary-200),var(--c-border));
}
.timeline-item{position:relative;min-width:0}
.timeline-item::before{
  content:"";
  position:absolute;
  top:5px;left:calc(var(--sp-6) * -1 + 1px);
  width:12px;height:12px;
  border-radius:50%;
  background:var(--c-surface);
  border:2px solid var(--c-primary);
  box-shadow:0 0 0 3px var(--c-primary-50);
}
.timeline-item.done::before{background:var(--c-success);border-color:var(--c-success)}
.timeline-item.warn::before{background:var(--c-warn);border-color:var(--c-warn)}
.timeline-time{
  display:block;
  font-size:var(--fs-2xs);
  color:var(--c-muted-2);
  font-variant-numeric:tabular-nums;
}
.timeline-title{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--c-text)}
.timeline-desc{font-size:var(--fs-xs);color:var(--c-muted);line-height:var(--lh-base);margin-top:2px}

/* --------------------------------------------------------------------------
   21. 键盘键位 / 代码
   -------------------------------------------------------------------------- */
.kbd{
  display:inline-block;
  min-width:22px;
  padding:2px 6px;
  border:1px solid var(--c-border-strong);
  border-bottom-width:2px;
  border-radius:var(--r-xs);
  background:var(--c-surface-2);
  color:var(--c-text-2);
  font-family:var(--font-mono);
  font-size:var(--fs-2xs);
  font-weight:var(--fw-semi);
  line-height:1.5;
  text-align:center;
  box-shadow:var(--sh-inset);
}
.code{
  display:inline-block;
  padding:2px 7px;
  border-radius:var(--r-xs);
  background:var(--c-surface-3);
  color:var(--c-primary-700);
  font-family:var(--font-mono);
  font-size:.92em;
  word-break:break-all;
}
pre.code,
pre .code{
  display:block;
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  background:var(--c-surface-2);
  color:var(--c-text-2);
  font-size:var(--fs-xs);
  line-height:var(--lh-base);
  overflow-x:auto;
  word-break:normal;
}

/* --------------------------------------------------------------------------
   22. 历史脚本使用的 .cap-wrap（图形验证码行）排版增强
   -------------------------------------------------------------------------- */
.cap-wrap{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
}
.cap-wrap input{flex:1 1 auto;min-width:0}
.cap-wrap canvas{
  flex:0 0 auto;
  border:1px solid var(--c-border);
  border-radius:var(--r-md);
  background:var(--c-surface-2);
  cursor:pointer;
  transition:border-color var(--dur-2) var(--ease);
}
.cap-wrap canvas:hover{border-color:var(--c-primary-200)}
