/* 管理端 / 教师端页面样式（owner: frontend-admin）
 * 依赖 app.css 中的基础类（.card/.btn/.field/.tablewrap 之前不存在则由本文件补齐）。
 * 令牌：优先消费新规范 --c-*（app.css 由 frontend-core 提供），回退兼容旧 --ink/--primary 命名，
 * 因此两套命名任一存在都能取到正确颜色，不会出现“颜色丢失”。
 * 断点与 app.css / pages.css 对齐：1199 / 1023 / 767 / 480；375 下表格容器横向滚动、页面本身不溢出。
 */
:root{
  --adm-ink: var(--c-ink, var(--ink, #1e2a36));
  --adm-ink2: var(--c-ink2, var(--ink2, #55636f));
  --adm-ink3: var(--c-ink3, var(--ink3, #5f6b77));
  --adm-line: var(--c-line, var(--line, #e4e9ee));
  --adm-line2: var(--c-line2, var(--line2, #eef2f6));
  --adm-card: var(--c-card, var(--card, #fff));
  --adm-bg: var(--c-bg, var(--bg, #f5f7f9));
  --adm-primary: var(--c-accent, var(--primary, #26705f));
  --adm-primary-d: var(--c-accent-d, var(--primary-d, #1d5a4c));
  --adm-primary-l: var(--c-accent-l, var(--primary-l, #e7f2f5));
  --adm-ok: var(--c-ok, var(--ok, #2c7550));
  --adm-ok-l: var(--c-ok-l, var(--ok-l, #e9f5ee));
  --adm-warn: var(--c-warn, var(--warn, #8f5a1a));
  --adm-warn-l: var(--c-warn-l, var(--warn-l, #fbf1e3));
  --adm-danger: var(--c-danger, var(--danger, #b3453f));
  --adm-danger-l: var(--c-danger-l, var(--danger-l, #fbeeee));
  --adm-fs-xs: var(--fs-xs, 11px);
  --adm-fs-sm: var(--fs-sm, 12px);
  --adm-fs-md: var(--fs-md, 13px);
  --adm-fs-lg: var(--fs-lg, 14px);
  --adm-fs-xl: var(--fs-xl, 16px);
  --adm-fs-xxl: var(--fs-xxl, 20px);
  --adm-shadow: var(--shadow, 0 1px 2px rgba(30,42,54,.04), 0 4px 14px rgba(30,42,54,.05));
  --adm-radius: var(--radius, 10px);
}

/* ---------- 可达性基础 ---------- */
.sr-only{position:absolute !important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
:where(.adm-pager .pg,.adm-seg button,.adm-th,.adm-actions .btn,.adm-modal button):focus-visible{
  outline:2px solid var(--adm-primary); outline-offset:2px}

/* ---------- 工具条：筛选 / 分段 tab ---------- */
.adm-toolbar{display:flex;flex-wrap:wrap;gap:10px 12px;align-items:flex-end;margin-bottom:14px}
.adm-toolbar .field{margin-bottom:0;min-width:158px}
.adm-toolbar .field.grow{flex:1 1 240px}
.adm-toolbar .field label{margin-bottom:4px}
.adm-toolbar .input,.adm-toolbar .select{height:34px;font-size:var(--adm-fs-md)}
.adm-seg{display:inline-flex;border:1px solid var(--adm-line);border-radius:8px;overflow:hidden;
  background:var(--adm-card);flex-wrap:wrap}
.adm-seg button{border:0;background:transparent;padding:7px 14px;font-size:var(--adm-fs-md);
  color:var(--adm-ink2);cursor:pointer;min-height:34px}
.adm-seg button+button{border-left:1px solid var(--adm-line)}
.adm-seg button.on{background:var(--adm-primary-l);color:var(--adm-primary);font-weight:600}
.adm-seg button:disabled{color:var(--adm-ink3);cursor:not-allowed;background:var(--adm-bg)}
.adm-seg-wrap{display:flex;flex-wrap:wrap;gap:10px;align-items:center}

/* ---------- 表格容器：横向滚动 + 首列吸顶 + 行高 ---------- */
.tablewrap{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:8px}
/* 「左右滑动查看更多」只在真的需要横滚的窄屏出现；宽屏表格完整可见时隐藏 */
.adm-scroll-hint{display:none;text-align:right;font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin:0 0 6px;user-select:none}
.tablewrap table{min-width:760px}
.adm-table{width:100%;border-collapse:collapse;font-size:var(--adm-fs-md);table-layout:auto}
.adm-table caption{text-align:left}
.adm-table th{position:relative;background:var(--adm-card);padding:10px 10px;border-bottom:1px solid var(--adm-line);
  color:var(--adm-ink3);font-weight:500;font-size:var(--adm-fs-sm);white-space:nowrap;text-align:left}
.adm-table td{padding:10px;border-bottom:1px solid var(--adm-line2);color:var(--adm-ink2);
  vertical-align:middle;height:44px;word-break:break-word}
.adm-table tbody tr:hover td{background:#fafcfd}
.adm-table td.nowrap,.adm-table th.nowrap{white-space:nowrap}
/* 数字列永不换行：「0.7504」被挤成「0.75 / 04」是视觉事故，不是排版容忍项 */
.adm-table td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
/* 单元格内的状态标签（如「协同过滤」「热度兜底」）保持单行，避免在窄列里竖排成一字一行 */
.adm-table td .tag{white-space:nowrap}
/* 推荐可解释性表：13 列信息密度高，固定列宽（合计 1080）刚好放进 1440 视口下的卡片，
   避免数字/标签被挤成两行，也避免宽屏仍需横向滚动 */
.adm-table-explain{table-layout:fixed;min-width:1080px}
.adm-table-explain th,.adm-table-explain td{padding:10px 6px}
.adm-table-explain th:nth-child(1),.adm-table-explain td:nth-child(1){width:40px}
.adm-table-explain th:nth-child(2),.adm-table-explain td:nth-child(2){width:54px}
.adm-table-explain th:nth-child(3),.adm-table-explain td:nth-child(3),
.adm-table-explain th:nth-child(4),.adm-table-explain td:nth-child(4),
.adm-table-explain th:nth-child(5),.adm-table-explain td:nth-child(5),
.adm-table-explain th:nth-child(6),.adm-table-explain td:nth-child(6){width:58px}
.adm-table-explain th:nth-child(7),.adm-table-explain td:nth-child(7){width:92px}
.adm-table-explain th:nth-child(8),.adm-table-explain td:nth-child(8){width:138px}
.adm-table-explain th:nth-child(9),.adm-table-explain td:nth-child(9){width:72px}
.adm-table-explain th:nth-child(10),.adm-table-explain td:nth-child(10){width:74px}
.adm-table-explain th:nth-child(11),.adm-table-explain td:nth-child(11){width:74px}
.adm-table-explain th:nth-child(12),.adm-table-explain td:nth-child(12){width:88px}
.adm-table-explain th:nth-child(13),.adm-table-explain td:nth-child(13){width:300px}
/* 召回来源是插值标识（pop_rule / cf_fallback），必须单行，不能被折成 pop_rul/e */
.adm-table-explain td:nth-child(10){white-space:nowrap;font-variant-numeric:tabular-nums}
.adm-table-explain td:nth-child(11){white-space:nowrap}
.adm-table-explain td:nth-child(12) .adm-cell-clip{max-width:100%}
/* 理由文案：早期复用 .adm-cell-clip 单行省略，300px 下只剩十几个字，
   「你在「数据分析」上的练习正确率偏低，这门课可以针对性补强」会被截成
   「你在「数据分析」上的练习…」，评审现场看不出理由到底说了什么。
   现在改为最多两行、按整句换行，hover 仍可通过 title 看全文。 */
.adm-table-explain td:nth-child(13) .adm-cell-clip{
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
  max-width:100%; white-space:normal; overflow:hidden; text-overflow:clip;
  vertical-align:top; line-height:1.55; word-break:break-word}
.adm-th{border:0;background:transparent;padding:2px 0;font:inherit;font-size:var(--adm-fs-sm);
  color:inherit;cursor:pointer;display:inline-flex;align-items:center;gap:4px;min-height:24px}
.adm-th:hover{color:var(--adm-primary)}
.adm-th .ar{font-size:var(--adm-fs-xs);color:var(--adm-primary)}
.adm-th .ar.off{color:var(--adm-line)}
.adm-cell-clip{display:inline-block;max-width:280px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;vertical-align:bottom}
/* 表格「两行信息」单元：主标题 + 次要信息 */
.adm-cell-2{display:flex;flex-direction:column;gap:2px;min-width:0}
.adm-cell-2 b{font-weight:600;color:var(--adm-ink);word-break:break-word}
.adm-cell-2 span{font-size:var(--adm-fs-xs);color:var(--adm-ink3)}
.tablewrap .adm-table th:first-child{position:sticky;left:0;z-index:3}
.tablewrap .adm-table td:first-child{position:sticky;left:0;z-index:2;background:var(--adm-card)}
.tablewrap .adm-table tbody tr:hover td:first-child{background:#fafcfd}
.tablewrap .adm-table th:first-child{box-shadow:1px 0 0 var(--adm-line)}
.tablewrap .adm-table td:first-child{box-shadow:1px 0 0 var(--adm-line2)}
/* 行高：≥1200 为 44（桌面密集），768–1199 为 48（触屏友好），与 app.css/pages.css 断点 1199/1023/767/480 完全一致 */
@media (max-width:1199px){ .adm-table td{height:48px} }

/* ---------- 分页 ---------- */
.adm-pager{display:flex;align-items:center;gap:6px;margin-top:16px;justify-content:center;flex-wrap:wrap}
.adm-pager .pg{border:1px solid var(--adm-line);background:var(--adm-card);color:var(--adm-ink2);
  border-radius:6px;min-width:32px;height:32px;padding:0 8px;font-size:var(--adm-fs-md);cursor:pointer}
.adm-pager .pg:hover:not(:disabled){border-color:var(--adm-primary);color:var(--adm-primary)}
.adm-pager .pg[aria-current="page"]{background:var(--adm-primary-l);border-color:var(--adm-primary);
  color:var(--adm-primary);font-weight:600}
.adm-pager .pg:disabled{opacity:.45;cursor:not-allowed}
.adm-pager .pg-info{font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin:0 6px}
.adm-pager .pg-size{height:32px;width:auto;min-width:64px;font-size:var(--adm-fs-sm);padding:0 6px}

/* ---------- 骨架屏 ---------- */
.sk{display:block;height:12px;border-radius:6px;
  background:linear-gradient(90deg,#eef2f6 25%,#e3e9ef 37%,#eef2f6 63%);
  background-size:400% 100%;animation:admShimmer 1.3s ease-in-out infinite}
.sk.lg{height:34px}
.sk.tall{height:76px}
@keyframes admShimmer{0%{background-position:100% 0}100%{background-position:-100% 0}}
@media (prefers-reduced-motion: reduce){.sk{animation:none}}
.adm-skel-table{padding:4px 0}
.adm-skel-row{display:flex;gap:12px;padding:12px 10px;border-bottom:1px solid var(--adm-line2);align-items:center}
.adm-skel-row .sk{height:14px}
.adm-skel-toolbar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.adm-skel-toolbar .sk{height:34px;border-radius:8px}

/* ---------- 空态 / 403 ---------- */
.adm-empty{padding:34px 16px;text-align:center;border:1px dashed var(--adm-line);border-radius:12px;
  background:#fcfdfe;margin:4px 0}
.adm-empty .ic{width:46px;height:46px;border-radius:50%;background:var(--adm-primary-l);color:var(--adm-primary);
  display:grid;place-items:center;margin:0 auto 10px;font-size:var(--adm-fs-xxl);font-weight:700}
.adm-empty h4{font-size:var(--adm-fs-lg);color:var(--adm-ink);margin-bottom:4px}
.adm-empty p{font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin-bottom:14px;line-height:1.7}
.adm-empty .adm-empty-acts{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.adm-empty.deny .ic{background:var(--adm-danger-l);color:var(--adm-danger)}
.adm-empty.deny h4{color:var(--adm-danger)}
.adm-empty.deny ul{list-style:none;font-size:var(--adm-fs-sm);color:var(--adm-ink2);margin:0 auto 14px;
  max-width:420px;text-align:left;background:var(--adm-bg);border-radius:8px;padding:10px 14px}
.adm-empty.deny li{margin:3px 0}

/* ---------- 内联错误 / 提示 ---------- */
.adm-alert{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--adm-danger-l);
  background:var(--adm-danger-l);color:#7a2f2a;border-radius:9px;padding:10px 13px;
  font-size:var(--adm-fs-md);margin-bottom:14px;line-height:1.6}
.adm-alert .t{flex:1}
.adm-alert.warn{border-color:var(--adm-warn-l);background:var(--adm-warn-l);color:#7c5417}
.adm-alert .btn.sm{padding:3px 10px}
.adm-note{font-size:var(--adm-fs-sm);color:var(--adm-ink3);line-height:1.7}

/* ---------- 卡片等高（课程卡 / 统计卡） ---------- */
.adm-card-list{display:grid;gap:14px;align-items:stretch}
.adm-cards2{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
.adm-card-list .ccard{height:100%;display:flex;flex-direction:column}
.ccard .adm-cov{aspect-ratio:16/9;border-radius:8px;overflow:hidden;background:var(--adm-bg);
  margin-bottom:10px;display:flex;align-items:center;justify-content:center}
.ccard .adm-cov img{width:100%;height:100%;object-fit:cover;display:block}
.ccard .adm-cov .ph{font-size:var(--adm-fs-sm);color:var(--adm-ink3)}
.ccard .adm-card-foot{margin-top:auto;display:flex;gap:8px;flex-wrap:wrap;
  padding-top:10px;border-top:1px dashed var(--adm-line)}
.adm-meta{display:flex;flex-wrap:wrap;gap:5px 14px;font-size:var(--adm-fs-sm);color:var(--adm-ink3)}
.adm-meta b{color:var(--adm-ink2);font-weight:600}
.adm-stats{display:grid;gap:14px;align-items:stretch;
  grid-template-columns:repeat(auto-fill,minmax(168px,1fr))}
.adm-stats .stat{height:100%;display:flex;flex-direction:column;justify-content:center}
.adm-stats .stat .n{font-size:var(--adm-fs-xxl)}
.adm-bar-list .row{margin-bottom:9px}
.adm-bar-list .nm{width:132px;font-size:var(--adm-fs-md);color:var(--adm-ink2);flex:none}
.adm-bar-list .bar{flex:1}
.adm-bar-list .val{width:66px;text-align:right;font-size:var(--adm-fs-sm);color:var(--adm-ink2);flex:none}

/* ---------- 表单 ---------- */
.adm-form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 16px}
.field{position:relative}
.field label{display:flex;align-items:center;gap:3px}
.req-mark{color:var(--adm-danger);font-size:var(--adm-fs-md);line-height:1}
.field-err{color:var(--adm-danger);font-size:var(--adm-fs-sm);margin-top:4px;line-height:1.5}
.input[aria-invalid="true"],.select[aria-invalid="true"],.textarea[aria-invalid="true"]{
  border-color:var(--adm-danger);box-shadow:0 0 0 3px rgba(179,69,63,.08)}
.adm-hint{font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin-top:-6px;margin-bottom:12px}

/* ---------- 详情键值 ---------- */
.adm-kv{display:grid;grid-template-columns:100px minmax(0,1fr);gap:8px 14px;font-size:var(--adm-fs-md)}
.adm-kv dt{color:var(--adm-ink3);font-size:var(--adm-fs-sm)}
.adm-kv dd{color:var(--adm-ink);word-break:break-all;margin:0}
.adm-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ---------- 分类树 ---------- */
.adm-tree{margin-top:12px}
.adm-tree .adm-node{transition:margin-left .15s ease}
.adm-tree .adm-node.ctx{opacity:.66}
.adm-caret{border:1px solid var(--adm-line);background:var(--adm-card);color:var(--adm-ink2);
  width:24px;height:24px;border-radius:6px;font-size:var(--adm-fs-sm);line-height:1;cursor:pointer;flex:none;
  display:inline-flex;align-items:center;justify-content:center;padding:0}
.adm-caret:hover{border-color:var(--adm-primary);color:var(--adm-primary)}
.adm-caret.ph{border-style:dashed;color:var(--adm-ink3);cursor:default}
@media (max-width:480px){.adm-caret{width:32px;height:32px;font-size:var(--adm-fs-md)}}
.adm-node{border:1px solid var(--adm-line);border-radius:10px;background:var(--adm-card);
  padding:10px 12px;margin-bottom:8px;box-shadow:var(--adm-shadow)}
.adm-node .adm-node-hd{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.adm-node .adm-node-hd .nm{font-size:var(--adm-fs-lg);font-weight:600;color:var(--adm-ink)}
.adm-node.lv2 .nm{font-size:var(--adm-fs-md)}
.adm-node.lv3 .nm{font-size:var(--adm-fs-md);font-weight:500}
.adm-node .adm-node-hd .adm-actions{margin-left:auto}
.adm-children{margin:8px 0 0 16px;padding-left:12px;border-left:1px dashed var(--adm-line)}
.adm-node.lv2,.adm-node.lv3{box-shadow:none;margin-bottom:6px;padding:8px 10px}

/* ---------- 模态 ---------- */
.adm-mask{position:fixed;inset:0;background:rgba(20,29,36,.44);z-index:300;display:grid;
  place-items:center;padding:20px;overflow:auto}
.adm-modal{width:100%;max-width:480px;background:var(--adm-card);border-radius:14px;
  box-shadow:0 24px 60px rgba(16,26,34,.3);padding:20px 22px 18px;max-height:calc(100vh - 40px);overflow:auto}
.adm-modal h3{font-size:var(--adm-fs-xl);color:var(--adm-ink);margin-bottom:8px}
.adm-modal .msg{font-size:var(--adm-fs-md);color:var(--adm-ink2);line-height:1.75}
.adm-modal .impact{background:var(--adm-warn-l);border-radius:8px;padding:9px 12px;margin:12px 0 0;
  font-size:var(--adm-fs-sm);color:#7c5417;line-height:1.7}
.adm-modal .impact ul{margin:4px 0 0 18px}
.adm-modal .req{font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin-top:10px;line-height:1.7}
.adm-modal .req code{font-size:var(--adm-fs-sm)}
.adm-modal .macts{display:flex;gap:10px;justify-content:flex-end;margin-top:18px;flex-wrap:wrap}
.adm-modal .btn{min-width:84px;min-height:36px}
.adm-modal .kv-title{font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin:0 0 6px}
.adm-modal .adm-fields{margin-top:14px}
.adm-modal .adm-fields .field{margin-bottom:12px}
.adm-modal .adm-fields .field:last-child{margin-bottom:0}
.adm-modal .adm-fields .textarea{min-height:84px;width:100%}
.adm-modal .adm-fields .input,.adm-modal .adm-fields .select{width:100%}
/* 危险操作实心按钮（确认删除 / 确认封禁） */
.btn.danger-solid{background:var(--adm-danger);border-color:var(--adm-danger);color:#fff}
.btn.danger-solid:hover{background:#9c3a35;border-color:#9c3a35;color:#fff}

/* ---------- 响应式：断点与 app.css / pages.css 完全对齐（1199 / 1023 / 767 / 480，避免 1024 宽时两套规则错位） ---------- */
@media (max-width:1023px){
  .adm-toolbar .field{min-width:0;flex:1 1 180px}
  .adm-cards2{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
  /* 平板及以下：表格（min-width 760px）会容器横滚，给出「左右滑动」提示；宽屏隐藏 */
  .adm-scroll-hint{display:block}
}
@media (max-width:767px){
  .adm-form-grid{grid-template-columns:1fr}
  .adm-seg{width:100%}
  .adm-seg button{flex:1 1 auto;justify-content:center}
  .tablewrap table{min-width:640px}
  .col-hide-sm{display:none !important}
  /* 窄屏表格只能容器横滚时给出「左右滑动」提示（product O-07），避免被认为操作列丢失 */
  .adm-scroll-hint{text-align:right;font-size:var(--adm-fs-sm);color:var(--adm-ink3);margin:0 0 6px;user-select:none}
  .adm-table td{height:auto;min-height:46px;padding:9px 10px}
  .adm-toolbar .field{flex:1 1 100%}
  .adm-toolbar .btn{flex:1 1 auto}
  .adm-actions .btn{min-height:36px}
  .adm-modal{max-width:none}
  .adm-bar-list .nm{width:96px}
}
@media (max-width:480px){
  .adm-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .adm-actions .btn,.adm-actions button{min-height:44px}
  .adm-pager .pg{min-width:44px;height:44px}
  .adm-modal .macts .btn{min-height:44px;flex:1 1 100%}
  .adm-modal{padding:16px 14px}
  .card{padding:14px}
  .adm-kv{grid-template-columns:84px minmax(0,1fr)}
  .adm-stats{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
}

/* ---------- 学生学情 #/learners（teacher / staff）：进度条 + KPI 补充说明 ---------- */
.adm-prog{display:flex;align-items:center;gap:8px;min-width:0}
.adm-prog-bar{flex:1 1 auto;min-width:72px;max-width:150px;height:8px;border-radius:999px;
  background:var(--adm-line2);overflow:hidden}
.adm-prog-bar i{display:block;height:100%;border-radius:999px;background:var(--adm-primary);
  transition:width .3s ease}
.adm-prog-t{flex:0 0 auto;min-width:40px;text-align:right;font-size:var(--adm-fs-sm);
  color:var(--adm-ink2);font-variant-numeric:tabular-nums}
.adm-stats .adm-stat-sub{font-size:var(--adm-fs-xs);color:var(--adm-ink3);margin-top:2px;
  line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
@media (prefers-reduced-motion: reduce){ .adm-prog-bar i{transition:none} }
@media (max-width:767px){
  .adm-prog-bar{max-width:none}
}

