/* ============================================================
   v2-ui.css — 容大培训系统（v2 页面 / base_v2.html）
   补齐 prototype.css 未覆盖的 BEM 类，使 App.modal / App.confirm /
   App.toast 以及课程库侧边栏（#vd-tree）按钮在 v2 壳下拥有完整样式。
   - 仅作用于 v2 页面（由 base_v2.html 引入），不影响旧版 style.css 体系。
   - 所有颜色统一走 prototype 设计令牌，禁止硬编码十六进制以外的颜色。
   - 作用域：弹窗样式全部挂在 .modal-overlay 下，避免与 prototype 既有
     .modal（.modal-hd/.modal-bd/.modal-ft）冲突。
   ============================================================ */
:root{
  /* prototype 无「警示」令牌，此处补齐，供 toast--warn / 下架态使用 */
  --warn:#E0A458;
  /* 转正彩带配色（prototype 未定义 --confetti-*） */
  --confetti-1:var(--accent);
  --confetti-2:var(--green);
  --confetti-3:var(--orange);
  --confetti-4:var(--purple);
  --confetti-5:var(--yellow);
}

/* ===== 令牌桥：旧 design-tokens.css 词汇 → prototype 令牌 =====
   目的：从 style.css 移植的 BEM 组件（.table/.form-field/.status-pill 等）
   在 v2 壳下（仅加载 prototype.css + v2-ui.css）能正确解析颜色/尺寸/动效。
   全部映射到 prototype 调色板，不新增硬编码十六进制（白字/黄底文字对比除外）。
   注：--warn / --confetti-* 已在上方 :root 定义，此处不再重复以免自引用。 */
:root{
  /* 表面层 */
  --surface-deep: var(--surface-2);
  --surface-warm: var(--accent-050);
  /* 前景层 */
  --fg: var(--ink-900);
  --fg-strong: var(--ink-900);
  --fg-2: var(--ink-500);
  --muted: var(--ink-400);
  --meta: var(--ink-300);
  /* 强调色派生 */
  --accent-deep: var(--accent-700);
  --accent-soft: var(--accent-050);
  --accent-on: #FFFFFF;
  --accent-hover: var(--accent-600);
  --accent-active: var(--accent-700);
  /* 边框 */
  --border: var(--line);
  --border-strong: var(--line-2);
  --border-soft: var(--line);
  /* 字体 */
  --font-display: var(--font);
  --font-body: var(--font);
  --font-mono: "JetBrains Mono","SF Mono",Menlo,monospace;
  /* 字号（rem 基准 16px） */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-md: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 2rem;
  --text-4xl: 2.5rem;
  /* 行高 / 字距 */
  --leading-body: 1.6;
  --leading-tight: 1.25;
  --leading-relax: 1.75;
  --tracking-tight: -0.01em;
  --tracking-normal: 0;
  --tracking-caps: 0.08em;
  /* 字重 */
  --fw-regular: 400;
  --fw-emph: 600;
  --fw-announce: 700;
  /* 容器 */
  --container-max: 1200px;
  --container-wide: 1440px;
  --container-gutter: 24px;
  --section-y-desktop: 80px;
  --section-y-tablet: 48px;
  --section-y-phone: 32px;
  /* 辅色（prototype 已定义 --orange/--yellow，仅补其 soft/on 变体） */
  --orange-soft: var(--orange-100);
  --yellow-soft: var(--yellow-100);
  /* 语义色 */
  --success: var(--green);
  --success-soft: var(--green-100);
  --warn-soft: var(--yellow-100);
  --danger: var(--red);
  --danger-soft: var(--red-100);
  --info: var(--accent);
  --info-soft: var(--accent-050);
  /* 圆角 */
  --radius-sm: var(--r-sm);
  --radius-md: var(--r-sm);
  --radius-lg: var(--r-card);
  --radius-xl: var(--r-card);
  --radius-pill: var(--r-pill);
  /* 阴影 */
  --elev-flat: none;
  --elev-ring: 0 0 0 1px var(--line);
  --elev-raised: var(--shadow-1);
  --elev-float: var(--shadow-2);
  --elev-modal: var(--shadow-2);
  /* 动效 */
  --motion-fast: var(--dur-fast);
  --motion-base: var(--dur);
  --motion-slow: 320ms;
  --ease-standard: var(--ease);
  --ease-emph: var(--ease);
  --ease-exit: cubic-bezier(0.4,0,1,1);
  /* 焦点环 */
  --focus-ring: 0 0 0 3px var(--focus);
  /* 弹窗遮罩（组件内不直接写 rgba，统一走令牌） */
  --overlay-dim: rgba(15,23,42,0.45);
  /* B-slot 语义别名 */
  --level-locked: var(--line-2);
  --level-active: var(--accent);
  --level-completed: var(--green);
  --level-master: var(--orange);
  --level-perfect: var(--yellow);
  /* 吉祥物色域（白羊 PNG 在浅色面上的对比度靠蓝底徽托底） */
  --mascot-bg: var(--accent);
  --mascot-glow: var(--accent-050);
  --mascot-cheer: var(--orange-100);

/* 吉祥物蓝底徽：用于浅色面（顶栏品牌/侧边栏/商城卡），白羊在蓝底上高对比 */
.mascot-badge {
  background: var(--mascot-bg);
  border-radius: 26%;
}
  /* 地图路径 / 倒计时（员工端地图与倒计时组件使用） */
  --map-track: var(--line);
  --map-track-done: var(--green);
  --map-track-now: var(--accent);
  --countdown-near: var(--warn);
  --countdown-due: var(--red);
  /* 断点 */
  --bp-sm: 640px;
  --bp-md: 768px;
  --bp-lg: 1024px;
  --bp-xl: 1280px;
  --bp-2xl: 1536px;
}

/* ---------- 弹窗（App.modal 注入 .modal-overlay > .modal > .modal__*） ---------- */
.modal-overlay{
  position:fixed;inset:0;
  background:var(--overlay-dim);
  display:flex;align-items:center;justify-content:center;
  z-index:1000;padding:24px;
  animation:vo-fade var(--dur-fast) var(--ease);
}
@keyframes vo-fade{from{opacity:0}to{opacity:1}}
.modal-overlay .modal{
  background:var(--surface);
  border-radius:var(--r-card);
  width:100%;max-width:620px;
  box-shadow:var(--shadow-2);
  max-height:88vh;display:flex;flex-direction:column;overflow:hidden;
  animation:vo-pop var(--dur-fast) var(--ease);
}
@keyframes vo-pop{from{transform:translateY(8px) scale(.99);opacity:.6}to{transform:none;opacity:1}}
.modal-overlay .modal--wide{max-width:860px}
.modal-overlay .modal--drawer{max-width:460px;margin-left:auto;height:100%;border-radius:0}
.modal-overlay .modal__head{
  display:flex;align-items:center;gap:10px;
  padding:16px 20px;border-bottom:1px solid var(--line);
}
.modal-overlay .modal__title{
  margin:0;font-size:16px;font-weight:700;color:var(--ink-900);
  flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.modal-overlay .modal__body{
  padding:20px;overflow:auto;color:var(--ink-700);font-size:13px;line-height:1.6;
}
.modal-overlay .modal__body p{margin:0 0 8px}
.modal-overlay .modal__body p:last-child{margin-bottom:0}
.modal-overlay .modal__foot{
  display:flex;justify-content:flex-end;gap:10px;
  padding:14px 20px;border-top:1px solid var(--line);background:var(--surface-2);
}
/* 弹窗内 X 关闭按钮（App.modal 注入 .icon-btn） */
.icon-btn{
  width:32px;height:32px;border:0;background:none;border-radius:8px;
  color:var(--ink-400);display:inline-flex;align-items:center;justify-content:center;
  cursor:pointer;flex:none;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease);
}
.icon-btn:hover{background:var(--surface-2);color:var(--ink-900)}

/* ---------- 按钮变体（App.confirm 注入 .btn--*；prototype 仅有 .btn.pri 之类） ---------- */
.btn--primary{background:var(--accent);color:#fff}
.btn--primary:hover{background:var(--accent-600)}
.btn--ghost{color:var(--ink-500)}
.btn--ghost:hover{background:var(--surface-2);color:var(--accent)}
.btn--danger{color:var(--red);border-color:var(--red-100);background:var(--red-100)}
.btn--danger:hover{background:var(--red);color:#fff;border-color:var(--red)}
.btn--sm{height:28px;padding:0 10px;font-size:12px}
.btn--block{width:100%}

/* ---------- Toast（App.toast 注入 .toast--*） ---------- */
#toast-root{
  position:fixed;top:18px;right:18px;z-index:1100;
  display:flex;flex-direction:column;gap:10px;
}
.toast{
  display:flex;align-items:flex-start;gap:10px;min-width:240px;max-width:360px;
  padding:12px 14px;border-radius:var(--r-card);
  background:var(--surface);box-shadow:var(--shadow-2);border:1px solid var(--line);
  font-size:13px;color:var(--ink-900);
  animation:vo-toast var(--dur-fast) var(--ease);
}
@keyframes vo-toast{from{transform:translateX(12px);opacity:0}to{transform:none;opacity:1}}
.toast.is-leaving{opacity:0;transform:translateX(12px);transition:all var(--dur-fast) var(--ease)}
.toast__icon{flex:none;display:inline-flex;line-height:0}
.toast__body{flex:1 1 auto;min-width:0;line-height:1.5}
.toast--success{border-left:3px solid var(--green)}
.toast--success .toast__icon{color:var(--green)}
.toast--warn{border-left:3px solid var(--warn)}
.toast--warn .toast__icon{color:var(--warn)}
.toast--danger{border-left:3px solid var(--red)}
.toast--danger .toast__icon{color:var(--red)}
.toast--info{border-left:3px solid var(--accent)}
.toast--info .toast__icon{color:var(--accent)}

/* ---------- 课程库侧边栏（#vd-tree）：层级缩进 / 按钮间距 / hover / active ---------- */
.tree .node{
  display:flex;align-items:center;gap:8px;
  padding:7px 8px;border-radius:10px;cursor:pointer;
  transition:background var(--dur-fast) var(--ease);
}
.tree .node:hover{background:var(--surface-2)}
.tree .node.on{background:var(--accent-050)}
.tree .node.on .node-label{color:var(--accent);font-weight:600}
.tree .node .caret{
  flex:none;width:18px;height:18px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--ink-400);border:0;background:none;cursor:pointer;
}
.tree .node .caret:hover{color:var(--accent)}
.tree .node.lv3{padding-left:30px}
.tree .node .row{display:flex;align-items:center;gap:4px;margin-left:auto}
.tree .node .row .btn{
  width:28px;height:28px;padding:0;
  border-color:transparent;background:transparent;color:var(--ink-400);
}
.tree .node .row .btn:hover{
  background:var(--accent-050);color:var(--accent);border-color:var(--accent-100);
}
/* 展开/收起箭头（.caret）旋转过渡 */
.tree .node .caret svg{transition:transform var(--dur-fast) var(--ease)}

/* 学习地图管理：培训类型选择器 */
.tt-sel{display:inline-flex;align-items:center;gap:6px;margin-right:2px}
.tt-sel>span{font-size:13px;color:var(--ink-500)}
.tt-sel .sel{height:34px}

/* 课程库侧边栏：名称完整展示 + 操作聚合为 kebab 菜单 */
.tree .node .node-label{flex:1;min-width:0;word-break:break-word}
.tree .node .node-kebab{
  flex:none;width:28px;height:28px;padding:0;
  border:1px solid transparent;background:transparent;color:var(--ink-400);border-radius:8px;
}
.tree .node .node-kebab:hover{background:var(--accent-050);color:var(--accent);border-color:var(--accent-100)}
.tree .node.on .node-kebab{color:var(--accent)}

/* 操作浮层菜单（kebab 展开） */
.acts-menu{
  position:fixed;z-index:200;min-width:152px;
  background:#fff;border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--shadow-2);padding:6px;
}
.acts-menu__i{
  display:flex;align-items:center;gap:8px;width:100%;
  padding:8px 10px;border:0;background:transparent;border-radius:8px;
  font-size:13px;color:var(--ink-700);cursor:pointer;text-align:left;
}
.acts-menu__i:hover{background:var(--accent-050);color:var(--accent)}
.acts-menu__i:disabled{opacity:.4;cursor:not-allowed}
.acts-menu__i.is-danger{color:var(--red)}
.acts-menu__i.is-danger:hover{background:var(--danger-soft);color:var(--red)}
.acts-menu__i svg{width:16px;height:16px;flex:none}

/* ---------- 课程卡片「下架 / 上架」切换（renderCards 注入） ---------- */
.ccard .cf .linkbtn{color:var(--ink-500)}
.ccard .cf .linkbtn:hover{color:var(--accent);text-decoration:underline}
.ccard .cf .linkbtn.is-danger{color:var(--red)}
.ccard .cf .linkbtn.is-danger:hover{color:var(--red)}
.ccard .cf .linkbtn.is-brand{color:var(--accent)}

/* ============================================================
   以下组件类原定义在 style.css（旧壳），v2 页面不加载 style.css，
   故在此移植。颜色经上方「令牌桥」全部解析为 prototype 调色板。
   ============================================================ */

/* ---------- 表单控件 ---------- */
.form-field { display: block; margin-bottom: 18px; }
.form-field__label {
  display: block; font-size: var(--text-sm); font-weight: var(--fw-emph);
  color: var(--fg-2); margin-bottom: 8px;
}
.form-field__label .req { color: var(--danger); margin-left: 2px; }

.form-field__input,
input[type="text"].form-field__input,
input[type="password"].form-field__input,
input[type="tel"].form-field__input,
input[type="number"].form-field__input,
input[type="email"].form-field__input,
input[type="date"].form-field__input,
select.form-field__input,
textarea.form-field__input {
  width: 100%; padding: 12px 14px; font-size: var(--text-md); color: var(--fg);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  font-family: inherit; line-height: 1.4;
  transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard);
  -webkit-appearance: none;
}
.form-field__input:hover { border-color: var(--accent); }
.form-field__input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); outline: none; }
.form-field__input::placeholder { color: var(--meta); }
.form-field__input.is-error { border-color: var(--danger); background: var(--danger-soft); }
.form-field__input.is-error:focus { box-shadow: 0 0 0 3px var(--danger-soft); }
.form-field__hint  { display: block; font-size: var(--text-xs); color: var(--meta); margin-top: 6px; }
.form-field__error { display: block; font-size: var(--text-xs); color: var(--danger); margin-top: 6px; min-height: 0; }
.form-field__error[hidden] { display: none; }

.form-row { display: flex; gap: 12px; align-items: flex-start; }
.form-row .form-field { flex: 1; }

.input-group { position: relative; display: flex; align-items: stretch; }
.input-group .form-field__input { padding-right: 80px; }
.input-group__append {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  border: none; background: var(--accent-soft); color: var(--accent-deep);
  padding: 6px 12px; border-radius: var(--radius-sm); cursor: pointer;
  font-size: var(--text-sm); font-weight: var(--fw-emph);
  transition: background var(--motion-fast) var(--ease-standard);
}
.input-group__append:hover:not([disabled]) { background: var(--accent); color: var(--accent-on); }
.input-group__append[disabled] { background: var(--surface-deep); color: var(--meta); cursor: not-allowed; }
.input-group__toggle {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  border: none; background: transparent; color: var(--muted); cursor: pointer;
  font-size: var(--text-sm); padding: 4px 6px;
}
.input-group__toggle:hover { color: var(--accent); }

.checkbox { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--text-sm); color: var(--fg-2); user-select: none; }
.checkbox input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.checkbox.is-error { color: var(--danger); }

.pw-strength { display: flex; gap: 4px; margin-top: 8px; }
.pw-strength__seg {
  flex: 1; height: 4px; border-radius: var(--radius-pill);
  background: var(--surface-deep); transition: background var(--motion-fast) var(--ease-standard);
}
.pw-strength__seg.is-weak   { background: var(--danger); }
.pw-strength__seg.is-mid    { background: var(--warn); }
.pw-strength__seg.is-strong { background: var(--success); }
.pw-strength__hint { display: block; font-size: var(--text-xs); color: var(--meta); margin-top: 4px; min-height: 1em; }

.alert {
  display: flex; gap: 10px; padding: 10px 14px;
  border-radius: var(--radius-md); font-size: var(--text-sm);
  border: 1px solid transparent; margin-bottom: 16px;
}
.alert--danger  { background: var(--danger-soft);  border-color: var(--danger);  color: var(--danger); }
.alert--info    { background: var(--info-soft);    border-color: var(--info);    color: var(--info); }

/* ---------- 表格 ---------- */
.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.table th, .table td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--border); }
.table th { background: var(--surface-deep); color: var(--fg-2); font-weight: var(--fw-emph); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; }
.table tr:hover td { background: var(--surface-warm); }
.table td.is-actions { text-align: right; white-space: nowrap; }
.table--compact th, .table--compact td { padding: 8px 12px; }
.table-wrap { overflow-x: auto; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface); }
.table-empty { padding: 48px 16px; text-align: center; color: var(--muted); }

/* ---------- 标签 / 状态 / 徽章 ---------- */
.tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 10px; font-size: var(--text-xs); font-weight: var(--fw-emph);
  border-radius: var(--radius-pill); background: var(--surface-deep); color: var(--muted);
}
.tag--accent { background: var(--accent-soft); color: var(--accent-deep); }
.tag--success { background: var(--green-100); color: var(--green); }
.tag--warn    { background: var(--warn-soft); color: var(--warn); }
.tag--danger  { background: var(--red-100); color: var(--red); }
.tag--info    { background: var(--info-soft); color: var(--info); }
.tag--ok      { background: var(--green-100); color: var(--green); }
.tag--muted   { background: var(--surface-deep); color: var(--muted); }
.tag-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.status-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; font-size: var(--text-xs); font-weight: var(--fw-emph);
  border-radius: var(--radius-pill);
}
.status-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status-pill--active   { background: var(--green-100); color: var(--green); }
.status-pill--locked   { background: var(--surface-deep); color: var(--muted); }
.status-pill--pending  { background: var(--warn-soft); color: var(--warn); }
.status-pill--approved { background: var(--accent-050); color: var(--accent); }
.status-pill--rejected { background: var(--red-100); color: var(--red); }
.status-pill--completed { background: var(--green-100); color: var(--green); }
.status-pill--unlocked { background: var(--accent-050); color: var(--accent); }

/* ---------- 兜底：裸 .input / .required / .linkbtn ---------- */
.input {
  width: 100%; padding: 12px 14px; font-size: var(--text-md); color: var(--fg);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  font-family: inherit; line-height: 1.4;
  transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard);
}
.input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); outline: none; }
.input::placeholder { color: var(--meta); }
.required { color: var(--danger); }
.linkbtn {
  display: inline-flex; align-items: center; gap: 4px;
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--accent); font-size: var(--text-sm); font-weight: var(--fw-emph);
}
.linkbtn:hover { color: var(--accent-hover); text-decoration: underline; }
.linkbtn.is-danger { color: var(--danger); }
.linkbtn.is-brand { color: var(--accent); }

/* ============================================================
   以下组件类原定义在 style.css（旧壳），经「令牌桥」解析为 prototype
   调色板后移植至此。颜色全部走令牌，无硬编码 hex/rgba，无弹跳缓动。
   ============================================================ */

/* ---------- 通用组件（无媒体查询） ---------- */
.auth-tab.is-active {
 background: var(--surface); color: var(--accent); box-shadow: var(--elev-raised); 
}
.auth-tab:hover:not(.is-active) {
 color: var(--fg); 
}
.btn[disabled], .btn.is-loading {
 opacity: 0.6; cursor: not-allowed; pointer-events: none; 
}
.btn.is-loading::after {

  content: ""; width: 14px; height: 14px; margin-left: 8px;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: spin 0.8s linear infinite;

}
.topbar {

  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 24px; background: var(--surface);
  border-bottom: 1px solid var(--border); box-shadow: var(--elev-raised);

}
.topbar__brand {

  display: inline-flex; align-items: center; gap: 8px;
  color: var(--accent); font-weight: var(--fw-announce); font-size: var(--text-lg);

}
.topbar__nav {
 display: none; gap: 24px; 
}
.topbar__link.is-active {
 color: var(--accent); border-bottom-color: var(--accent); 
}
.topbar__right {
 display: flex; align-items: center; gap: 8px; position: relative; 
}
.topbar__user {

  display: inline-flex; align-items: center; gap: 6px;
  color: var(--fg-2); padding: 6px 10px; border-radius: var(--radius-md);

}
.topbar__user:hover {
 background: var(--surface-deep); 
}
.topbar__dot {

  position: absolute; top: 6px; right: 6px;
  width: 8px; height: 8px; background: var(--danger); border-radius: 50%;

}
.mascot-fallback {

  display: inline-flex; align-items: center; justify-content: center;
  width: 160px; height: 200px; background: var(--mascot-bg); border-radius: var(--radius-lg);
  color: var(--muted); font-size: var(--text-sm);

}
.empty-state, .error-state {

  padding: 56px 24px; text-align: center; color: var(--muted);

}
.empty-state__title, .error-state__title {
 font-size: var(--text-md); color: var(--fg-2); 
}
.error-state__title {
 color: var(--danger); 
}
.page-shell--admin .sidebar {
 display: flex; 
}
.page-shell--admin .admin-topbar {
 display: flex; 
}
body.body--admin > .admin-topbar {
 grid-column: 1 / -1; grid-row: 1; display: flex; 
}
body.body--admin > .sidebar {
 grid-column: 1; grid-row: 2; display: flex; flex-direction: column; min-height: 0; 
}
.employee-content {
 flex: 1; padding: 24px 0 80px; 
}
.section-title {

  display: flex; align-items: center; justify-content: space-between;
  margin: 16px 0 12px;

}
.section-title h2 {

  font-size: var(--text-lg); font-weight: var(--fw-announce);
  color: var(--fg-strong); margin: 0; letter-spacing: var(--tracking-tight);

}
.card--hover {
 transition: box-shadow var(--motion-fast) var(--ease-standard), transform var(--motion-fast) var(--ease-standard); 
}
.card--hover:hover {
 box-shadow: var(--elev-float); transform: translateY(-2px); 
}
.card__head {
 display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; 
}
.card__head h3 {
 font-size: var(--text-lg); font-weight: var(--fw-announce); color: var(--fg-strong); margin: 0; 
}
.card__body {
 color: var(--fg); 
}
.sidebar {

  flex-direction: column; background: var(--surface);
  border-right: 1px solid var(--border); width: 240px; min-height: 100vh;

}
.sidebar__brand {

  display: flex; align-items: center; gap: 10px;
  padding: 20px 20px; font-size: var(--text-md); font-weight: var(--fw-announce);
  color: var(--accent); border-bottom: 1px solid var(--border-soft);

}
.sidebar__nav {
 flex: 1; padding: 12px 8px; display: flex; flex-direction: column; gap: 2px; overflow-y: auto; 
}
.sidebar__link.is-active {
 background: var(--accent-soft); color: var(--accent-deep); 
}
.sidebar__foot {

  padding: 16px 20px; border-top: 1px solid var(--border-soft);
  display: flex; flex-direction: column; gap: 10px;

}
.sidebar__name {
 font-size: var(--text-sm); color: var(--fg); font-weight: var(--fw-emph); 
}
.sidebar__logout {

  display: inline-flex; align-items: center; gap: 6px; background: transparent; border: none;
  color: var(--muted); cursor: pointer; padding: 6px 0; font-size: var(--text-sm);
  font-family: inherit; transition: color var(--motion-fast);

}
.sidebar__logout:hover {
 color: var(--danger); 
}
.admin-topbar {

  display: flex; align-items: center; gap: 12px;
  padding: 12px 24px; background: var(--surface); border-bottom: 1px solid var(--border);
  box-shadow: var(--elev-raised);

}
.admin-topbar__menu {
 display: inline-flex; 
}
.admin-topbar__crumb {
 flex: 1; font-size: var(--text-md); font-weight: var(--fw-emph); color: var(--fg); 
}
.admin-topbar__right {
 display: flex; align-items: center; gap: 6px; 
}
.admin-topbar__switch {

  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent-deep); border-color: var(--accent-soft);
  background: var(--accent-soft);

}
.admin-topbar__switch:hover {
 background: var(--accent); color: var(--accent-on); border-color: var(--accent); 
}
.impersonate-bar {

  position: relative; z-index: 120;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px;
  background: linear-gradient(135deg, var(--accent) 0%, var(--green) 100%);
  color: var(--accent-on); font-size: var(--text-sm);

}
.impersonate-bar__dot {

  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: var(--yellow-100); box-shadow: 0 0 0 4px var(--yellow-100);

}
.impersonate-bar__txt {
 flex: 1; font-weight: var(--fw-emph); 
}
.impersonate-bar__btn {

  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: var(--radius-pill);
  background: var(--accent-on); color: var(--accent-on); font-weight: var(--fw-emph);
  text-decoration: none; white-space: nowrap;

}
.impersonate-bar__btn:hover {
 background: var(--accent-on); 
}
.tabbar {

  position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
  display: flex; justify-content: space-around; align-items: stretch;
  padding: 6px 0 calc(6px + env(safe-area-inset-bottom));
  background: var(--surface); border-top: 1px solid var(--border); box-shadow: 0 -2px 12px var(--shadow-1);

}
.tabbar__item.is-active {
 color: var(--accent); 
}
.esidebar {
 display: none; 
}
.esidebar__brand {

  display: flex; align-items: center; gap: 10px;
  padding: 20px 20px; font-size: var(--text-md); font-weight: var(--fw-announce);
  color: var(--accent); border-bottom: 1px solid var(--border-soft);

}
.esidebar__nav {
 flex: 1; padding: 12px 8px; display: flex; flex-direction: column; gap: 2px; overflow-y: auto; 
}
.esidebar__link.is-active {
 background: var(--accent-soft); color: var(--accent-deep); 
}
.esidebar__foot {

  padding: 16px 20px; border-top: 1px solid var(--border-soft);
  display: flex; flex-direction: column; gap: 10px;

}
.esidebar__notify {

  display: inline-flex; align-items: center; gap: 8px; position: relative;
  background: transparent; border: none; color: var(--fg-2); cursor: pointer;
  padding: 6px 0; font-size: var(--text-sm); font-family: inherit; text-align: left;
  transition: color var(--motion-fast);

}
.esidebar__notify:hover {
 color: var(--accent); 
}
.esidebar__dot {

  position: absolute; top: 2px; left: 22px; width: 8px; height: 8px;
  background: var(--danger); border-radius: 50%;

}
.esidebar__name {
 font-size: var(--text-sm); color: var(--fg); font-weight: var(--fw-emph); 
}
.esidebar__logout {

  display: inline-flex; align-items: center; gap: 6px; background: transparent; border: none;
  color: var(--muted); cursor: pointer; padding: 6px 0; font-size: var(--text-sm);
  font-family: inherit; transition: color var(--motion-fast);

}
.esidebar__logout:hover {
 color: var(--danger); 
}
/* 管理端侧栏「退出登录」：复用 .sb a 链接样式，hover 转红（令牌，非硬编色） */
.sb .sb-logout:hover { color: var(--red); }
body.has-impersonate .esidebar {
 top: 38px; bottom: 0; 
}
.stat-card {

  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 18px 20px;
  display: flex; flex-direction: column; gap: 4px;
  transition: box-shadow var(--motion-fast) var(--ease-standard);

}
.stat-card:hover {
 box-shadow: var(--elev-raised); 
}
.stat-card__label {
 font-size: var(--text-sm); color: var(--muted); 
}
.stat-card--accent .stat-card__label, .stat-card--accent .stat-card__value {
 color: var(--accent-on); 
}
.badge-chip__icon {
 width: 64px; height: 64px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-md); background: var(--surface-deep); color: var(--warn); 
}
.gift-card {

  display: flex; flex-direction: column; gap: 8px;
  padding: 14px; border-radius: var(--radius-lg);
  background: var(--surface); border: 1px solid var(--border);

}
.gift-card__cover {

  width: 100%; aspect-ratio: 1 / 1; border-radius: var(--radius-md);
  background: var(--surface-deep); display: flex; align-items: center; justify-content: center;
  overflow: hidden; color: var(--muted);

}
.gift-card__cover img {
 width: 100%; height: 100%; object-fit: contain; 
}
.gift-card__ph {
 color: var(--muted); opacity: 0.7; 
}
.gift-card__name {
 font-weight: var(--fw-emph); color: var(--ink-900); 
}
.gift-card__desc {
 flex: 1; 
}
.gift-card__foot {
 display: flex; align-items: center; justify-content: space-between; gap: 8px; 
}
.gift-card__cost {
 font-weight: var(--fw-emph); color: var(--accent-deep); 
}
.stat-num {
 font-size: var(--text-xl); font-weight: var(--fw-announce); color: var(--ink-900); line-height: 1.2; 
}
.map-hero {

  background: linear-gradient(160deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on); border-radius: var(--radius-lg); padding: 28px 24px;
  display: flex; align-items: center; gap: 24px; flex-wrap: wrap;
  box-shadow: var(--elev-float);
  position: relative; overflow: hidden;

}
.map-hero::before {

  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle at 80% 20%, var(--mascot-glow) 0%, transparent 60%);
  pointer-events: none;

}
.map-banner {

  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 18px 20px;
  background: linear-gradient(135deg, var(--orange-100) 0%, var(--red-100) 60%, var(--red-100) 100%);
  border-radius: var(--radius-xl);
  box-shadow: var(--elev-raised);
  margin-bottom: 16px; position: relative; overflow: hidden;

}
.map-banner::before {

  content:""; position:absolute; inset:0;
  background: radial-gradient(circle at 90% 30%, var(--accent-on) 0%, transparent 55%);
  pointer-events: none;

}
.map-banner__greet h1 {

  font-size: var(--text-2xl); font-weight: var(--fw-announce);
  margin: 0 0 4px; color: var(--fg-strong); letter-spacing: var(--tracking-tight);

}
.map-banner__greet p {

  margin: 0; color: var(--ink-700); font-size: var(--text-sm); font-weight: var(--fw-emph);

}
.map-banner__stage {
 color: var(--accent-deep); padding: 1px 6px; background: var(--accent-on); border-radius: var(--radius-sm); 
}
.map-banner__stats {
 display: flex; gap: 12px; flex-wrap: wrap; 
}
.map-banner__stat {

  display: flex; flex-direction: column; align-items: center;
  background: var(--accent-on); padding: 6px 12px;
  border-radius: var(--radius-md); min-width: 64px;

}
.map-banner__stat .num {
 font-size: var(--text-xl); font-weight: var(--fw-announce); color: var(--fg-strong); line-height: 1; font-family: var(--font-num); 
}
.map-banner__stat .lab {
 font-size: 11px; color: var(--muted); 
}
.map-page {
 padding: 16px 0 24px; 
}
.map-world {

  position: relative;
  width: 100%; aspect-ratio: 1200 / 750;
  max-width: 1200px; margin: 0 auto;
  border-radius: var(--radius-xl);
  background: linear-gradient(180deg, var(--accent-050) 0%, var(--accent-100) 50%, var(--accent) 100%);
  overflow: hidden; box-shadow: var(--elev-float);

}
.map-world__bg {

  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
  display: block; user-select: none; pointer-events: none;

}
.map-stations {
 position: absolute; inset: 0; pointer-events: none; 
}
.station {

  --sx: 50%; --sy: 50%;
  position: absolute; left: var(--sx); top: var(--sy);
  transform: translate(-50%, -50%);
  pointer-events: auto; text-decoration: none; color: inherit;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  z-index: 3;

}
.station__dot {

  width: 56px; height: 56px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, var(--accent-on) 0%, var(--accent-050) 100%);
  border: 4px solid var(--accent);
  box-shadow: 0 6px 18px var(--accent), 0 0 0 4px var(--accent-on);
  transition: transform var(--motion-base) var(--ease-standard);
  position: relative;

}
.station__dot::before {

  content: ""; position: absolute; inset: -10px;
  border-radius: 50%;
  border: 2px dashed var(--accent);
  animation: dot-spin 12s linear infinite;
  pointer-events: none;

}
.station__dot-num {

  font-family: var(--font-num); font-size: 26px; font-weight: 800;
  color: var(--accent); line-height: 1;
  text-shadow: 0 1px 2px var(--accent);

}
.station--unlocked .station__dot {

  background: linear-gradient(180deg, var(--yellow-100) 0%, var(--orange) 100%);
  border-color: var(--accent-on);
  box-shadow: 0 6px 18px var(--orange), 0 0 0 4px var(--accent-on);
  animation: dot-pulse 1.6s ease-in-out infinite;

}
.station--unlocked .station__dot-num {
 color: var(--accent-on); text-shadow: 0 2px 4px var(--orange); 
}
.station--completed .station__dot {

  background: linear-gradient(180deg, var(--green-100) 0%, var(--green) 100%);
  border-color: var(--accent-on);
  box-shadow: 0 6px 18px var(--green), 0 0 0 4px var(--accent-on);

}
.station--completed .station__dot-num {
 color: var(--accent-on); text-shadow: 0 2px 4px var(--green); 
}
.station--locked .station__dot {

  background: var(--accent-on);
  border-color: var(--line);
  box-shadow: 0 4px 10px var(--shadow-1), 0 0 0 4px var(--accent-on);

}
.station--locked .station__dot::before {
 display: none; 
}
.station--locked .station__dot-num {
 color: var(--ink-400); 
}
.station:hover .station__dot {
 transform: scale(1.15); 
}
.station__card {

  position: absolute; bottom: calc(100% + 10px); left: 50%;
  transform: translate(-50%, 6px);
  width: 200px; padding: 10px 12px;
  background: var(--accent-on);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--shadow-1);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px var(--shadow-1);
  display: flex; flex-direction: column; gap: 4px;
  text-align: left;
  opacity: 0; pointer-events: none;
  transition: opacity var(--motion-base) var(--ease-standard),
              transform var(--motion-base) var(--ease-standard);
  z-index: 4;

}
.station__card::after {

  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent;
  border-top: 9px solid var(--accent-on);

}
.station__card-head {

  display: flex; align-items: center; justify-content: space-between;

}
.station__chip {

  font-size: 10px; font-weight: var(--fw-announce); padding: 2px 6px;
  background: var(--accent-soft); color: var(--accent-deep); border-radius: var(--radius-sm);

}
.station__day {
 font-size: 10px; color: var(--muted); font-family: var(--font-num); 
}
.station__name {

  font-size: 14px; font-weight: var(--fw-announce); color: var(--fg-strong);
  line-height: 1.2; margin-top: 2px;

}
.station__topic {

  font-size: 11px; color: var(--muted); line-height: 1.4;

}
.station__status {

  display: flex; align-items: center; justify-content: space-between;
  margin-top: 4px; padding-top: 6px; border-top: 1px dashed var(--border-soft);

}
.station__status-text {
 font-size: 11px; color: var(--muted); font-weight: var(--fw-emph); 
}
.station__status-text.is-active {
 color: var(--accent-deep); 
}
.station__status-text.is-done {
 color: var(--success); 
}
.station__cta {

  font-size: 11px; padding: 2px 8px; border-radius: var(--radius-pill);
  background: var(--surface-deep); color: var(--muted);
  display: inline-flex; align-items: center; gap: 2px;

}
.station__cta--go {

  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on);

}
.station__cta--done {
 background: var(--success); color: var(--accent-on); 
}
.station:hover .station__card,
.station:focus-within .station__card {

  opacity: 1; pointer-events: auto;
  transform: translate(-50%, 0);

}
.station--n1 .station__card,
.station--n4 .station__card {
 left: 0; transform: translate(0, 6px); 
}
.station--n1 .station__card::after,
.station--n4 .station__card::after {
 left: 24px; transform: none; 
}
.station--n1:hover .station__card,
.station--n4:hover .station__card,
.station--n1:focus-within .station__card,
.station--n4:focus-within .station__card {
 transform: translate(0, 0); 
}
.station--n5 .station__card {
 left: auto; right: 0; transform: translate(0, 6px); 
}
.station--n5 .station__card::after {
 left: auto; right: 24px; transform: none; 
}
.station--n5:hover .station__card,
.station--n5:focus-within .station__card {
 transform: translate(0, 0); 
}
.station--completed .station__card {
 background: linear-gradient(180deg, var(--green-100) 0%, var(--accent-on) 100%); border-color: var(--green-100); 
}
.station--locked .station__card {
 background: var(--surface); 
}
.station--locked .station__name {
 color: var(--muted); 
}
.station__here {

  position: absolute;
  left: calc(100% + 10px); top: 50%;
  transform: translate(8px, -50%) scale(.7);
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 11px;
  background: linear-gradient(180deg, var(--yellow-100) 0%, var(--yellow-100) 100%);
  border: 2px solid var(--orange);
  border-radius: 999px;
  color: var(--orange);
  font-size: 12px; font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 6px 14px var(--orange);
  opacity: 0; pointer-events: none;
  z-index: 6;

}
.station__here-arrow {

  width: 0; height: 0;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  border-right: 9px solid var(--orange);
  position: absolute; left: -9px; top: 50%; transform: translateY(-50%);

}
.station__here-text::before {
 content: ""; 
}
.station--side-left .station__here {

  left: auto; right: calc(100% + 10px);
  transform: translate(-8px, -50%) scale(.7);

}
.station--side-left .station__here-arrow {

  left: auto; right: -9px;
  border-right: none;
  border-left: 9px solid var(--orange);

}
.station.is-here .station__here {

  opacity: 1;
  transform: translate(0, -50%) scale(1);
  animation: here-pulse 1.6s ease-in-out infinite;

}
.station--side-left.station.is-here .station__here {

  transform: translate(0, -50%) scale(1);

}
.station.is-here .station__dot {

  animation: halo-pulse 1.6s ease-in-out infinite;

}
.map-shortcuts {

  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
  margin-top: 16px; max-width: 1200px; margin-left: auto; margin-right: auto;

}
.map-shortcut {

  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  color: var(--fg); font-weight: var(--fw-emph); font-size: var(--text-sm);
  transition: all var(--motion-fast) var(--ease-standard);

}
.map-shortcut:hover {

  border-color: var(--accent); color: var(--accent-deep);
  transform: translateY(-2px); box-shadow: var(--elev-raised);

}
.map-shortcut__ico {

  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-deep);

}
.map-mobile-list {
 display: none; 
}
.map-mobile-item {

  flex: 0 0 70vw; max-width: 260px; min-width: 200px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 14px; display: flex; flex-direction: column; gap: 6px;
  scroll-snap-align: center;
  box-shadow: var(--elev-raised);
  text-decoration: none; color: inherit;

}
.map-mobile-item:active {
 transform: scale(.98); 
}
.map-mobile-item__row {
 display: flex; align-items: center; justify-content: space-between; 
}
.map-mobile-item__chip {

  font-size: 11px; font-weight: var(--fw-announce); padding: 2px 6px;
  background: var(--accent-soft); color: var(--accent-deep); border-radius: var(--radius-sm);

}
.map-mobile-item__day {
 font-size: 11px; color: var(--muted); font-family: var(--font-num); 
}
.map-mobile-item__name {
 font-size: var(--text-md); font-weight: var(--fw-announce); color: var(--fg-strong); 
}
.map-mobile-item__topic {
 font-size: 12px; color: var(--muted); 
}
.map-mobile-item__status {

  display: flex; align-items: center; justify-content: space-between;
  margin-top: 6px; padding-top: 8px; border-top: 1px dashed var(--border-soft);

}
.map-mobile-item__btn {

  font-size: 12px; font-weight: var(--fw-emph);
  padding: 6px 14px; border-radius: var(--radius-pill);
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on);

}
.map-mobile-item--locked .map-mobile-item__btn {
 background: var(--surface-deep); color: var(--muted); 
}
.map-mobile-item--completed .map-mobile-item__btn {
 background: linear-gradient(135deg, var(--green) 0%, var(--green) 100%); 
}
.page-level .level-head {

  display: flex; align-items: center; gap: 16px; padding: 20px;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on); border-radius: var(--radius-lg); margin-bottom: 16px;

}
.page-level .level-head__icon {
 width: 56px; height: 56px; border-radius: 50%; background: var(--accent-on); display: flex; align-items: center; justify-content: center; 
}
.page-level .level-head h1 {
 margin: 0; font-size: var(--text-xl); color: var(--accent-on); 
}
.page-level .level-head p {
 margin: 4px 0 0; color: var(--accent-on); font-size: var(--text-sm); 
}
.video-grid {
 display: grid; gap: 16px; margin-top: 16px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); 
}
.video-card {

  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  overflow: hidden; cursor: pointer; transition: all var(--motion-fast) var(--ease-standard);

}
.video-card:hover {
 box-shadow: var(--elev-raised); transform: translateY(-2px); 
}
.video-card__cover {
 aspect-ratio: 16/9; background: linear-gradient(135deg, var(--accent-soft) 0%, var(--surface-deep) 100%); display: flex; align-items: center; justify-content: center; color: var(--accent); 
}
.video-card__body {
 padding: 12px 14px; 
}
.video-card__title {
 font-size: var(--text-md); font-weight: var(--fw-announce); color: var(--fg-strong); margin: 0 0 4px; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; 
}
.video-card__meta {
 font-size: var(--text-xs); color: var(--muted); display: flex; gap: 8px; 
}
.video-card__cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-card__done {
 position: absolute; left: 8px; top: 8px; display: inline-flex; align-items: center; gap: 4px;
 background: var(--green); color: #fff; font-size: 11px; line-height: 1; padding: 4px 8px;
 border-radius: var(--r-pill);
}
.lc-done-txt { color: var(--green); font-weight: var(--fw-announce); }
.lc-sec {
 font-size: var(--text-xs); color: var(--muted); font-weight: var(--fw-announce);
 padding: 12px 0 2px; letter-spacing: .02em;
}
.tabs__item.is-active {
 background: var(--surface); color: var(--accent); box-shadow: var(--elev-raised); 
}
.tabs__item:hover:not(.is-active) {
 color: var(--fg); 
}
.video-player:hover .player-controls, .video-player.show-controls .player-controls {
 opacity: 1; 
}
.exam-q {

  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 18px 20px;

}
.exam-option.is-selected {
 border-color: var(--accent); background: var(--accent-soft); 
}
.exam-option.is-selected .exam-option__letter {
 background: var(--accent); color: var(--accent-on); 
}
.survey-section {

  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 18px 20px;

}
.survey-section__title {
 font-size: var(--text-md); font-weight: var(--fw-announce); color: var(--fg-strong); margin: 0 0 12px; line-height: 1.5; 
}
.scale-row {
 display: flex; gap: 6px; flex-wrap: wrap; 
}
.scale-chip {

  flex: 1; min-width: 80px; padding: 12px 8px;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  cursor: pointer; font-size: var(--text-sm); color: var(--fg-2);
  transition: all var(--motion-fast);

}
.scale-chip:hover {
 border-color: var(--accent); 
}
.scale-chip.is-selected {
 background: var(--accent); color: var(--accent-on); border-color: var(--accent); 
}
.chip.is-selected {
 background: var(--accent); color: var(--accent-on); border-color: var(--accent); 
}
.page-profile {
 padding: 24px; 
}
.profile-row {

  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px; border-top: 1px solid var(--border-soft);
  cursor: pointer; transition: background var(--motion-fast);

}
.profile-row:first-child {
 border-top: none; 
}
.profile-row:hover {
 background: var(--surface-warm); 
}
.profile-row__icon {
 width: 36px; height: 36px; border-radius: var(--radius-md); background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; flex-shrink: 0; 
}
.onb-wrap {
 max-width: 640px; margin: 24px auto; padding: 0 16px; 
}
.onb-progress {
 height: 6px; background: var(--surface-deep); border-radius: var(--radius-pill); overflow: hidden; 
}
.onb-progress__bar {
 height: 100%; background: linear-gradient(90deg, var(--accent) 0%, var(--accent-deep) 100%); transition: width var(--motion-base) var(--ease-standard); 
}
.onb-step {
 display: block; 
}
.onb-step[hidden] {
 display: none; 
}
.onb-foot {
 display: flex; justify-content: space-between; gap: 8px; margin-top: 24px; 
}
.notify-drawer.is-open {
 transform: translateX(0); 
}
.notify-drawer__head {
 padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--border-soft); 
}
.notify-drawer__title {
 font-weight: var(--fw-announce); 
}
.notify-list {
 flex: 1; overflow-y: auto; 
}
.notify-item {
 padding: 14px 20px; border-bottom: 1px solid var(--border-soft); 
}
.notify-item.is-unread {
 background: var(--accent-soft); 
}
.notify-item__title {
 font-weight: var(--fw-announce); color: var(--fg-strong); 
}
.notify-item__content {
 font-size: var(--text-sm); color: var(--muted); margin-top: 4px; 
}
.notify-item__time {
 font-size: var(--text-xs); color: var(--meta); margin-top: 6px; 
}
.skeleton {
 background: linear-gradient(90deg, var(--surface-deep) 0%, var(--surface-warm) 50%, var(--surface-deep) 100%); background-size: 200% 100%; animation: skeleton-shimmer 1.2s infinite; border-radius: var(--radius-md); 
}
.mt-2 {
 margin-top: 8px; 
}
.text-sm {
 font-size: var(--text-sm); 
}
.vm-toolbar {
 display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; 
}
.tree-cat {
 border: 1px solid var(--border); border-radius: 10px; background: var(--surface); overflow: hidden; 
}
.tree-cat__head {
 display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; 
}
.tree-cat__head:hover {
 background: var(--surface-deep); 
}
.tree-cat__name {
 font-weight: var(--fw-announce); color: var(--fg-strong); flex: 1; 
}
.tree-cat__meta {
 color: var(--muted); font-size: var(--text-sm); 
}
.tree-cat__acts {
 display: flex; gap: 6px; 
}
.tree-cat__subs {
 border-top: 1px solid var(--border); background: var(--surface-deep); 
}
.tree-cat__subs--empty {
 padding: 10px 14px; color: var(--muted); font-size: var(--text-sm); 
}
.tree-sub {
 display: flex; align-items: center; gap: 10px; padding: 9px 14px 9px 30px; cursor: pointer; border-bottom: 1px solid var(--border); 
}
.tree-sub:last-child {
 border-bottom: none; 
}
.tree-sub:hover {
 background: var(--surface); 
}
.tree-sub__name {
 flex: 1; color: var(--fg); 
}
.tree-sub__meta {
 color: var(--muted); font-size: var(--text-sm); 
}
.tree-sub__acts {
 display: flex; gap: 6px; 
}
.lt-all {
 padding: 9px 12px; border-radius: 8px; cursor: pointer; color: var(--fg); 
}
.lt-all:hover, .lt-cat__head:hover, .lt-topic:hover {
 background: var(--surface-deep); 
}
.lt-cat {
 margin: 4px 0; 
}
.lt-cat.is-open .lt-chevron {
 transform: rotate(90deg); 
}
.lt-cat__head {
 display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 8px; cursor: pointer; 
}
.lt-chevron {
 transition: transform .15s; color: var(--muted); font-size: 12px; 
}
.lt-count {
 color: var(--muted); font-size: var(--text-xs); background: var(--surface-deep); border-radius: 10px; padding: 1px 8px; 
}
.lt-cat__subs {
 display: none; padding: 2px 0 4px 18px; 
}
.lt-cat.is-open .lt-cat__subs {
 display: block; 
}
.lt-topic {
 display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 8px; cursor: pointer; color: var(--fg); 
}
.lt-topic span:first-child {
 flex: 1; 
}
.lt-empty {
 padding: 6px 10px; color: var(--muted); font-size: var(--text-sm); 
}
.lt-cat__head.is-active, .lt-topic.is-active, .lt-all.is-active {
 background: var(--accent-soft) !important; color: var(--accent) !important; 
}
.lt-cat__head.is-active .lt-cat__name, .lt-topic.is-active span:first-child {
 color: var(--accent); 
}
.video-group {
 margin-top: 16px; 
}
.video-group__title {
 font-weight: var(--fw-announce); color: var(--fg-strong); margin-bottom: 10px; font-size: var(--text-md); 
}

/* ---------- 学习中心：培训类型分组头 / 考试状态点 / 逾期 / 封面图 ---------- */
.lt-tt {
 display: flex; align-items: center; gap: 8px; padding: 10px 12px 4px; font-size: var(--text-xs);
 color: var(--muted); font-weight: var(--fw-announce); letter-spacing: .02em;
}
.lt-tt .mini { margin-left: auto; }
.lc-dot {
 display: inline-block; width: 8px; height: 8px; border-radius: var(--r-pill); flex: 0 0 auto;
}
.is-overdue { color: var(--red); font-weight: var(--fw-announce); }
.ccard .cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-group .video-grid {
 margin-top: 0; 
}
.exam-q + .exam-q {
 margin-top: 14px; 
}
.exam-q__stem {
 font-size: var(--text-md); font-weight: var(--fw-announce); color: var(--fg-strong); margin: 0 0 12px; line-height: 1.5; 
}
.exam-q__type {
 color: var(--accent); font-size: var(--text-xs); margin-right: 4px; 
}
.exam-q__opt {
 display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); cursor: pointer; transition: all var(--motion-fast); font-size: var(--text-sm); margin-top: 8px; 
}
.exam-q__opt:hover {
 border-color: var(--accent); background: var(--accent-soft); 
}
.exam-q__opt input {
 margin-top: 2px; 
}
.exam-q__short {
 width: 100%; margin-top: 8px; font-family: inherit; resize: vertical; 
}
.rules-editor {
 margin-top: 6px; 
}
.grade-box {
 display: grid; gap: 14px; 
}
.grade-summary {
 background: var(--accent-soft); color: var(--accent-deep); border-radius: var(--radius-md); padding: 10px 14px; font-size: var(--text-sm); 
}
.grade-item {
 background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px 18px; 
}
.grade-item__no {
 display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: var(--accent); color: var(--accent-on); font-size: var(--text-xs); font-weight: var(--fw-announce); margin-right: 6px; 
}
.grade-item__q {
 font-weight: var(--fw-announce); color: var(--fg-strong); margin-bottom: 8px; 
}
.grade-item__ans, .grade-item__ref {
 font-size: var(--text-sm); margin: 6px 0; 
}
.grade-item__emp {
 background: var(--surface-deep); border-radius: var(--radius-sm); padding: 10px 12px; white-space: pre-wrap; line-height: 1.6; color: var(--fg); 
}
.grade-item__score {
 margin-top: 10px; max-width: 240px; 
}
.opt-list {
 display: flex; flex-direction: column; gap: 8px; 
}
.opt-row {
 display: flex; align-items: center; gap: 8px; 
}
.opt-row__idx {
 flex: 0 0 28px; height: 32px; display: inline-flex; align-items: center; justify-content: center; font-weight: 600; color: var(--accent); background: var(--accent-050); border-radius: var(--radius-sm); 
}
.opt-row__input {
 flex: 1 1 auto; 
}
.opt-row__check {
 flex: 0 0 auto; font-size: 12px; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: var(--radius-sm); 
}
.opt-row__check:hover {
 background: var(--accent-050); 
}
.opt-row__check input {
 margin: 0; cursor: pointer; 
}
.opt-row__del {
 flex: 0 0 28px; height: 28px; line-height: 1; padding: 0; 
}
.opt-add {
 margin-top: 10px; 
}
.pq-meta {
 display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; 
}
.pq-meta__stat {
 margin-left: auto; font-size: var(--text-sm); color: var(--muted); 
}
.pq-meta__stat b {
 color: var(--fg-strong); font-size: var(--text-md); 
}
.pq-modebar {
 display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: var(--info-soft); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px 14px; font-size: var(--text-sm); color: var(--fg-strong); margin-bottom: 12px; 
}
.pq-modebar b {
 font-weight: var(--fw-emph); 
}
.pq-modebar__warn {
 color: var(--danger); 
}
.pq-modebar .btn {
 margin-left: auto; 
}
.pq-supply {
 display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; 
}
.pq-score-ro {
 display: inline-block; min-width: 40px; color: var(--muted); font-size: var(--text-sm); 
}
.pq-grid {
 display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 14px; align-items: start; 
}
.pq-col {
 display: flex; flex-direction: column; min-width: 0; 
}
.pq-col .card__head {
 display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; 
}
.pq-col .card__head h3 {
 margin: 0; font-size: var(--text-md); 
}
.pq-scroll {
 max-height: 60vh; overflow: auto; 
}
.pq-filters {
 display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-bottom: 10px; 
}
.pq-hint {
 margin: 10px 0 0; font-size: var(--text-xs); color: var(--muted); 
}
.qform-prefill {

  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: var(--info-soft); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 8px 12px; margin-bottom: 12px;
  font-size: var(--text-xs); color: var(--fg);

}
.qform-prefill b {
 color: var(--fg-strong); font-weight: 600; 
}
.qform-score-note {

  display: inline-block; background: var(--surface-deep); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 8px 14px; font-size: var(--text-sm); color: var(--fg);

}
.qform-score-note b {
 color: var(--fg-strong); font-weight: var(--fw-emph); 
}

@media (max-width: 900px) {
  .page-shell--admin.sidebar-open .sidebar {
   display: flex; 
  }
  .page-shell--admin.sidebar-open::after {
   content: ""; position: fixed; inset: 0; background: var(--overlay-dim); z-index: 999; 
  }
  body.body--admin.sidebar-open > .sidebar {
   display: flex; 
  }
  body.body--admin.sidebar-open::after {
   content: ""; position: fixed; inset: 0; background: var(--overlay-dim); z-index: 999; 
  }
}

@media (min-width: 1024px) {
  body.body--employee > .topbar {
   display: none; 
  }
  body.body--employee > .page {
   margin-left: 260px; 
  }
}

/* ---------- 关键帧（被上方规则引用） ---------- */
@keyframes dot-pulse {

  0%, 100% { transform: scale(1); box-shadow: 0 3px 8px var(--orange); }
  50%      { transform: scale(1.14); box-shadow: 0 6px 16px var(--orange); }

}
@keyframes dot-spin {

  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }

}
@keyframes halo-pulse {

  0%, 100% { transform: scale(1);   box-shadow: 0 4px 12px var(--orange), 0 0 0 4px var(--accent-on); }
  50%      { transform: scale(1.12); box-shadow: 0 6px 22px var(--orange), 0 0 0 8px var(--yellow-100); }

}
@keyframes here-pulse {

  0%, 100% { transform: translate(0, -50%) scale(1); }
  50%      { transform: translate(0, -50%) scale(1.07); }

}
@keyframes skeleton-shimmer {
 from { background-position: 200% 0; } to { background-position: -200% 0; } 
}
@keyframes spin {
 to { transform: rotate(360deg); } 
}

/* ============================================================
   以下为「被 v2 页面引用、但 style.css 与原生均无定义」的组件类，
   按 prototype 设计语言手写（令牌化，仅 CSS 变量）。
   ============================================================ */

/* 复选框（员工/管理员表格行选择） */
.ck { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.chk { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: var(--text-sm); color: var(--ink-500); }

/* 进度条（员工端学习进度 / 主页地图进度）：.bar 轨道、i 填充、.bar.g 完成态 */
.bar { position: relative; height: 8px; background: var(--surface-2); border-radius: 9999px; overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--accent); border-radius: 9999px; transition: width var(--dur) var(--ease); }
.bar.g i { background: var(--green); }

/* 强调色修饰（<span class="tag accent">已点亮</span>） */
.accent { color: var(--accent); }
.tag.accent { background: var(--accent-050); color: var(--accent); }
.tag--soft { background: var(--surface-2); color: var(--ink-500); }

/* 通用块 */
.block { display: block; }

/* 卡片变体 */
.card--item { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); padding: 14px 16px; }
.card-ft { padding: 14px 16px; border-top: 1px solid var(--line); background: var(--surface-2); }

/* 表单内勾选行 */
.form-field__check { display: flex; align-items: center; gap: 8px; font-size: var(--text-sm); color: var(--ink-500); }

/* 邀请列表 */
.inv-list { display: flex; flex-direction: column; gap: 8px; }
.inv-list .item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); }

/* Tab 面板：默认可见（各页非激活面板均有内联 display:none 兜底；
   若默认 none 会把学习中心/商城管理/关卡任务的首个面板整体藏掉） */
.tabpane { display: block; }
.tabpane.active, .tabpane.is-active { display: block; }

/* 学习路线 */
.lt-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--r-sm); cursor: pointer; transition: background var(--dur-fast) var(--ease); }
.lt-item:hover { background: var(--surface-2); }
.lt-item.on { background: var(--accent-050); color: var(--accent); }
.lt-name { font-weight: 600; color: var(--ink-900); }

/* 入职引导 */
.onb-head { padding: 16px; border-bottom: 1px solid var(--line); }
.onb-body { padding: 16px; }
.onb-step-label { font-size: var(--text-sm); color: var(--ink-500); }

/* 考试填空 */
.exam-q__fill { width: 100%; padding: 10px 12px; border: 1px solid var(--line-2); border-radius: var(--r-sm); font-size: var(--text-md); background: var(--surface); color: var(--ink-900); font-family: inherit; }
.exam-q__fill:focus { border-color: var(--accent); box-shadow: var(--focus-ring); outline: none; }

/* 统计卡数字 */
.stat-card__num { font-size: 28px; font-weight: 700; color: var(--ink-900); font-family: var(--font-num); line-height: 1.2; }

/* 地图站点锁定态 CTA */
.station__cta--locked { background: var(--surface-2); color: var(--ink-400); cursor: not-allowed; }

/* 视频封面色调（adm_videos.js 注入 class="cover o|g"） */
.cover { display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; border-radius: var(--r-card); background: var(--accent-050); color: var(--accent); flex: none; }
.cover.o { background: var(--orange-100); color: var(--orange); }
.cover.g { background: var(--green-100); color: var(--green); }
.tones { display: inline-flex; gap: 6px; flex-wrap: wrap; }

/* 视频卡片时长徽标 / 播放器 */
.video-card__duration { position: absolute; right: 8px; bottom: 8px; background: var(--ink-900); color: #fff; font-size: 11px; line-height: 1; padding: 3px 7px; border-radius: var(--r-pill); }
.video-player__el { width: 100%; border-radius: var(--r-card); background: var(--ink-900); display: block; }
.video-player__placeholder { aspect-ratio: 16 / 9; display: flex; align-items: center; justify-content: center; background: var(--surface-2); color: var(--ink-400); border-radius: var(--r-card); }

/* 空状态副文案 */
.empty-state__sub { margin-top: 6px; font-size: var(--text-sm); color: var(--ink-400); }

/* 芯片组（入职引导） */
.chip-group { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---------- 长文本省略号工具（P1 溢出防护） ---------- */
.ellipsis, .text-ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.video-card__title, .gift-card__name, .lt-name, .station__name, .station__topic,
.notify-item__title, .grade-item__q, .grade-item__emp, .exam-q__stem,
.pq-meta__stat, .map-mobile-item__name, .tag, .badge-chip__name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
/* flex 子项需要 min-width:0 才能正确省略 */
.lt-item, .video-card, .gift-card, .notify-item, .station { min-width: 0; }

/* ---------- 响应式安全网（1366~1920 不拉伸、不溢出） ---------- */
img, video { max-width: 100%; }
@media (min-width: 1536px) {
  .container, .page-inner { max-width: var(--container-wide, 1440px); margin-inline: auto; }
}

/* ---------- 首页「我的学习任务」：培训类型分组（默认展开，可折叠） ---------- */
.hp-group { border-bottom: 1px solid var(--line-2); }
.hp-group:last-child { border-bottom: none; }
.hp-ghd {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 12px 2px 8px;
  background: none; border: none; cursor: pointer; text-align: left; font-family: inherit;
}
.hp-ghd__name { font-size: 13px; font-weight: var(--fw-announce); color: var(--fg-strong); }
.hp-ghd .tag, .hp-ghd .mini { margin-left: auto; }
.hp-chev { color: var(--muted); transition: transform var(--motion-fast) var(--ease-standard); flex: none; }
.hp-ghd[aria-expanded="false"] .hp-chev { transform: rotate(-90deg); }
.hp-gbd { padding: 0 2px 6px; }

/* ---------- 首页「学习地图速览」：可点击站点 + 节点任务面板 ---------- */
.hp-station {
  display: flex; flex-direction: column; align-items: center; gap: 5px; flex: 0 0 auto; min-width: 0;
  background: none; border: none; padding: 0 2px; cursor: pointer; font-family: inherit;
}
.hp-station__dot {
  width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center;
  justify-content: center; font-size: 13px; font-weight: var(--fw-announce); flex: none;
  transition: all var(--motion-fast) var(--ease-standard);
}
.hp-station.is-done .hp-station__dot { background: var(--green-100); color: var(--green); }
.hp-station.is-cur .hp-station__dot { background: var(--accent); color: var(--accent-on); }
.hp-station.is-lock .hp-station__dot { background: var(--surface-2); color: var(--ink-400); }
.hp-station__name { font-size: 11px; color: var(--muted); line-height: 1.3; }
.hp-station.is-cur .hp-station__name { color: var(--accent); font-weight: var(--fw-announce); }
.hp-station:hover .hp-station__dot { box-shadow: var(--elev-raised); }
.hp-station[aria-expanded="true"] .hp-station__dot { outline: 2px solid var(--accent); outline-offset: 2px; }
.hp-station-line {
  flex: 1 1 auto; min-width: 14px; height: 0;
  border-top: 1px dashed var(--line); background: none; margin: 17px 2px 0;
}
.hp-station-line.is-done { border-top-color: var(--green); }
.hp-station-line.is-cur  { border-top-color: var(--accent); }
.hp-station-line.is-lock { border-top-color: var(--line); }

.hp-node-panel {
  margin-top: 14px; border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface-2); padding: 12px 14px;
}
.hp-np-hd {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-bottom: 8px; border-bottom: 1px solid var(--line-2);
}
.hp-np-row {
  display: flex; align-items: center; gap: 8px; padding: 9px 0;
  border-bottom: 1px solid var(--line-2); flex-wrap: wrap;
}
.hp-np-row:last-child { border-bottom: none; }
.hp-np-name { font-size: 13px; font-weight: var(--fw-announce); color: var(--fg); flex: 1; min-width: 0; }
.hp-np-meta { flex-basis: 100%; }
.hp-np-row.is-locked .hp-np-name { color: var(--muted); }
.hp-np-row .btn { margin-left: auto; }

/* 节点面板摘要行：主线/支线各一行（x/y + 细进度条），点击展开具体任务 */
.hp-np-sum {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 10px 2px;
  background: none; border: none; border-bottom: 1px solid var(--line-2);
  cursor: pointer; font-family: inherit; text-align: left;
}
.hp-np-sum:last-of-type { border-bottom: none; }
.hp-np-sum__name { font-size: 13px; font-weight: var(--fw-announce); color: var(--fg); }
.hp-np-sum__num { flex: none; }
.hp-np-sum__bar { flex: 1; min-width: 40px; }
.hp-np-sum[aria-expanded="false"] .hp-chev { transform: rotate(-90deg); }
.hp-np-sec { padding: 2px 0 4px; }

/* ---------- 部门树多选 + 搜索选择器（dept_picker.js，组织管理地基组件） ---------- */
.dp-wrap { display: flex; flex-direction: column; gap: 10px; }
.dp-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dp-bar .dp-search { flex: 1; min-width: 200px; }
.dp-inc { flex: none; }
.dp-tree {
  max-height: 320px; overflow: auto; border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 6px 0;
}
.dp-node {
  display: flex; align-items: center; gap: 4px; padding: 5px 10px 5px 0;
  border-radius: var(--r-sm);
}
.dp-node:hover { background: var(--surface-2); }
.dp-caret {
  width: 22px; height: 22px; flex: none; display: inline-flex; align-items: center;
  justify-content: center; background: none; border: none; cursor: pointer;
  color: var(--muted); padding: 0; transition: transform var(--motion-fast) var(--ease-standard);
}
.dp-caret.is-closed { transform: rotate(-90deg); }
.dp-caret.is-hidden { visibility: hidden; }
.dp-chk {
  display: inline-flex; align-items: center; gap: 7px; flex: 1; min-width: 0;
  cursor: pointer; font-size: 13px; color: var(--fg);
}
.dp-chk input { position: absolute; opacity: 0; width: 0; height: 0; }
.dp-box {
  width: 15px; height: 15px; flex: none; border: 1.5px solid var(--border-strong);
  border-radius: 4px; background: var(--surface); position: relative;
  transition: all var(--motion-fast) var(--ease-standard);
}
.dp-chk input:checked + .dp-box { background: var(--accent); border-color: var(--accent); }
.dp-chk input:checked + .dp-box::after {
  content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.dp-chk input:focus-visible + .dp-box { box-shadow: var(--focus-ring); }
.dp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dp-count { font-size: 11px; color: var(--muted); font-family: var(--font-num); flex: none; }
.dp-empty { padding: 18px; text-align: center; color: var(--muted); font-size: 13px; }
.dp-sel { display: flex; flex-direction: column; gap: 6px; }
.dp-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.dp-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 6px 3px 9px;
  background: var(--accent-soft); color: var(--accent-deep); font-size: 12px;
  border-radius: var(--r-pill);
}
.dp-chip button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border: none; background: none; padding: 0;
  cursor: pointer; color: inherit; border-radius: var(--r-pill);
}
.dp-chip button:hover { background: var(--accent); color: var(--accent-on); }

/* ---------- 组织架构页：批量操作条 / 员工类型标签管理 ---------- */
.org-batchbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin: 10px 0 0; background: var(--accent-soft);
  border-radius: var(--radius-md);
}
.etag {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px;
  border: 1px solid var(--border); border-radius: var(--r-pill);
  font-size: 13px; color: var(--fg); background: var(--surface);
}
.etag.is-off { opacity: .55; }
.etag__cnt { font-size: 11px; color: var(--muted); font-family: var(--font-num); }
.etag__acts { display: inline-flex; gap: 2px; margin-left: 2px; }
.etag__acts button {
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; padding: 0; cursor: pointer; color: var(--muted);
  border-radius: var(--r-pill);
}
.etag__acts button:hover { background: var(--surface-2); color: var(--accent); }

/* ---------- 组织架构页：部门树（无限层级 + 树内搜索） ---------- */
.ot-tree {
  max-height: calc(100vh - 236px); overflow: auto; padding: 6px 10px 12px;
}
.ot-node {
  display: flex; align-items: center; gap: 6px; padding: 7px 8px;
  border-radius: var(--r-sm); cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.ot-node:hover { background: var(--surface-2); }
.ot-node.on { background: var(--accent-050); }
.ot-node.on .ot-name { color: var(--accent); font-weight: 600; }
.ot-all .ot-name { font-weight: 600; }
.ot-caret {
  flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center;
  justify-content: center; border: 0; background: none; cursor: pointer;
  color: var(--muted); padding: 0; transition: transform var(--dur-fast) var(--ease);
}
.ot-caret:hover { color: var(--accent); }
.ot-caret.is-closed { transform: rotate(-90deg); }
.ot-caret.is-hidden { visibility: hidden; }
.ot-caret svg { transition: transform var(--dur-fast) var(--ease); }
.ot-name { font-size: 13px; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ot-cnt { margin-left: auto; flex: none; font-size: 11px; color: var(--muted); font-family: var(--font-num); }

/* 表格内勾选框（复用 dp-chk/dp-box，取消 flex 拉伸） */
.tbl .dp-chk { flex: none; }

/* 单选圆点（批量更改员工类型弹窗） */
.dp-box--radio { border-radius: var(--r-pill); }
.dp-chk input:checked + .dp-box--radio::after {
  content: ""; position: absolute; left: 4px; top: 4px; width: 5px; height: 5px;
  border: none; background: #fff; border-radius: 50%; transform: none;
}

/* 员工类型管理弹窗：名称 / 可点击人数 */
.etag__name { font-weight: 500; }
.etag__cnt { cursor: pointer; }
.etag__cnt:hover { color: var(--accent); }

/* ============================================================
   第十四轮 UI 美观度修复（#1/#3/#4/#5/#6/#7）
   全部走 prototype 设计令牌，无硬编码十六进制（白字/黄底文字对比除外），
   无弹跳缓动，无紫粉渐变；与既有 .ic / .bar / .chk / .statbar 体系一致。
   ============================================================ */

/* #1 员工端顶部主导航：菜单项禁止逐字折行；容器过窄时横向滚动不溢出 */
.tn-in { gap: 18px; }
.tn .brand { white-space: nowrap; flex: 0 0 auto; }
.tn nav { flex-wrap: nowrap; flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tn nav::-webkit-scrollbar { height: 0; display: none; }
.tn nav a { white-space: nowrap; flex: 0 0 auto; }

/* #5 管理端侧边栏：菜单文字不折行（溢出省略），并适当加宽侧栏。
   直接设置 .sb 宽度（不依赖 --sb-w 变量级联），并把标签包进 .sb-label 真实元素以稳定 nowrap。 */
.sb { width: 248px; }
.sb a { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.sb a .ic, .sb a svg, .sb a .badge { flex: 0 0 auto; }
.sb-label {
  flex: 1 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* #6 管理端页标题：标题单行不折行，右侧操作区可换行 */
.pagetitle h1 { white-space: nowrap; }
.pagetitle .right { flex-wrap: wrap; justify-content: flex-end; align-items: center; }

/* #3 学习中心左侧分类树：状态点 / 计数垂直居中，计数右对齐，长名称省略 */
.lt-cat__head, .lt-topic, .lt-all { align-items: center; }
.lc-dot { flex: 0 0 auto; align-self: center; vertical-align: middle; }
.lt-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lt-count { margin-left: auto; flex: 0 0 auto; }

/* #4 培训档案进度条：填充居中轨道、不溢出（border-radius 继承，避免圆角错位） */
.bar { display: flex; align-items: center; }
.bar i { border-radius: inherit; min-width: 0; }

/* #7 角色权限：功能权限保持「复选框左 · 标签右」横排，长标签不折行，整体换行排布 */
#r-perms, #mr-perms { display: flex; flex-wrap: wrap; gap: 10px 22px; }
#r-perms .chk, #mr-perms .chk { white-space: nowrap; }

/* ============================================================
   证书模板配置页（/admin/cert）—— 仅追加，全部走 prototype 设计令牌
   无硬编码 hex / rgba，无弹跳缓动；选中态外发光统一用 var(--focus)
   ============================================================ */
.cert-pagedesc { margin:-6px 0 16px; font-size:13px; color:var(--ink-500); }
.cert-count { margin-left:auto; font-size:12px; font-weight:400; color:var(--ink-400); }

.cert-tcard { transition:border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease); }
.cert-tcard:hover { border-color:var(--accent-100); }
.cert-tcard.is-sel { border-color:var(--accent); box-shadow:var(--focus); background:var(--accent-050); }
.cert-tcard__name { font-size:14px; font-weight:600; color:var(--ink-900); }
.cert-tcard.is-sel .cert-tcard__name { font-weight:700; }
.cert-detail__name { font-size:17px; font-weight:700; color:var(--ink-900); }

.cert-form-grid { align-items:start; }
.cert-themes { display:flex; gap:10px; }
.cert-theme {
  flex:1; min-width:0; border:2px solid var(--line); border-radius:10px; padding:8px;
  text-align:center; cursor:pointer; background:var(--surface);
  transition:border-color var(--dur-fast) var(--ease);
}
.cert-theme:hover { border-color:var(--accent-100); }
.cert-theme.is-on { border-color:var(--accent); }
.cert-theme__swatch { height:38px; border-radius:6px; }
.cert-theme__swatch--brand { background:linear-gradient(180deg,var(--accent-050),var(--surface)); border:1px solid var(--accent-100); }
.cert-theme__swatch--green { background:linear-gradient(180deg,var(--green-100),var(--surface)); border:1px solid var(--green-100); }
.cert-theme__swatch--gray { background:linear-gradient(180deg,var(--surface-2),var(--surface)); border:1px solid var(--line); }
.cert-theme.is-on .cert-theme__label { color:var(--accent); font-weight:600; }

.cert-fields-grid { gap:10px; }
.cert-nr__f { width:150px; }
.cert-nr-tip {
  display:flex; align-items:flex-start; gap:10px; margin-top:14px; padding:11px 14px;
  border-radius:var(--r-card); font-size:12.5px; line-height:1.6;
  background:var(--green-100); color:var(--ink-700); border:1px solid var(--green-100);
}
.cert-nr-tip .ic { margin-top:2px; color:var(--green); }
.cert-nr-tip__txt { flex:1; min-width:0; }
.cert-mono { font-family:var(--font-num); font-weight:600; color:var(--ink-900); }

.cert-stage {
  position:relative; width:100%; aspect-ratio:297 / 210;
  border:1px solid var(--accent-100); border-radius:var(--r-card); overflow:hidden;
  background:linear-gradient(180deg,var(--accent-050),var(--surface));
}
.cert-stage.is-portrait { aspect-ratio:210 / 297; max-width:440px; margin:0 auto; }
.cert-stage__inner { position:absolute; inset:0; }
/* 后端片段 .cert-sheet 自带 width + aspect-ratio，前端不覆盖尺寸，仅兜底防溢出 */
.cert-stage__inner > * { max-width:100%; }

.cert-modal-form { display:flex; flex-direction:column; gap:12px; }

@media print {
  .cert-print-body { margin:0; padding:0; background:var(--surface); }
}

/* ============================================================
   证书查看 / 打印独立文档（/certificate/<cid>，cert_view.html）
   与配置页共用同一套 prototype 令牌；不引入 cert.css（其 :root
   会把 --accent 覆盖成金色、并把 .cert-sheet 写死为 A4 竖向）。
   横/竖方向由渲染片段自带的 aspect-ratio 决定，此处不写死。
   ============================================================ */
.certv-body { margin:0; background:var(--surface-2); }
.certv-bar {
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:14px 24px; background:var(--surface); border-bottom:1px solid var(--line);
}
.certv-bar__label { font-size:13px; font-weight:600; color:var(--ink-700); }
.certv-canvas {
  padding:24px; display:flex; justify-content:center; align-items:flex-start;
  background:var(--surface-2);
}
.certv-canvas > .cert-sheet {
  width:100%; max-width:1122px;
  box-shadow:var(--shadow-1); background-color:var(--surface);
}

@media print {
  .certv-body { background:var(--surface); }
  .no-print { display:none !important; }
  .certv-canvas { padding:0; background:var(--surface); }
  .certv-canvas > .cert-sheet { max-width:none; box-shadow:none; border:0; }
  @page { size:A4; margin:12mm; }
}

/* ---------- 权限分配优化（分组 / 每组全选 / 搜索 / 模板 / ? 说明） ---------- */
.perm-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin-bottom:12px; }
.perm-search { flex:1 1 240px; min-width:160px; }
.perm-tpls { display:flex; flex-wrap:wrap; gap:8px; }
.perm-list { display:flex; flex-direction:column; gap:10px; }
.perm-group { border:1px solid var(--line); border-radius:var(--r-card); padding:10px 12px; background:var(--surface); }
.perm-group__hd { margin-bottom:6px; font-size:13px; }
.perm-group__items { display:flex; flex-wrap:wrap; gap:8px 18px; padding-left:6px; }
.perm-item { display:inline-flex; align-items:center; gap:6px; margin:0; }
.perm-q { display:inline-flex; align-items:center; justify-content:center; width:16px; height:16px;
  border-radius:50%; background:var(--accent-100); color:var(--accent); font-size:11px; font-weight:700; cursor:help; }
@media (max-width: 900px) {
  .perm-group__items { gap:8px 12px; }
}
