/* ===== WJS-C 五健儿童健康 · 浅彩玻璃主题（与统算仪表盘一致） ===== */
:root{
  --bg1:#fff5fb; --bg2:#eef5ff; --bg3:#f3fff6;
  --card:#ffffff; --ink:#3a3a52; --ink-soft:#7a7a96; --line:#ececf6;
  --primary:#7c6cff; --primary-d:#5b4fe0; --primary-soft:#efeaff;
  --sleep:#6c8cff; --nutri:#46c08a; --sport:#ffab4c; --vision:#33c6d8; --psy:#ff7eb6; --tcm:#b08bff;
  --green:#37c98d; --yellow:#ffce4f; --orange:#ff9f43; --red:#ff6b6b;
  --shadow:0 14px 34px rgba(124,108,255,.16);
  --shadow-sm:0 4px 14px rgba(120,110,200,.10);
  --radius:22px; --radius-sm:14px;
  --glass:linear-gradient(160deg, rgba(255,255,255,.92), rgba(250,251,255,.84));
  --glass-line:rgba(124,108,255,.14);
  --font:"PingFang SC","Hiragino Sans GB","Microsoft YaHei",-apple-system,"Segoe UI",sans-serif;
}
*{box-sizing:border-box}
body{margin:0;font-family:var(--font);color:var(--ink);
  background:
    radial-gradient(900px 520px at 6% -6%, rgba(124,108,255,.28), transparent 52%),
    radial-gradient(820px 500px at 98% -2%, rgba(63,214,240,.22), transparent 52%),
    radial-gradient(960px 640px at 50% 122%, rgba(255,126,182,.20), transparent 52%),
    linear-gradient(160deg,#eef0ff 0%, #e7f1ff 46%, #fbeef8 100%);
  background-attachment:fixed;min-height:100vh;font-size:15px;line-height:1.6}
a{color:var(--primary);text-decoration:none}
h1,h2,h3,h4{margin:0 0 .4em;font-weight:800;letter-spacing:.3px}
.btn{display:inline-flex;align-items:center;gap:6px;border:none;cursor:pointer;
  background:linear-gradient(135deg,var(--primary),var(--primary-d));color:#fff;
  padding:11px 20px;border-radius:999px;font-weight:700;font-size:14px;
  box-shadow:var(--shadow-sm);transition:transform .15s,box-shadow .15s}
.btn:hover{transform:translateY(-2px);box-shadow:0 8px 20px rgba(124,108,255,.30)}
.btn:active{transform:translateY(0)}
.btn.ghost{background:#fff;color:var(--primary);border:2px solid var(--primary-soft)}
.btn.soft{background:var(--primary-soft);color:var(--primary-d)}
.btn.sm{padding:7px 14px;font-size:13px}
.btn.danger{background:linear-gradient(135deg,#ff8585,#ff5d5d)}
.btn.gray{background:#eef0f7;color:var(--ink-soft)}
input,select,textarea{font-family:var(--font);font-size:15px;padding:11px 14px;
  border:2px solid var(--line);border-radius:var(--radius-sm);width:100%;background:#fff;color:var(--ink)}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 4px var(--primary-soft)}
input[readonly]{background:#fafaff;cursor:pointer}
.date-picker{background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%237c6cff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E") no-repeat right 12px center;background-size:18px;padding-right:40px;cursor:pointer}
label{font-weight:700;font-size:13px;color:var(--ink-soft);display:block;margin:10px 0 4px}
.field{margin-bottom:6px}

/* 证件类型（身份证号 / 健康卡号）：类型下拉 + 号码输入 组合控件 */
.id-combo{display:flex;gap:8px}
.id-combo select{flex:none;width:124px}
.id-combo input{flex:1;min-width:0}
.id-hint{margin-top:6px;font-size:12.5px;line-height:1.5;min-height:18px}
.id-hint.ok{color:var(--green)}
.id-hint.warn{color:var(--orange)}
.id-hint.err{color:var(--red)}

/* layout */
/* 外壳：横向铺满整屏。原 `max-width:1600px;margin:0 auto` 会让全站在宽屏被压成中间一条、
   两侧留大片背景空白（2026-09-23 按需求解除）。 */
.app{display:flex;min-height:100vh;width:100%;background:rgba(255,255,255,.55);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.sidebar{width:248px;flex:none;background:rgba(255,255,255,.70);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-right:1px solid rgba(124,108,255,.12);padding:18px 14px;display:flex;flex-direction:column;gap:6px;position:sticky;top:0;height:100vh}
.brand{display:flex;align-items:center;gap:10px;padding:8px 10px 16px;font-weight:900;font-size:18px;color:var(--primary-d)}
.brand .logo{width:30px;height:30px;flex:none;border-radius:9px;display:block;
  box-shadow:0 4px 12px rgba(124,108,255,.28)}
.nav a{display:flex;align-items:center;gap:10px;padding:11px 14px;border-radius:14px;color:var(--ink-soft);font-weight:700;transition:.15s}
.nav a:hover{background:var(--primary-soft);color:var(--primary-d)}
.nav a.active{background:linear-gradient(135deg,var(--primary),var(--primary-d));color:#fff;box-shadow:var(--shadow-sm)}
.nav .ic{font-size:18px;width:22px;text-align:center}
.content{flex:1;padding:22px 28px;min-width:0}
.topbar{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:18px;flex-wrap:wrap}
.topbar h1{font-size:24px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 顶栏左右两组的伸缩：左侧标题可压缩，右侧（机构+用户+账户操作）保持贴右不被换行挤走。
   - flex-basis 必须给具体值（不能 auto）：flex-wrap 的换行判定用的是各组 max-content，
     h1 含 nowrap 长文本时会虚高，导致右侧组被挤到第二行。
   - 左侧组必须 nowrap：否则标题+返回按钮自身折行会把整条顶栏撑高（实测 98.8px），
     右侧组随之垂直居中下移，账户操作看上去「掉到了下面」。 */
.topbar > .row{flex:1 1 200px;min-width:0;flex-wrap:nowrap}
.topbar > div:last-child{flex:0 0 auto}
.topbar .row > .hamburger,.topbar .row > .back-btn{flex:none}
.userchip{display:flex;align-items:center;gap:10px;background:var(--glass);border:1px solid var(--glass-line);padding:8px 14px;border-radius:999px;box-shadow:var(--shadow-sm)}
.avatar{width:38px;height:38px;border-radius:50%;background:var(--primary-soft);display:flex;align-items:center;justify-content:center;font-size:20px}
.rolebadge{font-size:12px;font-weight:800;padding:3px 10px;border-radius:999px;background:var(--primary-soft);color:var(--primary-d)}
.warnbadge{font-size:12px;font-weight:800;padding:4px 10px;border-radius:999px;white-space:nowrap;display:inline-flex;align-items:center;gap:4px}
.warnbadge.green{background:#e8f9f1;color:#229e6b}
.warnbadge.yellow{background:#fff7e0;color:#b38600}
.warnbadge.orange{background:#fff0e0;color:#c46a1e}
.warnbadge.red{background:#ffeaea;color:#d94444}
.warnbadge.gray{background:#f2f3f7;color:var(--ink-soft)}
.hamburger{display:none;font-size:26px;background:#fff;border:none;border-radius:12px;padding:6px 12px;cursor:pointer;box-shadow:var(--shadow-sm)}

/* cards & grid */
.grid{display:grid;gap:16px}
.cards{grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.card{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow);border:1px solid var(--glass-line)}
.card.pad{padding:22px}
/* ---- 整卡可点 · stretched link（2026-10-12）----------------------------------
   需求：点卡片任意位置即进入该卡片的"主操作"，不必精确点到卡片里的小按钮。
   ─ 为什么用"覆盖层"而不是把整卡包进 <a>：HTML 规范禁止 <a> 嵌套 <a>，
     浏览器会把内层按钮从包裹链接中"拆"出去（DOM 被重排），渲染与点击都会错乱。
   ─ 为什么不用 JS：覆盖层纯 HTML/CSS，无脚本报错风险、无加载时序问题，
     且卡片本身已内联 position:relative（绝对定位的包含块来源）。
   ─ 使用纪律：覆盖层 href 必须与卡片内【第一个按钮】的 href 完全同源。
     模板里用同一个 {% set card_href %} 变量同时生成两者，避免日后改了按钮漏改覆盖层。
   ─ 卡片内的按钮/表单必须提到覆盖层之上（z-index:2），否则按钮点不到。 */
.card.clickable{position:relative;cursor:pointer;transition:box-shadow .16s ease,transform .16s ease}
.card.clickable:hover{box-shadow:0 12px 28px rgba(124,108,255,.18);transform:translateY(-2px)}
.card.clickable:active{transform:translateY(0)}
.card-link{position:absolute;inset:0;z-index:1;border-radius:inherit}
.card.clickable a.btn,
.card.clickable button,
.card.clickable form{position:relative;z-index:2}
.card .head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:8px}
.card .head h4{margin-bottom:0}
.d-flex{display:flex}.d-flex.align-items-center{align-items:center}
.gap-2{gap:8px}.gap-3{gap:12px}
.row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.between{justify-content:space-between}
.wrap{flex-wrap:wrap}
.stat{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-radius:var(--radius);padding:18px 20px;box-shadow:var(--shadow);flex:1;min-width:150px;border:1px solid var(--glass-line)}
.stat .n{font-size:30px;font-weight:900;color:var(--primary-d)}
.stat .l{color:var(--ink-soft);font-weight:700;font-size:13px}
.muted{color:var(--ink-soft)}
.pill{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:999px;font-weight:800;font-size:12px;background:var(--primary-soft);color:var(--primary-d)}
/* 预约状态徽章（与全站四档语义一致：warn/info/success/danger/muted） */
.st{display:inline-block;padding:3px 11px;border-radius:8px;font-weight:800;font-size:12px;white-space:nowrap}
.st-warn{background:#fff4d6;color:#a3680a}
.st-info{background:#e6f0ff;color:#1f5fbf}
.st-success{background:#e3f9e5;color:#1f8a3b}
.st-danger{background:#ffe3e3;color:#c0392b}
.st-muted{background:#eef0f3;color:#7a828c}
.chip{display:inline-block;padding:6px 14px;border-radius:999px;background:rgba(255,255,255,.8);border:2px solid var(--line);font-weight:700;color:var(--ink-soft);cursor:pointer;font-size:13px}
.chip.active{background:var(--primary);color:#fff;border-color:var(--primary)}

/* level colors */
.lv{font-weight:900;padding:5px 14px;border-radius:999px;color:#fff;display:inline-flex;gap:6px;align-items:center}
.lv-绿{background:var(--green)} .lv-黄{background:var(--yellow);color:#7a5b00}
.lv-橙{background:var(--orange)} .lv-红{background:var(--red)}
.lv-蓝{background:#4aa3ff}
.dot{width:10px;height:10px;border-radius:50%;display:inline-block}
.d-green{background:var(--green)} .d-yellow{background:var(--yellow)} .d-orange{background:var(--orange)} .d-red{background:var(--red)}

/* child card */
.child-card{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow);transition:.18s;cursor:pointer;border:1px solid var(--glass-line);position:relative;overflow:hidden}
.child-card:hover{transform:translateY(-4px);box-shadow:0 16px 36px rgba(124,108,255,.20)}
.child-card .face{font-size:46px;text-align:center;margin:6px 0}
.child-card .nm{font-weight:900;font-size:17px}
.child-card .meta{color:var(--ink-soft);font-size:13px}
.child-index{position:absolute;top:8px;left:8px;z-index:2;min-width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;padding:0 7px;border-radius:999px;background:linear-gradient(135deg,var(--primary),var(--vision));color:#fff;font-weight:900;font-size:13px;box-shadow:0 2px 8px rgba(124,108,255,.35)}
.child-del-form{position:absolute;top:8px;right:8px;z-index:2;margin:0;padding:0}
.child-del-form button{padding:4px 8px;font-size:14px;line-height:1;border-radius:8px;opacity:.85}
.child-del-form button:hover{opacity:1}

/* assessment */
.progress{height:14px;background:#eef0f7;border-radius:999px;overflow:hidden;margin:14px 0}
.progress > i{display:block;height:100%;background:linear-gradient(90deg,var(--primary),var(--vision));width:0;transition:width .3s}
.qcard{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-radius:var(--radius);padding:18px 20px;box-shadow:var(--shadow);margin-bottom:14px;border:1px solid var(--glass-line);border-left:6px solid var(--primary)}
.qcard .q{font-weight:800;margin-bottom:4px}
.qcard .q .code{color:var(--ink-soft);font-size:12px;font-weight:700;margin-right:8px}
.qcard .dim{font-size:12px;color:var(--ink-soft);margin-bottom:10px}
.opts{display:flex;gap:8px;flex-wrap:wrap}
.opt{flex:1;min-width:72px;text-align:center;padding:10px 6px;border-radius:14px;border:2px solid var(--line);background:#fff;cursor:pointer;font-weight:800;transition:.12s;user-select:none}
.opt:hover{border-color:var(--primary)}
.opt.sel{color:#fff;border-color:transparent}
/* freq 4 档：未选中即各自彩色（柔和底+彩边+彩字），选中实心深色 */
.opt.s0{background:#e9faf2;border-color:#9fe0bd;color:#1d9e6f}
.opt.s1{background:#f4fadf;border-color:#c6e79a;color:#6f9e3a}
.opt.s2{background:#fff3e4;border-color:#ffcf9e;color:#d97a1f}
.opt.s3{background:#ffecec;border-color:#ffb4b4;color:#d94b4b}
.opt.s0:hover{background:#d9f6e6;border-color:var(--green)}
.opt.s1:hover{background:#ecf9d0;border-color:#9bd17a}
.opt.s2:hover{background:#ffe8cd;border-color:var(--orange)}
.opt.s3:hover{background:#ffd9d9;border-color:var(--red)}
.opt.s0.sel{background:var(--green)} .opt.s1.sel{background:#9bd17a}
.opt.s2.sel{background:var(--orange)} .opt.s3.sel{background:var(--red)}
/* V5.0 五级第 5 档（深红） */
.opt.s4{background:#ffe3e3;border-color:#ff9d9d;color:#c23535}
.opt.s4:hover{background:#ffd2d2;border-color:#ff8080}
.opt.s4.sel{background:#d93838}
.opt.y0.sel{background:var(--green)} .opt.y1.sel{background:var(--red)}
.group-title{display:flex;align-items:center;gap:10px;margin:22px 0 6px;font-weight:900;font-size:18px}
.group-title .gi{font-size:24px}

/* report */
.bar{height:16px;background:#eef0f7;border-radius:999px;overflow:hidden;margin-top:6px}
.bar > i{display:block;height:100%;border-radius:999px}
.presc{display:inline-flex;align-items:center;gap:8px;background:rgba(255,255,255,.9);border:2px solid var(--line);border-radius:16px;padding:10px 16px;font-weight:800;margin:6px 6px 0 0}
.presc .pi{font-size:22px}
.table{width:100%;border-collapse:collapse;background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow);border:1px solid var(--glass-line)}
.table th,.table td{padding:11px 14px;text-align:left;border-bottom:1px solid var(--line);font-size:14px}
.table th{background:var(--primary-soft);color:var(--primary-d);font-weight:800}
.table tr:last-child td{border-bottom:none}

/* ===== 列表通栏（2026-09-23 按需求：所有列表横向铺满）=====
   背景：`.table` 自身已带圆角 / 边框 / 阴影，本身就是「一张卡」；项目里又常把它套进
   `.card` / `.card.pad`，卡片 18 / 22px 的水平内边距让表格左右各缩进，同一页里就比其它
   卡片窄一截。用真实 Chromium 量测（1920 视口）：11 个页面 gapRight = 19 / 23px
   （= 卡片 padding + 1px 边框），而未套卡片的 /screening/child/pick、/admin/users 等为 0。
   表格左右外框改由卡片提供（去掉自身左右 border，避免双层框）。

   ★ 卡片有两种形态，必须分开处理（2026-10-11 修正）：
     形态 A「卡片自带内边距」 class="flush card pad"（14 处：/admin/*、/data/、/growth/*、
       /screening/*）—— 卡片里除表格外还有标题 / 筛选栏 / 表单等，**必须保留 .card.pad 的
       22px 内边距**，否则这些内容会贴到卡片边缘；表格用负 margin 抵消该内边距。
     形态 B「卡片不吃内边距」 class="card flush" + 内联 padding:0（4 处：/appointments/、
       /appointments/slots、/appointments/<id>、/children/audit）—— 卡片内只有表格，
       表格 width:100% 即通栏，**不能加负 margin**。
   原实现只用一条 `.card.flush > .table{margin-left:-22px}` 覆盖两种形态，对形态 B 就是
   负 margin 无处抵消 → 表格整体左移 22px、被卡片 overflow:hidden 裁掉首列约 8px。
   实测被切：审核台「验收新建儿童」首字「验」、预约详情 / 预约列表「预约号」首字「预」。
   分流手段用 `:not(.pad)` —— 两张卡片形态的唯一 class 差异。 */
.card.flush{overflow:hidden}

/* ---- 形态 A：带 .pad（22px 内边距）→ 用负 margin 抵消 ---- */
.card.flush.pad > .table-scroll,
.card.flush.pad > form > .table-scroll,
.card.flush.pad > .table{margin-left:-22px;margin-right:-22px}
/* 有滚动层：滚动层已被负 margin 撑到卡片全宽，表格占满它即可，切不可再叠加
   calc(100% + 44px)（会溢出 43px，实测 gapRight = -43）。
   `> form >` 分支：/admin/roles 的权限矩阵表格被 <form id="rolesForm"> 包住，
   只写直接子选择器会漏掉它（实测该页 ml=0 完全未生效）。 */
.card.flush.pad > .table-scroll > .table,
.card.flush.pad > form > .table-scroll > .table{width:100%;border-left:0;border-right:0;
  border-radius:0;box-shadow:none;margin-bottom:0}
/* 无滚动层：表格自己负 margin 抵消卡片内边距，要把被抵消掉的宽度补回来 */
.card.flush.pad > .table{width:calc(100% + 44px);border-left:0;border-right:0;
  border-radius:0;box-shadow:none;margin-bottom:0}

/* ---- 形态 B：不带 .pad → 卡片自身 padding:0，表格 width:100% 即通栏 ---- */
.card.flush:not(.pad){padding:0}
.card.flush:not(.pad) > .table-scroll,
.card.flush:not(.pad) > form > .table-scroll,
.card.flush:not(.pad) > .table{margin-left:0;margin-right:0}
.card.flush:not(.pad) > .table-scroll > .table,
.card.flush:not(.pad) > form > .table-scroll > .table,
.card.flush:not(.pad) > .table{width:100%;border-left:0;border-right:0;border-radius:0;
  box-shadow:none;margin-bottom:0}
/* 通栏表格与卡片同宽后，表头左右两端的圆角也交给卡片 */
.card.flush > .table-scroll > .table:first-child thead tr:first-child th:first-child,
.card.flush > .table thead tr:first-child th:first-child{border-top-left-radius:0}
.card.flush > .table-scroll > .table:first-child thead tr:first-child th:last-child,
.card.flush > .table thead tr:first-child th:last-child{border-top-right-radius:0}

/* login */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}
.login-card{background:var(--glass);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--glass-line);border-radius:28px;padding:34px;box-shadow:0 20px 60px rgba(124,108,255,.22);width:380px;max-width:100%;text-align:center}
.login-card .mascot{font-size:64px}
.login-card h2{font-size:22px;margin-top:6px}
.login-card .sub{color:var(--ink-soft);margin-bottom:20px}

/* flash */
.flash{position:fixed;top:18px;left:50%;transform:translateX(-50%);z-index:999;display:flex;flex-direction:column;gap:8px}
.flash .msg{padding:12px 22px;border-radius:14px;font-weight:800;box-shadow:var(--shadow);animation:pop .3s}
.flash .success{background:#e7fbf1;color:#1d9e6a}
.flash .error{background:#ffeaea;color:#d84545}
.flash .warning{background:#fff4e0;color:#b3710a}
.flash .info{background:#eef0ff;color:#5b4fe0}
/* 别名：历史代码里用 'ok' / 'danger' 作分类（全项目 16 处），但此前没有对应样式，
   会渲染成「无底色裸文本」浮在页面顶部（2026-09-23 在五健筛查入口页截图确认）。
   补成与 success / error 同色即可，避免去改 16 处调用点。 */
.flash .ok{background:#e7fbf1;color:#1d9e6a}
.flash .danger{background:#ffeaea;color:#d84545}
@keyframes pop{from{opacity:0;transform:translateY(-8px)}to{opacity:1}}

.section-title{display:flex;align-items:center;gap:10px;margin:6px 0 14px}
.section-title .si{font-size:22px}

/* ============ 档案详情页（children/detail.html，2026-10-31 重做） ============
   旧版 .detail-card / .info-rows / .guardian-rows 已随模板一起下线：
   .guardian-rows 用 justify-content:space-between 撑满整列，把 6 行家长信息
   拉成 40px 行距；两卡等高等距导致大面积留白。新版全部换成 cd-* 命名空间，
   不复用旧类名（避免以后有人以为旧样式还在用）。 */

/* ⓪ 页签条（2026-10-31 详情页改页签式）
   复用全站既有契约 .gtab / .gtab-h / .gtab-b / .gtab-p（与 screening/group.html 同源），
   这里只调本页的间距、字号与徽标配色。
   ★ 打印时「隐藏面板也展开」由 .gtab-p.is-hide 的 @media print 规则负责，此处不重复声明 —— 
     重复声明容易在后续改动里先被删掉，导致 Ctrl+P 丢内容。 */
.cd-tabs{margin:-2px 0 4px}
.cd-tabs .gtab-h{margin-bottom:16px}
.cd-tabs .gtab-b{font-size:14.5px;padding:11px 15px}
.cd-tabs .gtab-b:first-child{margin-left:-15px}   /* 首字与卡片左边缘对齐，避免整体右移一格 */
.cd-tabs .gtab-b .n{font-size:11.5px;font-weight:800;line-height:1;padding:3px 7px;border-radius:999px;
  background:rgba(124,108,255,.12);color:var(--primary-d)}
.cd-tabs .gtab-b.is-on .n{background:var(--primary);color:#fff}
.cd-tabs .gtab-b .n-warn{background:#fff2d9;color:#b7791f}
.cd-tabs .gtab-b.is-on .n-warn{background:#e08a1e;color:#fff}

/* 健康宣教卡片内的表格（住在「健康宣教」页签里）
   原表头写死内联 width:56px，但 .table 是 table-layout:auto —— 固定宽压不住内容：
   「序号」被折成「序 / 号」两行、下发时间折成日期+时刻两行、操作列两个按钮上下叠，
   整行虚高到 79px（8 行吃掉 640px）。改类名 + nowrap，让列宽按内容撑。 */
.edu-c-no{width:62px;white-space:nowrap}
.edu-c-time{width:150px;white-space:nowrap}
.edu-c-ops{width:148px;white-space:nowrap}
.edu-ops{flex-wrap:nowrap}

/* ① 身份条 */
.cd-hero{display:flex;align-items:center;gap:20px;flex-wrap:wrap;padding:18px 22px;margin-bottom:14px}
.cd-hero-id{display:flex;align-items:center;gap:16px;flex:1;min-width:280px}
.cd-ava{flex:none;width:66px;height:66px;border-radius:20px;display:grid;place-items:center;
  font-size:34px;line-height:1;
  background:linear-gradient(150deg,#efeaff 0%,#e6f2ff 55%,#ffe9f4 100%);
  border:1px solid rgba(124,108,255,.20);box-shadow:0 8px 18px rgba(124,108,255,.14)}
.cd-ident{min-width:0}
.cd-name{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin:0;line-height:1.3}
.cd-name .cd-nm{font-size:22px;font-weight:900;letter-spacing:.4px}
.cd-meta{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:5px;font-size:13px;
  font-weight:600;color:var(--ink-soft)}
.cd-meta b{color:var(--ink);font-weight:900;font-variant-numeric:tabular-nums}
.cd-meta span+span{position:relative}
.cd-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.cd-tag{display:inline-flex;align-items:center;gap:5px;flex:none;white-space:nowrap;
  padding:3px 10px;border-radius:999px;font-size:12px;font-weight:700;
  color:var(--primary-d);background:rgba(124,108,255,.09);border:1px solid rgba(124,108,255,.16)}
.cd-tag .icv{opacity:.85}
.cd-tag-mute{color:var(--ink-soft);background:rgba(122,122,150,.08);border-color:rgba(122,122,150,.16)}
.cd-acts{display:flex;align-items:center;gap:9px;flex-wrap:wrap;justify-content:flex-end}
.cd-del-form{margin:0;padding:0;display:flex}
.btn.cd-del{background:#fdecec;color:#d84545}
.btn.cd-del:hover{background:#ffdede;box-shadow:0 8px 18px rgba(255,107,107,.22)}

/* 小尺寸状态胶囊（表格与身份条共用；沿用全站 .pill 底色系） */
.pill.cd-pill{font-size:11.5px;padding:3px 10px;font-weight:800}
.pill.cd-pill-ok{background:#e7fbf1;color:#1d9e6a}
.pill.cd-pill-warn{background:#fff4e5;color:#d88410}
.pill.cd-pill-pend{background:#fff9e6;color:#b89100}
.pill.cd-pill-bad{background:#ffeaea;color:#d84545}
.pill.cd-pill-mute{background:rgba(122,122,150,.10);color:var(--ink-soft)}

/* ② 关键指标条 */
.cd-metrics{display:grid;gap:12px;margin-bottom:16px;
  grid-template-columns:repeat(auto-fit,minmax(168px,1fr))}
.cd-mt{position:relative;padding:12px 16px 13px;border-radius:18px;overflow:hidden;
  background:var(--glass);border:1px solid var(--glass-line);box-shadow:var(--shadow-sm)}
.cd-mt-bar{position:absolute;left:0;top:13px;bottom:13px;width:3px;border-radius:0 3px 3px 0}
.cd-mt-k{display:flex;align-items:center;gap:6px;font-size:12px;font-weight:800;
  letter-spacing:.3px;color:var(--ink-soft)}
.cd-mt-v{margin-top:5px;font-size:23px;font-weight:900;line-height:1.15;color:var(--ink);
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:4px}
.cd-mt-u{margin-left:2px;font-size:12px;font-weight:700;color:var(--ink-soft)}
.cd-mt-na{color:#c9c9d8;font-weight:800}
.cd-mt-s{margin-top:3px;font-size:12px;font-weight:800}
.cd-mt-s.ok{color:#1d9e6a}
.cd-mt-s.warn{color:#d88410}
.cd-mt-s.bad{color:#d84545}
.cd-mt-s.info{color:#2b8fd0}
.cd-mt-s.mute{color:#a6a6bb;font-weight:700}

/* ③ 双栏字段卡 */
/* 双栏等高：默认 align-items:stretch（原先 start 会让右侧卡片随内容变矮，底边参差）。
   卡片内部用 flex 列布局，字段区不拉伸（grid 行会被均分拉高 → 虚线间距忽大忽小），
   多出来的空间留作卡片底部留白。 */
.cd-cols{display:grid;gap:16px;grid-template-columns:1.15fr 1fr;align-items:stretch}
.cd-cols>.cd-card{display:flex;flex-direction:column}
.cd-cols>.cd-card>.cd-fields{flex:0 0 auto}
.cd-card{padding:18px 22px}
.cd-card .section-title{margin:0 0 6px}
.cd-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:26px}
.cd-f{min-width:0;padding:10px 0 9px;border-bottom:1px dashed var(--line)}
.cd-f.full{grid-column:1 / -1}
.cd-f-k{font-size:12px;font-weight:800;color:var(--ink-soft);letter-spacing:.2px;
  margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cd-f-v{font-size:14px;font-weight:800;color:var(--ink);line-height:1.45;
  overflow-wrap:anywhere}
.cd-f-v a{color:var(--primary-d);font-weight:800}
.cd-f-v a:hover{text-decoration:underline}
.cd-f-sub{margin-left:6px;font-size:12px;font-weight:700;color:#d88410}
.cd-f-none{color:#b9b9cc;font-weight:800}
.cd-mono{font-family:"SF Mono",Menlo,Consolas,"Courier New",monospace;
  font-size:13.5px;font-variant-numeric:tabular-nums;letter-spacing:.2px}
.cd-empty-lite{padding:16px 0 6px;color:var(--ink-soft);font-weight:700;font-size:13px}

/* ④ 测评记录 */
.cd-list{margin-top:16px}
.cd-tool{margin-bottom:12px;gap:12px;align-items:center}
.cd-tool .section-title{margin:0}
.cd-count{display:inline-flex;align-items:center;justify-content:center;min-width:26px;
  height:22px;padding:0 8px;border-radius:999px;font-size:12px;font-weight:900;
  color:var(--primary-d);background:rgba(124,108,255,.12)}
.cd-filter{display:flex;align-items:center;gap:8px;flex-wrap:nowrap}
/* ★ flex 子项默认 flex-shrink:1：筛选行窄一点就把「筛选 / 重置」压成逐字竖排
   （实测 1440 视口出现「筛\n选」「重\n置」）。按钮必须 flex:none + nowrap。 */
.cd-filter .btn{flex:none;white-space:nowrap}
.cd-sel{appearance:none;-webkit-appearance:none;padding:6px 26px 6px 10px;border-radius:10px;
  border:1px solid var(--line);background:#fff
    url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%237a7a96' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E")
    no-repeat right 9px center;
  font-size:13px;font-weight:700;color:var(--ink);min-width:118px;cursor:pointer}
.cd-sel:focus{outline:none;border-color:rgba(124,108,255,.45);
  box-shadow:0 0 0 3px rgba(124,108,255,.13)}
.cd-bulk{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:7px 12px;margin-bottom:10px;border-radius:12px;
  background:rgba(124,108,255,.055);border:1px dashed rgba(124,108,255,.22);
  font-size:12.5px;font-weight:700}
.cd-bulk .muted{font-weight:700}
.cd-bulk #cdSelN{color:var(--primary-d);font-weight:900}
.btn.cd-bulk-del{background:#fff;color:#d84545;border:1px solid rgba(216,69,69,.35);
  padding:4px 11px;font-size:12.5px}
.btn.cd-bulk-del:hover{background:#fdecec;box-shadow:0 6px 14px rgba(255,107,107,.18)}

.cd-table th,.cd-table td{padding:10px 12px}
.cd-table .cd-c-chk{width:42px;text-align:center;padding-left:14px;padding-right:0}
.cd-table .cd-c-chk input{width:15px;height:15px;cursor:pointer;accent-color:var(--primary)}
.cd-table .cd-c-ops{text-align:right;white-space:nowrap;width:1%}
.cd-table th{font-size:12.5px;letter-spacing:.3px;white-space:nowrap}
.cd-src{padding:2px 8px;border-radius:8px;background:rgba(122,122,150,.09);
  font-size:12px;font-weight:800;color:var(--ink-soft);white-space:nowrap}
/* 操作列：必须包一层 flex 容器。inline-flex 直接放进 td 会按基线对齐，
   单元格底部多出 descender 空隙（实测行高 51px 而按钮只有 28px）。 */
.cd-ops{display:flex;align-items:center;justify-content:flex-end;gap:1px;white-space:nowrap}
/* 图标 + 文字的小胶囊，删除做成纯图标（确认框仍会把话说全） */
.cd-ops .cd-op{display:inline-flex;align-items:center;gap:4px;flex:none;
  padding:4px 8px;border-radius:9px;border:1px solid transparent;background:none;
  font-size:12.5px;font-weight:800;line-height:1.35;color:var(--primary-d);cursor:pointer;
  transition:background .14s ease,color .14s ease}
.cd-ops .cd-op:hover{background:rgba(124,108,255,.10)}
.cd-op-go{color:#1d9e6a}
.cd-op-go:hover{background:rgba(29,158,106,.10)}
.cd-op-form{display:flex;align-items:center;margin:0;padding:0;flex:none}
.cd-ops .cd-op-x{color:#b9b9cc;padding:4px 6px}
.cd-ops .cd-op-x:hover{background:#fdecec;color:#d84545}

/* 窄屏收敛：表格里「来源 / 填写人」属次要信息，先让位，避免操作列被挤换行 */
@media (max-width:1240px){
  .cd-table .cd-c-src,.cd-table .cd-c-rater{display:none}
}
@media (max-width:1000px){
  .cd-table .cd-c-age{display:none}
}

.cd-empty{padding:26px 12px 30px;text-align:center;color:var(--ink-soft)}
.cd-empty .icv{color:#cdc9ea}
.cd-empty-t{margin-top:8px;font-size:15px;font-weight:900;color:var(--ink)}
.cd-empty-s{margin:4px auto 14px;max-width:460px;font-size:13px;font-weight:600;line-height:1.6}
.cd-empty-s a{font-weight:800}

@media (max-width:1180px){
  .cd-cols{grid-template-columns:1fr}
  /* 指标条：≤1180 收成 2×2。四块挤在 ~800px 内容区时每块仅 171px，
     「0.496 · 中心性肥胖」会被拆成「中心性肥 / 胖」（实测 1024 视口）。 */
  .cd-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:760px){
  .cd-fields{grid-template-columns:1fr}
  .cd-metrics{grid-template-columns:1fr}
  .cd-hero{padding:16px}
  .cd-acts{width:100%;justify-content:flex-start}
  .cd-filter{flex-wrap:wrap}
  .cd-sel{min-width:100px}
  .cd-mono{font-size:12.5px}
}


/* hospital management two-column layout */
@media (max-width:920px){
  .hospital-layout{grid-template-columns:1fr !important}
}

/* mobile */
@media (max-width:860px){
  .sidebar{position:fixed;left:0;top:0;z-index:50;transform:translateX(-100%);transition:.25s;box-shadow:var(--shadow)}
  .sidebar.open{transform:translateX(0)}
  .hamburger{display:block}
  .content{padding:16px}
  .topbar h1{font-size:20px}
  .cards{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  .opts .opt{min-width:60px;font-size:13px;padding:9px 4px}
  .stat{min-width:120px}
}
.overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.3);z-index:40}
.overlay.show{display:block}

/* 密码查看切换 */
.pw-wrap{position:relative;display:block}
.pw-wrap input{padding-right:40px}
.pw-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;font-size:16px;line-height:1;padding:6px;color:#8a8fb0;border-radius:8px;z-index:2}
.pw-toggle:hover{background:var(--primary-soft);color:var(--primary-d)}

/* 顶部医院徽章 */
.hosp-badge{display:flex;align-items:center;gap:9px;
  background:linear-gradient(135deg,var(--primary-soft) 0%,rgba(63,214,240,.12) 100%);
  border:1px solid rgba(124,108,255,.28);border-radius:16px;padding:6px 14px 6px 10px;
  box-shadow:0 2px 12px rgba(124,108,255,.12);position:relative;overflow:hidden}
.hosp-badge::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(60px 30px at 90% -10%,rgba(124,108,255,.18),transparent)}
.hosp-badge .hosp-ico{width:34px;height:34px;flex:none;border-radius:10px;
  background:linear-gradient(135deg,var(--primary),var(--vision));
  display:flex;align-items:center;justify-content:center;font-size:17px;
  box-shadow:0 4px 10px rgba(124,108,255,.35)}
.hosp-badge .hosp-name{font-weight:800;font-size:13px;color:var(--primary-d);line-height:1.5;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hosp-badge .hosp-code{font-size:10px;color:#8a8fb0;font-weight:600;letter-spacing:.3px;margin-top:3px}
/* 窄屏优先保证右上角账户操作贴边：机构徽章提前收起（原 720px 收起会导致顶栏换行、按钮掉行）。
   阈值 1400：≥1401 时一行可容纳「标题 + 机构徽章 + 用户 + 两个操作按钮」实测约 1097px；
   1366 及以下收起徽章，保证最长的页面标题（园所/班级五健筛查汇总表）不被省略号截断。 */
@media (max-width:1400px){.hosp-badge{display:none}}

/* 小屏（手机）：用户信息只留头像，保证两个账户操作按钮仍贴在右上角同一行 */
@media (max-width:600px){
  .topbar > .row{flex:1 1 140px}
  .userchip{padding:6px 10px}
  .userchip > .uinfo{display:none}
}

/* 右上角账户操作（修改密码 / 退出登录） */
.top-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.top-act{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  background:var(--glass);border:1px solid var(--glass-line);border-radius:999px;
  padding:8px 14px;font-weight:700;font-size:13px;color:var(--primary-d);
  box-shadow:var(--shadow-sm);transition:transform .15s,box-shadow .15s,background .15s,border-color .15s}
.top-act .ic{font-size:15px;line-height:1}
.top-act:hover{transform:translateY(-2px);background:var(--primary-soft);color:var(--primary-d);
  box-shadow:0 8px 18px rgba(124,108,255,.22)}
.top-act:active{transform:translateY(0)}
.top-act.on{background:var(--primary-soft);border-color:rgba(124,108,255,.38)}
.top-act.danger{color:#d94444}
.top-act.danger:hover{background:#ffeaea;border-color:rgba(255,107,107,.38);
  box-shadow:0 8px 18px rgba(255,107,107,.20);color:#d94444}
@media (max-width:1180px){
  .top-act .tx{display:none}
  .top-act{padding:8px 11px}
}

/* 右上角用户菜单（2026-10-11）：用户名徽章改为下拉触发器，
   「修改密码 / 退出登录」默认收起，点击用户名才展开。
   - .userchip 由 div 改为 button（去掉浏览器默认 button 样式，视觉与原来一致）；
   - 下拉面板绝对定位在徽章下方右对齐，按钮的 .top-act 保留原图标/配色，
     仅把胶囊外形改为整行菜单项（悬停仍高亮，不位移）。 */
.user-menu{position:relative;z-index:60}
button.userchip{font:inherit;color:inherit;cursor:pointer;transition:box-shadow .15s,border-color .15s}
button.userchip:hover{border-color:rgba(124,108,255,.38);box-shadow:0 6px 18px rgba(124,108,255,.20)}
button.userchip:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.ucaret{width:0;height:0;flex:none;margin-left:3px;
  border-left:4.5px solid transparent;border-right:4.5px solid transparent;
  border-top:5.5px solid #868aa8;transition:transform .18s}
.user-menu.open .ucaret{transform:rotate(180deg)}
.user-menu-pop{position:absolute;right:0;top:calc(100% + 8px);min-width:174px;
  display:none;flex-direction:column;gap:4px;padding:7px;
  background:#fff;border:1px solid var(--glass-line);border-radius:16px;
  box-shadow:0 14px 34px rgba(60,60,110,.16);z-index:60}
.user-menu.open .user-menu-pop{display:flex}
.user-menu-pop .top-act{display:flex;width:100%;justify-content:flex-start;gap:9px;
  background:transparent;border:none;border-radius:11px;padding:10px 12px;
  font-size:13.5px;box-shadow:none;transform:none;color:var(--ink)}
.user-menu-pop .top-act:hover{transform:none;background:var(--primary-soft);color:var(--primary-d);box-shadow:none}
.user-menu-pop .top-act.on{background:var(--primary-soft);color:var(--primary-d)}
.user-menu-pop .top-act.danger{color:#d94444}
.user-menu-pop .top-act.danger:hover{background:#ffeaea;color:#d94444;box-shadow:none}
/* 窄屏原会把 .top-act 文字隐藏（换行免挤），菜单里的文字必须保留 */
.user-menu-pop .top-act .tx{display:inline}
/* 手机端：用户名徽章只留头像，箭头保留（提示可点开） */
@media (max-width:600px){
  .user-menu-pop{min-width:156px}
}

/* ===== 测评 · 对话式向导 ===== */
.wz-bar{display:flex;align-items:center;gap:12px;margin:0 0 14px}
.chat-box{background:linear-gradient(180deg, rgba(255,255,255,.94), rgba(248,246,255,.88));border-radius:var(--radius);
  padding:30px 22px 16px;box-shadow:var(--shadow);
  height:210px;min-height:210px;overflow-y:auto;
  display:flex;flex-direction:column;gap:14px}
.chat-row{display:flex;gap:12px;align-items:flex-start}
.chat-row.doc{animation:chatIn .32s ease}
.chat-row.user{justify-content:flex-end;animation:chatIn .28s ease}
.chat-avatar{width:44px;height:44px;flex:none;border-radius:50%;
  background:linear-gradient(135deg,var(--primary),var(--vision));
  display:flex;align-items:center;justify-content:center;font-size:22px;
  box-shadow:0 4px 12px rgba(124,108,255,.28)}
.chat-row.user .chat-avatar{background:linear-gradient(135deg,var(--nutri),#2aa573)}
.chat-bubble{max-width:82%;background:rgba(255,255,255,.92);border-radius:4px 18px 18px 18px;
  padding:14px 18px;box-shadow:var(--shadow-sm);border:1px solid #f0eefc}
.chat-bubble.user{background:linear-gradient(135deg,var(--primary-soft),#eafcff);
  border-radius:18px 4px 18px 18px;font-weight:800;color:var(--primary-d)}
.chat-meta{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.q-dim{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:800;
  background:var(--primary-soft);color:var(--primary-d);padding:3px 10px;border-radius:999px}
.q-code{font-size:11px;color:#a3a6c6;font-weight:700}
.chat-q{font-size:17px;font-weight:800;line-height:1.7;color:var(--ink)}
.opts.big{margin-top:16px}
.opts.big .opt{min-width:96px;padding:16px 10px;font-size:16px;border-radius:16px}
.opts.big .opt:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
.wz-nav{display:flex;align-items:center;justify-content:space-between;margin-top:18px;gap:10px}
.rev-row{display:flex;align-items:center;gap:12px;background:rgba(255,255,255,.9);border-radius:var(--radius-sm);
  padding:11px 14px;margin-bottom:8px;box-shadow:var(--shadow-sm);cursor:pointer;
  transition:opacity .35s ease, transform .12s, border-color .12s;
  opacity:0;pointer-events:none}
.rev-row.rev-in{opacity:1}
.rev-row.ready{pointer-events:auto}
.rev-row:hover{border-color:var(--primary);transform:translateX(3px)}
.rev-no{width:28px;height:28px;flex:none;border-radius:50%;
  background:var(--primary-soft);color:var(--primary-d);font-weight:900;font-size:12px;
  display:flex;align-items:center;justify-content:center}
.rev-q{flex:1;font-size:14px;font-weight:700;color:var(--ink);display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.rev-a{flex:none;font-size:13px;font-weight:900;color:var(--nutri);
  background:#e9faf2;padding:4px 12px;border-radius:999px}
.rev-a.none{color:var(--red);background:#ffecec}
@keyframes chatIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (max-width:720px){
  .chat-bubble{max-width:90%}
  .opts.big .opt{min-width:72px;padding:13px 6px;font-size:14px}
}

/* ===== 测评向导 · 增强 ===== */
.wz-bar{justify-content:space-between;flex-wrap:wrap}
.wz-right{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dim-bar{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 14px}
.dim-chip{display:inline-flex;align-items:center;gap:6px;padding:7px 13px;border-radius:999px;
  background:#fff;border:2px solid var(--line);font-size:12px;font-weight:800;color:var(--ink-soft);
  cursor:pointer;transition:.12s;user-select:none}
.dim-chip:hover{border-color:var(--primary);transform:translateY(-1px)}
.dim-chip.on{background:var(--primary-soft);border-color:var(--primary);color:var(--primary-d)}
.dim-chip .dc-cnt{font-size:10px;opacity:.75;font-weight:700}
.dim-chip .dc-cnt.dc-done{color:var(--nutri)}
#toast.err{background:var(--red)}
.btn:disabled{opacity:.55;cursor:not-allowed;transform:none}
#reviewJump{margin:0 0 10px}

/* ===== 侧边栏「系统设置」折叠分组（2026-09-23）=====
   原一级导航的 8 个配置类入口收进此分组，侧边栏不再流水线式堆长。
   展开时若超出视口高度，由 .nav 自身滚动，不撑破 sticky 侧栏。 */
.nav{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding-right:2px;scrollbar-width:thin}
.nav::-webkit-scrollbar{width:6px}
.nav::-webkit-scrollbar-thumb{background:rgba(124,108,255,.20);border-radius:3px}
.nav::-webkit-scrollbar-track{background:transparent}
.nav-group{position:relative}
.nav-group > a{padding-right:48px}
.nav-caret{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:32px;height:32px;
  padding:0;border:none;background:transparent;cursor:pointer;border-radius:10px;
  color:var(--ink-soft);font-size:13px;line-height:1;display:flex;align-items:center;
  justify-content:center;transition:.15s}
.nav-caret:hover{background:var(--primary-soft);color:var(--primary-d)}
.nav-group.open > a{background:var(--primary-soft);color:var(--primary-d)}
.nav-group.open .nav-caret{transform:translateY(-50%) rotate(180deg);color:var(--primary-d)}
.nav-sub{display:none;flex-direction:column;gap:2px;margin:3px 0 3px 10px;padding-left:9px;
  border-left:2px solid var(--primary-soft)}
.nav-sub.open{display:flex}
.nav-sub a{padding:9px 12px;font-size:13.5px;border-radius:12px}
.nav-sub a .ic{font-size:15px;width:20px}
@media (max-width:900px){.nav-sub a{padding:11px 12px;font-size:14px}}

/* ===== 侧边栏分组标题（2026-10-30 导航分类改造）=====
   纯视觉分隔：不可点、不折叠。左侧小字标签 + 右侧渐隐细线，与 .nav-group 的折叠箭头区分开。
   首组（档案管理）顶部留白略小，避免与上方「统算仪表盘」拉开过大空隙。 */
.nav-sec{display:flex;align-items:center;gap:9px;padding:15px 14px 7px;
  font-size:11px;font-weight:900;color:#9aa1b8;letter-spacing:.06em;line-height:1;
  white-space:nowrap;user-select:none}
.nav-sec::before{content:"";width:3px;height:10px;border-radius:2px;flex:none;
  background:linear-gradient(180deg,var(--primary),var(--primary-d));opacity:.55}
.nav-sec::after{content:"";flex:1;height:1px;
  background:linear-gradient(90deg,rgba(124,108,255,.22),rgba(124,108,255,0))}
.nav > .nav-sec:first-of-type{padding-top:8px}
@media (max-width:900px){.nav-sec{padding:16px 14px 8px;font-size:11.5px}}

/* ===== 侧边栏手风琴分组（2026-10-30）=====
   每组 .nav-acc = 可点标题 .nav-acc-head + 内容 .nav-acc-body。
   · 折叠规则只在 html.js 下生效：脚本被禁用/加载失败时全部展开，入口不会变成不可达。
   · 5 组一律可折叠（2026-10-30 二次调整后「档案管理」也并入手风琴，不再有常展开组）。
   · 视觉沿用原 .nav-sec：左侧紫竖条 + 小字标题 + 右侧渐隐细线，箭头在线条右侧。 */
.nav-acc{display:block}
.nav-acc-head{display:flex;align-items:center;gap:9px;width:100%;margin:0;
  padding:14px 8px 6px 14px;background:none;border:0;font:inherit;
  font-size:11px;font-weight:900;color:#9aa1b8;letter-spacing:.06em;line-height:1;
  white-space:nowrap;text-align:left;cursor:pointer;transition:color .15s}
.nav-acc-head::before{content:"";width:3px;height:10px;border-radius:2px;flex:none;
  background:linear-gradient(180deg,var(--primary),var(--primary-d));opacity:.55;transition:opacity .15s}
.nav-acc-head .nav-sec-t{flex:none}
.nav-acc-head .line{flex:1;height:1px;min-width:8px;
  background:linear-gradient(90deg,rgba(124,108,255,.22),rgba(124,108,255,0))}
.nav-acc-head .acc-ar{flex:none;font-size:11px;opacity:.7;transform:rotate(-90deg);
  transition:transform .2s,opacity .15s}
/* 可点提示：整行淡底 + 文字变主色（常展开组除外，见下） */
.nav-acc-head:hover{color:var(--primary-d);background:rgba(124,108,255,.07);border-radius:12px}
.nav-acc-head:hover::before{opacity:1}
.nav-acc-head:hover .acc-ar{opacity:.9}
.nav-acc.open > .nav-acc-head{color:var(--primary-d)}
.nav-acc.open > .nav-acc-head::before{opacity:1}
/* 展开态箭头朝下 ▾，收起态朝右 ▸（默认 -90°） */
.nav-acc.open > .nav-acc-head .acc-ar{transform:rotate(0)}
/* .always（历史兼容：当前无分组使用；保留规则以防回退）标题静态、不响应悬停变色 */
.nav-acc.always > .nav-acc-head{cursor:default}
.nav-acc.always > .nav-acc-head:hover{color:#9aa1b8;background:none}
.nav-acc.always > .nav-acc-head:hover::before{opacity:.55}
.nav-acc-body{display:block}
/* 首组顶部留白略小，避免与上方「统算仪表盘」拉开过大空隙 */
.nav > .nav-acc:first-of-type > .nav-acc-head{padding-top:10px}
/* ★ 关键：只折叠「非 .always」的组，且只在启用 JS 时折叠 */
html.js .nav-acc:not(.always):not(.open) > .nav-acc-body{display:none}
/* 无 JS 时全部展开、折叠不可用 → 隐藏箭头并禁止点击，避免“点了没反应” */
html:not(.js) .nav-acc-head{cursor:default;pointer-events:none}
html:not(.js) .nav-acc-head .acc-ar{display:none}
@media (max-width:900px){.nav-acc-head{padding:16px 8px 8px 14px;font-size:11.5px}}

/* ===== 导航栏视觉升级（2026-10-30）=====
   目标：让「分组标题」与「功能入口」一眼分得开，并统一入口的图标底片 / 字号 / 间距。
   分层逻辑（不靠颜色猜，靠结构特征辨认）：
     · 分组标题 —— 无图标、小字疏排、前置短竖条、右侧渐隐细线、可折叠组另有 chevron，像章节眉标；
     · 功能入口 —— 一律带方形图标底片 + 整项胶囊，组内再整体内缩并挂一条竖向引导线，形成归属。
   全部为视觉覆盖：不改 DOM、不改权限判定与端点，只调字号 / 间距 / 圆角 / 配色。 */

/* 品牌区与导航区之间加一道细分隔，视觉上分出「标识」与「菜单」两块 */
.sidebar .brand{padding:4px 10px 14px;margin-bottom:8px;
  border-bottom:1px solid rgba(124,108,255,.10)}

/* —— 功能入口：统一字号、字重、圆角；图标加柔和底片 —— */
.nav a{padding:9px 11px;border-radius:12px;font-size:14px;font-weight:700;
  letter-spacing:.01em;color:#666d8a;gap:9px}
.nav a .ic{width:28px;height:28px;border-radius:9px;flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:16px;color:#8b86b8;background:rgba(124,108,255,.08);
  transition:background .16s,color .16s}
.nav a:hover .ic{background:rgba(124,108,255,.16);color:var(--primary-d)}
.nav a.active .ic{background:rgba(255,255,255,.20);color:#fff}
.nav a.active{box-shadow:0 6px 16px rgba(92,79,224,.26)}
/* 组内相邻项之间留 2px，悬停底色不会连成一片 */
.nav-acc-body .nav a + a{margin-top:2px}

/* 2026-10-30 按需求：分组内展开的入口字号整体收小一档（14 → 13px），
   图标底片 28 → 25px、内边距 9/11 → 8/10，条目更紧凑；顶部「统算仪表盘」不在此列，保持原尺寸。 */
.nav-acc-body > a{padding:8px 10px;border-radius:11px;font-size:13px;gap:8px}
.nav-acc-body > a .ic{width:25px;height:25px;border-radius:8px;font-size:14.5px}

/* —— 组内容区：整体内缩 + 左侧竖向引导线，明确「这些项属于上一个分组标题」 —— */
.nav-acc-body{margin:5px 0 8px 12px;padding-left:7px;
  border-left:1.5px solid rgba(124,108,255,.18)}

/* —— 分组标题：更像章节眉标（更大上下留白、更深的字、更实的竖条、箭头换 chevron） —— */
.nav-acc-head{padding:19px 8px 8px 10px;font-size:11.5px;font-weight:800;
  letter-spacing:.09em;color:#767d99}
/* 悬停 / 展开统一 10px 圆角淡紫底，收起时保持纯文字，三态不至于跳变 */
.nav-acc-head:hover{background:rgba(124,108,255,.09);border-radius:10px}
.nav-acc-head::before{width:3px;height:11px;border-radius:2px;opacity:.9;
  background:linear-gradient(180deg,var(--primary),rgba(124,108,255,.45))}
.nav-acc-head .line{background:linear-gradient(90deg,rgba(124,108,255,.26),rgba(124,108,255,.02))}
/* chevron：收起 ›，展开 ˅（用两条边框画，比 ▾ 字符更细更稳） */
.nav-acc-head .acc-ar{width:18px;height:18px;font-size:0;border-radius:6px;
  display:inline-flex;align-items:center;justify-content:center;
  color:#b6bad0;opacity:1;transform:none;transition:color .15s,background .15s}
.nav-acc-head .acc-ar::before{content:"";width:6px;height:6px;border-radius:1px;
  border-top:1.7px solid currentColor;border-right:1.7px solid currentColor;
  transform:rotate(45deg);transition:transform .2s;margin-right:2px}
.nav-acc.open > .nav-acc-head .acc-ar::before{transform:rotate(135deg);margin:2px 0 0 0}
.nav-acc-head:hover .acc-ar{color:var(--primary-d);background:rgba(124,108,255,.12)}
.nav-acc.open > .nav-acc-head .acc-ar{color:var(--primary-d)}
/* 当前所在分组（展开态）标题加一层淡紫底，进一步与「收起的分组」区分开，
   也让用户一眼知道「我现在在哪个分类里」。5 组一致（含档案管理）。 */
html.js .nav-acc.open:not(.always) > .nav-acc-head{background:rgba(124,108,255,.07);border-radius:10px}
/* 首组（档案管理）顶部留白与其它组一致 */
.nav > .nav-acc:first-of-type > .nav-acc-head{padding-top:13px}
/* 顶部「统算仪表盘」是唯一不归组的顶层入口，与下方分组之间留出间隔 */
.nav > a{margin-bottom:2px}

@media (max-width:900px){
  .nav a{font-size:14.5px;padding:10px 11px}
  /* 手机抽屉：组内入口仍比顶层略小一档，且不低于 13.6px 保证可读 */
  .nav-acc-body > a{font-size:13.6px;padding:9px 10px}
  .nav-acc-head{padding:19px 8px 8px 10px;font-size:12px}
}

/* ===== 系统设置总览页（/admin/settings）===== */
.set-hero{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  background:linear-gradient(135deg,#f4f1ff,#eef6ff);border:1px solid var(--glass-line);
  border-radius:var(--radius);padding:18px 22px;margin-bottom:14px}
.set-h1{font-size:20px;font-weight:900;color:var(--primary-d)}
.set-sub{font-size:13px;color:var(--ink-soft);margin-top:4px}
.set-id{display:flex;gap:8px;flex-wrap:wrap}
.set-id span{background:#fff;border:1px solid var(--line);border-radius:999px;padding:5px 13px;
  font-size:12.5px;font-weight:700;color:var(--ink-soft)}
.set-note{display:flex;gap:10px;align-items:flex-start;background:#fffdf3;border:1px solid #ffe9b8;
  border-radius:16px;padding:13px 16px;font-size:12.5px;color:#8a7a45;line-height:1.65}
.set-sec{margin-bottom:20px}
.set-sh{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--ink-soft);margin:0 0 10px}
.set-sh .bar{width:4px;height:15px;border-radius:2px;
  background:linear-gradient(180deg,var(--primary),var(--primary-d))}
/* 固定列数（不用 auto-fit）：auto-fit 会让「只有 1~2 张卡」的分组被撑满整行，
   导致同页不同分组卡片宽度在 289 / 591 / 1196 之间跳变、高度也不齐。 */
/* 2026-10-31 按需求改为每行 4 张（原 3 张）：
   ≥1320 视口 4 列 → 卡宽约 270~300px（.set-d 描述折 3 行，卡高自适应不裁字）；
   1320 以下逐级降 3 / 2 / 1 列，避免窄屏把标题和箭头挤成竖排。 */
.set-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media (max-width:1319px){.set-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:1099px){.set-grid{grid-template-columns:repeat(2,1fr)}}
/* 4 列时单卡更窄：图标与内边距略收，描述字号 12.5→12，保证 1440 下不出现「一行只剩两个字」 */
@media (min-width:1320px){
  .set-card{padding:14px 14px;gap:11px}
  .set-ic{width:40px;height:40px;border-radius:12px}
  .set-d{font-size:12px}
}
.set-card{position:relative;overflow:hidden;display:flex;align-items:center;gap:13px;background:#fff;
  border:1px solid #eef0f7;border-radius:18px;padding:15px 16px;
  box-shadow:0 4px 16px rgba(120,110,200,.09);
  transition:transform .15s,box-shadow .15s,border-color .15s}
.set-card:hover{transform:translateY(-3px);border-color:var(--c);
  box-shadow:0 12px 26px rgba(124,108,255,.20)}
.set-card::after{content:"";position:absolute;right:-24px;bottom:-24px;width:88px;height:88px;
  border-radius:50%;background:var(--c);opacity:.09}
.set-ic{width:44px;height:44px;flex:none;border-radius:14px;display:flex;align-items:center;
  justify-content:center;font-size:20px;
  background:radial-gradient(circle at 32% 26%,rgba(255,255,255,.45),transparent 62%),var(--c);
  box-shadow:0 6px 14px rgba(90,80,170,.18)}
.set-bd{min-width:0;flex:1}
.set-t{font-weight:800;font-size:15px;color:var(--ink);display:flex;align-items:center;
  gap:8px;flex-wrap:wrap}
.set-b{font-size:11px;font-weight:800;color:#6b6b8c;background:#f2f3fa;border-radius:999px;padding:2px 9px}
.set-d{font-size:12.5px;color:var(--ink-soft);margin-top:3px;line-height:1.5}
.set-go{flex:none;color:#c8cadf;font-weight:900;font-size:16px;transition:.15s}
.set-card:hover .set-go{color:var(--primary);transform:translateX(3px)}
@media (max-width:720px){
  .set-hero{padding:15px 16px}
  .set-grid{grid-template-columns:1fr}
  .set-card{padding:13px 14px}
}

/* ===== 系统设置 · 功能模块开关（2026-10-30）=====
   用途：控制左侧导航里「公众号菜单」「HIS 对接」「数据归集」三个入口是否显示。
   交互用原生 checkbox + CSS 画的开关，不引第三方库；label 包住整行，点哪都能切换。 */
.feat-card{background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--radius);
  padding:16px 18px}
.feat-hint{display:flex;gap:9px;font-size:12.5px;color:var(--ink-soft);line-height:1.55;
  background:#f7f4ff;border:1px solid rgba(124,108,255,.16);border-radius:12px;
  padding:10px 12px;margin-bottom:12px}
.feat-hint .hi{flex:none;font-size:15px;line-height:1.3}
.feat-list{display:flex;flex-direction:column;gap:8px}
/* 宽屏三列一行（2026-10-30 改）：三个入口正好排满一行，不再出现「第三个掉到第二行」；
   单列/两列时开关会被推到行尾、与文字空出几百像素。grid 行内 stretch 保证三张卡等高，
   卡内的开关按 center 垂直居中 → 三卡开关 y 恒定一致，不受描述是否折行影响。 */
@media (min-width:900px){
  .feat-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
  /* 描述统一占两行高度（2×18px 行高）：否则「HIS 对接」描述只一行 → 该卡内容整体下移。
     但行数会随列宽变（960px 下各列折 2~3 行互不相同），仅靠 min-height 兜不住 →
     三列模式一律顶部对齐（align-items:flex-start），标题永远齐平，不再随描述行数浮动。
     开关 26px 高、标题行高约 20px，顶对齐后中心比标题中心低 3px → 上提 3px 对齐视觉中心。 */
  /* 必须带 .feat-list 前缀：本条写在 .feat-row 定义之前，同特异性会被后面的 align-items:center 覆盖
     （实测首版就踩了这个：媒体查询里写 .feat-row{align-items:flex-start} 完全没生效）。 */
  .feat-list .feat-row{align-items:flex-start}
  .feat-list .feat-d{min-height:36px}
  .feat-list .sw{margin-top:-3px}
}
.feat-row{display:flex;align-items:center;gap:14px;margin:0;padding:12px 14px;
  background:#fff;border:1px solid var(--line);border-radius:14px;cursor:pointer;
  font-weight:400;transition:border-color .15s,box-shadow .15s}
.feat-row:hover{border-color:var(--primary);box-shadow:var(--shadow-sm)}
.feat-tb{flex:1;min-width:0}
.feat-t{font-size:14px;font-weight:800;color:var(--ink)}
.feat-d{font-size:12px;color:var(--ink-soft);margin-top:3px;line-height:1.5}
/* 开关本体：46×26 胶囊，勾选后滑块右移并渐变为主色 */
.sw{position:relative;flex:none;width:46px;height:26px;display:inline-block}
.sw input{position:absolute;opacity:0;width:0;height:0;margin:0;padding:0;border:0}
.sw i{position:absolute;inset:0;border-radius:999px;background:#dcdfea;transition:.18s}
.sw i::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.18);transition:transform .18s}
.sw input:checked + i{background:linear-gradient(135deg,var(--primary),var(--primary-d))}
.sw input:checked + i::after{transform:translateX(20px)}
.sw input:focus-visible + i{box-shadow:0 0 0 4px var(--primary-soft)}
.feat-foot{display:flex;align-items:center;gap:12px;margin-top:14px;flex-wrap:wrap}
.feat-tip{font-size:12px;color:var(--ink-soft)}
/* 平台账号无法在此改（开关按租户存），给一条说明即可 */
.feat-ro{font-size:12.5px;color:var(--ink-soft);line-height:1.6}
@media (max-width:720px){
  .feat-card{padding:14px}
  .feat-row{padding:11px 12px}
}

/* ===== 横向铺满：单卡片表单页（2026-09-23）=====
   原写法是每页各自 inline `max-width:460~760px`，宽屏下卡片只占左边一条、右侧全空。
   现在统一用 .form-wide：
     - 卡片本身铺满整行（width:100%，并显式 max-width:none 覆盖历史 inline 值）；
     - ≥1100px 时字段**固定两列**。只让 `.field` 参与多列，其余直接子节点
       （.row / 裸 label + input / 表格 / 按钮组 / 宏输出）一律 grid-column:1/-1 整行，
       因此「字段规整型」「裸 label 型」「纯 .row 型」三种结构都不会错位。
     - 这里刻意用固定 2 列而不是 repeat(auto-fill,minmax(300px,1fr))：
       auto-fill 在 1920 屏会生成 4 列，而表单字段数常常是奇数/非 4 的倍数，
       第一行只填 2 个字段 → 右侧空掉两列，看着像「还是没铺满」。
       固定 2 列时每列约 800px（1920）/ 525px（1366），首行正好填满，观感最饱满。
     - 不这么做而只是解除 max-width，输入框会被拉成 1900px 宽，是反向优化。 */
.form-wide{width:100%;max-width:none}
@media (min-width:1100px){
  /* 两种页面结构都要覆盖：
       a) <form class="card pad form-wide">        → 容器本身就是 form（如 user_form）
       b) <div class="card pad form-wide"><form>…  → 容器外面还套了一层 form
          （hospital_form / tenants/form / config / database / dept_form 都是这种）
     只写 `.form-wide` 时，b) 的唯一直接子元素是 <form>，网格只有 1 项，
     字段仍然单列堆叠 —— 卡片宽了、字段却全挤在左半边，是「假铺满」。
    2026-09-23 实测：9 个表单页里只有 1 个真正多列，就是漏了这一层。 */
  .form-wide,
  .form-wide > form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:0 22px;align-items:start}
  .form-wide > :not(.field),
  .form-wide > form > :not(.field){grid-column:1/-1}
}

/* ===== 健康宣教组件（2026-10-11）=====
   背景：全局 `input,select,textarea{width:100%}`（本文件第 36 行）是为「表单控件」
   写的，但复选框与「工具栏里的紧凑下拉/搜索框」被它一并撑满容器：
   实测下发页 `.edu-pick` 内的复选框被撑到 326px，把同排的文字列挤成 0 宽
   —— 文字逐字竖排、整页布局崩坏。此处按用途分档修正，只作用于 .edu-* 组件，
   不影响站内既有表单（既有页面靠 td 宽度或 max-width 自行兜住）。
   同时把宣教组件样式集中到本文件（单一来源），模板里不再各写一份 <style>。 */
.edu-toolbar input:not([type=checkbox]):not([type=radio]),
.edu-toolbar select{width:auto}
.edu-check{width:auto;flex:none;padding:0}
.edu-pick{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;
  border-radius:14px;border:1.5px solid var(--line);background:#fff;
  cursor:pointer;transition:.15s;margin:0;font-weight:400;color:var(--ink)}
.edu-pick:hover{border-color:var(--primary-soft)}
.edu-pick.rec{border-color:rgba(255,159,67,.55);background:#fffaf3}
.edu-pick.done{opacity:.62}
.edu-pick > input[type=checkbox]{width:auto;flex:none;padding:0;margin:3px 0 0}
.edu-pick .bd{flex:1;min-width:0}
.edu-pick .ti{font-weight:800;font-size:14.5px;display:flex;align-items:center;
  gap:6px;flex-wrap:wrap}
.edu-pick .meta{font-size:12px;color:var(--ink-soft);margin-top:3px}
.edu-pick .sb{font-size:12.5px;color:var(--ink-soft);margin-top:5px;line-height:1.6}
.edu-rec{padding:12px 14px;border-radius:14px;
  border:1.5px solid rgba(255,159,67,.45);background:#fffaf3}

/* 号源排班：批量操作工具条（列表卡片内、表格之上）。
   注意全局 input{width:100%} 会把复选框撑爆，故复选框一律 width:auto（见 .slot-pick）。 */
.slot-bulkbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:12px 14px 10px;border-bottom:1px solid var(--line,#eef1f5)}
.slot-bulkbar .btn{width:auto}
.table input.slot-pick{width:auto;padding:0;margin:0;cursor:pointer}
.table input#slotCheckAll{width:auto;padding:0;margin:0;cursor:pointer}

/* ---- 号源排班：14 天日期条（窗口以「今天」为绝对锚点，‹ › 整块平移）---- */
.daybar{display:flex;align-items:center;gap:8px}
.daybar-days{display:flex;gap:6px;overflow-x:auto;padding:2px 2px 6px;flex:1;min-width:0}
/* flex:none 必须有 —— 否则 chip 作为 flex 子项会被压缩到 min-width，
   带「●12」的宽内容溢出到 chip 外，被 .daybar-days 的 overflow-x:auto 裁掉，
   于是「数字在 DOM 里、肉眼却看不见」。 */
.daybar .chip{min-width:74px;flex:none;text-align:center;white-space:nowrap;text-decoration:none}
/* 真今天：虚线圈（未选中时也能一眼认出「今天」在哪，与「·今」文案同源） */
.daybar .chip.is-today{border-style:dashed;border-color:var(--primary);color:var(--primary)}
.daybar .chip.is-today.active{color:#fff;border-style:solid}
.daynav{flex:none;width:30px;height:30px;line-height:28px;text-align:center;border-radius:999px;
  border:1.5px solid var(--line);background:rgba(255,255,255,.8);color:var(--ink-soft);
  font-weight:700;text-decoration:none;cursor:pointer;user-select:none}
.daynav:hover{border-color:var(--primary);color:var(--primary)}
.dbar-dot{margin-left:3px;font-size:11px;color:var(--primary);font-weight:700}
.dbar-dot.off{color:var(--ink-soft);font-weight:400}
/* 高亮块是主色底，● 数字必须转白 —— 否则紫底紫字，DOM 里在、肉眼看不见 */
.daybar .chip.active .dbar-dot{color:#fff}
.daybar-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:8px;font-size:12.5px}
.daybar-foot .btn{width:auto}

/* ===== 通用页内 Tab（2026-10-30）=====
   用途：把同一页面里的多块长内容折叠为几个页签（首个用例：screening/group.html 园所/班级汇总）。
   视觉取下划线指示条 + 计数徽标，不抢卡片本身；激活态跟随 `--primary`（租户换主色自动同步）。
   结构：.gtab > .gtab-h（role=tablist）> .gtab-b[data-t] ；.gtab > .gtab-p[data-p]
   ★★ 打印铁律：`.gtab-p.is-hide` 必须放开（见下方 @media print），否则隐藏页签的内容
     会在「打印 / 导出 PDF」时整块消失（明细表直接没了，且不报错）。 */
.gtab-h{display:flex;align-items:center;gap:2px;border-bottom:1px solid var(--line);
  margin-bottom:14px;overflow-x:auto;scrollbar-width:none}
.gtab-h::-webkit-scrollbar{display:none}
.gtab-b{appearance:none;border:0;background:transparent;font:inherit;font-size:14px;font-weight:700;
  color:var(--ink-soft);padding:10px 14px;border-radius:10px 10px 0 0;cursor:pointer;white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px;position:relative;
  transition:color .15s,background .15s}
.gtab-b:hover{color:var(--ink);background:rgba(124,108,255,.06)}
.gtab-b::after{content:"";position:absolute;left:10px;right:10px;bottom:-1px;height:2px;border-radius:2px;
  background:transparent;transition:background .15s}
.gtab-b.is-on{color:var(--primary)}
.gtab-b.is-on::after{background:var(--primary)}
.gtab-b:focus-visible{outline:2px solid var(--primary-soft);outline-offset:-2px}
/* 计数徽标：页签内的条目数（维度数 / 儿童数），让切换前就能判断内容量 */
.gtab-b .n{font-size:11.5px;font-weight:800;line-height:1;padding:3px 6px;border-radius:999px;
  background:#f0eefc;color:var(--ink-soft);transition:background .15s,color .15s}
.gtab-b.is-on .n{background:var(--primary-soft);color:var(--primary-d)}
.gtab-p.is-hide{display:none}
@media print{
  .gtab-h{display:none!important}
  .gtab-p.is-hide{display:block!important}
}

/* ===== 运营配置台表格（2026-10-30）=====
   筛查项目库 / 筛查方案 / 筛查任务 / 筛查引导单 / 消息模板 / 发送记录 这几张表
   列多（9~10 列）+ 每行 2~3 个操作按钮，浏览器按内容分配列宽时会把状态胶囊和
   按钮压成竖排（实测「启用」渲染成 启/用、「进行中」渲染成 进行/中）。
   给关键单元格加 nowrap；表格整体变宽由 .table-wrap 的 overflow-x:auto 兜底。 */
.ops-tbl th{white-space:nowrap}
.ops-tbl td code{white-space:nowrap}
.ops-tbl td .pill{white-space:nowrap}
.ops-tbl td .btn{white-space:nowrap}
/* 短字段（名称/类别/版本/生效日期）用 .nw 单行；长字段（说明/项目组合）保持可换行 */
.ops-tbl td.nw{white-space:nowrap}

/* ===== 机构候选下拉（2026-10-30）=====
   用于园所汇总页「所属机构 / 班级」：每项右侧带该机构已建档人数。
   替代原生 datalist —— 原生候选文本只能取 option 的 value，把人数写进 value 会让
   ?org= 精确匹配失效；label 属性各浏览器是否显示不保证。自绘后可完全控制显示文本。
   面板 absolute 定位，父级 .card 无 overflow,不会被裁剪。 */
.ocmb{position:relative}
.ocmb input{padding-right:32px}
.ocmb-t{position:absolute;right:1px;top:1px;bottom:1px;width:30px;padding:0;border:0;
  background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center}
.ocmb-t::after{content:'';width:0;height:0;border-left:4.5px solid transparent;
  border-right:4.5px solid transparent;border-top:5px solid var(--ink-soft,#7a8194);
  transition:transform .16s ease}
.ocmb.on .ocmb-t::after{transform:rotate(180deg)}
/* 面板挂到 body 上（JS portal）+ fixed 定位：
   .card 用了 backdrop-filter，它会同时创建层叠上下文与 fixed 包含块，
   面板留在卡内时 z-index 再高也盖不住后面的 KPI 卡片（实测点击被
   「存在异常项（橙/红）」拦截）。移出后由 JS 按输入框 rect 摆位。 */
.ocmb-pop{position:fixed;z-index:9999;
  background:#fff;border:1px solid var(--line,#e6e8ef);border-radius:12px;
  box-shadow:0 14px 34px rgba(24,32,54,.16);padding:5px;max-height:268px;overflow:auto}
.ocmb-pop[hidden]{display:none}
.ocmb-i{display:flex;align-items:center;gap:10px;padding:7px 9px;border-radius:8px;
  cursor:pointer;font-size:13.5px;color:var(--ink,#1f2740)}
.ocmb-i:hover,.ocmb-i.on{background:rgba(124,108,255,.09)}
.ocmb-i.on{box-shadow:inset 2px 0 0 var(--primary,#7c6cff)}
.ocmb-n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ocmb-c{flex:none;font-weight:600;font-size:12px;line-height:1.5;color:var(--primary,#7c6cff);
  background:rgba(124,108,255,.10);border-radius:999px;padding:1px 8px;
  font-variant-numeric:tabular-nums}
.ocmb-all{border-bottom:1px solid var(--line,#e6e8ef);border-radius:8px 8px 0 0;
  margin-bottom:3px;padding-bottom:9px}
.ocmb-all .ocmb-n{color:var(--ink-soft,#7a8194)}
.ocmb-e{padding:9px;font-size:13px;color:var(--ink-soft,#7a8194);text-align:center}
/* 面板 portal 在 body 上，打印/导出时若正好展开会被印出来 → 一律不打印 */
@media print{.ocmb-pop{display:none!important}}

/* ===== 儿童档案搜索选择器（开始测评页 · 2026-10-31）=====================
   替代「原生 select 装全机构档案」：输入即搜、键盘可选、选中后换成已选卡片。
   面板由 static/js/child_pick.js portal 到 body（.card 的 backdrop-filter 会形成
   fixed 包含块，留在卡内压不住后面的卡片），所以这里是 position:fixed。 */
.cpk{position:relative}
.cpk-tip{font-weight:400;font-size:11.5px;color:var(--ink-soft);margin-left:4px}
.cpk-in{position:relative}
.cpk-in input{width:100%}
.cpk-in.on input{border-color:var(--primary);box-shadow:0 0 0 3px rgba(124,108,255,.12)}
.cpk-clr{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;
  display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;
  background:rgba(122,122,150,.12);color:var(--ink-soft);cursor:pointer;padding:0}
.cpk-clr[hidden]{display:none!important}
.cpk-clr:hover{background:rgba(122,122,150,.22);color:var(--ink)}
.cpk-pop{position:fixed;z-index:9999;background:#fff;border:1px solid rgba(124,108,255,.18);
  border-radius:16px;box-shadow:0 18px 46px rgba(38,34,80,.18);padding:6px;
  overflow:auto;overscroll-behavior:contain}
.cpk-pop[hidden]{display:none!important}
.cpk-hd{display:flex;align-items:baseline;gap:8px;padding:7px 9px 5px;
  font-size:11.5px;font-weight:800;letter-spacing:.3px;color:var(--ink-soft)}
.cpk-hd2{margin-left:auto;font-weight:600;letter-spacing:0;color:#a9a8c4}
.cpk-i{display:flex;align-items:center;gap:10px;padding:7px 9px;border-radius:11px;cursor:pointer}
.cpk-i:hover,.cpk-i.on{background:rgba(124,108,255,.09)}
.cpk-i.on{box-shadow:inset 2px 0 0 var(--primary)}
.cpk-av{flex:none;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:12px;font-weight:800;color:#fff;letter-spacing:-.5px;
  background:linear-gradient(135deg,#8b7cff,#5ec8f0)}
.cpk-av.lg{width:42px;height:42px;border-radius:14px;font-size:15px}
.cpk-m{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.cpk-nm{font-size:14px;font-weight:800;color:var(--ink);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.cpk-meta{font-size:12px;color:var(--ink-soft);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.cpk-tag{flex:none;font-size:11px;font-weight:800;padding:1px 7px;border-radius:999px;
  background:rgba(124,108,255,.10);color:var(--primary-d);font-variant-numeric:tabular-nums}
.cpk-hit{background:rgba(255,196,0,.38);color:inherit;border-radius:3px;padding:0 1px}
.cpk-e{padding:16px 12px;text-align:center;font-size:13px;color:var(--ink-soft);line-height:1.9}
.cpk-e2{font-size:11.5px;color:#a9a8c4}
/* 已选卡片：选中后输入区整体替换（输入框里永远只是关键字，不回填人名） */
.cpk-sel{display:flex;align-items:center;gap:12px;padding:11px 13px;
  border:1px solid rgba(124,108,255,.34);border-radius:16px;
  background:linear-gradient(135deg,rgba(124,108,255,.08),rgba(94,200,240,.06))}
.cpk-sel[hidden]{display:none!important}
.cpk-badge{display:inline-block;margin-left:2px;padding:0 7px;border-radius:999px;
  background:rgba(124,108,255,.14);color:var(--primary-d);font-size:11px;font-weight:800;
  vertical-align:1px}
.cpk-chg{flex:none}
.ap-grid{grid-template-columns:1fr 1fr;gap:16px;align-items:start}
@media (max-width:1080px){.ap-grid{grid-template-columns:1fr}}
/* 顶部「档案范围」条：年龄段 chips + 当前范围计数（替代原来的搜索框表单） */
.ap-scope .row{gap:10px}
.ap-scope-l{display:inline-flex;align-items:center;gap:6px;font-size:13px;
  font-weight:800;color:var(--ink-soft);letter-spacing:.3px}
.ap-scope-n{margin-left:auto;font-size:12.5px;color:var(--ink-soft);
  font-variant-numeric:tabular-nums}
/* 「已自动定位」标记：从档案详情/报告页带 ?child_id= 进来时，范围条已按该档案的
   年龄段/学校/班级收窄，用这枚小胶囊说明「数字变小不是我筛错了」。
   ★ flex:none + nowrap：否则窄屏会把「已自动定位」压成逐字竖排。 */
.ap-auto{display:inline-flex;align-items:center;gap:4px;flex:none;white-space:nowrap;
  font-size:11.5px;font-weight:700;color:var(--primary-d);text-decoration:none;
  background:rgba(124,92,255,.1);border-radius:999px;padding:3px 9px;line-height:1.5}
a.ap-auto:hover{background:rgba(124,92,255,.18);color:var(--primary-d)}
.ap-scope-n b{color:var(--primary-d);font-size:14px;margin:0 2px}
@media (max-width:720px){.ap-scope-n{margin-left:0}}
/* 学校 / 班级下拉（2026-10-31）：高度与年龄段 chips 齐平（34px）、同为胶囊形外观。
   ★ flex 子项默认 flex-shrink:1，窄屏下不加 flex:none 会把「全部学校」压成逐字竖排；
   ★ 高度由 sel_count.js 按 data-sc-h="34" 写入内联，这里的 height 只是无 JS 时的兜底。 */
.ap-scope .ap-scope-ages,.ap-scope .scw{flex:none}
.ap-scope .ap-sc-sch{width:200px}
.ap-scope .ap-sc-cls{width:184px}
.ap-scope .sc-btn{height:34px;min-height:34px;padding:0 28px 0 13px;border-radius:999px;
  font-size:13px;font-weight:600;gap:6px;white-space:nowrap;
  background:rgba(255,255,255,.8);border:2px solid var(--line)}
.ap-scope .sc-btn:hover{border-color:#dcdcf0}
.ap-scope .sc-nm{white-space:nowrap}
/* 1280 附近整条只差 10~20px 就会换行 → 收一点间距和胶囊内边距，把「当前范围」拉回同一行；
   再窄（≤1180）就让它自然换行，不再硬挤。 */
@media (max-width:1360px){
  .ap-scope .row{gap:8px}
  .ap-scope .ap-scope-ages .chip{padding:6px 11px}
  .ap-scope .ap-sc-sch{width:186px}
  .ap-scope .ap-sc-cls{width:170px}
}
@media (max-width:1180px){.ap-scope .ap-sc-sch{width:168px}.ap-scope .ap-sc-cls{width:156px}}
@media (max-width:720px){.ap-scope .ap-sc-sch,.ap-scope .ap-sc-cls{width:100%}}
@media print{.cpk-pop{display:none!important}}

/* ===== 新建 / 编辑儿童档案：紧凑分区表单（2026-10-30 重设计）=====
   设计目标：① 一屏信息密度提升，字段按 4 列栅格成行排布（原为逐条竖排，全页 1190px 高）；
   ② 分区用「窄标题条 + 小图标 + 右侧说明徽标」替代大号 emoji 标题，观感更接近临床系统；
   ③ 输入框 46px → 32px，标签 13px → 11.5px，间距统一 8~10px；
   ④ 底部操作条 sticky，长表单滚动时不丢保存入口。
   ★ 全部选择器带 .cf 前缀，只作用于本页；不动 .field/.opt/.id-combo 等全局类。 */
.cf{--cf-lbl:#6b7191;--cf-bd:#e6e7f4;--cf-gap:9px 10px}
.cf-head{display:flex;align-items:flex-end;gap:12px;margin:0 0 10px}
.cf-row{display:grid;grid-template-columns:1fr;gap:11px}
/* —— 分区卡 —— */
.cf-card{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--glass-line);border-radius:18px;box-shadow:var(--shadow-sm);overflow:hidden}
.cf-h{display:flex;align-items:center;gap:8px;padding:9px 14px;
  border-bottom:1px solid rgba(124,108,255,.10);
  background:linear-gradient(120deg,rgba(124,108,255,.10),rgba(124,108,255,.015) 62%,transparent)}
.cf-h h3{margin:0;font-size:14px;font-weight:800;color:#3f3f5c;letter-spacing:.02em}
.cf-h .cf-ic{width:24px;height:24px;border-radius:8px;flex:none;display:inline-flex;
  align-items:center;justify-content:center;color:var(--primary-d);
  background:linear-gradient(135deg,rgba(124,108,255,.20),rgba(124,108,255,.05))}
.cf-tag{margin-left:auto;font-size:11px;font-weight:800;color:#8b86b8;background:#f4f2ff;
  border:1px solid rgba(124,108,255,.14);border-radius:999px;padding:2px 9px;white-space:nowrap}
.cf-tag.warn{color:#b38600;background:#fff7e0;border-color:#ffe0a3}
.cf-body{padding:11px 14px 13px}
/* —— 字段栅格：默认 4 列，sp2/sp4 跨列 —— */
.cf-fg{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--cf-gap);align-items:start}
.cf-fg.auto{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.cf-f{min-width:0}
.cf-f.sp2{grid-column:span 2}
.cf-f.sp3{grid-column:span 3}
.cf-f.sp4{grid-column:span 4}
.cf-f > label{display:flex;align-items:center;gap:4px;margin:0 0 3px;font-size:11.5px;line-height:1.2;
  font-weight:800;color:var(--cf-lbl);letter-spacing:.02em}
.cf-f > label .req{color:#ff5d5d;font-style:normal;font-weight:900}
.cf-f > label .cf-age{display:none;margin-left:auto;font-size:10.5px;font-weight:900;color:var(--primary-d);
  background:#f1eeff;border-radius:999px;padding:1px 7px;letter-spacing:0;white-space:nowrap}
/* 只有真的算出年龄才显示（空值不显示「—」，否则标签行右侧挂一个孤立短横，看着像错位） */
.cf-f > label .cf-age.on{display:inline-flex}
.cf input,.cf select,.cf textarea{padding:6px 9px;font-size:13px;border-width:1.5px;border-radius:9px}
/* ★ 原生 select 的内容盒比 input 高 2px（实测底边 210.8 vs 208.8）→ 显式锁死同高，同行底边才齐 */
.cf input:not([type="hidden"]),.cf select{height:31px}
.cf input:focus,.cf select:focus,.cf textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
.cf input[readonly]{background:#fafaff}
.cf textarea{resize:vertical;min-height:46px;line-height:1.5}
.cf-hint{margin-top:3px;font-size:10.5px;line-height:1.35;color:#9aa1b8}
.cf .id-combo{gap:6px}
.cf .id-combo select{width:104px;flex:none}
.cf .id-hint{margin-top:3px;font-size:10.5px;min-height:0;line-height:1.35}
.cf .id-hint:empty{display:none}
.cf .warnbadge{font-size:11px;padding:3px 9px;margin:0}
/* 日期选择器图标：适配收小后的内边距 */
.cf .date-picker{background-position:right 7px center;background-size:15px;padding-right:28px}
/* —— 头像点选：从 72px 大方块改为 30px 圆形芯片，12 个一行 —— */
.cf-avs{display:flex;flex-wrap:wrap;gap:6px}
.cf-avs .opt{flex:none;min-width:0;width:30px;height:30px;padding:0;border-radius:10px;
  border:1.5px solid var(--cf-bd);background:#fff;color:inherit;font-size:16px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;text-align:center}
.cf-avs .opt:hover{border-color:rgba(124,108,255,.55);background:#faf9ff}
.cf-avs .opt.sel,.cf-avs .opt.s0.sel{background:#f1eeff;border-color:var(--primary);color:inherit;
  box-shadow:0 0 0 3px var(--primary-soft)}
/* —— 底部操作条 ——
   ★ 不用 position:sticky：sticky bottom 在「文档比视口略高」时会把整条操作条顶进内容区，
     实测压住「备注」卡底部（2026-10-30 首版即如此）。本页高度已压到一屏内，改为常规流式页脚。 */
.cf-bar{display:flex;align-items:center;gap:12px;margin-top:11px;
  padding:8px 14px;border-radius:16px;border:1px solid var(--glass-line);
  background:rgba(255,255,255,.88);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 6px 20px rgba(124,108,255,.10)}
.cf-bar .cf-legend{font-size:11.5px;font-weight:700;color:#8b8ba6;line-height:1.3}
.cf-bar .cf-legend .req{color:#ff5d5d;font-style:normal;font-weight:900}
.cf-bar .cf-btns{margin-left:auto;display:flex;gap:8px}
.cf-bar .btn{padding:8px 18px;font-size:13.5px}
@media (max-width:1180px){
  .cf-fg{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px 9px}
  .cf-f.sp4{grid-column:span 3}
}
@media (max-width:900px){
  .cf-fg{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cf-f.sp3,.cf-f.sp4{grid-column:span 2}
  .cf-body{padding:10px 11px 12px}
  /* 窄屏回退到 34px，保证触摸目标不至于过小 */
  .cf input:not([type="hidden"]),.cf select{height:34px}
  .cf-bar{flex-wrap:wrap;gap:8px}
  .cf-bar .cf-btns{margin-left:0;width:100%;justify-content:flex-end}
}
@media (max-width:560px){
  .cf-fg{grid-template-columns:1fr}
  .cf-f.sp2,.cf-f.sp3,.cf-f.sp4{grid-column:span 1}
}

/* ===== 系统重置页（2026-10-30）=====
   危险操作用红色系，与常规配置页（紫/青）明确区分；所有数字用等宽感对齐，
   让操作者在按下确认前能清楚看到「到底会删多少行」。 */
.rs-hero{display:flex;gap:14px;align-items:flex-start;padding:16px 18px;border-radius:18px;
  border:1px solid #ffd0d0;background:linear-gradient(120deg,#fff5f5,#fffafa 60%,#fff);
  box-shadow:0 6px 20px rgba(255,93,93,.10)}
.rs-hero-ic{flex:none;width:38px;height:38px;border-radius:12px;display:flex;align-items:center;
  justify-content:center;font-size:20px;color:#e03b3b;background:#ffe3e3;border:1px solid #ffc9c9}
.rs-hero-t{font-size:16px;font-weight:900;color:#a32b2b;letter-spacing:.02em;margin-bottom:4px}
.rs-hero-d{font-size:12.5px;line-height:1.75;color:#8a4b4b}
.rs-hero-d strong{color:#c02d2d}

/* —— 机构选择 —— */
.rs-pick{background:var(--glass);border:1px solid var(--glass-line);border-radius:16px;
  padding:14px 16px;box-shadow:var(--shadow-sm)}
.rs-pick-f{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.rs-pick-f label{font-size:12px;font-weight:800;color:#6b7191;white-space:nowrap}
.rs-pick-f select{flex:1;min-width:260px;max-width:520px;padding:7px 10px;font-size:13px;
  border:1.5px solid var(--line);border-radius:10px;background:#fff}
.rs-pick-h{margin-top:9px;font-size:11.5px;line-height:1.7;color:#8a6d3b;background:#fffaf0;
  border:1px solid #ffe6b8;border-radius:10px;padding:8px 11px}

/* —— 作用域概览 —— */
.rs-scope{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:12px 16px;
  border-radius:16px;border:1px solid var(--glass-line);background:var(--glass);
  box-shadow:var(--shadow-sm);margin-bottom:12px}
.rs-scope-l{display:flex;align-items:center;gap:9px;flex-wrap:wrap;flex:1;min-width:260px}
.rs-lbl{font-size:11.5px;font-weight:800;color:#8b8ba6;letter-spacing:.04em}
.rs-org{font-size:15px;font-weight:900;color:#3f3f5c}
.rs-org em{font-style:normal;font-size:11.5px;font-weight:800;color:#8b86b8;margin-left:6px;
  background:#f4f2ff;border:1px solid rgba(124,108,255,.16);border-radius:999px;padding:1px 8px}
.rs-change{font-size:12px;font-weight:800;color:var(--primary-d);text-decoration:none;
  border-bottom:1px dashed currentColor}
.rs-lock{font-size:11.5px;font-weight:700;color:#9aa1b8}
.rs-scope-r{display:flex;gap:8px;flex-wrap:wrap}
.rs-kpi{min-width:82px;text-align:center;padding:6px 12px;border-radius:12px;background:#fff;
  border:1px solid var(--glass-line)}
.rs-kpi b{display:block;font-size:19px;font-weight:900;color:#3f3f5c;line-height:1.2}
.rs-kpi span{font-size:10.5px;font-weight:700;color:#9aa1b8;white-space:nowrap}

.rs-warn{margin:0 0 12px;padding:10px 13px;border-radius:12px;font-size:12px;line-height:1.7;
  color:#a33;background:#fff5f5;border:1px solid #ffd0d0}
.rs-empty{padding:26px;text-align:center;font-size:13px;color:#8b8ba6;background:var(--glass);
  border:1px dashed var(--glass-line);border-radius:16px}

/* —— 影响范围分组卡（瀑布流三列）——
   ★ 不用 grid：各组行数差异极大（档案主体 2 行 / 测评与报告 10 行），
     grid 的行高对齐会在短卡下方留下 100px+ 空白，页面一下拉长、显得松散。
     改 column 瀑布流后每列各自堆叠，无空白；break-inside:avoid 保证卡片不被跨列切断。 */
.rs-groups{columns:3;column-gap:10px;margin-bottom:14px}
.rs-grp{border:1px solid var(--glass-line);border-radius:14px;background:var(--glass);
  box-shadow:var(--shadow-sm);overflow:hidden;break-inside:avoid;
  -webkit-column-break-inside:avoid;page-break-inside:avoid;margin:0 0 10px}
.rs-grp-h{display:flex;align-items:center;gap:8px;padding:8px 12px;
  background:linear-gradient(120deg,rgba(255,133,133,.10),rgba(255,133,133,.02) 65%,transparent);
  border-bottom:1px solid rgba(255,93,93,.10)}
.rs-grp-t{font-size:12.5px;font-weight:900;color:#5c4a4a}
.rs-grp-n{margin-left:auto;font-size:11px;font-weight:900;color:#c02d2d;background:#ffeaea;
  border-radius:999px;padding:1px 9px;white-space:nowrap}
.rs-t{width:100%;border-collapse:collapse;table-layout:auto}
/* 表名（英文，最长 health_edu_deliveries）与中文名都不折行：折行会让同一张卡的行高
   参差不齐，也让「行数」列错位，读起来像排版事故。 */
.rs-t td{padding:5px 9px;font-size:12px;color:#5a5a72;white-space:nowrap;
  border-bottom:1px solid rgba(124,108,255,.06)}
.rs-t tr:last-child td{border-bottom:none}
/* 表名是英文且最长 21 字符（anthro_authorizations），在 10px 字号 + nowrap 下约 130px；
   卡片内宽足够，故不设 max-width（设了反而会提前出现省略号）。父级 .rs-grp 的
   overflow:hidden 作为最后兜底。 */
.rs-t code{font-size:10px;color:#8b86b8;background:#f7f6ff;border-radius:5px;padding:1px 5px;
  white-space:nowrap}
.rs-t .rs-zero{opacity:.38}
.rs-n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;width:64px}
.rs-hit{font-weight:900;color:#c02d2d}

/* —— 保留项 —— */
.rs-keep{border:1px solid #d8f0e4;background:linear-gradient(120deg,#f6fffb,#fff);
  border-radius:16px;padding:12px 15px;margin-bottom:14px}
.rs-keep-h{font-size:12.5px;font-weight:900;color:#2b7a5c;margin-bottom:8px}
.rs-keep-g{display:grid;gap:5px}
.rs-keep-i{display:flex;gap:9px;font-size:11.5px;line-height:1.6}
.rs-keep-k{flex:none;min-width:96px;font-weight:800;color:#3f6f5e}
.rs-keep-v{color:#7b8f88;word-break:break-word}
.rs-keep-f{margin-top:9px;padding-top:8px;border-top:1px dashed #cfeadd;font-size:11.5px;color:#6f8b81;line-height:1.7}

/* —— 确认执行 —— */
.rs-confirm{border:2px solid #ffc9c9;border-radius:18px;padding:14px 16px;
  background:linear-gradient(120deg,#fffafa,#fff);box-shadow:0 8px 26px rgba(255,93,93,.10)}
.rs-cf-h{font-size:13px;font-weight:900;color:#a32b2b;margin-bottom:10px;letter-spacing:.02em}
.rs-ack{display:flex;gap:9px;align-items:flex-start;font-size:12px;line-height:1.7;color:#6b4a4a;
  background:#fff;border:1px solid #ffe0e0;border-radius:12px;padding:10px 12px;cursor:pointer}
.rs-ack input{margin-top:2px;width:15px;height:15px;flex:none;accent-color:#e03b3b}
.rs-phrase{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:11px}
.rs-phrase label{font-size:12px;font-weight:800;color:#6b4a4a;white-space:nowrap}
.rs-phrase code{font-size:13px;font-weight:900;color:#c02d2d;background:#ffeaea;
  border:1px solid #ffd0d0;border-radius:6px;padding:1px 7px;letter-spacing:.04em}
.rs-phrase input{flex:1;min-width:200px;max-width:300px;padding:7px 11px;font-size:13px;
  border:1.5px solid #ffd0d0;border-radius:10px;background:#fff}
.rs-phrase input:focus{outline:none;border-color:#ff8f8f;box-shadow:0 0 0 3px rgba(255,93,93,.12)}
.rs-go{white-space:nowrap;padding:9px 20px;font-size:13.5px;font-weight:900}

/* —— 执行结果 —— */
.rs-result{border:1px solid #d8f0e4;border-radius:16px;background:linear-gradient(120deg,#f6fffb,#fff);
  padding:14px 16px;box-shadow:var(--shadow-sm)}
.rs-ok{display:flex;gap:11px;align-items:flex-start}
.rs-ok-ic{flex:none;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-weight:900;color:#fff;background:linear-gradient(135deg,#46c08a,#2fa877)}
.rs-ok-t{font-size:13.5px;font-weight:900;color:#2b7a5c}
.rs-ok-d{margin-top:3px;font-size:12px;color:#5f7f73;line-height:1.6}
.rs-ok-d b{color:#2b7a5c;font-size:13px}
.rs-bk{margin-top:11px;padding:9px 12px;border-radius:11px;background:#fff;border:1px solid #e6f3ec}
.rs-bk-k{font-size:11px;font-weight:900;color:#6b8d80;letter-spacing:.04em}
.rs-bk-v{display:block;margin-top:3px;font-size:11px;color:#3f6f5e;word-break:break-all;
  background:#f6fffb;border-radius:6px;padding:4px 7px}
.rs-bk-h{margin-top:4px;font-size:11px;color:#8aa79c;line-height:1.6}
.rs-tbl{margin-top:11px;max-height:340px;overflow:auto;border-radius:11px;border:1px solid #e6f3ec;background:#fff}
.rs-tbl .ops-tbl{width:100%;border-collapse:collapse}
.rs-tbl .ops-tbl th{position:sticky;top:0;background:#f6fffb;font-size:11px;font-weight:900;
  color:#5f7f73;text-align:left;padding:6px 11px;border-bottom:1px solid #e6f3ec;z-index:1}
.rs-tbl .ops-tbl td{padding:5px 11px;font-size:11.5px;color:#4c6b60;border-bottom:1px solid #f0f8f4}
.rs-tbl .ops-tbl code{font-size:10.5px;color:#7fa295;background:#f4fbf7;border-radius:4px;padding:1px 5px}
.rs-stat{margin-top:9px;font-size:11.5px;color:#7b8f88;display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.rs-chip{background:#eef8f3;border:1px solid #d8f0e4;border-radius:999px;padding:1px 9px;
  font-weight:800;color:#3f6f5e;white-space:nowrap}

@media (max-width:1240px){
  .rs-groups{columns:2}
}
@media (max-width:900px){
  .rs-hero{padding:13px 14px;gap:11px}
  .rs-hero-t{font-size:15px}
  .rs-scope{padding:11px 13px}
  .rs-kpi{min-width:70px;padding:5px 9px}
  .rs-kpi b{font-size:17px}
  .rs-groups{columns:1}
  .rs-phrase{gap:8px}
  .rs-phrase input{max-width:none;width:100%}
  .rs-go{width:100%;justify-content:center}
}

/* ===== 系统设置 → 危险操作卡（2026-10-30）=====
   重置入口必须一眼可辨且与常规配置卡明显区分：红边框 + 红底，右侧独立按钮。 */
.dz-bar{background:#ff5d5d !important}
.dz{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:14px 16px;border-radius:16px;
  border:1.5px solid #ffd0d0;background:linear-gradient(120deg,#fff6f6,#fffbfb 65%,#fff);
  box-shadow:0 6px 20px rgba(255,93,93,.10)}
.dz-l{flex:1;min-width:280px}
.dz-t{font-size:14px;font-weight:900;color:#a32b2b;letter-spacing:.02em}
.dz-d{margin-top:5px;font-size:12px;line-height:1.75;color:#8a5a5a}
.dz-d strong{color:#c02d2d}
.dz-safe{margin-top:6px;padding:6px 10px;border-radius:9px;background:#f6fffb;
  border:1px solid #d8f0e4;color:#3f6f5e;font-size:11.5px}
.dz-b{white-space:nowrap;padding:9px 18px;font-size:13px;font-weight:900;flex:none}
@media (max-width:900px){
  .dz{padding:12px 13px;gap:11px}
  .dz-b{width:100%;justify-content:center}
}

/* 侧栏「系统重置」入口：与其它条目同尺寸，仅用红色文字+淡红图标底片做危险标识，
   不做大色块（避免长期占据视觉重心，也与「当前选中」的紫底不冲突）。 */
.nav-acc-body > a.danger-link{color:#c94a4a}
.nav-acc-body > a.danger-link .ic{color:#d35656;background:linear-gradient(135deg,rgba(255,120,120,.20),rgba(255,120,120,.06))}
.nav-acc-body > a.danger-link:hover{background:rgba(255,93,93,.08)}
.nav-acc-body > a.danger-link.active{background:rgba(255,93,93,.13);color:#b33636}
.nav-acc-body > a.danger-link.active .ic{color:#fff;background:linear-gradient(135deg,#ff8585,#ff5d5d)}

/* 审计日志「脱钩」提示条：与「不会被删除」的绿色块区分开 —— 它是「保留行、只断关联」，
   用琥珀色，避免被误读成「这些都删」或「这些都不动」。 */
.rs-detach{margin:0 0 14px;padding:11px 14px;border-radius:14px;border:1px solid #ffe0a3;
  background:linear-gradient(120deg,#fffaf0,#fffdf7 70%,#fff)}
.rs-detach-h{font-size:12.5px;font-weight:900;color:#8a6100}
.rs-detach-h b{color:#b38600;font-size:13.5px}
.rs-detach-l{margin-top:6px;display:flex;gap:7px;flex-wrap:wrap}
.rs-detach-i{font-size:11.5px;font-weight:800;color:#8a6100;background:#fff4d9;
  border:1px solid #ffe0a3;border-radius:999px;padding:1px 9px;white-space:nowrap}
.rs-detach-f{margin-top:7px;font-size:11.5px;line-height:1.7;color:#9a7c3f}
.rs-detach-f code{font-size:11px;background:#fff4d9;border-radius:4px;padding:1px 5px}

/* ===========================================================================
   全站图标化（2026-10-30）
   页面标题图标由 page_icons.py 按 endpoint 决定，base.html 的 <h1> 统一输出；
   模板里的 {% block h1 %} 只写文字，不再出现 emoji。
   =========================================================================== */
.topbar h1 .h1-ic{display:inline-flex;align-items:center;justify-content:center;
  vertical-align:-3px;margin-right:9px;color:var(--primary);flex:none}
.topbar h1 .h1-ic svg{vertical-align:0}
/* 图标化的按钮 / 行内操作：保证图标与文字同一基线，不把按钮顶高 */
.btn .icv,.btn-sm .icv,.card-h .icv,.sec-h .icv{vertical-align:-3px}
/* 空状态大图标 */
.empty-ic{display:flex;align-items:center;justify-content:center;width:64px;height:64px;
  margin:0 auto 14px;border-radius:20px;background:var(--primary-soft);color:var(--primary)}

/* —— 搜索框内嵌图标（2026-10-30 图标化）
   原先靠 placeholder 里的 🔍 / 🆔 emoji 充当图标，emoji 清掉后输入框失去提示；
   这里改用 CSS 背景图（描边色 #a9a8c4），placeholder 只留文字。 —— */
input.ic-search,input.ic-id{padding-left:38px;background-color:#fff;
  background-repeat:no-repeat;background-position:12px center;background-size:16px 16px}
input.ic-search{background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a9a8c4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='10.8' cy='10.8' r='6.2'/><path d='M15.4 15.4 20.8 20.8'/></svg>")}
input.ic-id{background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a9a8c4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='5.4' width='18' height='13.2' rx='2.2'/><path d='M6.6 11.6h4.6M6.6 14.8h6.6'/><circle cx='16.8' cy='11.2' r='1.7'/></svg>")}
/* 机构选择器：左侧内嵌「机构」图标（原为 placeholder 里的 🏫 emoji） */
.ocmb > input{padding-left:36px;background-color:#fff;
  background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%237c6cff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M4.4 20.6V8.6L12 4l7.6 4.6v12'/><path d='M2.6 20.6h18.8'/><path d='M9.6 20.6v-5.6h4.8v5.6'/></svg>");
  background-repeat:no-repeat;background-position:11px center;background-size:15px 15px}

/* 风险等级圆点：替代 🟢🟡🟠🔴 emoji（尺寸/颜色完全可控，跨平台渲染一致） */
.i-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:currentColor;flex:none;margin-right:6px;vertical-align:1px}
.i-dot.on-fill{background:rgba(255,255,255,.88);margin-right:5px}
.i-dot.c-绿{background:#1d9e6a} .i-dot.c-黄{background:#dfa50b}
.i-dot.c-橙{background:#e8830f} .i-dot.c-红{background:#e04b4b}
.chip .i-dot{margin-right:5px}

/* 素材封面缩略底座：让 cover_emoji（用户自定义）与图标底座视觉一致 */
.m-cover{width:22px;height:22px;flex:none;border-radius:7px;background:#ece9ff;color:var(--primary);
  display:inline-flex;align-items:center;justify-content:center;font-size:13px;line-height:1;
  box-shadow:inset 0 0 0 1px rgba(124,108,255,.2)}
.m-cover svg{width:14px;height:14px}

/* ===== 整站全屏（2026-10-31，参照更年期健康管理系统 women_health 的实现）=====
   顶栏一个 34px 圆形图标按钮。点击瞬间把当前页装进一个同源 iframe，全屏的是外层
   文档；之后所有跳页都发生在 iframe 内部，外层文档不换 → 全屏不掉。
   为什么必须绕这一层：Fullscreen API 的全屏状态属于「当前文档」，顶层文档一旦导航
   全屏必然退出（W3C 规范，脚本拦不住；页面加载后也不许用代码重新进入，必须由真实
   用户手势触发）。详见 templates/base.html 末尾脚本注释。 */
.fs-toggle{display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;padding:0;flex:0 0 auto;cursor:pointer;
  background:#fff;border:1px solid var(--glass-line);border-radius:999px;
  box-shadow:var(--shadow-sm);color:var(--primary-d);
  transition:border-color .15s,box-shadow .15s,color .15s,transform .1s}
.fs-toggle:hover{border-color:rgba(124,108,255,.48);box-shadow:0 4px 14px rgba(124,108,255,.18)}
.fs-toggle:active{transform:scale(.94)}
/* 设备不支持 Element.requestFullscreen（iOS Safari / 内嵌 WebView）时由 JS 置 hidden，
   不留一个点了没反应的死按钮 */
.fs-toggle[hidden]{display:none!important}
/* 图标由模板渲染（唯一图标源 _icons.html），这里只控制显示哪个 + 抹掉宏给的基线偏移 */
.fs-toggle .icv{vertical-align:0!important}
.fs-toggle .fs-ic-off{display:none;align-items:center;justify-content:center}
html.in-fs .fs-toggle .fs-ic-on{display:none}
html.in-fs .fs-toggle .fs-ic-off{display:inline-flex}

/* 全屏态：浏览器给全屏元素的 ::backdrop 是黑底，显式兜住 html 背景，
   否则侧栏外的空隙在全屏时露出黑色。伪类与 .in-fs 分开写，避免列表里混入
   浏览器不认的 -webkit- 伪类导致整条规则被丢弃。 */
html:fullscreen{background:#eef0ff}
html.in-fs{background:#eef0ff}

/* 全屏壳：铺满视口并盖住侧栏/顶栏，用户在壳里看到的就是完整系统页面 */
#__fsWrap{position:fixed;inset:0;z-index:2147483000;background:#eef0ff}
#__fsWrap[hidden]{display:none!important}
#__fsFrame{display:block;width:100%;height:100%;border:0;background:#eef0ff}
#__fsHint{position:absolute;left:50%;bottom:20px;transform:translateX(-50%);
  display:inline-flex;align-items:center;gap:10px;padding:6px 8px 6px 15px;
  border-radius:999px;background:rgba(42,36,72,.86);color:#fff;font-size:12px;
  white-space:nowrap;box-shadow:0 6px 20px rgba(0,0,0,.22);transition:opacity .35s}
#__fsHint.dim{opacity:.16}
#__fsHint:hover{opacity:1}
#__fsHint kbd{font:inherit;padding:1px 5px;border-radius:4px;background:rgba(255,255,255,.18)}
#__fsHint button{font:inherit;cursor:pointer;padding:3px 11px;border:0;border-radius:999px;
  background:#fff;color:var(--primary-d);font-weight:800}
/* 被壳装进来的页面（同源 iframe 内）：隐藏它自己的全屏入口，否则内外两层全屏互相顶掉 */
html.wh-embed .fs-toggle{display:none!important}
html.wh-embed .top-act[data-present]{display:none!important}

/* ============================================================
   随访管理（followup）公共样式 —— 统一 5 个页面视觉语言
   主色沿用全局 --primary（紫），不再各页重复定义 KPI/表格/徽标
   ============================================================ */

/* ---- 页头：口径说明 + 快捷入口 ---- */
.fu-head{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-bottom:14px}
.fu-head-info{display:flex;align-items:flex-start;gap:11px;flex:1 1 auto;min-width:300px;
  max-width:720px;background:var(--glass);border:1px solid var(--glass-line);
  border-radius:14px;padding:11px 15px;box-shadow:var(--shadow-sm)}
.fu-head-info .fu-head-ico{flex:0 0 30px;width:30px;height:30px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;color:var(--primary-d);
  background:var(--primary-soft)}
.fu-head-txt{min-width:0}
.fu-head-txt b{display:block;font-size:13px;font-weight:800;color:var(--ink);margin-bottom:3px}
.fu-head-txt span{display:block;font-size:11.5px;color:var(--ink-soft);line-height:1.6}
.fu-head .fu-acts{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:0 0 auto}

/* ---- KPI 指标行（独立一行 5 卡） ---- */
.fu-kpi{display:grid;gap:12px;margin-bottom:16px;grid-template-columns:repeat(5,minmax(0,1fr))}
.fu-k{position:relative;display:flex;align-items:center;gap:11px;background:var(--glass);
  border:1px solid var(--glass-line);border-radius:16px;padding:15px 15px;box-shadow:var(--shadow-sm);
  overflow:hidden;text-decoration:none;color:inherit}
.fu-k::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:linear-gradient(180deg,var(--kc),transparent 85%);opacity:.75}
.fu-k::after{content:"";position:absolute;right:-30px;top:-30px;width:96px;height:96px;border-radius:50%;
  background:radial-gradient(circle,var(--kc),transparent 70%);opacity:.14;pointer-events:none}
.fu-k .ic{width:38px;height:38px;flex:0 0 38px;border-radius:11px;display:flex;align-items:center;
  justify-content:center;font-size:17px;background:color-mix(in srgb,var(--kc) 14%,#fff);color:var(--kc)}
.fu-k .bd{min-width:0}
.fu-k .l{font-size:12px;font-weight:700;color:var(--ink-soft);white-space:nowrap}
.fu-k .n{font-size:22px;font-weight:900;line-height:1.1;letter-spacing:-.5px;color:var(--kn);margin-top:2px;
  font-variant-numeric:tabular-nums}
.fu-k .n small{font-size:11px;font-weight:700;color:var(--ink-soft);margin-left:4px;letter-spacing:0}
.fu-k .x{font-size:11px;color:var(--ink-soft);margin-top:3px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.fu-k:hover{transform:translateY(-2px);box-shadow:0 12px 26px rgba(120,110,200,.18);transition:all .18s}

/* ---- 分类型完成率 ---- */
.fu-rate{background:var(--glass);border:1px solid var(--glass-line);border-radius:18px;
  padding:15px 18px;box-shadow:var(--shadow-sm);margin-bottom:16px;
  display:flex;flex-direction:column;justify-content:center}
.fu-rate-h{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px;flex-wrap:wrap}
.fu-rate-h b{font-size:13px;display:flex;align-items:center;gap:7px}
.fu-rate-h b .si{color:var(--primary-d)}
.fu-rate-h span{font-size:11.5px;color:var(--ink-soft)}
.fu-rate-g{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(196px,1fr))}
.fu-rt{min-width:0;text-decoration:none;color:inherit;background:#fff;border:1px solid var(--line);
  border-radius:13px;padding:11px 13px;transition:all .16s}
.fu-rt:hover{border-color:var(--rc,#7c6cff);box-shadow:0 5px 14px rgba(120,110,200,.12);transform:translateY(-1px)}
.fu-rt-top{display:flex;align-items:baseline;gap:6px;margin-bottom:6px}
.fu-rt-lb{flex:1 1 auto;min-width:0;font-size:12px;font-weight:700;color:var(--ink-soft);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fu-rt-v{font-size:15px;font-weight:900;color:var(--rc,#7c6cff);white-space:nowrap}
.fu-bar{position:relative;height:6px;border-radius:999px;background:#efeafd;overflow:hidden}
.fu-bar>i{position:absolute;left:0;top:0;bottom:0;border-radius:999px;background:var(--rc,#7c6cff);opacity:.9}
.fu-rt-x{font-size:10.5px;color:var(--ink-soft);margin-top:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---- 清单面板 + 状态 Tab ---- */
.fu-panel{background:var(--glass);border:1px solid var(--glass-line);border-radius:20px;
  box-shadow:var(--shadow);overflow:hidden}
.fu-tabs{display:flex;align-items:stretch;gap:2px;padding:0 14px;border-bottom:1px solid var(--line);
  overflow-x:auto;scrollbar-width:none}
.fu-tabs::-webkit-scrollbar{display:none}
.fu-tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:12px 14px 11px;
  font-size:13px;font-weight:700;color:var(--ink-soft);white-space:nowrap;text-decoration:none;
  border-bottom:2px solid transparent;transition:color .15s}
.fu-tab:hover{color:var(--primary-d)}
.fu-tab .n{min-width:20px;padding:0 6px;height:18px;border-radius:999px;background:var(--primary-soft);
  color:var(--primary-d);font-size:11px;font-weight:800;display:inline-flex;align-items:center;
  justify-content:center;font-variant-numeric:tabular-nums}
.fu-tab.on{color:var(--primary-d);border-bottom-color:var(--primary)}
.fu-tab.on .n{background:var(--primary);color:#fff}
.fu-tab.warn .n{background:#fff2d9;color:#b7791f}
.fu-tab.danger .n{background:#fde3e3;color:#c53030}

/* ---- 工具条（筛选） ---- */
.fu-tb{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line);
  flex-wrap:wrap}
.fu-tb select,.fu-tb input[type=text]{height:34px;border:1px solid var(--line);border-radius:9px;
  padding:0 11px;font-size:12.5px;background:#fff;color:var(--ink);font-family:inherit}
.fu-tb select{width:auto;min-width:136px}
.fu-tb input[type=text]{width:auto;min-width:180px;flex:0 1 240px}
.fu-tb .sp{flex:1 1 auto}

/* ---- 表格 ---- */
.fu-tbl{width:100%;border-collapse:collapse}
.fu-tbl th,.fu-tbl td{padding:11px 13px;text-align:left;border-bottom:1px solid var(--line);font-size:13px;
  vertical-align:middle}
.fu-tbl th{background:rgba(124,108,255,.06);color:var(--primary-d);font-weight:800;font-size:12px;
  white-space:nowrap;letter-spacing:.2px}
.fu-tbl tbody tr{transition:background .12s}
.fu-tbl tbody tr:hover{background:rgba(124,108,255,.04)}
.fu-tbl td.nw{white-space:nowrap}
.fu-who{display:flex;align-items:center;gap:10px}
.fu-ava{flex:0 0 34px;width:34px;height:34px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:14px;font-weight:800;color:#fff;
  background:linear-gradient(135deg,var(--av),color-mix(in srgb,var(--av) 70%,#fff))}
.fu-who-bd{min-width:0}
.fu-who-bd b{display:block;font-size:13.5px;font-weight:800;color:var(--ink)}
.fu-who-bd b.muted{color:var(--ink-soft);font-weight:700}
.fu-who-bd span{display:block;font-size:11px;color:var(--ink-soft);white-space:nowrap}

/* ---- 状态徽标（统一加左侧色点） ---- */
.fu-pill{display:inline-flex;align-items:center;gap:5px;padding:2.5px 10px;border-radius:999px;
  font-size:11px;font-weight:800;white-space:nowrap}
.fu-pill::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.85}

/* ---- 行操作按钮 ---- */
.fu-acts{display:flex;gap:5px;flex-wrap:nowrap;justify-content:flex-end}
.fu-act{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 11px;border-radius:8px;
  font-size:12px;font-weight:700;text-decoration:none;white-space:nowrap;border:1px solid transparent;
  background:#fff;color:var(--primary-d);box-shadow:inset 0 0 0 1px rgba(124,108,255,.28);cursor:pointer;
  transition:all .14s}
.fu-act .si{flex:0 0 auto}
.fu-act:hover{background:var(--primary);color:#fff;box-shadow:none}
.fu-act.pri{background:var(--primary);color:#fff;box-shadow:none}
.fu-act.pri:hover{background:var(--primary-d);color:#fff}
.fu-act.g{background:#fff;color:#5b6b7c;box-shadow:inset 0 0 0 1px #e5e7f0}
.fu-act.g:hover{background:#eef0f7;color:#3a3a52}
.fu-act.d{background:#fff;color:#c53030;box-shadow:inset 0 0 0 1px rgba(197,48,48,.28)}
.fu-act.d:hover{background:#c53030;color:#fff}

/* ---- 空态 / 分页 ---- */
.fu-empty{text-align:center;padding:52px 16px;color:var(--ink-soft);font-size:13px;line-height:1.8}
.fu-empty .big{font-size:30px;display:block;margin-bottom:8px;opacity:.5}
.fu-page{display:flex;align-items:center;justify-content:center;gap:8px;padding:13px;border-top:1px dashed var(--line)}
.fu-page a,.fu-page span{font-size:12.5px;font-weight:700;color:var(--primary-d);text-decoration:none;
  padding:5px 12px;border-radius:8px;border:1px solid var(--line);background:#fff}
.fu-page span.off{color:#b9bccb;background:#f7f7fb;border-color:transparent}

@media (max-width:1280px){.fu-kpi{grid-template-columns:repeat(5,minmax(0,1fr))}}
@media (max-width:900px){.fu-kpi{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fu-tbl th:nth-child(6),.fu-tbl td:nth-child(6){display:none}}

/* ============================================================
   量表管理（scale_admin）公共样式 —— 独立 .sc- 命名空间
   沿用全局 --primary 紫，概览卡/表格/表单/JSON 区块统一视觉
   ============================================================ */

/* ---- 页头 ---- */
.sc-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-bottom:14px}
.sc-desc{font-size:13px;color:var(--ink-soft);margin:0;max-width:820px;line-height:1.7}
.sc-acts{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* ---- 概览 KPI（横向 4 卡，图标圆底） ---- */
.sc-kpi{display:grid;gap:12px;grid-template-columns:repeat(4,minmax(0,1fr));margin-bottom:14px}
.sc-k{position:relative;display:flex;align-items:center;gap:12px;background:var(--glass);
  border:1px solid var(--glass-line);border-radius:16px;padding:15px 16px;box-shadow:var(--shadow-sm);
  overflow:hidden;text-decoration:none;color:inherit}
.sc-k::after{content:"";position:absolute;right:-28px;top:-28px;width:92px;height:92px;border-radius:50%;
  background:radial-gradient(circle,var(--kc),transparent 70%);opacity:.14;pointer-events:none}
.sc-k .ic{width:42px;height:42px;flex:0 0 42px;border-radius:12px;display:flex;align-items:center;
  justify-content:center;font-size:20px;background:color-mix(in srgb,var(--kc) 15%,#fff);color:var(--kc)}
.sc-k .bd{min-width:0;flex:1 1 auto}
.sc-k .l{font-size:12px;font-weight:700;color:var(--ink-soft);white-space:nowrap}
.sc-k .n{font-size:24px;font-weight:900;line-height:1.12;letter-spacing:-.5px;color:var(--kc);margin-top:2px}
.sc-k .n small{font-size:12px;font-weight:700;color:var(--ink-soft);margin-left:4px;letter-spacing:0}
.sc-k .x{font-size:11px;color:var(--ink-soft);margin-top:2px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.sc-k:hover{transform:translateY(-2px);box-shadow:0 10px 24px rgba(120,110,200,.16);transition:all .18s}

/* ---- 筛选工具条 ---- */
.sc-tb{display:flex;align-items:center;gap:10px;padding:12px 14px;background:var(--glass);
  border:1px solid var(--glass-line);border-radius:16px;box-shadow:var(--shadow-sm);margin-bottom:14px;
  flex-wrap:wrap}
.sc-tb select,.sc-tb input[type=text]{height:34px;border:1px solid var(--line);border-radius:9px;
  padding:0 11px;font-size:12.5px;background:#fff;color:var(--ink);font-family:inherit}
.sc-tb select{width:auto;min-width:136px}
.sc-tb input[type=text]{width:auto;min-width:180px;flex:0 1 240px}
.sc-tb .sc-count{margin-left:auto;font-size:12px;color:var(--ink-soft);font-weight:700}

/* ---- 清单面板 + 表格 ---- */
.sc-panel{background:var(--glass);border:1px solid var(--glass-line);border-radius:20px;
  box-shadow:var(--shadow);overflow:hidden}
.sc-tbl{width:100%;border-collapse:collapse}
.sc-tbl th,.sc-tbl td{padding:12px 14px;text-align:left;border-bottom:1px solid var(--line);font-size:13px;
  vertical-align:middle}
.sc-tbl th{background:rgba(124,108,255,.06);color:var(--primary-d);font-weight:800;font-size:12px;
  white-space:nowrap;letter-spacing:.2px}
.sc-tbl tbody tr{transition:background .12s}
.sc-tbl tbody tr:hover{background:rgba(124,108,255,.04)}
.sc-tbl td.nw{white-space:nowrap}
.sc-who b{font-size:13.5px;font-weight:800;color:var(--ink)}
.sc-who span{display:block;font-size:11px;color:var(--ink-soft);white-space:nowrap;margin-top:1px}
.sc-code{display:inline-block;font-size:11px;color:var(--primary-d);background:var(--primary-soft);
  border-radius:5px;padding:1px 6px;margin-top:3px;font-family:ui-monospace,Consolas,monospace}

/* ---- 状态/类别徽标（统一左侧色点） ---- */
.sc-pill{display:inline-flex;align-items:center;gap:5px;padding:2.5px 10px;border-radius:999px;
  font-size:11px;font-weight:800;white-space:nowrap}
.sc-pill::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.85}

/* ---- 空态 ---- */
.sc-empty{text-align:center;padding:52px 16px;color:var(--ink-soft);font-size:13px;line-height:1.8}
.sc-empty svg{display:block;margin:0 auto 8px;opacity:.5}
.sc-empty .big{display:block;font-size:15px;font-weight:800;color:var(--ink)}

/* ---- 编辑页：卡片分区 ---- */
.sc-card{background:var(--glass);border:1px solid var(--glass-line);border-radius:18px;
  padding:16px 18px;box-shadow:var(--shadow-sm);margin-bottom:16px}
.sc-card-h{display:flex;align-items:center;gap:7px;font-size:13.5px;font-weight:800;color:var(--ink);
  margin-bottom:14px}
.sc-card-h svg{color:var(--primary)}
.sc-card-h span{font-size:11.5px;color:var(--ink-soft);font-weight:500;margin-left:2px}

/* ---- 表单栅格 ---- */
.sc-grid{display:grid;grid-template-columns:1fr 1fr;gap:13px 14px}
.sc-f{display:flex;flex-direction:column;gap:5px;font-size:12px;font-weight:700;color:var(--ink-soft)}
.sc-f input[type=text],.sc-f input[type=number],.sc-f select,.sc-f textarea{
  width:100%;border:1px solid var(--line);border-radius:9px;padding:0 11px;font-size:13px;
  background:#fff;color:var(--ink);font-family:inherit;box-sizing:border-box}
.sc-f input[type=text],.sc-f input[type=number],.sc-f select{height:34px}
.sc-f textarea{padding:8px 11px;resize:vertical;line-height:1.6}
.sc-f input:focus,.sc-f select:focus,.sc-f textarea:focus{border-color:var(--primary);outline:none;
  box-shadow:0 0 0 3px var(--primary-soft)}
.sc-f-full{grid-column:1/-1}
.sc-check{flex-direction:row;align-items:center;gap:8px;padding:8px 12px;background:var(--primary-soft);
  border-radius:10px;color:var(--ink);font-weight:600}
.sc-check input[type=checkbox]{width:16px;height:16px;accent-color:var(--primary)}
.sc-check span{display:inline-flex;align-items:center;gap:5px}

/* ---- JSON 提示 + 文本框 ---- */
.sc-hint{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--ink-soft);
  background:var(--primary-soft);border-radius:9px;padding:7px 11px;margin:0 0 10px;line-height:1.6;flex-wrap:wrap}
.sc-hint svg{color:var(--primary);flex:none}
.sc-hint code{font-family:ui-monospace,Consolas,monospace;font-size:11px;background:#fff;
  color:var(--primary-d);border-radius:4px;padding:0 5px}
.sc-json{width:100%;border:1px solid var(--line);border-radius:10px;padding:11px 13px;
  font-family:ui-monospace,Consolas,monospace;font-size:12px;line-height:1.7;background:#faf9ff;
  color:var(--ink);resize:vertical;box-sizing:border-box}
.sc-json:focus{border-color:var(--primary);outline:none;box-shadow:0 0 0 3px var(--primary-soft)}

/* ---- 底部操作条 ---- */
.sc-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:2px 0 6px}
.sc-warn{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:#b7791f;
  background:#fff2d9;border-radius:9px;padding:7px 12px}

@media (max-width:1100px){.sc-kpi{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:900px){.sc-grid{grid-template-columns:1fr}}

/* ---- 园所汇总表 · 维度覆盖表（2026-10-31）---- */
.ki{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;
  border-radius:10px;background:var(--primary-soft);color:var(--primary-d);flex:none}
.ki svg{flex:none}
table .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:700}
.cov-pct{font-variant-numeric:tabular-nums;font-weight:700;font-size:13px;color:var(--primary-d)}
.cov-pct.zero{color:var(--ink-soft);font-weight:600}
.empty-hint{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  padding:44px 20px;text-align:center;color:var(--ink-soft);font-size:13.5px}
.empty-hint svg{color:#b7b0dc}

/* ===== 打印通用：去掉浏览器页眉页脚、消除空白尾页（2026-10-31）=====
   1) Chrome/Edge 的「页眉和页脚」（左上日期、右上文档标题、底部 URL 与页码）画在
      @page 边距区内、位于渲染树之外，@media print 管不到；只有把 @page 的 margin
      整条设为 0，打印预览里那个复选框才会消失（各打印页各自声明 @page）。留白因此
      改由 body padding 提供。
   2) ★ 但 html/body/.app 都设了 min-height:100vh —— 打印时 100vh 约等于一整页高，
      再叠加 body 的上下 padding 必然溢出，结果就是「内容只占半页、却多打一张白纸」。
      实测 5 个报告页都踩到（screening/report、report_summary、growth/group、
      edu/print、tenants/qr 都多出空白第 2 页）。这里统一归零。
   3) box-decoration-break:clone 让 body 的 padding 在每个分页片段都重复，
      否则多页时只有首页/末页有留白，中间页会贴纸边被打印机裁掉。 */
@media print{
  html,body,.app{min-height:0!important}
  body{-webkit-box-decoration-break:clone;box-decoration-break:clone}
}

/* ==========================================================================
   院校管理组 · 统一视觉（2026-10-31）
   作用页面：学校学生 / 学校·班级设置 / 学校·班级汇总 / 体质健康测试
   新类名一律独立前缀（pghead / metrics / metric / scard / notice / footnote），
   不改 .stat / .card / .table 等全局类的既有行为，避免波及其它页面。
   ========================================================================== */

/* ---------- 页面头：左侧说明 + 右侧操作 ---------- */
.pghead{display:flex;justify-content:space-between;align-items:flex-start;
  gap:16px;flex-wrap:wrap;margin-bottom:16px}
/* ★ 说明区必须给「确定的」flex-basis：写成 `flex:1 1 auto` 时 basis 取 max-content
   （整段说明的单行宽度，远超容器），flex-wrap 在收缩之前就判定放不下，
   于是「按钮组」被整体折到下一行左侧（实测 1500 宽窗口 + 3 个按钮必现）。
   给 320px 的明确 basis 后：320 + 按钮组宽度 < 容器 → 始终同一行，再由 grow 填满。 */
.pghead .lead{margin:0;font-size:13px;line-height:1.72;color:var(--ink-soft);
  flex:1 1 320px;min-width:0;max-width:none}
.pghead .lead b{color:var(--ink)}
.pghead .acts{display:flex;gap:8px;flex-wrap:wrap;flex:none}

/* ---------- 指标栅格：等宽等高 ----------
   原 `.row > .stat` 是 flex:1 + min-width:150px，内容长的标签会把那张卡撑宽
   （体质测试页「达标优良率（目标 ≥ 60%）· 无有效测试数据」就撑成了两倍宽）。
   这里改 grid 自动均分，标签过长时省略号，保证一排卡永远齐平。 */
.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));
  gap:12px;margin-bottom:16px}
.metric{display:flex;align-items:center;gap:12px;min-width:0;
  background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--radius-sm);
  padding:14px 16px;box-shadow:var(--shadow-sm)}
.metric > .ic{width:38px;height:38px;flex:none;border-radius:11px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--primary-soft);color:var(--primary-d)}
.metric > .tx{min-width:0}
.metric .v{font-size:23px;font-weight:900;line-height:1.2;color:var(--primary-d);
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.metric .v small{font-size:13px;font-weight:700;color:var(--ink-soft)}
/* 标签允许折到两行：一行 178px 放不下「达标优良率 · 目标 ≥ 60%」这类长标签，
   硬省略会把口径说明吃掉；grid 行内等高，多一行不会让卡片高低不齐。 */
.metric .k{font-size:12px;font-weight:700;color:var(--ink-soft);margin-top:2px;
  line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;white-space:normal}
/* 文字型指标（如「当前统计范围」）允许换行、字号收一档 */
.metric.txt{align-items:flex-start}
.metric.txt .v{font-size:15.5px;line-height:1.45;white-space:normal;overflow:visible;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.metric.txt .k{margin-top:4px}
.metric.warn > .ic{background:#fff4e3;color:#c1801a}
.metric.warn .v{color:#c1801a}
.metric.ok > .ic{background:#e8f8f1;color:#12946a}
.metric.ok .v{color:#12946a}
.metric.bad > .ic{background:#ffecec;color:#d04545}
.metric.bad .v{color:#d04545}

/* ---------- 学校卡片 ---------- */
.scard{display:flex;flex-direction:column;min-width:0;
  background:var(--glass);border:1px solid var(--glass-line);border-radius:var(--radius);
  padding:16px 18px 14px;box-shadow:var(--shadow-sm);
  transition:box-shadow .16s ease,transform .16s ease}
.scard:hover{box-shadow:0 14px 30px rgba(124,108,255,.17);transform:translateY(-2px)}
.scard.is-off{opacity:.62}
.scard.is-off:hover{transform:none;box-shadow:var(--shadow-sm)}
.scard-h{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.scard-h .t{min-width:0}
.scard-h h3{margin:0 0 3px;font-size:16.5px;line-height:1.35;color:var(--ink)}
.scard-h .meta{font-size:12px;color:var(--ink-soft);line-height:1.6}
.scard-h .meta code{font-size:11.5px}
.scard-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  margin:14px 0;background:var(--line);border:1px solid var(--line);
  border-radius:12px;overflow:hidden}
.scard-stats > div{background:#fbfaff;padding:8px 6px;text-align:center;min-width:0}
.scard-stats b{display:block;font-size:18px;font-weight:900;color:var(--ink);
  font-variant-numeric:tabular-nums;line-height:1.25}
.scard-stats span{font-size:11.5px;font-weight:700;color:var(--ink-soft)}
.scard-stats .alert b{color:#d04545}
.scard-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:auto}

/* ---------- 学校卡片栅格：每行 5 个（2026-10-31） ----------
   不写死 repeat(5,1fr) —— 那样在 1280/1440 上每张卡只剩 190~216px，
   校名两行、三个按钮各占一行，反而更难看。
   这里用 minmax(max(240px, (100% - 4×gap)/5), 1fr)：
     · 容器够宽（≥ 5×240+4×14 = 1256px）时，最小列宽正好等于「5 等分」，auto-fill 必然排成 5 列；
     · 容器变窄时列宽保底 240px，列数自动退到 4/3/2，绝不挤扁。
   即「宽屏每行 5 个、窄屏自适应」，不依赖具体视口宽度，侧栏折叠/展开都正确。 */
.sch-grid{display:grid;gap:14px;
  grid-template-columns:repeat(auto-fill,minmax(max(240px,(100% - 56px)/5),1fr))}
/* 5 列时卡片内宽只有 276px（312 - 内边距 36），默认 .btn.sm 三个按钮需要 306px，
   会折成两行、卡片变高且参差不齐。这里只在本栅格内收紧按钮的内边距与字距（合计 265px），
   让「学生名单 / 年级班级 / 花名册」保持一行；再窄（4 列以下）自然折行，不影响可读性。 */
.sch-grid .scard-acts{gap:6px}
.sch-grid .scard-acts .btn{padding:7px 9px;font-size:12.5px;gap:4px}
/* 5 列较窄时（1600 及以下），让「在读 N」徽标整体换到下一行，
   而不是把校名挤成两行——校名断行比徽标换行难看得多。宽屏时二者仍然并排。 */
.sch-grid .scard-h{flex-wrap:wrap}
.sch-grid .scard-h .t{flex:1 1 auto}
.sch-grid .scard-h .pill{padding:3px 9px;font-size:11.5px;gap:4px}

/* ---------- 提示条（待补项 / 口径提醒） ---------- */
.notice{display:flex;align-items:flex-start;gap:11px;margin-bottom:16px;
  padding:12px 15px;border-radius:14px;font-size:13px;line-height:1.72;
  background:#fffaf0;border:1px solid #f0dcae;color:#7c5a14}
.notice > .ni{flex:none;color:#c99417;margin-top:2px}
.notice b{color:#6b4a08}
.notice .btn{flex:none;align-self:center}

/* ---------- 表格增强：行悬停 / 数字列 / 主单元格 ---------- */
.table tbody tr{transition:background .12s ease}
.table tbody tr:hover{background:rgba(124,108,255,.05)}
.table th.num,.table td.num{text-align:right;font-variant-numeric:tabular-nums}
/* 表格内按钮禁止折行：操作列一挤，.btn 里的「编/辑」会被压成竖排单字（实测学校列表 4 个按钮时必现） */
.table .btn{white-space:nowrap;flex:none}
.table td .sub{display:block;font-size:11.5px;color:var(--ink-soft);font-weight:600;margin-top:1px}
.cellmain{display:flex;align-items:center;gap:10px;min-width:0}
.cellmain .av{width:32px;height:32px;flex:none;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--primary-soft);color:var(--primary-d);font-weight:900;font-size:13px}
.cellmain .tx{min-width:0}
.cellmain .tx b{display:block;font-weight:800;line-height:1.35}
.cellmain .tx i{font-style:normal;font-size:11.5px;color:var(--ink-soft);font-weight:600}

/* ---------- 页脚说明 ---------- */
.footnote{margin:14px 0 0;font-size:12px;line-height:1.8;color:var(--ink-soft)}
.footnote b{color:var(--ink)}

/* 无数据态指标（如「暂无」优良率）：用中性灰，避免与真实数值同色造成误读 */
.metric.none > .ic{background:#eef0f7;color:#8b90a5}
.metric.none .v{color:var(--ink-soft)}

/* ============================================================
   带人数的自绘下拉（全站统一，2026-10-31）
   ------------------------------------------------------------
   原生 <select> 的 option 是纯文本：人数既不能靠右对齐，也不能只给数字着色。
   故外观自绘，原生 select 仍原样留在 DOM 里（绝对定位铺满、透明、不吃鼠标），
   当唯一数据源与表单值 —— 既有联动脚本（读 options / 改 innerHTML / 监听 change）
   与表单提交一个字都不用改。
   模板用法（.sc-btn / .sc-pop 由 sel_count.js 自动补）：
     <div class="scw" data-sc>
       <select name="school_id">
         <option value="" data-count="">全部学校</option>
         <option value="5" data-name="某某小学" data-count="399">…</option>
       </select>
     </div>
   无 JS（html 无 .js）时自动退回原生 select。
   ============================================================ */
.scw{position:relative;min-width:0}
html.js .scw > select{position:absolute;inset:0;width:100%;height:100%;opacity:0;
  pointer-events:none;margin:0;padding:0;border:0}
html:not(.js) .sc-btn,html:not(.js) .sc-pop{display:none}
.sc-btn{display:flex;align-items:center;gap:8px;width:100%;min-height:38px;
  padding:7px 30px 7px 12px;font:inherit;font-size:13.5px;color:var(--ink);background:#fff;
  border:1px solid var(--line);border-radius:10px;cursor:pointer;text-align:left;position:relative;
  transition:border-color .15s,box-shadow .15s}
.sc-btn:hover{border-color:#dcdcf0}
.sc-btn:focus-visible{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
.sc-btn[aria-disabled="true"]{background:#f7f7fc;color:#a2a2b8;cursor:not-allowed}
.sc-nm{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sc-mt{flex:none;font-size:11.5px;color:var(--ink-soft);font-weight:600}
.sc-ct{flex:none;color:#2563eb;font-weight:700;font-size:12.5px;font-variant-numeric:tabular-nums}
.sc-ar{position:absolute;right:11px;top:50%;margin-top:-2px;width:0;height:0;
  border-left:4.5px solid transparent;border-right:4.5px solid transparent;border-top:5.5px solid #b9b9d0;
  transition:transform .15s}
.scw.on .sc-ar{transform:rotate(180deg);margin-top:2px}
/* 面板 portal 到 body + position:fixed：.card 的 backdrop-filter 会创建层叠上下文与
   fixed 包含块，面板留在卡内会被后面的元素压住、点击被拦截。 */
.sc-pop{position:fixed;z-index:9000;background:#fff;border:1px solid #e6e6f2;border-radius:12px;
  box-shadow:0 12px 32px rgba(30,30,60,.14);padding:6px;max-height:320px;overflow:auto}
.sc-op{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;
  cursor:pointer;font-size:13.5px;color:var(--ink)}
.sc-op:hover,.sc-op.on{background:#f4f2ff}
.sc-op[aria-selected="true"]{background:var(--primary-soft);font-weight:600}
.sc-op .sc-ct{font-size:12px}
/* optgroup 标题（如「按学校分组的班级」）：只作视觉分隔，不可点 */
.sc-grp{padding:8px 10px 4px;font-size:11.5px;font-weight:700;color:var(--ink-soft);
  letter-spacing:.4px;pointer-events:none}
.sc-grp + .sc-op{border-top:none}

/* ===================================================================
   PG 页面级设计层（2026-11-02）
   给「运营服务」下的列表页 / 表单页提供统一版式。
   纪律：一律 pg- 前缀，**不覆盖任何既有 .card/.table/.btn/label 规则**，
   没套用 pg- 的老页面外观零变化（可回退：删掉本段即可）。
   命名：pg-lead 说明条 / pg-kpis 指标条 / pg-panel 面板 / pg-bar 工具条 /
        pg-tbl 规范表格 / pg-empty 空状态 / pg-sec 表单分区 / pg-foot 操作条。
   =================================================================== */

/* 说明条：替代原来「一行灰色小字」，给页面一个明确的用途说明 */
.pg-lead{display:flex;gap:9px;align-items:flex-start;margin:0 0 14px;padding:10px 14px;
  border-radius:12px;background:rgba(124,108,255,.055);border-left:3px solid var(--primary);
  font-size:13px;line-height:1.6;color:var(--ink-soft)}
.pg-lead b{color:var(--ink);font-weight:800}
.pg-lead .ii{flex:none;margin-top:2px;color:var(--primary);display:inline-flex}

/* 指标条：让列表页第一屏就有"概览"，而不是一上来就是一张表 */
.pg-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:12px;margin-bottom:14px}
.pg-kpi{background:#fff;border:1px solid var(--line);border-radius:16px;padding:12px 16px;
  box-shadow:0 2px 10px rgba(120,110,200,.06)}
.pg-kpi .k{font-size:12px;font-weight:700;color:var(--ink-soft);margin-bottom:3px;
  display:flex;align-items:center;gap:5px;white-space:nowrap}
.pg-kpi .v{font-size:21px;font-weight:800;line-height:1.25;color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.pg-kpi .v small{font-size:12px;font-weight:700;color:var(--ink-soft);margin-left:3px}
.pg-kpi.ok .v{color:#1d9e6a}
.pg-kpi.warn .v{color:#d98a1c}
.pg-kpi.mute .v{color:#8a8aa3}

/* 面板：工具条 + 表格合成一张卡，避免原来「说明条浮在表外」的散乱感 */
.pg-panel{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--glass-line);border-radius:var(--radius);box-shadow:var(--shadow);
  overflow:hidden}
.pg-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 16px;
  border-bottom:1px solid var(--line);background:rgba(255,255,255,.5)}
.pg-bar .grow{flex:1 1 auto;min-width:0}
.pg-bar select{width:auto;min-width:132px;height:36px;padding:0 34px 0 12px;font-size:13.5px;
  border-radius:10px}
.pg-search{position:relative;flex:0 1 260px;min-width:190px}
.pg-search input{height:36px;font-size:13.5px;padding:0 12px 0 34px;border-radius:10px}
.pg-search .ii{position:absolute;left:11px;top:50%;transform:translateY(-50%);
  color:var(--ink-soft);pointer-events:none;display:inline-flex}
.pg-bar .btn.sm{padding:8px 15px}

/* 规范表格：fixed 布局 + 列宽由 th 决定。
   为什么必须 fixed：auto 布局下内容会把列撑开，中文被压成一字一行、操作列被挤出可视区
   （2026-11-02 在筛查任务页实测 tableW 1562 > wrapW 1296）。 */
.pg-tbl{width:100%;border-collapse:collapse;table-layout:fixed}
.pg-tbl th,.pg-tbl td{padding:11px 14px;text-align:left;vertical-align:middle;
  font-size:13.5px;border-bottom:1px solid var(--line)}
.pg-tbl th{background:rgba(124,108,255,.07);color:var(--primary-d);font-weight:800;
  font-size:12.5px;letter-spacing:.2px;white-space:nowrap;border-bottom:1px solid rgba(124,108,255,.14)}
.pg-tbl tbody tr{transition:background .12s}
.pg-tbl tbody tr:hover{background:rgba(124,108,255,.045)}
.pg-tbl tbody tr:last-child td{border-bottom:none}
.pg-tbl .nowrap{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ★★ .clip2 只能用在 td **里面**的 div 上，绝不能直接加到 <td>：
   `display:-webkit-box` 会把 table-cell 的显示类型顶掉，单元格不再按表格排版，
   内容会溢出到下一行（2026-11-02 在 1080 屏的项目库截图里看到第 3 行文字穿过行线）。 */
.pg-tbl .clip2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.5}
.pg-tbl .dim{color:var(--ink-soft);font-size:12.5px}
/* ---- 序号列（2026-11-03）：运营服务下所有列表的第 1 列 ----
   46px 放得下 4 位数；居中 + 次要色 + tabular-nums，不抢主列视线。
   ★ 序号列**不参与窄屏折叠** —— 屏越窄越需要「第几条」来定位。
   ★ 前端筛选后由 base.html 的 wjsReindex() 重排，避免「1、5、9」跳号。 */
.pg-tbl .c-idx,.table .c-idx,.ops-tbl .c-idx{width:46px;text-align:center;color:var(--ink-soft);
  font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.pg-tbl th.c-idx,.table th.c-idx,.ops-tbl th.c-idx{color:var(--primary-d);opacity:.75}
/* ★ 表格内的 pill / btn 必须 nowrap：中文 + 内联 svg 在窄列里会逐字折行
   （2026-11-02 实测：状态列 80px 时「启用」被压成「启/用」两行），
   只在 .pg-tbl 作用域内加，不影响表格外的 .pill。 */
.pg-tbl .pill,.ops-tbl .pill{white-space:nowrap;flex:none;padding:3px 9px;font-size:11.5px}
.pg-tbl .pill svg,.ops-tbl .pill svg{flex:none}
.pg-tbl code{font-size:11.5px;background:rgba(124,108,255,.09);color:var(--primary-d);
  padding:2px 6px;border-radius:5px;white-space:nowrap;font-family:var(--font-mono,ui-monospace,monospace)}
/* .ops-tbl 仍被 10 个模板共用（任务列表/名单/统算/批量建档…）。
   它的 code 之前没有 nowrap —— 列宽一紧（153px 可用 125 < 内容 127）就折成两行。
   只补 nowrap，不改这些页面的视觉基调。 */
.ops-tbl td code{white-space:nowrap}
/* 操作列：必须 nowrap 且按钮不收缩，否则 flex-wrap 会把 3 个按钮折成 3 行、行高翻倍 */
.pg-tbl .ops{display:flex;gap:6px;align-items:center;flex-wrap:nowrap}
.pg-tbl .ops form{display:inline-flex;margin:0}
.pg-tbl .ops .btn,.pg-tbl .ops button{flex:none;white-space:nowrap}
.pg-tbl .ops .btn.sm{padding:6px 13px;font-size:12.5px}
/* ★ 统一行内按钮高度：实测 <a class="btn sm"> 是 32px、<form><button class="btn sm"> 是 28px
   （a 继承 body 的 line-height 1.6，button 用 normal），同一行里差 4px、看着参差。
   给死高度后两者都是 30px，纵向基线一致（2026-11-02 实测 top 407.2 vs 409.2）。
   .ops-tbl 是筛查任务页仍在用的旧表格类，一并修，否则那一页还是参差。 */
.pg-tbl .ops .btn,.pg-tbl .ops button,
.ops-tbl td.row .btn,.ops-tbl td.row button{
  height:30px;padding-top:0;padding-bottom:0;align-items:center}

/* 空状态 */
.pg-empty{padding:52px 20px;text-align:center}
.pg-empty .ii{color:rgba(124,108,255,.45);margin-bottom:10px;display:inline-flex}
.pg-empty .t1{font-size:15px;font-weight:800;color:var(--ink);margin-bottom:6px}
.pg-empty .t2{font-size:13px;color:var(--ink-soft);line-height:1.6}

/* 表单分区 */
.pg-form{display:grid;gap:14px;max-width:1180px}
.pg-sec{background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--glass-line);border-radius:18px;padding:18px 20px 20px;
  box-shadow:0 4px 16px rgba(120,110,200,.07)}
.pg-sec > .hd{display:flex;align-items:center;gap:8px;margin:0 0 4px}
.pg-sec > .hd .n{flex:none;width:20px;height:20px;border-radius:6px;background:var(--primary);
  color:#fff;font-size:12px;font-weight:800;display:inline-flex;align-items:center;justify-content:center}
.pg-sec > .hd h3{font-size:14px;font-weight:800;color:var(--primary-d);margin:0;letter-spacing:.2px}
.pg-sec > .hint{font-size:12.5px;color:var(--ink-soft);line-height:1.6;margin:0 0 14px 28px}
.pg-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:14px 18px}
.pg-grid .field{margin:0}
.pg-grid .field.full{grid-column:1/-1}
.pg-grid label{margin:0 0 5px}
.pg-grid .req::after{content:" *";color:#e2606d}
.pg-checks{display:flex;flex-wrap:wrap;gap:8px}
.pg-checks label{display:inline-flex;align-items:center;gap:7px;margin:0;padding:9px 14px;
  border:1.5px solid var(--line);border-radius:11px;background:#fff;cursor:pointer;
  font-size:13px;font-weight:700;color:var(--ink-soft);white-space:nowrap;
  transition:border-color .14s,background .14s,color .14s}
.pg-checks label:hover{border-color:rgba(124,108,255,.45)}
.pg-checks label:has(input:checked){border-color:var(--primary);background:var(--primary-soft);
  color:var(--primary-d)}
.pg-checks input{width:auto;margin:0;flex:none}
/* 原生 checkbox 的默认蓝框和紫色主题不搭，统一成主题色（只在本层作用域内） */
.pg-checks input[type="checkbox"]{width:15px;height:15px;accent-color:var(--primary);cursor:pointer}
/* 底部操作条：主按钮在前、次按钮弱化，和表单一卡到底 */
.pg-foot{display:flex;align-items:center;gap:10px;padding:2px}
.pg-foot .grow{flex:1;min-width:0}
.pg-foot .btn.ghost{border-width:1.5px}

/* ---- 行内操作：文字链（2026-11-02） ----
   为什么不用 .btn：密列表一行有 4~5 个操作，每个按钮 54~76px，操作列被撑到 300px+，
   必须给表格加 min-width，结果在 1440 屏上整表溢出、最右侧「删除」被卡片裁掉（用户截图）。
   改成文字链后 5 个操作只占 214px，整表不用横向滚动。
   ★ 分隔线用 1px 竖条而不是「·」，中文标点在 12.5px 下容易和文字粘连。
   ★ 三个子项（a / form>button / sep）必须给死高度 26px 并垂直居中：
     a 的行高来自 1.5 倍行距、button 来自 padding，不等高会造成「同一行按钮顶部不齐」
     （实测 a@377 / button@374），验收脚本按 top 去重判「折成两行」会直接 FAIL。 */
.pg-acts{display:flex;align-items:center;flex-wrap:nowrap}
.pg-acts > *{flex:none}
.pg-acts a,.pg-acts button{display:inline-block;margin:0;padding:0;border:0;background:none;
  height:26px;line-height:26px;font-family:inherit;font-size:12.5px;font-weight:700;
  color:var(--primary-d);cursor:pointer;text-decoration:none;white-space:nowrap}
.pg-acts a:hover,.pg-acts button:hover{color:var(--primary);text-decoration:underline}
.pg-acts form{display:inline-flex;align-items:center;margin:0;height:26px}
.pg-acts .sep{width:1px;height:11px;background:rgba(124,108,255,.28);margin:0 9px}
.pg-acts .del{color:#d84545}
.pg-acts .del:hover{color:#b02a2a}

/* ---- 列表页进度条（迷你）：一行数字 + 一条细条，比「0/70（0%）」更直观 ---- */
.pg-prog .top{display:flex;align-items:baseline;gap:4px;font-size:13px;font-weight:800;
  color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums;line-height:1.35}
.pg-prog .top i{font-style:normal;color:var(--ink-soft);font-weight:700;font-size:12px}
.pg-prog .top em{font-style:normal;font-size:11.5px;font-weight:700;color:var(--ink-soft);
  margin-left:auto;padding-left:6px}
.pg-prog .bar{height:5px;border-radius:3px;background:rgba(124,108,255,.14);overflow:hidden;margin-top:5px}
.pg-prog .bar span{display:block;height:100%;border-radius:3px;background:var(--primary)}
.pg-prog .bar span.full{background:#1d9e6a}
.pg-prog .note{font-size:10.5px;color:#9aa6b8;margin-top:4px;white-space:nowrap}

/* ---- 标题行下方的一行元信息（编码 · 年度 · 方案…），列表主列专用 ---- */
.pg-tbl .meta{display:flex;align-items:center;gap:7px;margin-top:4px;font-size:12px;
  color:var(--ink-soft);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pg-tbl .meta .dot{flex:none;width:1px;height:10px;background:rgba(0,0,0,.13)}
.pg-tbl .meta .k{flex:none;color:#9aa6b8}
/* ---- 分区小标题（统算页的「一、二、三」） ---- */
.pg-sub{display:flex;align-items:center;gap:8px;margin:18px 0 8px;font-size:14px;font-weight:800;
  color:var(--primary-d)}
.pg-sub:first-child{margin-top:0}
.pg-sub .n{flex:none;width:18px;height:18px;border-radius:5px;background:rgba(124,108,255,.14);
  color:var(--primary-d);font-size:11.5px;display:inline-flex;align-items:center;justify-content:center}
.pg-sub .r{margin-left:auto;font-size:12px;font-weight:600;color:var(--ink-soft)}
.pg-tbl tr.tot td{background:rgba(124,108,255,.05);font-weight:800;border-top:1px solid rgba(124,108,255,.18)}

/* ---- 四档分布：一条堆叠条 + 右侧数字（数字用 title 兜完整口径） ---- */
.pg-dist{display:flex;align-items:center;gap:9px}
.pg-dist .bar{flex:1 1 auto;display:flex;height:8px;border-radius:4px;overflow:hidden;background:#eef1f7;min-width:70px}
.pg-dist .bar span{display:block;height:100%}
.pg-dist .nums{flex:none;font-size:11.5px;font-weight:700;white-space:nowrap;font-variant-numeric:tabular-nums}
.pg-dist .nums i{font-style:normal;margin-left:6px}


/* ===================================================================
   窄屏列折叠（2026-11-02 二轮）
   背景：用户在 ~1080 宽的窗口里用系统（截图 1080×618）。1440 屏内容区 1136，
   1080 屏只有 776 —— 6 列表格如果每列都死宽，「任务」这种主列只剩 70px，
   名称被压成「202…」，比横向滚动更糟。
   做法：按视口宽度分档隐藏次要列（不是缩字号、不是横向滚动），主列始终拿剩余宽度。
   视口 ↔ 内容区：内容 = 视口 − 304（侧栏 250 + 内边距）。
   ★ 这些类只出现在具体页面的 th/td 上，其他页面不受影响。
   =================================================================== */
@media (max-width:1340px){
  /* 内容区 <= 1036：先砍「时间/次数/变量」这类可推断信息 */
  .pg-tbl .c-per,        /* 任务：周期 */
  .pg-tbl .c-date,       /* 方案：有效期 */
  .pg-tbl .c-print,      /* 引导单：打印次数 */
  .pg-tbl .c-var         /* 消息模板：变量（正文里也能看到） */
  {display:none}
}
@media (max-width:1160px){
  /* 内容区 <= 856：再砍「范围/组合/类别/项目」—— 任务名与方案名里通常已含这些信息 */
  .pg-tbl .c-scope,      /* 任务：筛查范围 */
  .pg-tbl .c-proj,       /* 方案：项目组合 / 引导单：项目 */
  .pg-tbl .c-cat,        /* 项目库：类别 */
  .pg-tbl .c-ch          /* 消息模板：渠道/分类 */
  {display:none}
}
@media (max-width:1120px){
  /* 内容区 <= 816：消息模板的编码也让位给「标题」 */
  .pg-tbl .c-code{display:none}
}

/* ===================================================================
   家长扫码页（方案码 / 任务统一码共用，2026-11-03 抽出）
   原本内联在 ops/plan_qr.html 里；任务统一码要复用同一视觉，
   再复制一份就会出现「改一处漏一处」。两类页面都从这里取样式。
   =================================================================== */
.pq-wrap{display:grid;grid-template-columns:318px minmax(0,1fr);gap:16px;align-items:start}
@media (max-width:1080px){.pq-wrap{grid-template-columns:1fr}}
.pq-left{display:flex;flex-direction:column;gap:12px}

.pq-qr{background:#fff;border:1px solid var(--line);border-radius:18px;padding:18px 16px 14px;
  text-align:center;box-shadow:0 3px 14px rgba(120,110,200,.08)}
.pq-qr img{display:block;margin:10px auto;border-radius:6px}
.pq-qr-hd{font-size:14.5px;font-weight:800;color:var(--ink);line-height:1.45}
.pq-qr-sub{font-size:12px;color:var(--ink-soft);margin-top:3px}
.pq-qr-ft{font-size:11.5px;color:#98a0b3;margin-top:2px}
.pq-qr.empty{padding:26px 18px}
.pq-qr.empty b{display:block;font-size:15px;color:var(--ink);margin:10px 0 6px}
.pq-qr.empty p{font-size:12.5px;color:var(--ink-soft);line-height:1.7;margin:0 0 14px}
.pq-empty-ic{color:#c9cde0}

.pq-link label{display:block;font-size:12px;color:var(--ink-soft);margin-bottom:5px}
.pq-link .row{display:flex;gap:8px}
.pq-link .row input{flex:1 1 auto;min-width:0;height:34px;font-size:12px;
  font-family:var(--font-mono,ui-monospace,monospace);border-radius:9px}
.pq-link .row .btn{flex:none;height:34px;padding:0 13px}
.pq-link .hint{font-size:11.5px;color:#98a0b3;margin-top:6px;line-height:1.6}

.pq-act{display:flex;gap:8px;flex-wrap:wrap}
.pq-act .btn{flex:1 1 auto;justify-content:center;white-space:nowrap}

.pq-steps{margin:0;padding:14px 20px 4px 38px;font-size:13px;line-height:2;color:var(--ink-soft)}
.pq-steps b{color:var(--ink)}
.pq-warn{display:flex;gap:8px;align-items:flex-start;margin:0 16px 16px;padding:10px 12px;
  border-radius:11px;background:#fff8ea;color:#8a6420;font-size:12.5px;line-height:1.7}
.pq-warn .ic{flex:none;margin-top:2px}

.pq-danger{display:flex;gap:14px;align-items:center;justify-content:space-between;
  margin-top:14px;padding:12px 16px;border:1px dashed #f0c9c9;border-radius:14px;
  background:#fffafa}
.pq-danger b{display:block;font-size:13px;color:#b03a3a}
.pq-danger span{font-size:12px;color:var(--ink-soft);line-height:1.6}
.pq-danger form{flex:none}

/* 打印只留二维码白卡：直接贴班级门口用，不要打印整个后台界面 */
@media print{
  @page{size:A5;margin:10mm}
  .app>aside,.sidebar,.topbar,.pg-lead,.pq-right,.pq-link,.pq-act,
  .pg-foot,header,footer,nav{display:none !important}
  html,body,.app,.main,.content{min-height:0 !important;background:#fff !important;
    box-shadow:none !important;padding:0 !important;margin:0 !important}
  .pq-wrap{display:block}
  .pq-qr{border:1px solid #ddd;box-shadow:none;margin:0 auto;max-width:360px}
  .pq-qr img{width:260px;height:260px}
}
