/* ==================================================================
   设计令牌 —— 全系统颜色 / 间距 / 圆角 / 阴影 / 字号的唯一来源
   ------------------------------------------------------------------
   约定：组件里不允许再写死颜色，一律引用这里的变量。
   旧变量名（--brand / --brand-dark / --brand-light …）全部保留为别名，
   老规则里引用它们的地方会自动跟着升级，不必逐条改。
   ================================================================== */
:root{
  /* ---- 品牌蓝：保留原有藏青血统，提亮提纯到现代蓝 ---- */
  --brand-50:#eff5ff;  --brand-100:#dbeafe; --brand-200:#bfdbfe;
  --brand-300:#93c5fd; --brand-400:#60a5fa; --brand-500:#3b82f6;
  --brand-600:#2563eb; --brand-700:#1d4ed8; --brand-800:#1e40af;
  --brand-900:#1e3a8a;
  --brand:#2563eb; --brand-dark:#1e40af; --brand-light:#eff5ff;

  /* ---- 中性灰阶（冷调 slate，比原来的蓝灰更干净） ---- */
  --g-25:#fcfdfe; --g-50:#f7f9fc; --g-100:#eef2f7; --g-150:#e6ebf3;
  --g-200:#dde4ee; --g-300:#c8d3e1; --g-400:#94a3b8; --g-500:#64748b;
  --g-600:#4a5568; --g-700:#334155; --g-800:#1e2a3d; --g-900:#0f1a2b;

  /* ---- 语义色 ---- */
  --ok-50:#ecfdf5; --ok-100:#d1fae5; --ok-600:#059669; --ok-800:#065f46;
  --warn-50:#fffbeb; --warn-100:#fef3c7; --warn-600:#d97706; --warn-800:#92400e;
  --danger-50:#fef2f2; --danger-100:#fee2e2; --danger-600:#dc2626; --danger-800:#991b1b;
  --ok:#059669; --ok-light:#ecfdf5;
  --warn:#d97706; --warn-light:#fffbeb;
  --danger:#dc2626; --danger-light:#fef2f2;
  --gold:#b8934a; --gold-light:#fff8ec;

  /* ---- 文本 / 描边 / 底色 ---- */
  --ink:#0f1a2b;      /* 标题级最深 */
  --text:#1b2537;     /* 正文 */
  --text-2:#5b6779;   /* 次要 */
  --text-3:#8c97a8;   /* 提示 */
  --line:#e2e8f0;     /* 主描边 */
  --line-2:#eef2f7;   /* 浅分隔线 */
  --bg:#f5f7fa;       /* 页面底 */
  --card:#ffffff;

  /* ---- 圆角梯度 ---- */
  --r-xs:6px; --r-sm:8px; --r-md:10px; --r-lg:14px; --r-xl:18px; --r-full:999px;
  --radius:14px;

  /* ---- 阴影梯度：用柔和投影分层，不再拿一圈硬描边当层次 ---- */
  --sh-xs:0 1px 2px rgba(15,26,43,.04);
  --sh-sm:0 1px 2px rgba(15,26,43,.05), 0 1px 3px rgba(15,26,43,.04);
  --sh-md:0 2px 6px rgba(15,26,43,.05), 0 6px 16px rgba(15,26,43,.06);
  --sh-lg:0 8px 20px rgba(15,26,43,.08), 0 20px 44px rgba(15,26,43,.10);
  --ring:0 0 0 3px rgba(37,99,235,.16);

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

  /* ---- 字号阶梯 ---- */
  --fs-11:11px; --fs-12:12px; --fs-13:13px; --fs-14:14px; --fs-15:15px;
  --fs-17:17px; --fs-20:20px; --fs-24:24px; --fs-30:30px;

  /* ---- 动效 ---- */
  --tr:.16s cubic-bezier(.4,0,.2,1);
  --tr-slow:.28s cubic-bezier(.4,0,.2,1);

  /* ---- 布局尺寸 ---- */
  --sb-w:238px;
  --topbar-h:60px;
  --content-max:1180px;
}
/* ==================================================================
   基础层：重置 / 排版 / 滚动条
   ================================================================== */
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",
    "Hiragino Sans GB","Microsoft YaHei",sans-serif;
  background:var(--bg);color:var(--text);font-size:var(--fs-15);line-height:1.65;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
}
a{color:var(--brand);text-decoration:none;transition:color var(--tr)}
a:hover{color:var(--brand-700)}
h1,h2,h3,h4{color:var(--ink);font-weight:600;line-height:1.35}
/* 数字统一等宽：表格里的编号、人数、金额上下对齐，扫读快很多 */
.tbl,.stat,.proj-stats,.score-cell,.mod-metrics,.cert-row-meta,
.past-meta,.hw-sum,.att{font-variant-numeric:tabular-nums}
::selection{background:var(--brand-100);color:var(--brand-900)}
/* 细滚动条，替掉系统默认那根灰色粗条 */
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--g-300);border-radius:var(--r-full);
  border:3px solid transparent;background-clip:content-box}
*::-webkit-scrollbar-thumb:hover{background:var(--g-400);border:3px solid transparent;
  background-clip:content-box}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.wrap{max-width:540px;margin:0 auto;padding:0 var(--sp-4) 48px}

/* ==================================================================
   页头（前台：查验 / 签到 / 个人中心共用）
   ================================================================== */
.site-head{
  position:relative;
  background:linear-gradient(157deg,var(--brand-700) 0%,var(--brand-900) 100%);
  color:#fff;padding:30px 16px 34px;text-align:center;
}
/* 底部一线高光：纯色大字块没有它就显得死板 */
.site-head::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:1px;
  background:rgba(255,255,255,.14);
}
.site-head .org{font-size:var(--fs-13);opacity:.8;letter-spacing:1.2px}
.site-head h1{font-size:var(--fs-20);font-weight:600;margin-top:8px;
  letter-spacing:.4px;color:#fff}
.site-head .seal{
  display:inline-flex;align-items:center;justify-content:center;
  width:50px;height:50px;border-radius:var(--r-lg);
  background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.28);
  margin-bottom:12px;font-size:var(--fs-20);letter-spacing:1px;
}

/* ==================================================================
   卡片
   ================================================================== */
.card{
  background:var(--card);border-radius:var(--r-lg);padding:var(--sp-5);
  box-shadow:var(--sh-sm);border:1px solid var(--line);
}
.card + .card{margin-top:var(--sp-4)}
.card-title{font-size:var(--fs-15);font-weight:600;margin-bottom:4px;color:var(--ink)}
.card-sub{font-size:var(--fs-13);color:var(--text-2);margin-bottom:var(--sp-4)}
.pull-up{margin-top:-18px;position:relative;z-index:2}

/* ==================================================================
   表单控件
   ================================================================== */
.field{margin-bottom:var(--sp-4)}
.field label{display:block;font-size:var(--fs-13);color:var(--text-2);
  margin-bottom:6px;font-weight:500}
.field label .req{color:var(--danger);margin-left:2px}
input[type=text],input[type=tel],input[type=number],input[type=password],
input[type=datetime-local],input[type=date],input[type=search],select,textarea{
  width:100%;padding:10px 13px;border:1px solid var(--line);border-radius:var(--r-md);
  font-size:var(--fs-15);font-family:inherit;color:var(--text);background:var(--card);
  transition:border-color var(--tr),box-shadow var(--tr),background var(--tr);
}
input::placeholder,textarea::placeholder{color:var(--text-3)}
input:hover:not(:focus):not(:disabled),
select:hover:not(:focus):not(:disabled),
textarea:hover:not(:focus):not(:disabled){border-color:var(--g-300)}
input:focus,select:focus,textarea:focus{
  outline:none;border-color:var(--brand);box-shadow:var(--ring);
}
input:disabled,select:disabled,textarea:disabled{
  background:var(--g-50);color:var(--text-3);cursor:not-allowed}
textarea{min-height:84px;resize:vertical}
/* 下拉箭头自绘：系统默认那个箭头在深浅背景下都不协调 */
select{
  appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:34px;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5l3-3' fill='none' stroke='%2394a3b8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;
}
.hint{font-size:var(--fs-12);color:var(--text-3);margin-top:5px;line-height:1.6}

/* ==================================================================
   按钮
   ================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  padding:9px 16px;border-radius:var(--r-md);border:1px solid var(--line);
  font-size:var(--fs-14);font-family:inherit;font-weight:500;line-height:1.5;
  cursor:pointer;background:var(--card);color:var(--text);
  transition:background var(--tr),border-color var(--tr),color var(--tr),
    box-shadow var(--tr),transform var(--tr);
  white-space:nowrap;text-decoration:none;
}
/* 不再用 opacity 做 hover：那会把按钮里的字一起变淡，像禁用态 */
.btn:hover{background:var(--g-50);border-color:var(--g-300);color:var(--text)}
.btn:active{transform:translateY(1px)}
.btn:focus-visible{outline:none;box-shadow:var(--ring)}
.btn-primary{background:var(--brand);border-color:var(--brand);color:#fff;
  box-shadow:0 1px 2px rgba(37,99,235,.24)}
.btn-primary:hover{background:var(--brand-700);border-color:var(--brand-700);color:#fff}
.btn-primary:disabled{background:var(--brand-200);border-color:var(--brand-200);
  color:#fff;cursor:not-allowed;box-shadow:none;transform:none}
.btn-ok{background:var(--ok);border-color:var(--ok);color:#fff;
  box-shadow:0 1px 2px rgba(5,150,105,.24)}
.btn-ok:hover{background:var(--ok-800);border-color:var(--ok-800);color:#fff}
.btn-ghost{background:transparent;border-color:var(--line);color:var(--text-2)}
.btn-ghost:hover{background:var(--g-50);border-color:var(--g-300);color:var(--text)}
.btn-danger{background:var(--danger-50);border-color:var(--danger-100);color:var(--danger)}
.btn-danger:hover{background:var(--danger-100);border-color:#fbc4c4;color:var(--danger-800)}
.btn-sm{padding:5px 11px;font-size:var(--fs-13);border-radius:var(--r-sm)}
.btn-block{display:flex;width:100%}
.btn-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}

/* ==================================================================
   结果块（查验页：验真 / 未通过）
   ================================================================== */
.result{border-radius:var(--r-lg);padding:var(--sp-6) var(--sp-5);text-align:center;
  border:1px solid transparent}
.result-ok{background:var(--ok-50);border-color:var(--ok-100)}
.result-fail{background:var(--danger-50);border-color:var(--danger-100)}
.result-icon{
  width:56px;height:56px;border-radius:var(--r-full);margin:0 auto 14px;
  display:flex;align-items:center;justify-content:center;font-size:26px;color:#fff;
}
.result-ok .result-icon{background:var(--ok);box-shadow:0 6px 16px rgba(5,150,105,.28)}
.result-fail .result-icon{background:var(--danger);box-shadow:0 6px 16px rgba(220,38,38,.28)}
.result h2{font-size:var(--fs-17);font-weight:600;margin-bottom:6px}
.result-ok h2{color:var(--ok-800)}
.result-fail h2{color:var(--danger-800)}
.result p{font-size:var(--fs-13);color:var(--text-2)}

/* ==================================================================
   证书信息表（查验结果 / 个人中心共用）
   ================================================================== */
.cert-box{background:var(--card);border-radius:var(--r-lg);padding:var(--sp-5);
  border:1px solid var(--line);text-align:left}
.cert-box .seal-row{display:flex;align-items:center;gap:10px;padding-bottom:14px;
  border-bottom:1px dashed var(--line);margin-bottom:14px}
.cert-box .seal-row .mark{
  width:40px;height:40px;border-radius:var(--r-md);background:var(--ok-50);color:var(--ok);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-15);
  font-weight:600;flex:none;
}
.cert-box .seal-row .t1{font-size:var(--fs-14);font-weight:600;color:var(--ok-800)}
.cert-box .seal-row .t2{font-size:var(--fs-12);color:var(--text-3)}
.kv{display:flex;padding:9px 0;border-bottom:1px solid var(--line-2);font-size:var(--fs-14)}
.kv:last-child{border-bottom:none}
.kv .k{width:84px;color:var(--text-2);flex:none}
.kv .v{flex:1;word-break:break-all}
.kv .v.mono{font-family:ui-monospace,Menlo,Consolas,monospace;letter-spacing:.5px;
  color:var(--brand);font-weight:600}

/* ==================================================================
   标签胶囊
   ================================================================== */
.tag{display:inline-block;padding:2px 10px;border-radius:var(--r-full);
  font-size:var(--fs-12);line-height:1.75;font-weight:500}
.tag-ok{background:var(--ok-50);color:var(--ok-800)}
.tag-warn{background:var(--warn-50);color:var(--warn-800)}
.tag-danger{background:var(--danger-50);color:var(--danger-800)}
.tag-gray{background:var(--g-100);color:var(--text-2)}
.tag-brand{background:var(--brand-50);color:var(--brand-700)}

/* ==================================================================
   提示条：软底 + 左侧色条
   原来是一整块饱和色块，糊在页面上很吵；改成安静底 + 一条定位色。
   ================================================================== */
.alert{position:relative;padding:11px 14px 11px 17px;
  border-radius:var(--r-md);font-size:var(--fs-13);margin-bottom:var(--sp-4);
  line-height:1.65;overflow:hidden}
.alert::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px}
.alert-ok{background:var(--ok-50);color:var(--ok-800)}
.alert-ok::before{background:var(--ok)}
.alert-warn{background:var(--warn-50);color:var(--warn-800)}
.alert-warn::before{background:var(--warn)}
.alert-error{background:var(--danger-50);color:var(--danger-800)}
.alert-error::before{background:var(--danger)}
.alert-info{background:var(--brand-50);color:var(--brand-800)}
.alert-info::before{background:var(--brand)}

/* 行内警告文字（如「尚未维护单位清单」）。
   模板里用 .warn-text 标了，但样式表一直没这个类，标了等于没标 —— 补上。 */
.warn-text{color:var(--danger);font-weight:600}

/* ==================================================================
   二维码
   ================================================================== */
.qr-box{text-align:center}
.qr-box img{width:180px;height:180px;border:1px solid var(--line);
  border-radius:var(--r-md);background:var(--card);padding:8px}

/* ==================================================================
   页脚
   ================================================================== */
.site-foot{text-align:center;font-size:var(--fs-12);color:var(--text-3);
  padding:26px 16px 34px;line-height:1.9}
.site-foot a{color:var(--text-3)}
.site-foot a:hover{color:var(--brand)}

/* ==================================================================
   加载态
   ================================================================== */
.loading{text-align:center;padding:26px;color:var(--text-3);font-size:var(--fs-14)}
.spinner{
  width:22px;height:22px;border:2px solid var(--line);border-top-color:var(--brand);
  border-radius:var(--r-full);margin:0 auto 10px;animation:spin .8s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
.hidden{display:none !important}

/* ==================================================================
   后台外壳：左侧分组导航 + 吸顶操作区 + 内容区
   ------------------------------------------------------------------
   原来是一条深藏青顶栏 + 一条下划线二级模块条，两条横带吃掉近 110px 高度，
   每换一级就多一层横条和一层边框，层级全靠「条」区分。
   改成侧边栏之后：模块纵向铺开一眼看全，当前项目上下文固定在顶部，
   内容区从第一屏就能直接开始。
   ================================================================== */
.admin-body{background:var(--bg);font-size:var(--fs-14)}
.app{display:flex;min-height:100vh;align-items:flex-start}

/* ---- 侧边栏 ---- */
.app-side{
  flex:0 0 var(--sb-w);width:var(--sb-w);height:100vh;position:sticky;top:0;
  background:var(--card);border-right:1px solid var(--line);
  display:flex;flex-direction:column;z-index:40;
}
.side-brand{display:flex;align-items:center;gap:10px;
  padding:15px var(--sp-4) 14px;border-bottom:1px solid var(--line-2)}
.side-brand .logo{
  flex:none;width:34px;height:34px;border-radius:var(--r-md);
  background:linear-gradient(145deg,var(--brand-500),var(--brand-700));
  color:#fff;font-size:var(--fs-15);font-weight:600;
  display:flex;align-items:center;justify-content:center;letter-spacing:.5px;
}
.side-brand .bn{min-width:0}
.side-brand .bn b{display:block;font-size:var(--fs-14);font-weight:600;
  color:var(--ink);line-height:1.3;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.side-brand .bn span{display:block;font-size:var(--fs-11);color:var(--text-3);
  margin-top:1px;letter-spacing:.3px}

.side-nav{flex:1;overflow-y:auto;padding:var(--sp-2) 10px var(--sp-4)}
.side-group{font-size:var(--fs-11);color:var(--text-3);font-weight:500;
  padding:var(--sp-3) 10px 5px;letter-spacing:.7px}
.side-item{
  display:flex;align-items:center;gap:9px;padding:8px 10px;
  border-radius:var(--r-md);font-size:var(--fs-13);color:var(--text-2);
  font-weight:500;transition:background var(--tr),color var(--tr);
}
.side-item svg{flex:none;width:15px;height:15px;opacity:.65}
.side-item:hover{background:var(--g-50);color:var(--text)}
.side-item:hover svg{opacity:1}
.side-item.on{background:var(--brand-50);color:var(--brand-700);font-weight:600}
.side-item.on svg{opacity:1}
.side-item .cnt{margin-left:auto;font-size:var(--fs-11);color:var(--text-3);
  background:var(--g-100);border-radius:var(--r-full);padding:1px 7px;
  font-variant-numeric:tabular-nums}
.side-item.on .cnt{background:var(--brand-100);color:var(--brand-700)}
/* 有待办的模块在侧边栏直接标一个红点，不必进页面才知道 */
.side-item .alertb{margin-left:auto;width:6px;height:6px;border-radius:var(--r-full);
  background:var(--danger);flex:none;box-shadow:0 0 0 3px var(--danger-50)}
.side-sep{height:1px;background:var(--line-2);margin:var(--sp-2) 10px}
.side-foot{padding:10px;border-top:1px solid var(--line-2);
  display:flex;align-items:center;gap:9px}
.side-foot .av{flex:none;width:28px;height:28px;border-radius:var(--r-full);
  background:var(--brand-50);color:var(--brand-700);font-size:var(--fs-12);
  font-weight:600;display:flex;align-items:center;justify-content:center}
.side-foot .fn{flex:1;min-width:0;font-size:var(--fs-12);color:var(--text-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side-foot .out{flex:none;font-size:var(--fs-12);color:var(--text-3);padding:4px 6px;
  border-radius:var(--r-sm);transition:background var(--tr),color var(--tr)}
.side-foot .out:hover{background:var(--danger-50);color:var(--danger)}

/* ---- 右侧主体 ---- */
.app-body{flex:1;min-width:0;display:flex;flex-direction:column;min-height:100vh}
.topbar{position:sticky;top:0;z-index:30;
  background:rgba(255,255,255,.88);
  -webkit-backdrop-filter:saturate(180%) blur(10px);
  backdrop-filter:saturate(180%) blur(10px);
  border-bottom:1px solid var(--line)}
.tb-inner{max-width:var(--content-max);margin:0 auto;height:var(--topbar-h);
  display:flex;align-items:center;gap:var(--sp-3);padding:0 var(--sp-6)}
.topbar-burger{display:none;align-items:center;justify-content:center;
  width:34px;height:34px;flex:none;border:1px solid var(--line);
  border-radius:var(--r-md);background:var(--card);color:var(--text-2);
  cursor:pointer;font-family:inherit;transition:background var(--tr)}
.topbar-burger:hover{background:var(--g-50)}
.tb-crumb{display:flex;align-items:center;gap:7px;font-size:var(--fs-13);
  color:var(--text-3);min-width:0;flex:1}
.tb-crumb a{color:var(--text-2);white-space:nowrap}
.tb-crumb a:hover{color:var(--brand)}
.tb-crumb i{font-style:normal;opacity:.45;flex:none}
.tb-crumb b{color:var(--ink);font-weight:600;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;max-width:38vw}
.tb-acts{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  justify-content:flex-end}
.app-main{flex:1;width:100%;max-width:var(--content-max);margin:0 auto;
  padding:var(--sp-6) var(--sp-6) 64px}

/* ---- 页头 ---- */
.page-head{display:flex;align-items:flex-start;justify-content:space-between;
  margin-bottom:var(--sp-5);gap:var(--sp-3);flex-wrap:wrap}
.page-head h2{font-size:var(--fs-20);font-weight:600;letter-spacing:-.2px}
.page-head .sub{font-size:var(--fs-13);color:var(--text-2);margin-top:4px;
  line-height:1.7;max-width:76ch}

/* ---- 指标卡：浅底无描边，和白卡片放一起自然分层 ---- */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  gap:var(--sp-4);margin-bottom:var(--sp-5)}
.stat{background:var(--g-50);border-radius:var(--r-lg);padding:var(--sp-4) var(--sp-5);
  border:1px solid var(--line-2);transition:border-color var(--tr),background var(--tr)}
.stat:hover{border-color:var(--line)}
.stat .lab{font-size:var(--fs-12);color:var(--text-3);font-weight:500}
.stat .num{font-size:var(--fs-24);font-weight:600;margin-top:5px;line-height:1.2;
  color:var(--ink);letter-spacing:-.4px}
.stat .num.brand{color:var(--brand)}
.stat .num.ok{color:var(--ok)}

/* ---- 表格 ---- */
table.tbl{width:100%;border-collapse:collapse;background:var(--card);
  border-radius:var(--r-lg);overflow:hidden;font-size:var(--fs-13)}
table.tbl th{
  background:var(--g-50);text-align:left;padding:11px 14px;font-weight:600;
  color:var(--text-2);border-bottom:1px solid var(--line);white-space:nowrap;
  font-size:var(--fs-12);
}
table.tbl td{padding:12px 14px;border-bottom:1px solid var(--line-2);
  vertical-align:middle}
table.tbl tr:last-child td{border-bottom:none}
table.tbl tr:hover td{background:var(--brand-50)}
.tbl-wrap{overflow-x:auto;border-radius:var(--r-lg);border:1px solid var(--line);
  background:var(--card);box-shadow:var(--sh-xs)}
.inline-form{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:0}
.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:var(--sp-4)}
.form-grid .full{grid-column:1/-1}
.chk{display:flex;align-items:center;gap:8px;font-size:var(--fs-13);
  color:var(--text-2);cursor:pointer;user-select:none}
.chk input{width:16px;height:16px;accent-color:var(--brand);cursor:pointer;flex:none}
.section-title{display:flex;align-items:center;gap:8px;font-size:var(--fs-14);
  font-weight:600;color:var(--ink);margin:var(--sp-6) 0 var(--sp-3)}
.section-title::before{content:'';flex:none;width:3px;height:14px;border-radius:2px;
  background:var(--brand)}
.pager{display:flex;gap:6px;align-items:center;justify-content:center;
  margin-top:var(--sp-5);font-size:var(--fs-13);color:var(--text-2);flex-wrap:wrap}
.pager a,.pager span{padding:6px 12px;border-radius:var(--r-sm);
  border:1px solid var(--line);background:var(--card);
  transition:background var(--tr),border-color var(--tr),color var(--tr)}
.pager a:hover{border-color:var(--brand);color:var(--brand)}
.pager span.cur{background:var(--brand);color:#fff;border-color:var(--brand);font-weight:600}
.empty{text-align:center;padding:48px 20px;color:var(--text-3);font-size:var(--fs-14)}
.divider{height:1px;background:var(--line);margin:var(--sp-5) 0}

/* ---- 窄屏：侧边栏收成抽屉 ---- */
@media (max-width:1080px){
  .app-side{
    position:fixed;left:0;top:0;bottom:0;height:100vh;
    transform:translateX(-100%);transition:transform var(--tr-slow);
    box-shadow:var(--sh-lg);
  }
  .app.side-open .app-side{transform:none}
  .app.side-open::after{content:'';position:fixed;inset:0;
    background:rgba(15,26,43,.4);z-index:35}
  .topbar-burger{display:inline-flex}
}
@media (max-width:640px){
  .tb-inner{padding:0 var(--sp-4)}
  .app-main{padding:var(--sp-4) var(--sp-4) 48px}
  .page-head h2{font-size:var(--fs-17)}
  .form-grid{grid-template-columns:1fr}
  .stat-grid{grid-template-columns:repeat(auto-fit,minmax(136px,1fr));gap:var(--sp-3)}
  .stat{padding:var(--sp-3) var(--sp-4)}
  .stat .num{font-size:var(--fs-20)}
}

/* ================================================================
   项目化后台新增样式（v2）
   ================================================================ */

.dim{color:var(--text-3)}
.small{font-size:12px}
.center{text-align:center}

/* ---- 页头操作区 ---- */
/* 页头：标题 + 说明 + 右侧操作。
   操作区曾经是 position:absolute; right:0，长说明文字会一直排到按钮底下被压掉
   （「签到记录」这类带长 sub 的页面尤其明显）。改成正常 flex 项：说明占满剩余宽度
   自行换行，操作区固定不被压缩，窄屏再整行折下去。 */
.page-head{position:relative}
.page-head h2{flex:none}
.page-head .sub{flex:1 1 auto;min-width:0}
.page-head .head-actions{position:static;flex:none;margin-left:auto;display:flex;
  gap:8px;flex-wrap:wrap;justify-content:flex-end}
.page-head .head-actions .btn{text-decoration:none}

/* ---- 项目卡片 ---- */
.proj-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:16px}
.proj-card{background:var(--card);border-radius:var(--radius);padding:18px 20px;
  box-shadow:var(--sh-xs);border:1px solid var(--line);
  display:flex;flex-direction:column;gap:11px}
.proj-card-head{display:flex;align-items:flex-start;gap:10px;justify-content:space-between}
.proj-card-head h3{font-size:16px;line-height:1.4;font-weight:600}
.proj-meta{display:flex;gap:14px;flex-wrap:wrap;font-size:12.5px;color:var(--text-3)}
.proj-stats{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;
  background:var(--g-50);border-radius:var(--r-md);padding:11px 6px}
.proj-stats div{text-align:center}
.proj-stats b{display:block;font-size:17px;color:var(--brand);font-variant-numeric:tabular-nums}
.proj-stats span{font-size:11px;color:var(--text-3)}
.proj-no{font-size:12.5px;color:var(--text-3)}
.proj-no code{background:var(--g-100);padding:2px 7px;border-radius:var(--r-xs);color:var(--brand-dark)}
.proj-card-foot{display:flex;gap:8px;flex-wrap:wrap;padding-top:4px;
  border-top:1px solid var(--line);margin-top:2px}
.proj-card-foot .btn{text-decoration:none}

/* ---- 两栏布局 ---- */
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:16px}
.two-col .card{margin:0}
.two-col.tight{grid-template-columns:1.4fr 1fr;gap:20px}
.two-col.tight>div{min-width:0}

/* ---- 迷你列表 ---- */
.mini-list{display:flex;flex-direction:column}
.mini-row{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 0;border-bottom:1px solid var(--g-100)}
.mini-row:last-child{border-bottom:none}
.mini-main b{display:block;font-size:13.5px;font-weight:600}
.mini-main .dim{font-size:12px}
.mini-right{display:flex;align-items:center;gap:9px;font-size:12.5px;white-space:nowrap}

/* ---- 编号预览 ---- */
.no-preview{margin-top:16px;background:var(--g-50);border-radius:var(--r-md);padding:14px 16px}
.no-preview .lab{font-size:12.5px;color:var(--text-3);display:block;margin-bottom:8px}
.chips{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.chips code{background:#fff;border:1px solid var(--line);padding:4px 11px;border-radius:var(--r-xs);
  font-size:13.5px;color:var(--brand-dark);font-family:ui-monospace,Menlo,Consolas,monospace}
.no-preview .hint{margin-top:9px}

/* ---- 表格内小元素 ---- */
.tbl-wrap .tbl{margin:0}
/* 带勾选列的名单表：列最多。中文可以逐字换行，浏览器于是能把「单位」压到
   一个字宽——看着像竖排的对联。给整表钉一个最小宽度，放不下就交给
   .tbl-wrap 横向滚动（它本来就是干这个的），列宽才不会被压变形。 */
table.tbl.tbl-pick{min-width:1080px;table-layout:fixed}
/* fixed 布局下「已开通」这类标签会被逐字折行，钉住不换行 */
table.tbl.tbl-pick .tag{white-space:nowrap}
.row-actions{display:flex;gap:5px;flex-wrap:wrap;align-items:center}
.row-actions form{display:inline;margin:0}
.row-actions .btn{text-decoration:none;white-space:nowrap}
.edit-row td{background:var(--brand-50);padding:14px 13px!important}
.tight-grid{grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px 12px}
.filter-bar{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.makeup-bar{display:flex;gap:9px;align-items:center;flex-wrap:wrap;
  padding:12px;background:var(--g-50);border-radius:var(--r-md);margin-top:4px}
.qr-row td{background:var(--brand-50)}
.qr-inline{display:flex;gap:16px;align-items:center}
.qr-inline img{width:112px;height:112px;background:#fff;padding:5px;border:1px solid var(--line);border-radius:var(--r-sm)}
.qr-inline .mono{font-family:ui-monospace,Menlo,Consolas,monospace;color:var(--brand-dark)}

/* ---- 缩略图 ---- */
.thumb{width:38px;height:48px;object-fit:cover;border-radius:var(--r-xs);border:1px solid var(--line);display:block}
.thumb-empty{display:flex;align-items:center;justify-content:center;font-size:11px;
  color:var(--text-3);background:var(--bg)}

/* ---- 照片网格 ---- */
.photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px}
.photo-cell{background:var(--g-25);border:1px solid var(--line);border-radius:var(--r-md);
  padding:11px;text-align:center}
.photo-thumb{width:100%;height:104px;border-radius:var(--r-sm);background:#eef2f8;color:var(--text-3);
  display:flex;align-items:center;justify-content:center;font-size:12px;margin-bottom:8px}
.photo-name{font-size:13px;font-weight:600}
.photo-org{font-size:11.5px;color:var(--text-3);margin-bottom:8px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.photo-form{display:flex;flex-direction:column;gap:6px}
.photo-form input[type=file]{font-size:11px;width:100%}

/* ---- 危险操作区 ---- */
.danger-zone{border:1px solid var(--danger-100);background:var(--danger-50)}

/* ---- 前台查验页：标签页 ---- */
.tabs{display:flex;gap:6px;background:var(--g-100);padding:4px;border-radius:var(--r-md);margin-bottom:16px}
.tab-btn{flex:1;padding:9px;border:none;border-radius:var(--r-sm);background:transparent;
  color:var(--text-2);font-size:14px;font-weight:500;font-family:inherit;cursor:pointer}
.tab-btn.on{background:#fff;color:var(--brand);box-shadow:var(--sh-xs)}

/* ---- 前台查验页：结果卡片 ---- */
.cert-box.with-photo{display:flex;gap:16px;align-items:flex-start}
.cert-box.with-photo .cert-photo{flex:0 0 86px}
.cert-box .cert-photo img{width:86px;height:110px;object-fit:cover;border-radius:var(--r-sm);
  border:2px solid #fff;box-shadow:var(--sh-sm);display:block}
.cert-box.with-photo .cert-body{flex:1;min-width:0}
.kv .v.name-line{font-weight:600;font-size:15px}
.dl-box{margin-top:14px}
.dl-box .hint{margin-top:8px}
.result{margin-bottom:14px}
.cert-box{margin-bottom:14px}

@media (max-width:820px){
  .two-col,.two-col.tight{grid-template-columns:1fr}
  .page-head .head-actions{position:static;margin-top:10px}
  .proj-stats{grid-template-columns:repeat(3,1fr);row-gap:10px}
  .cert-box.with-photo{flex-direction:column;align-items:center;text-align:center}
  .cert-box.with-photo .cert-photo{flex:none}
}

/* ================================================================
   教师个人中心（v2.1）
   ================================================================ */

/* 页头右侧链接（查验页 / 个人中心通用） */
.site-head{position:relative}
.site-head .head-link{position:absolute;top:14px;right:16px}
.site-head .head-link a{display:inline-block;padding:6px 14px;border-radius:var(--r-full);
  background:rgba(255,255,255,.16);color:#fff;font-size:13px;text-decoration:none;
  transition:background .15s}
.site-head .head-link a:hover{background:rgba(255,255,255,.28)}

/* 用户信息卡 */
.me-user{display:flex;align-items:center;gap:14px}
.me-avatar{width:52px;height:52px;border-radius:var(--r-full);background:var(--brand);color:#fff;
  display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:600;flex:none}
.me-user-info{display:flex;flex-direction:column;gap:3px;min-width:0}
.me-user-info b{font-size:16px}
.me-user-info span{font-size:12.5px;color:var(--text-3)}

/* 项目卡 */
.me-proj{margin-top:12px}
.me-proj-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.me-proj-head b{font-size:15.5px;line-height:1.45}
.me-proj-foot{display:flex;justify-content:space-between;align-items:center;gap:10px;
  flex-wrap:wrap;margin-top:12px;padding-top:11px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--text-3)}
.me-proj-foot a{color:var(--brand);text-decoration:none}

/* 场次行 */
.me-sessions{margin-top:12px;display:flex;flex-direction:column}
.me-session{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 0;border-bottom:1px solid var(--g-100)}
.me-session:last-child{border-bottom:none}
.me-session-main{display:flex;flex-direction:column;gap:2px;min-width:0}
.me-session-main b{font-size:13.5px}
.me-session-main span{font-size:12px;color:var(--text-3)}

/* 证书信息 */
.me-cert{display:flex;gap:14px;margin-top:12px;align-items:flex-start}
.me-photo{width:64px;height:84px;object-fit:cover;border-radius:var(--r-sm);border:1px solid var(--line);flex:none}
.me-cert-info{flex:1;min-width:0}

/* 修改密码 / 更换头像 折叠卡 */
.me-pwd summary,.me-avatar-edit summary{cursor:pointer;font-weight:600;font-size:14px;
  list-style:none;display:flex;align-items:center;gap:8px}
.me-pwd summary::before,.me-avatar-edit summary::before{content:'▸';transition:transform .15s;color:var(--text-3)}
.me-pwd[open] summary::before,.me-avatar-edit[open] summary::before{transform:rotate(90deg)}
.me-pwd form{margin-top:14px}
.me-avatar-edit{padding:14px 16px}

/* ---- v2.2 发证单位电子章 ---- */
.seal-box {
  margin: 6px 0;
  padding: 6px;
  border: 1px dashed var(--line, #d7dee8);
  border-radius:var(--r-sm);
  background: var(--g-50);
  display: inline-block;
}
.seal-box img {
  display: block;
  max-width: 72px;
  max-height: 72px;
}


/* ---- 个人中心：打卡墙与作业 ---- */
.me-extra{border-top:1px dashed var(--line-2);margin-top:12px;padding-top:10px}
.me-extra summary{cursor:pointer;font-weight:600;font-size:14px;color:var(--ink)}
.me-extra form{margin-top:10px}
.me-extra textarea{width:100%;box-sizing:border-box;font:inherit;padding:8px 10px;border:1px solid var(--line);border-radius:var(--r-xs)}
.my-wall-list{margin-top:8px}
.my-wall-item{font-size:13px;color:var(--text-2);padding:6px 8px;border-left:3px solid var(--brand-200);background:var(--g-50);margin-bottom:6px;border-radius:0 6px 6px 0}
.my-wall-item .mono{color:var(--text-3);margin-right:8px;font-size:12px}

/* 得分卡：浅底无描边（与白卡片自然分层），大数字 + 达标进度条 + 四项明细 */
.me-score{margin-top:12px;padding:13px 15px;border-radius:var(--r-md);
  background:var(--brand-50);box-shadow:inset 0 0 0 1px var(--brand-100)}
.me-score.is-pass{background:var(--ok-50);box-shadow:inset 0 0 0 1px var(--ok-100)}
.me-score-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.me-score-total{display:flex;align-items:baseline;gap:6px}
.me-score-total .num{font-size:32px;font-weight:700;color:var(--brand);line-height:1;
  font-variant-numeric:tabular-nums}
.me-score.is-pass .me-score-total .num{color:var(--ok-800)}
.me-score-total .label{font-size:12.5px;color:var(--text-3)}
/* 进度条：达标线 80 分。宽度由模板按分数算，这里只负责画轨道 */
.me-score-bar{height:7px;border-radius:4px;background:var(--brand-100);overflow:hidden;margin:11px 0 10px}
.me-score.is-pass .me-score-bar{background:var(--ok-100)}
.me-score-bar i{display:block;height:100%;border-radius:4px;background:var(--brand);
  transition:width .4s ease}
.me-score.is-pass .me-score-bar i{background:var(--ok-600)}
.me-score-detail{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:3px 14px;font-size:12.5px;color:var(--text-2);line-height:1.7}
.me-score-pass{flex:none}

/* 功能入口：2 列磁贴。手机上小按钮挤成一排不好点，磁贴每格够大、还带状态副标题 */
.me-entries{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;margin-top:12px}
.me-entry{display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  padding:12px 13px;border-radius:var(--r-md);border:1px solid var(--line);
  background:var(--g-25);color:var(--ink);text-decoration:none;font-family:inherit;
  cursor:pointer;transition:border-color var(--tr),background var(--tr),transform var(--tr)}
.me-entry:hover{border-color:var(--brand-100);background:var(--brand-50)}
.me-entry:active{transform:scale(.985)}
.me-entry b{font-size:var(--fs-14);font-weight:600;line-height:1.4}
.me-entry span{font-size:var(--fs-12);color:var(--text-3);line-height:1.5;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
/* 待办项（有签到可去 / 有问卷待填）用品牌色强调，让人一眼看到该做什么 */
.me-entry.hot{border-color:var(--brand-100);background:var(--brand-50)}
.me-entry.hot b{color:var(--brand-dark)}
.me-entry.done{background:var(--ok-50);border-color:var(--ok-100)}
.me-entry.done b{color:var(--ok-800)}
.me-entry.off{opacity:.6;cursor:default}
.me-entry-ico{flex:none;width:28px;height:28px;border-radius:9px;display:flex;
  align-items:center;justify-content:center;margin-bottom:5px;
  background:var(--brand-50);color:var(--brand)}
.me-entry-ico svg{width:16px;height:16px}
.me-entry.hot .me-entry-ico{background:var(--brand);color:#fff}
.me-entry.done .me-entry-ico{background:var(--ok-600);color:#fff}
.me-entry.off .me-entry-ico{background:var(--g-100);color:var(--text-3)}

/* ---- 完成情况统计卡 ---- */
.stat-row{display:flex;flex-wrap:wrap;gap:12px}
.stat-box{flex:1 1 160px;background:var(--brand-50);border:1px solid var(--line);border-radius:var(--r-sm);padding:12px 14px;min-width:150px}
.stat-box.warn{background:var(--warn-50);border-color:var(--warn-100)}
.stat-num{font-size:26px;font-weight:700;color:var(--brand);line-height:1.1}
.stat-box.warn .stat-num{color:var(--danger)}
.stat-unit{font-size:13px;font-weight:400;color:var(--text-3)}
.stat-lab{font-size:12.5px;color:var(--text-2);margin-top:4px}

/* ---- 优秀学员标记 ---- */
.award-tag{font-size:11.5px;color:var(--gold);margin-top:3px}
.me-award{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;padding:8px 12px;background:var(--gold-light);border:1px solid var(--warn-100);border-radius:var(--r-sm)}

/* ---- 二次确认弹窗 ---- */
.modal-mask{position:fixed;inset:0;background:rgba(15,25,40,.45);display:none;align-items:center;justify-content:center;z-index:99}
.modal-mask.show{display:flex}
.modal{background:#fff;border-radius:var(--r-md);padding:22px 24px;width:min(560px,92vw);box-shadow:var(--sh-lg)}
.modal h3{margin:0 0 8px;font-size:18px;color:var(--ink)}
.modal-tip{font-size:13px;color:var(--text-2);line-height:1.7;margin:0 0 10px}
.modal-who{font-size:14px;background:var(--brand-50);border:1px solid var(--line);border-radius:var(--r-xs);padding:8px 12px;margin-bottom:12px}
.modal .btn-row{margin-top:14px}

/* ---- 个人中心：作业任务列表 ---- */
.hw-task-item{border-top:1px dashed var(--line-2);padding:10px 0}
.hw-task-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.hw-form{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.hw-form input[type=file]{font-size:13px}

/* ---- 打卡墙页面 ---- */
.wall-list{display:flex;flex-direction:column;gap:10px}
.wall-item{background:var(--g-50);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px}
.wall-item.mine{border-left:3px solid var(--brand);background:var(--brand-50)}
.wall-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:12.5px;color:var(--text-3);margin-bottom:4px}
.wall-org{color:var(--text-3)}
.wall-text{font-size:14px;color:var(--text);line-height:1.75;white-space:pre-wrap}

/* ---- 个人中心：我的证书 ---- */
.cert-shelf{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:14px}
.cert-card{border-left:4px solid var(--brand);padding:14px 16px}
.cert-card-revoked{border-left-color:var(--danger);background:var(--danger-50)}
.cert-card-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px;font-size:15px;color:var(--ink)}
.cert-kind{font-size:12px;padding:2px 9px;border-radius:var(--r-md);font-weight:600;white-space:nowrap}
.kind-graduation{background:#eaf2fd;color:var(--brand)}
.kind-excellent{background:var(--gold-light);color:var(--warn-800)}
.cert-card-body{margin-bottom:4px}
.cert-card-revoked .cert-card-body{opacity:.75}
.cert-card .btn-row{margin-top:10px;flex-wrap:wrap}

/* ---- 查验页：下载提示框 ---- */
.dl-box-tip{background:var(--g-50);border:1px dashed var(--line);border-radius:var(--r-sm);padding:10px 12px;margin-top:10px}

/* ---- 表单内等宽编号输入 ---- */
input.mono{font-family:ui-monospace,Menlo,Consolas,monospace;letter-spacing:.5px}

/* ================= 个人中心 v2.5 ================= */

/* ---- 头像 ---- */
.me-user{padding:16px}
.me-avatar-wrap{position:relative;flex:none;width:64px;height:64px}
.me-avatar-img{
  width:64px;height:64px;border-radius:var(--r-full);object-fit:cover;display:block;
  border:2px solid #fff;background:var(--g-100);box-shadow:var(--sh-sm);
}
.me-avatar-btn{
  position:absolute;right:-3px;bottom:-3px;width:25px;height:25px;padding:0;
  border-radius:var(--r-full);border:2px solid #fff;background:var(--brand);color:#fff;
  font-size:13px;line-height:1;display:flex;align-items:center;justify-content:center;
  cursor:pointer;font-family:inherit;
}
.me-avatar-btn:hover{background:var(--brand-dark)}
.me-avatar-form{margin-top:14px;padding-top:14px;border-top:1px dashed var(--line)}
.me-avatar-hint{font-size:12.5px;color:var(--text-3);margin-bottom:10px;line-height:1.7}
.me-avatar-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* ---- 三标签页 ---- */
.me-tabs{
  display:flex;gap:4px;background:#e9eef7;border-radius:var(--r-md);padding:4px;margin-top:18px;
  position:sticky;top:0;z-index:5;
}
.me-tab{
  flex:1;text-align:center;padding:9px 4px;border-radius:var(--r-sm);font-size:14px;font-weight:600;
  color:var(--text-2);cursor:pointer;border:none;background:transparent;font-family:inherit;
  transition:background .15s,color .15s;white-space:nowrap;
}
.me-tab:hover{color:var(--brand)}
.me-tab.active{background:#fff;color:var(--brand);box-shadow:var(--sh-xs)}
.me-tab .cnt{font-size:12px;font-weight:400;opacity:.72}
.me-panel{display:none}
.me-panel.active{display:block}
.me-panel > .section-title:first-child{margin-top:16px}

/* ---- 已完成项目：精简列表 ---- */
.past-list{display:flex;flex-direction:column;gap:10px;margin-top:12px}
.past-item{padding:14px 16px}
.past-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.past-head b{font-size:15px;line-height:1.5;color:var(--ink)}
/* 标题很长时右侧状态标签被挤成竖排，这里禁止换行并固定不压缩 */
.me-proj-head .tag,.past-head .tag{flex:none;white-space:nowrap}
.past-meta{display:flex;flex-wrap:wrap;gap:5px 20px;margin-top:10px;font-size:13px;color:var(--text-2)}
.past-meta .k{color:var(--text-3);margin-right:5px}
.past-meta .v{color:var(--text)}
.past-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.past-foot{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:11px;
  padding-top:10px;border-top:1px dashed var(--line);font-size:12.5px;color:var(--text-3)}
.past-foot a{color:var(--brand)}
.past-note{font-size:12.5px;color:var(--text-3);line-height:1.75;margin-top:12px}

/* ---- 证书清单：一行一证 + 行尾下载 ---- */
.cert-list{display:flex;flex-direction:column;gap:10px;margin-top:12px}
.cert-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:13px 15px;
  border-left:4px solid var(--brand)}
.cert-row.is-excellent{border-left-color:var(--gold)}
.cert-row.is-revoked{border-left-color:var(--danger);background:var(--danger-50)}
.cert-row-main{flex:1;min-width:190px}
.cert-row-title{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.5}
.cert-row-meta{display:flex;flex-wrap:wrap;gap:3px 16px;margin-top:6px;
  font-size:12.5px;color:var(--text-2)}
.cert-row-meta .k{color:var(--text-3);margin-right:4px}
.cert-row-meta .no{font-family:ui-monospace,Menlo,Consolas,monospace;color:var(--text)}
.cert-row-act{flex:none;display:flex;align-items:center;gap:7px;margin-left:auto}
.cert-row.is-revoked .cert-row-main{opacity:.78}


/* ---- 签到页：名单制「一键签到」身份卡 ---- */
.btn-lg{padding:14px 18px;font-size:16.5px;letter-spacing:2px}
.who{display:flex;align-items:center;gap:13px;padding:14px;border-radius:var(--r-md);
  background:linear-gradient(135deg,var(--brand-50),#e9f1fd);border:1px solid var(--brand-100);margin-bottom:6px}
.who-badge{flex:none;width:52px;height:52px;border-radius:var(--r-full);display:flex;align-items:center;
  justify-content:center;background:var(--brand);color:#fff;font-size:23px;font-weight:600}
.who-main{flex:1;min-width:0}
.who-name{font-size:19px;font-weight:700;color:var(--ink);line-height:1.4;word-break:break-all}
.who-org{font-size:13px;color:var(--text-2);margin-top:3px;line-height:1.5}
.who-id{flex:none;font-size:11.5px;color:var(--ok);background:var(--ok-light);
  border-radius:var(--r-full);padding:3px 9px;white-space:nowrap}

/* ---- 单位：可搜索下拉 ---- */
.sd{position:relative}
.sd .sd-input{padding-right:42px}
.sd-caret{position:absolute;right:1px;top:1px;bottom:1px;width:40px;border:0;background:transparent;
  color:var(--text-3);font-size:15px;line-height:1;cursor:pointer;border-radius:0 9px 9px 0}
.sd-caret:hover{color:var(--brand)}
.sd.open .sd-caret{color:var(--brand)}
.sd-panel{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:40;max-height:246px;
  overflow-y:auto;-webkit-overflow-scrolling:touch;background:#fff;border:1px solid var(--line);
  border-radius:var(--r-md);box-shadow:var(--sh-md);padding:5px}
.sd-item{padding:10px 12px;border-radius:var(--r-sm);font-size:14.5px;color:var(--text);cursor:pointer;
  line-height:1.5}
.sd-item:hover,.sd-item:active{background:var(--brand-light);color:var(--brand-dark)}
.sd-empty{padding:11px 12px;font-size:12.5px;color:var(--text-3);line-height:1.6}

/* ---- 后台：签到方式选择卡 ---- */
.mode-pick{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.mode-card{display:flex;gap:10px;align-items:flex-start;padding:14px;border:1.5px solid var(--line);
  border-radius:var(--r-md);background:#fff;cursor:pointer;transition:border-color .15s,background .15s}
.mode-card:hover{border-color:var(--brand-200)}
.mode-card.on,.mode-card:has(input:checked){border-color:var(--brand);background:var(--brand-50)}
.mode-card input{margin-top:3px;flex:none;accent-color:var(--brand)}
.mode-body{flex:1;min-width:0}
.mode-head{display:flex;align-items:center;gap:7px;font-size:14.5px;font-weight:700;color:var(--ink)}
.mode-desc{font-size:12.5px;color:var(--text-2);line-height:1.75;margin-top:6px}
.mode-desc b{color:var(--text)}
.mode-flow{margin-top:8px;font-size:11.5px;color:var(--brand);background:var(--brand-light);
  border-radius:var(--r-xs);padding:5px 9px;line-height:1.5;word-break:break-all}
.mode-banner .mode-now{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px}
.mode-banner .mode-now .dim{flex:1;min-width:220px;line-height:1.7}
@media (max-width:760px){.mode-pick{grid-template-columns:1fr}}

/* ================================================================
   后台 v3：按模块组织（工作台 / 各模块页）
   注：原「深藏青顶栏 + 下划线二级模块条 + 面包屑条」三套规则已随
   侧边栏外壳（.app-side / .topbar）整体移除，不在这里重复定义。
   ================================================================ */

/* ---- 工作台：五大模块方框 ---- */
.mod-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));
  gap:var(--sp-4);margin-top:var(--sp-2)}
.mod-card{display:flex;flex-direction:column;gap:var(--sp-3);background:var(--card);
  border-radius:var(--r-lg);padding:var(--sp-5);border:1px solid var(--line);
  box-shadow:var(--sh-sm);transition:box-shadow var(--tr),transform var(--tr),
  border-color var(--tr);text-decoration:none;color:inherit;min-height:172px}
.mod-card:hover{box-shadow:var(--sh-md);transform:translateY(-2px);
  border-color:var(--brand-200)}
.mod-card-top{display:flex;align-items:center;gap:var(--sp-3)}
.mod-ico{flex:none;width:42px;height:42px;border-radius:var(--r-md);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-20);
  background:var(--brand-50);color:var(--brand)}
/* 图标改用内联 SVG 线条图，与侧边栏同一套，不再拿 emoji 凑 */
.mod-ico svg{width:20px;height:20px}
.mod-card h3{font-size:var(--fs-17);font-weight:600;color:var(--ink)}
.mod-card .mod-desc{font-size:var(--fs-13);color:var(--text-2);line-height:1.75;flex:1}
.mod-metrics{display:flex;flex-wrap:wrap;gap:6px var(--sp-4);font-size:var(--fs-13);
  color:var(--text-2);padding-top:var(--sp-3);border-top:1px solid var(--line-2)}
.mod-metrics b{color:var(--brand);font-variant-numeric:tabular-nums;font-size:var(--fs-14)}
.mod-metrics .alert-num{color:var(--danger)}
.mod-card-foot{display:flex;align-items:center;gap:8px;font-size:var(--fs-13);
  color:var(--brand);font-weight:600;transition:color var(--tr)}
.mod-card:hover .mod-card-foot{color:var(--brand-700)}
.mod-card.m-ok .mod-ico{background:var(--ok-50);color:var(--ok)}
.mod-card.m-warn .mod-ico{background:var(--warn-50);color:var(--warn)}

/* ---- 列表页统一：顶部一行工具条 ---- */
.toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:14px}
.toolbar .grow{flex:1}
.toolbar .btn{text-decoration:none}
/* 工具条里常要并列好几个各自独立的 form（导入名单、一键发证…）。
   form 不能互相嵌套，所以只能平级摆放：给它自己一层 flex，别撑破行距。 */
.tb-form{display:flex;align-items:center;gap:8px;margin:0}

/* ---- 学员批量操作条 ----
   行勾选框在下方表格里，靠 HTML5 form 属性关联回来；
   这条工具条本身不参与表格布局，单独一行贴在表格上方。 */
.bulk-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:10px 12px;margin-bottom:10px;
  border:1px solid var(--line);border-radius:var(--r-md);background:var(--g-50)}
.bulk-bar .grow{flex:1}
.bulk-count{font-size:var(--fs-13);font-weight:600;color:var(--text-2);
  padding:0 4px;min-width:76px}
.bulk-count.on{color:var(--brand-700)}
.pick-cell{text-align:center}
.pick-cell input{width:16px;height:16px;accent-color:var(--brand);cursor:pointer}

/* 纯行为类：带 .js-danger 的表单在提交前走三次确认（逻辑在 base.html）。
   它不负责外观，但类名门禁要求「模板用到的类名样式表里必须有定义」，
   所以这里保留一条真实声明（顺带清掉 form 默认外边距）。 */
.js-danger{margin:0}

/* ---- 得分徽标 ---- */
.score-cell{font-variant-numeric:tabular-nums;white-space:nowrap}
.score-cell b{font-size:15px;color:var(--brand)}
.score-cell b.pass{color:var(--ok)}
.score-cell .of{font-size:11.5px;color:var(--text-3)}
.score-cell .brk{display:block;font-size:11px;color:var(--text-3);line-height:1.5}

/* ---- 出勤：完成 / 未完成 ---- */
.att{display:flex;flex-direction:column;gap:2px;font-size:12.5px;white-space:nowrap}
.att .ok-n{color:var(--ok);font-weight:600}
.att .miss-n{color:var(--danger);font-weight:600}
.att .att-total{color:var(--text-3);font-size:11.5px}

/* ---- 未签到名单弹窗 ---- */
.miss-list{max-height:52vh;overflow-y:auto;margin:10px 0 4px;border:1px solid var(--line);
  border-radius:var(--r-sm)}
.miss-list table{width:100%;border-collapse:collapse;font-size:13px}
.miss-list th{background:var(--g-50);text-align:left;padding:8px 11px;font-weight:600;
  color:var(--text-2);position:sticky;top:0;font-size:12.5px;border-bottom:1px solid var(--line)}
.miss-list td{padding:8px 11px;border-bottom:1px solid var(--g-100)}
.miss-list tr:last-child td{border-bottom:none}
.miss-empty{text-align:center;padding:26px;color:var(--text-3);font-size:13px}

/* ---- 证书预览弹窗 ---- */
.pv-mask{position:fixed;inset:0;background:rgba(15,25,40,.6);display:none;
  align-items:center;justify-content:center;z-index:120;padding:20px}
.pv-mask.show{display:flex}
.pv-box{background:#fff;border-radius:var(--r-lg);padding:14px;width:min(980px,96vw);
  max-height:94vh;display:flex;flex-direction:column;gap:10px}
.pv-head{display:flex;align-items:center;gap:10px}
.pv-head b{font-size:15px;color:var(--ink);flex:1}
/* 弹窗右上角关闭钮。模板里一直挂着 .pv-x，样式表却从来没有这个类，
   所以它在页面上是个浏览器原生灰按钮，和整体完全脱节 —— 补上。 */
.pv-x{
  flex:none;width:30px;height:30px;padding:0;border:0;border-radius:var(--r-sm);
  background:transparent;color:var(--text-3);font-size:20px;line-height:1;
  font-family:inherit;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:background var(--tr),color var(--tr);
}
.pv-x:hover{background:var(--danger-50);color:var(--danger)}
.pv-stage{flex:1;overflow:auto;background:var(--g-100);border-radius:var(--r-sm);padding:12px;
  text-align:center}
.pv-stage img{max-width:100%;height:auto;box-shadow:var(--sh-md);
  border-radius:4px;background:#fff}
.pv-foot{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.pv-foot .hint{flex:1;min-width:180px;margin:0}

/* ---- 版式微调面板 ---- */
.layout-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
.layout-item{border:1px solid var(--line);border-radius:var(--r-md);padding:12px 14px;background:var(--g-25)}
.layout-item h4{font-size:13.5px;font-weight:600;color:var(--ink);margin-bottom:9px}
.layout-row{display:flex;align-items:center;gap:8px;margin-bottom:7px;font-size:12.5px;
  color:var(--text-2)}
.layout-row label{flex:0 0 62px}
.layout-row input[type=number]{width:84px;padding:5px 8px;font-size:13px}
.layout-row .unit{color:var(--text-3);font-size:11.5px}
.layout-reset{font-size:11.5px}

/* ---- 打卡墙：卡片式清单 ---- */
.wall-admin-list{display:flex;flex-direction:column;gap:10px}
.wall-admin-item{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--r-md);background:#fff}
.wall-admin-main{flex:1;min-width:0}
.wall-admin-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  font-size:13px;color:var(--text-2)}
.wall-admin-head b{font-size:14px;color:var(--ink)}
.wall-admin-text{font-size:13.5px;color:var(--text);line-height:1.8;white-space:pre-wrap;
  margin-top:5px}
.wall-admin-act{flex:none}

/* ---- 作业管理：概览条 ---- */
.hw-sum{display:flex;flex-wrap:wrap;gap:10px 22px;align-items:center;
  background:var(--g-50);border:1px solid var(--line);border-radius:var(--r-md);padding:11px 14px;
  font-size:13px;color:var(--text-2);margin-bottom:14px}
.hw-sum b{color:var(--brand);font-size:15px;font-variant-numeric:tabular-nums}
.hw-sum .warn-n b{color:var(--danger)}
.hw-sum .grow{flex:1}

/* ---- 学员端：文件上传区（明确「选文件 / 拍照」两条路） ---- */
.up-box{border:1px dashed var(--line);border-radius:var(--r-md);padding:12px 13px;background:var(--g-25)}
.up-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.up-tip{font-size:12px;color:var(--text-3);margin-top:7px;line-height:1.65}
.wx-warn{background:var(--warn-50);border:1px solid var(--warn-100);border-radius:var(--r-md);padding:11px 13px;
  font-size:12.5px;color:var(--warn-800);line-height:1.75;margin-bottom:10px}
.wx-warn b{color:var(--warn-800)}
.wx-warn .btn{margin-top:8px}

@media (max-width:760px){
  .mod-grid{grid-template-columns:1fr}
  .mod-card{min-height:auto}
  .pv-box{width:96vw;padding:10px}
}

/* ---- 学员端：作业上传（隐藏原生控件，改用「选择文件 / 拍照」按钮） ---- */
.up-input{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.up-box{position:relative}
.up-name{font-size:12.5px;color:var(--text-3);max-width:52vw;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.up-name.has-file{color:var(--brand);font-weight:600}
.up-row .grow{flex:1}
.hw-form{margin-top:8px}
.hw-task-item{border:1px solid var(--line);border-radius:var(--r-md);padding:12px 14px;
  background:#fff;margin-bottom:10px}
.hw-task-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:6px}
.hw-task-head b{font-size:14px;color:var(--ink)}
.cert-row-act{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
@media (max-width:760px){
  .up-name{max-width:100%;flex:1 1 100%}
  .up-row .grow{display:none}
  .pv-stage iframe{height:56vh}
}

/* ==================================================================
   证书设计器（上传背景图 + 网页上摆位置）
   画布按 design.w/h 等比缩放：JS 只算 scale，具体尺寸由这里约束。
   ================================================================== */
.desk-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.desk-tabs{display:flex;gap:6px;background:#eaf0f8;border-radius:var(--r-md);padding:4px}
.desk-tabs .tab{padding:7px 15px;border-radius:var(--r-sm);font-size:13.5px;color:var(--text-2);
  font-weight:500;white-space:nowrap}
.desk-tabs .tab.on{background:#fff;color:var(--brand);font-weight:600;
  box-shadow:var(--sh-xs)}
.desk-top .spacer{flex:1}
.desk-acts{display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.desk-file{display:inline-flex;align-items:center;cursor:pointer}

.desk-wrap{display:flex;gap:16px;align-items:flex-start}
.desk-stage{flex:1 1 auto;min-width:0}
.desk-side{flex:0 0 300px;max-width:300px;background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);padding:14px;position:sticky;top:12px}
@media (max-width:1100px){
  .desk-wrap{flex-direction:column}
  .desk-side{flex:1 1 auto;max-width:none;width:100%;position:static}
}

.desk-canvas{position:relative;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);
  overflow:hidden;box-shadow:var(--sh-md);margin:0 auto}
.desk-canvas img#bgImg{position:absolute;left:0;top:0;display:block;pointer-events:none}
.desk-items{position:absolute;inset:0}
.desk-item{position:absolute;cursor:move;user-select:none;white-space:pre-wrap;
  outline:1px dashed transparent;outline-offset:2px;min-width:6px}
.desk-item:hover{outline-color:var(--brand-300)}
.desk-item.sel{outline:2px solid var(--brand);outline-offset:2px;background:rgba(27,75,143,.05)}
.desk-item.empty{color:var(--g-300) !important}
.desk-item.qr,.desk-item.seal{display:flex;align-items:center;justify-content:center;
  border:1px dashed var(--g-400);background:rgba(255,255,255,.72);color:var(--g-500);
  font-size:12px;border-radius:4px;overflow:hidden}
.desk-item.seal{border-radius:var(--r-full);border-color:var(--danger);color:var(--danger-800);
  background:rgba(255,235,232,.75)}
.desk-hint{font-size:12.5px;color:var(--text-3);margin-top:9px;line-height:1.75}

.desk-side-h{font-size:13px;font-weight:600;color:var(--ink);margin:14px 0 8px;
  padding-bottom:6px;border-bottom:1px solid var(--line)}
.desk-side-h:first-child{margin-top:0}
.desk-list{display:flex;flex-direction:column;gap:5px;max-height:190px;overflow-y:auto}
.desk-li{display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  background:var(--g-50);border:1px solid transparent;border-radius:var(--r-sm);padding:7px 10px;
  font-size:12.5px;cursor:pointer;color:var(--text-2)}
.desk-li:hover{background:var(--g-100)}
.desk-li.on{border-color:var(--brand);background:var(--brand-light);color:var(--brand);
  font-weight:600}
.desk-li .k{flex:0 0 74px;font-weight:600;color:var(--text)}
.desk-li.on .k{color:var(--brand)}
.desk-li .v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--text-3)}
.desk-li.on .v{color:var(--brand)}

.desk-props .row{display:flex;align-items:flex-start;gap:8px;margin-bottom:9px}
.desk-props .row>label{flex:0 0 84px;font-size:12.5px;color:var(--text-2);
  padding-top:6px;line-height:1.4}
.desk-props .ctl{flex:1;min-width:0}
.desk-props .row.act{justify-content:flex-end}
.desk-props input[type=text],.desk-props input[type=number],
.desk-props textarea,.desk-props select{
  width:100%;border:1px solid var(--line);border-radius:var(--r-sm);padding:6px 8px;
  font-size:13px;color:var(--text);background:#fff;font-family:inherit}
.desk-props textarea{resize:vertical;line-height:1.6}
.desk-props .mono{font-family:Consolas,Monaco,monospace}
.desk-props .clr,.desk-props .xy,.desk-props .seg{display:flex;gap:6px;align-items:center}
.desk-props .clr input[type=color]{flex:0 0 40px;height:32px;padding:2px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:#fff;cursor:pointer}
.desk-props .xy input{flex:1}
.desk-props .seg button{flex:1;padding:6px 0;border:1px solid var(--line);
  background:#fff;border-radius:var(--r-sm);font-size:12.5px;color:var(--text-2);cursor:pointer}
.desk-props .seg button.on{border-color:var(--brand);background:var(--brand-light);
  color:var(--brand);font-weight:600}

.desk-ph{display:flex;flex-wrap:wrap;gap:6px}
.ph{background:var(--g-100);border:1px solid var(--line);border-radius:var(--r-lg);padding:4px 11px;
  font-size:12px;color:var(--brand);cursor:pointer;font-family:Consolas,Monaco,monospace}
.ph:hover{background:var(--brand-light);border-color:var(--brand)}
.desk-ph .hint{flex:1 1 100%;margin:2px 0 0}

.pv-wide{width:min(1200px,97vw)}
.pv-body{flex:1;overflow:auto;background:var(--g-100);border-radius:var(--r-sm);padding:12px;text-align:center}
.pv-body img{max-width:100%;height:auto;border-radius:4px;
  box-shadow:var(--sh-md)}

.desk-toast{position:fixed;left:50%;bottom:34px;transform:translate(-50%,14px);
  background:var(--g-800);color:#fff;font-size:13.5px;padding:10px 18px;border-radius:var(--r-full);
  box-shadow:var(--sh-md);opacity:0;pointer-events:none;
  transition:opacity .18s ease,transform .18s ease;z-index:200;max-width:86vw}
.desk-toast.show{opacity:1;transform:translate(-50%,0)}
.desk-toast.ok{background:var(--ok)}
.desk-toast.err{background:var(--danger)}

.desk-note{font-size:12.5px;color:var(--text-3);margin:-4px 0 12px;line-height:1.7}

.desk-note{font-size:12.5px;color:var(--text-3);margin:-4px 0 12px;line-height:1.7}

/* ==================================================================
   证书管理页：区块导航 + 发放概览 + 发证前自检
   ================================================================== */
/* 页面很长（配置项多），用吸顶导航直达。后台顶栏本身不吸顶，所以贴 top:0 即可。 */
.sect-nav{
  position:sticky;top:0;z-index:20;display:flex;gap:6px;overflow-x:auto;
  background:rgba(244,246,250,.96);backdrop-filter:blur(6px);
  padding:10px 0;margin-bottom:14px;border-bottom:1px solid var(--line);
  scrollbar-width:none;
}
.sect-nav::-webkit-scrollbar{display:none}
.sect-nav a{
  flex:none;padding:7px 14px;border-radius:var(--r-full);font-size:13.5px;color:var(--text-2);
  background:#fff;border:1px solid var(--line);white-space:nowrap;
}
.sect-nav a:hover{color:var(--brand);border-color:var(--brand)}
.sect-nav a.on{background:var(--brand);border-color:var(--brand);color:#fff;font-weight:600}
/* 锚点跳转后标题别被吸顶条盖住 */
[id^="sec-"]{scroll-margin-top:66px}

.board-hint{font-size:12.5px;color:var(--text-3);margin:-6px 0 0}
.board .stat .num small{font-size:13px;font-weight:400;color:var(--text-3);margin-left:2px}
.stat.is-warn{border-color:var(--warn-100);background:var(--warn-50)}
.stat.is-warn .num{color:var(--warn)}
.stat.is-ok .num{color:var(--ok)}

/* 发证前自检：每行 = 状态点 + 标题说明 + 去处 */
.health{display:flex;flex-direction:column;gap:2px;margin-top:6px}
.health-item{display:flex;align-items:flex-start;gap:10px;padding:9px 2px;
  border-bottom:1px dashed var(--line)}
.health-item:last-child{border-bottom:none}
.health-item .dot{flex:none;width:18px;height:18px;border-radius:var(--r-full);margin-top:3px;
  display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff;line-height:1}
.health-item.ok .dot{background:var(--ok)}
.health-item.warn .dot{background:var(--warn)}
.health-item.bad .dot{background:var(--danger)}
.health-item.info .dot{background:#aab3c4}
.health-item .txt{flex:1;min-width:0;font-size:13.5px;line-height:1.7}
.health-item .txt b{color:var(--text)}
.health-item .txt .d{color:var(--text-2)}
.health-item .go{flex:none;font-size:13px;white-space:nowrap}
.health-item.bad .txt b{color:var(--danger)}

/* 独立提交的表单：控件仍在卡片里，靠 HTML5 form 属性关联，
   避免把上传表单嵌进保存表单（嵌套 form 会被浏览器拆散）。 */
.hidden-form{display:none}
.seal-cell{display:flex;flex-direction:column;gap:8px}

/* 卡片内的小节标题（证书内容里的 1./2./3./4.） */
.sub-h{font-size:13.5px;font-weight:600;color:var(--ink);margin:20px 0 10px}
.sub-h:first-of-type{margin-top:6px}
/* 文件选择框：默认控件太宽，收一收，别把按钮挤到下一行
   （电子印章区是四列，留给控件的宽度只有 200 出头） */
.file-in{max-width:150px;font-size:12.5px;color:var(--text-2)}
.file-in::file-selector-button{
  font-family:inherit;font-size:12.5px;padding:6px 10px;margin-right:8px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:#fff;color:var(--text);cursor:pointer;
}
.file-in::file-selector-button:hover{border-color:var(--brand);color:var(--brand)}
/* 预览弹窗底部选人下拉 */
.pv-select{
  font-family:inherit;font-size:13px;padding:6px 8px;border-radius:var(--r-sm);
  border:1px solid var(--line);background:#fff;color:var(--text);max-width:220px;
}

/* ================================================================
   签到场次 · 地图选点器（腾讯位置服务 JS API GL）
   ================================================================ */
.geo-box{
  background:var(--g-50);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:var(--sp-4);margin-top:var(--sp-3);
}

/* 未开启定位核验时不要把整块压暗——面板这么大，半透明会像「坏了、点不动」。
   改为在面板上方显式说明「设置会保存但暂不生效」。
   初始态由服务端按 row.geo_required 渲染，勾选变化由 JS 切换 .hidden。 */
.geo-off-note{
  display:flex;align-items:center;gap:6px;margin-top:var(--sp-3);
  padding:9px 12px;border-radius:var(--r-sm);font-size:12.5px;line-height:1.6;
  background:var(--warn-50);color:var(--warn-800);
}
.geo-off-note b{font-weight:600}

/* ---- 顶部：搜索 + 自动定位 ---- */
.geo-toolbar{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;margin-bottom:var(--sp-3)}
.geo-search{
  position:relative;flex:1;min-width:260px;display:flex;align-items:center;gap:var(--sp-2);
  background:#fff;border:1px solid var(--line);border-radius:var(--r-md);
  padding:0 6px 0 10px;transition:border-color var(--tr), box-shadow var(--tr);
}
.geo-search:focus-within{border-color:var(--brand);box-shadow:var(--ring)}
.geo-search-ico{flex:none;width:16px;height:16px;color:var(--text-3);display:flex}
.geo-search-ico svg{width:16px;height:16px}
.geo-kw{
  flex:1;min-width:0;border:none !important;background:transparent !important;
  padding:10px 0 !important;font-size:14px;box-shadow:none !important;
}
.geo-kw:focus{outline:none;box-shadow:none !important}
.geo-now{flex:none}
.geo-now-ico{display:inline-flex;width:15px;height:15px;margin-right:5px}
.geo-now-ico svg{width:15px;height:15px}

/* ---- 搜索结果下拉 ---- */
.geo-results{
  position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:40;
  background:#fff;border:1px solid var(--line);border-radius:var(--r-md);
  box-shadow:var(--sh-lg);max-height:296px;overflow-y:auto;padding:var(--sp-1);
}
.geo-res-item{
  display:block;width:100%;text-align:left;border:none;background:transparent;
  font-family:inherit;cursor:pointer;padding:9px 11px;border-radius:var(--r-sm);
  transition:background var(--tr);
}
.geo-res-item:hover{background:var(--brand-50)}
.geo-res-item.is-empty{cursor:default;color:var(--text-3);font-size:13px}
.geo-res-item.is-empty:hover{background:transparent}
.geo-res-t{display:block;font-size:13.5px;font-weight:600;color:var(--text)}
.geo-res-s{display:block;font-size:12px;color:var(--text-3);margin-top:2px}

/* ---- 地图容器：必须有确定高度，否则不渲染 ---- */
.geo-map{
  height:380px;border-radius:var(--r-md);overflow:hidden;
  background:var(--g-100);border:1px solid var(--line);
}
.geo-tip{
  margin-top:var(--sp-3);padding:9px 12px;border-radius:var(--r-sm);
  font-size:12.5px;line-height:1.6;
  background:var(--brand-50);color:var(--brand-dark);
}
.geo-tip.is-warn{background:var(--warn-50);color:var(--warn-800)}
.geo-tip.is-error{background:var(--danger-50);color:var(--danger-800)}

/* ---- 已选点状态条 ---- */
.geo-status{
  display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  margin-top:var(--sp-3);padding:10px 12px;background:#fff;
  border:1px solid var(--line);border-radius:var(--r-md);font-size:13.5px;
}
.geo-dot{flex:none;width:8px;height:8px;border-radius:var(--r-full);background:var(--g-300)}
.geo-dot.is-on{background:var(--ok);box-shadow:0 0 0 3px var(--ok-100)}
.geo-name{font-weight:600;color:var(--text);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.geo-coord{margin-left:auto;font-size:12px;color:var(--text-3);white-space:nowrap}

/* ---- 未配置 Key 时的引导卡 ---- */
.geo-guide{
  background:#fff;border:1px dashed var(--line);border-radius:var(--r-md);padding:var(--sp-4);
}
.geo-guide-head{display:flex;gap:var(--sp-3);align-items:flex-start}
.geo-guide-ico{
  flex:none;width:40px;height:40px;border-radius:var(--r-md);
  display:flex;align-items:center;justify-content:center;
  background:var(--brand-50);color:var(--brand);
}
.geo-guide-ico svg{width:22px;height:22px}
.geo-guide-head b{font-size:14.5px;color:var(--ink)}
.geo-guide-head p{font-size:13px;color:var(--text-2);line-height:1.75;margin-top:3px}
.geo-steps{
  margin:var(--sp-3) 0 0;padding-left:20px;
  font-size:13px;color:var(--text-2);line-height:1.95;
}
.geo-steps code{
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12.5px;
  background:var(--g-100);padding:1px 5px;border-radius:var(--r-xs);
}

/* ---- 半径 / 精度 ---- */
.geo-params{margin-top:var(--sp-4)}

/* ---- 高级：手动输入坐标 ---- */
.geo-adv{margin-top:var(--sp-3);border-top:1px dashed var(--line);padding-top:var(--sp-3)}
.geo-adv summary{
  cursor:pointer;font-size:13px;font-weight:600;color:var(--text-2);
  list-style:none;display:flex;align-items:center;gap:6px;
}
.geo-adv summary::-webkit-details-marker{display:none}
.geo-adv summary::before{content:'▸';color:var(--text-3);transition:transform var(--tr)}
.geo-adv[open] summary::before{transform:rotate(90deg)}
.geo-adv summary:hover{color:var(--brand)}
.geo-adv .form-grid{margin-top:var(--sp-3)}

@media (max-width:640px){
  .geo-map{height:270px}
  .geo-search{min-width:100%}
  .geo-now{width:100%;justify-content:center}
  .geo-coord{margin-left:0;width:100%}
  .geo-box{padding:var(--sp-3)}
}

/* ================================================================
   签到大屏设置页
   左栏调参数、右栏实时预览。预览是真正的 /screen 页面缩放进来的，
   不是画出来的示意图——所见即现场。
   ================================================================ */
.scr-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:var(--sp-4);align-items:start}
.scr-col{min-width:0;display:flex;flex-direction:column;gap:var(--sp-4)}
.scr-col form{display:flex;flex-direction:column;gap:var(--sp-4)}
/* 预览跟随滚动，调参数时不用来回翻 */
.scr-prev-card{position:sticky;top:calc(var(--topbar-h) + var(--sp-4))}

/* ---- Logo 预览与操作 ---- */
.scr-logo{
  margin-top:var(--sp-3);min-height:96px;padding:var(--sp-4);
  display:flex;align-items:center;justify-content:center;
  border:1px dashed var(--line);border-radius:var(--r-md);
  background:repeating-conic-gradient(var(--g-50) 0% 25%,#fff 0% 50%) 50%/16px 16px;
}
.scr-logo-img{max-width:100%;object-fit:contain;display:block}
.scr-logo-none{font-size:var(--fs-13);color:var(--text-3)}
.scr-acts{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-3)}

/* ---- 滑杆 ---- */
.scr-rng-row{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  margin-top:var(--sp-4);padding-top:var(--sp-3);border-top:1px dashed var(--line)}
.scr-rng-lab{font-size:var(--fs-13);color:var(--text-2);font-weight:500}
.scr-rng{
  flex:1;min-width:140px;height:6px;appearance:none;cursor:pointer;padding:0;
  border-radius:var(--r-full);background:var(--g-200);border:0;
}
.scr-rng::-webkit-slider-thumb{
  appearance:none;width:18px;height:18px;border-radius:50%;
  background:var(--brand);border:2px solid #fff;box-shadow:var(--sh-sm);cursor:pointer;
}
.scr-rng::-moz-range-thumb{
  width:18px;height:18px;border-radius:50%;background:var(--brand);
  border:2px solid #fff;box-shadow:var(--sh-sm);cursor:pointer;
}
.scr-rng:focus-visible{outline:none;box-shadow:var(--ring)}
.scr-rng-val{font-size:var(--fs-12);color:var(--text-2);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.scr-rng-val b{color:var(--brand);font-size:var(--fs-14)}

/* ---- 预览窗 ---- */
.scr-bar{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.scr-bar select{
  flex:1;min-width:150px;padding:8px 10px;font-size:var(--fs-13);
  border:1px solid var(--line);border-radius:var(--r-sm);background:#fff;font-family:inherit;
}
.scr-prev{
  position:relative;width:100%;overflow:hidden;
  border-radius:var(--r-md);background:#07111d;
  box-shadow:var(--sh-md);border:1px solid var(--g-800);
}
/* iframe 固定按 1600×900 渲染，再整体缩放到容器宽度：
   大屏内部全是 vh 单位，只有视口比例与现场一致，预览才有参照意义。 */
.scr-frame{
  position:absolute;left:0;top:0;width:1600px;height:900px;border:0;
  transform-origin:0 0;background:#07111d;
}

@media (max-width:1080px){
  .scr-layout{grid-template-columns:minmax(0,1fr)}
  .scr-prev-card{position:static}
}


/* ==================================================================
   调查问卷（后台列表 / 题目编辑 / 数据统计 / 学员端填写）
   ================================================================== */

/* ---- 问卷卡片（后台列表） ---- */
.sv-head{display:flex;align-items:flex-start;justify-content:space-between;
  gap:14px;flex-wrap:wrap;margin-bottom:10px}
.sv-title{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:var(--fs-15);font-weight:600;color:var(--ink)}
.sv-meta{display:flex;gap:6px 18px;flex-wrap:wrap;font-size:var(--fs-13);
  color:var(--text-2)}
.sv-meta b{color:var(--brand);font-size:var(--fs-15);font-variant-numeric:tabular-nums}
.sv-meta .warn-n{color:var(--danger)}
.sv-bar{height:6px;border-radius:3px;background:var(--g-100);overflow:hidden;margin-top:10px}
.sv-bar i{display:block;height:100%;background:var(--brand);border-radius:3px}

/* ---- 题目编辑 ---- */
.sv-q{border:1px solid var(--line);border-radius:var(--r-md);background:var(--card);
  padding:14px 16px;margin-bottom:12px}
.sv-q-h{display:flex;align-items:center;gap:9px;margin-bottom:11px}
.sv-q-no{flex:none;width:24px;height:24px;border-radius:7px;background:var(--brand-50);
  color:var(--brand-dark);font-size:var(--fs-12);font-weight:600;
  display:flex;align-items:center;justify-content:center}
.sv-q-t{flex:1;font-size:var(--fs-14);font-weight:600;color:var(--ink);min-width:0}
.sv-opt{display:flex;align-items:center;gap:9px;font-size:var(--fs-13);
  color:var(--text-2);padding:4px 0}
.sv-opt-s{flex:none;width:14px;height:14px;border:1.5px solid var(--line);border-radius:50%}
.sv-opt-s.box{border-radius:3px}
.sv-opt-s.on{border-color:var(--brand);background:var(--brand);
  box-shadow:inset 0 0 0 2px var(--card)}
.sv-scale{display:flex;gap:6px;flex-wrap:wrap;align-items:center;font-size:var(--fs-12);
  color:var(--text-3)}
.sv-scale span{min-width:34px;text-align:center;padding:5px 8px;border:1px solid var(--line);
  border-radius:var(--r-xs);background:var(--g-25)}
.sv-tpls{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px}
.sv-tpl{border:1px solid var(--line);border-radius:var(--r-md);padding:12px 13px;
  background:var(--g-25);cursor:pointer;transition:border-color var(--tr),background var(--tr)}
.sv-tpl:hover{border-color:var(--brand);background:var(--brand-50)}
.sv-tpl b{display:block;font-size:var(--fs-13);color:var(--ink);margin-bottom:4px}
.sv-tpl .hint{margin:0;font-size:var(--fs-12)}

/* ---- 问卷模板库：一行一套模板 ---- */
.tpl-row{display:flex;align-items:flex-start;justify-content:space-between;
  gap:14px flex-wrap:wrap;padding:13px 0}
.tpl-main{flex:1;min-width:0}
.tpl-name{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:var(--fs-15);font-weight:600;color:var(--ink)}
.tpl-desc{font-size:var(--fs-13);color:var(--text-3);margin:5px 0 7px;line-height:1.55}
@media (max-width:560px){
  .tpl-row .row-actions{width:100%}
  .tpl-row .btn{flex:1}
}

/* ---- 学员端填写 ---- */
.sv-fill{max-width:720px;margin:0 auto;padding:0 2px}
.sv-prog{position:sticky;top:0;z-index:5;background:var(--bg);padding:10px 0 8px}
.sv-prog .sv-bar{margin-top:7px}
.sv-prog-t{display:flex;justify-content:space-between;font-size:var(--fs-12);
  color:var(--text-3)}
.sv-qi{border:1px solid var(--line);border-radius:var(--r-md);background:var(--card);
  padding:16px 18px;margin-bottom:13px}
.sv-qi.req-miss{border-color:var(--danger);background:var(--warn-50)}
.sv-qi-h{display:flex;gap:9px;margin-bottom:12px}
.sv-qi-t{font-size:var(--fs-15);font-weight:600;color:var(--ink);line-height:1.55}
.sv-qi-hint{font-size:var(--fs-12);color:var(--text-3);margin-top:5px;line-height:1.6}
.sv-opts{display:flex;flex-direction:column;gap:2px}
.sv-opt-pick{display:flex;align-items:center;gap:10px;padding:9px 11px;
  border:1px solid var(--line);border-radius:var(--r-sm);cursor:pointer;
  font-size:var(--fs-14);color:var(--text);transition:all var(--tr)}
.sv-opt-pick:hover{border-color:var(--brand-100);background:var(--brand-50)}
.sv-opt-pick input{margin:0;flex:none;accent-color:var(--brand);width:16px;height:16px}
.sv-opt-pick.on{border-color:var(--brand);background:var(--brand-50);color:var(--brand-dark);
  font-weight:500}
.sv-mx{width:100%;border-collapse:collapse}
.sv-mx th,.sv-mx td{padding:8px 10px;border-bottom:1px solid var(--g-100);
  font-size:var(--fs-13);text-align:left}
.sv-mx th{color:var(--text-3);font-weight:500;font-size:var(--fs-12)}
.sv-mx td.pick{text-align:center;width:52px}
.sv-mx input{margin:0;accent-color:var(--brand);width:17px;height:17px;cursor:pointer}
.sv-rate{display:flex;gap:7px;flex-wrap:wrap}
.sv-rate label{border:1px solid var(--line);border-radius:var(--r-sm);padding:8px 0;
  min-width:44px;text-align:center;font-size:var(--fs-13);color:var(--text-2);
  cursor:pointer;background:var(--card);transition:all var(--tr)}
.sv-rate label:hover{border-color:var(--brand-100);background:var(--brand-50)}
.sv-rate label.on{border-color:var(--brand);background:var(--brand);color:#fff;font-weight:600}
.sv-rate input{display:none}

/* ---- 数据统计 ---- */
.sv-stats{border-top:1px solid var(--line-2);padding-top:14px;margin-top:14px}
.sv-stats:first-child{border-top:none;padding-top:0;margin-top:0}
.sv-stats-h{display:flex;gap:9px;align-items:baseline;margin-bottom:11px;flex-wrap:wrap}
.sv-stats-h b{font-size:var(--fs-14);color:var(--ink)}
.sv-rows{display:flex;flex-direction:column;gap:7px}
.sv-row{display:grid;grid-template-columns:minmax(90px,1.1fr) 3fr 62px 62px;
  gap:10px;align-items:center;font-size:var(--fs-13);color:var(--text-2)}
.sv-row .lb{overflow-wrap:anywhere}
.sv-track{height:16px;border-radius:4px;background:var(--g-100);overflow:hidden}
.sv-track i{display:block;height:100%;background:var(--brand);border-radius:4px;
  transition:width var(--tr)}
.sv-row .n{text-align:right;font-variant-numeric:tabular-nums;color:var(--text-3)}
.sv-row .pc{text-align:right;font-variant-numeric:tabular-nums;color:var(--ink);font-weight:500}
.sv-row.top .lb,.sv-row.top .pc{color:var(--brand-dark);font-weight:600}
.sv-texts{display:flex;flex-direction:column;gap:9px}
.sv-text{border-left:3px solid var(--brand-100);padding:7px 0 7px 12px;
  font-size:var(--fs-13);color:var(--text-2);line-height:1.75}
.sv-text .who{font-size:var(--fs-12);color:var(--text-3);margin-bottom:3px}
.sv-auto{background:var(--g-25);border:1px solid var(--line);border-radius:var(--r-md);
  padding:14px 16px;font-size:var(--fs-13);color:var(--text-2);line-height:1.9}
.sv-auto p{margin:0 0 10px}
.sv-auto p:last-child{margin-bottom:0}

@media (max-width:820px){
  .sv-row{grid-template-columns:minmax(70px,1fr) 2fr 48px 54px;gap:7px;font-size:var(--fs-12)}
}

/* 矩阵题在手机上的宽度分配：5 个评分列各占 52px 会把行标签挤成一列一个字
   （「培训内容的针对性」被拆成四行），所以窄屏下把评分列收窄、内边距压小，
   把省下来的宽度还给行标签。 */
@media (max-width:560px){
  .sv-mx th,.sv-mx td{padding:7px 4px;font-size:var(--fs-12)}
  .sv-mx td.pick{width:38px}
  .sv-mx input{width:15px;height:15px}
}

/* ---- 问卷编辑页补充 ---- */
.sv-q details{margin-top:11px}
.sv-q summary{cursor:pointer;font-size:var(--fs-13);color:var(--brand);font-weight:500;
  list-style:none;user-select:none;padding:6px 0}
.sv-q summary::-webkit-details-marker{display:none}
.sv-q summary::before{content:'▸ ';font-size:var(--fs-11)}
.sv-q details[open] summary::before{content:'▾ '}
.sv-q-body{padding-top:10px}
button.sv-tpl{font-family:inherit;font-size:inherit;color:inherit;display:block}
.sv-tpl .hint{display:block;margin-top:2px}
.row-actions .grow{flex:1}
.warn-n{color:var(--danger);font-weight:500}

/* ================= 学员端个人中心 v3（手机第一） =================
   这一版只做三件事：① 该做的事做成够大的磁贴（一排小按钮在手机上不好点）
   ② 得分给一条达标进度条（学员真正关心的是「还差多少」）
   ③ 折叠区改成卡片，不再用虚线分隔（与全站卡片风格统一）。
   旧规则保留在上方，这里按同名选择器覆盖，不删旧的是为了老页面仍能回退。 */

/* ---- 折叠区：卡片式，取代原来的虚线上边框 ---- */
.me-extra{border-top:none;margin-top:12px;padding:10px 12px;
  border-radius:var(--r-md);background:var(--g-50);box-shadow:inset 0 0 0 1px var(--line-2)}
.me-extra summary{cursor:pointer;font-weight:600;font-size:var(--fs-14);color:var(--ink);
  list-style:none;user-select:none;padding:2px 0}
.me-extra summary::-webkit-details-marker{display:none}
.me-extra summary::before{content:'▸ ';color:var(--text-3);font-size:var(--fs-12)}
.me-extra[open] summary::before{content:'▾ '}
.me-extra textarea{width:100%;box-sizing:border-box;font:inherit;padding:9px 11px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--card)}
.me-pwd,.me-avatar-edit{border-radius:var(--r-md)}
.me-pwd summary,.me-avatar-edit summary{list-style:none;padding:2px 0}
.me-pwd summary::-webkit-details-marker,.me-avatar-edit summary::-webkit-details-marker{display:none}
.me-avatar-form{border-top:1px solid var(--line-2)}

/* ---- 证书行：等级色条沿用上方已有的 border-left（别再叠一层 inset 阴影，
      两条色条并排会出现"双线"），这里只补投影与排版 ---- */
.cert-row{box-shadow:var(--sh-sm);border-radius:var(--r-md);background:var(--card);
  padding:14px 16px}
.cert-list{gap:11px}
.cert-row-title{font-size:var(--fs-15);font-weight:600;color:var(--ink)}
.cert-row-act{gap:8px}

/* ---- 已完成项目：信息改成两列，扫一眼就能读完 ---- */
.past-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:4px 14px}
.past-foot{font-size:var(--fs-13)}

/* ---- 标签页：吸顶时给一层底，避免内容从缝隙里透出来 ---- */
.me-tabs{background:var(--g-100);padding:4px;box-shadow:var(--sh-xs)}
.me-tab.active{box-shadow:var(--sh-sm)}
.me-tab{border-radius:calc(var(--r-md) - 3px)}

/* ---- 窄屏（手机）---- */
@media (max-width:400px){
  /* 极窄屏（≤400px）改成单列横排：图标跨两行、标题与副标题各占一行。
     纯 flex-direction:row 会让标题和副标题并排挤在一起，副标题被截断。 */
  .me-entries{grid-template-columns:1fr}
  .me-entry{display:grid;grid-template-columns:auto minmax(0,1fr);
    grid-template-rows:auto auto;align-items:center;column-gap:10px}
  .me-entry-ico{grid-row:span 2;margin-bottom:0}
  .me-entry b,.me-entry span{justify-self:start;max-width:100%}
  .cert-row-act{width:100%;margin-left:0;justify-content:flex-end}
  .me-score-total .num{font-size:28px}
}

/* ================= 学员端 v4：项目详情页与网页版 =================
   手机优先，但**作业提交主要在电脑上做**（要选 Word / PDF 文件），
   所以宽屏（≥760px）另给一套排布：磁贴四列、作业两列、任务行横向铺开。
   返回条是新增的：所有二级页共用 `_me_parts.html` 里的同一个宏，位置与文案不会走样。 */

/* ---- 二级页顶部的返回条（吸顶，滚到哪都能一步返回） ---- */
.back-bar{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:10px;
  padding:9px var(--sp-4);background:var(--card);border-bottom:1px solid var(--line)}
.back-btn{display:inline-flex;align-items:center;gap:2px;flex:none;padding:5px 12px 5px 7px;
  border-radius:var(--r-full);background:var(--g-100);color:var(--ink);
  font-size:var(--fs-13);font-weight:600;text-decoration:none}
.back-btn svg{width:17px;height:17px}
.back-btn:hover{background:var(--brand-50);color:var(--brand)}
.back-title{font-size:var(--fs-14);font-weight:600;color:var(--ink);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.back-sub{font-size:var(--fs-12);color:var(--text-3)}

/* ---- 网页版容器：比手机版宽，作业表单在电脑上才不显得局促 ---- */
.wrap.wide{max-width:920px}

/* ---- 区块小标题 ---- */
.sect-title{font-size:var(--fs-14);font-weight:600;color:var(--ink);margin-bottom:10px}

/* ---- 「进入项目」按钮：列表页唯一的主行动 ---- */
.me-go{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:12px;
  padding:12px 16px;border-radius:var(--r-md);background:var(--brand);color:#fff;
  font-size:var(--fs-15);font-weight:600;text-decoration:none;box-shadow:var(--sh-sm)}
.me-go svg{width:18px;height:18px;flex:none}
.me-go:hover{background:var(--brand-700)}
.me-go:active{transform:translateY(1px)}

/* ---- 全部任务：三档（正在签到 / 待办 / 已完成） ----
   未完成的加深、已完成的转浅灰并沉底；排序在 app.me_tasks() 里做，
   这里只负责让三档一眼能分出来。 */
.tk-list{display:flex;flex-direction:column;gap:8px}
.tk-row{display:flex;align-items:center;gap:10px;padding:11px 13px;
  border-radius:var(--r-md);background:var(--card);box-shadow:var(--sh-sm)}
.tk-main{min-width:0;flex:1}
.tk-main b{display:block;font-size:var(--fs-14);font-weight:600;color:var(--ink)}
.tk-main span{display:block;font-size:var(--fs-12);color:var(--text-3);margin-top:2px}
.tk-side{display:flex;align-items:center;gap:8px;flex:none}
.tk-tag{font-size:var(--fs-12);color:var(--text-3);white-space:nowrap}
.tk-row.lv0{background:var(--brand-50)}
.tk-row.lv0 .tk-main b{color:var(--brand-800)}
.tk-row.lv0 .tk-tag{color:var(--brand-700);font-weight:600}
/* lv1（待办）显式写出来：它就是标准态，但类名契约要求模板用到的类都有定义，
   免得以后改 .tk-row 默认值时，待办与已完成分不出来。 */
.tk-row.lv1{background:var(--card);box-shadow:var(--sh-sm)}
.tk-row.lv1 .tk-main b{color:var(--ink)}
.tk-row.lv2{background:transparent;box-shadow:inset 0 0 0 1px var(--line-2)}
.tk-row.lv2 .tk-main b{color:var(--text-3);font-weight:500}
.tk-row.lv2 .tk-main span{color:var(--text-3)}
.tk-row.lv2 .tk-tag{color:var(--text-3)}

/* ---- 作业：已提交记录 + 撤销 ---- */
.hw-list{display:flex;flex-direction:column;gap:12px}
.grow{flex:1}
.hw-done{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 11px;
  margin-bottom:9px;border-radius:var(--r-sm);background:var(--g-100)}
.hw-file{display:flex;align-items:center;gap:7px;min-width:0;flex:1;
  font-size:var(--fs-13);color:var(--ink)}
.hw-file svg{width:17px;height:17px;flex:none;color:var(--brand)}
.hw-name{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hw-size{flex:none;font-size:var(--fs-12);color:var(--text-3)}
.hw-file .mono{flex:none;font-size:var(--fs-12);color:var(--text-3)}
.hw-del{flex:none;margin:0}

/* ---- 宽屏（网页版）：作业提交的主战场 ---- */
@media (min-width:760px){
  .me-entries{grid-template-columns:repeat(4,1fr)}
  .hw-list{display:grid;grid-template-columns:1fr 1fr;gap:14px}
  .tk-row{padding:13px 16px}
  .tk-main b{font-size:var(--fs-15)}
  .up-row .up-name{font-size:var(--fs-13)}
}
