@charset "utf-8";
/* ============================================================
   七给村村民委员会管理系统 —— 公共样式
   ------------------------------------------------------------
   仅补充 Layui 未覆盖的部分：
   页面容器、统计卡片、筛选栏、状态标签、模板预览与 A4 打印。
   ============================================================ */

/* ---------- 一、全局基础 ---------- */
html, body {
    height: 100%;
    background: #f2f5f9;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "微软雅黑", sans-serif;
    color: #2b3a4a;
}

.cw-body {
    padding: 14px 14px 10px;
    box-sizing: border-box;
}

/* 内容区最后一个元素去掉下边距，避免页脚上方多出一条空行 */
.cw-body > :last-child { margin-bottom: 0; }

/* 页脚版本号：随内容滚动，不悬浮；尽量压矮，不占页面空间 */
.cw-footer {
    padding: 0 14px 8px;
    text-align: center;
    font-size: 12px;
    line-height: 1.6;
    color: #9aa7b5;
}

/* 手机端页脚：版本与版权各占一行居中，避免长文本挤成一团 */
@media screen and (max-width: 768px) {
    .cw-footer { padding: 4px 10px 12px; font-size: 11px; line-height: 1.7; }
    .cw-footer .cw-f-sep { display: none; }
    .cw-footer .cw-f-copy { display: block; }
}

/* ---------- 侧边导航：二级菜单右移，凸显从属关系 ----------
   layui 默认一级项与二级项的左内边距都是 20px，而一级项的文字排在图标之后
   （实测图标占 20~34px），二级项反而比一级文字还靠左 14px 左右，
   层级看着是反的。这里把二级项右推，一眼能看出是从属于上一级的子项。

   缩进值的两轮取值：
     · v27.2 起是 52px（一级文字起点 ≈38px 再进约 1 个字）；
     · v27.9 用户反馈「左侧菜单的二级分类距离左侧 52px，改为 35px」
       → 收到 35px。此时文字起点 = 35 + 图标槽 16 + 间距 6 = 57px，
       仍比一级文字起点（≈34px）靠右 23px，层级关系不受影响。 */
.layui-nav-tree .layui-nav-child dd a {
    padding-left: 35px;
}

/* 手机端抽屉侧栏更窄，留出同样的层次感但少推一点，避免文字被挤成省略号。
   v27.9 随桌面一起收：44px → 30px（保持原来「手机比桌面少推 5px」的关系）。 */
@media screen and (max-width: 768px) {
    .layui-nav-tree .layui-nav-child dd a {
        padding-left: 30px;
    }
}

/* ---------- 后台内容区 ---------- */
/* 内容区自身滚动（顶栏/侧栏固定），长页面不撑破整体布局 */
.layui-layout-admin > .layui-body {
    overflow-y: auto;
    overflow-x: hidden;
}

/* 桌面端收起侧边栏：内容区跟随铺满整行 */
@media screen and (min-width: 769px) {
    .layui-layout-admin.cw-side-collapsed .layui-side { display: none; }
    .layui-layout-admin.cw-side-collapsed .layui-body { left: 0 !important; }
}

/* 手机端顶栏 logo 显示当前页面名，桌面端显示机构名 */
.cw-logo-page { display: none; }
@media screen and (max-width: 768px) {
    .cw-logo-org { display: none; }
    .cw-logo-page { display: inline; }
}

/* ---------- 侧边导航二级项：图标 + 文字 ----------
   layout.php 现在给每个二级项也带上了图标（与一级项视觉语言一致）。
   二级项本身只有一段 padding-left（v27.9 起 35px，见本文件上方），
   这里再给图标一个固定槽位，
   让同一级下的所有子项文字左边界严格对齐（图标宽度不同也不会参差）。 */
.layui-nav-tree .layui-nav-child a > .layui-icon {
    display: inline-block;
    width: 16px;
    margin-right: 6px;
    font-size: 13px;
    text-align: center;
    vertical-align: middle;
}

/* ---------- 顶栏快捷入口（电脑端） ----------
   layout.php 在「首页」右侧渲染 cw_top_menus() 里的高频入口。
   比侧栏项紧凑一档：1366 宽度下 5 项 + 首页 + 侧栏开关仍能排下，
   不会顶到右侧的用户名区。手机端整组隐藏（见文末手机端区块）。 */
.layui-header .cw-top-quick > a {
    /* 入口从 5 个变 6 个（v27.8）后，左内边距由 11px 收到 9px：
       每项省 4px、整组省 24px，1366 视口下左区右边界由 963 退到 939，
       离右侧用户区 58px，不再擦边。 */
    padding: 0 9px;
    font-size: 13px;
}

.layui-header .cw-top-quick > a > .layui-icon {
    font-size: 14px;
    margin-right: 3px;
}

/* 平板与 1280 宽的笔记本空间不够放文字：只留图标，靠 title 提示。
   分界由 1180 提到 1320：顶栏入口从 5 个加到 6 个后，左区右边界固定到
   939px，而 1280 视口下右侧用户区左边界只有 911px —— 文字会直接压上去
   （1280 实测重叠 52px）。要把六个入口的文字全排开需要 ≥1320px：
   1320 时左区 939 < 右区 951，1366 时 939 < 997。 */
@media screen and (min-width: 769px) and (max-width: 1320px) {
    .layui-header .cw-top-quick .cw-top-text { display: none; }
    .layui-header .cw-top-quick > a > .layui-icon { margin-right: 0; font-size: 15px; }
}

/* 文本截断 */
.cw-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 通用间距 */
.cw-mt-0 { margin-top: 0 !important; }
.cw-mt-8 { margin-top: 8px; }
.cw-mt-14 { margin-top: 14px; }
.cw-mb-8 { margin-bottom: 8px; }
.cw-mb-14 { margin-bottom: 14px; }
.cw-mr-6 { margin-right: 6px; }
.cw-ml-6 { margin-left: 6px; }
.cw-tc { text-align: center; }
.cw-tr { text-align: right; }

/* ---------- 二、卡片 ---------- */
.cw-card {
    background: #fff;
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(24, 46, 74, .08);
    padding: 12px 14px;
    margin-bottom: 10px;
}

.cw-card-title {
    font-size: 14.5px;
    font-weight: 600;
    color: #1b2b3a;
    padding-left: 10px;
    border-left: 3px solid #1e9fff;
    line-height: 1;
    margin-bottom: 10px;
}

.cw-card-title .cw-card-sub {
    font-size: 12px;
    font-weight: 400;
    color: #93a2b3;
    margin-left: 8px;
}

/* 卡片头为 flex 时，标题自带的 10px 下外边距会把自身顶到行首、
   右侧提示文字随居中线下坠约 5px，视觉上一高一低，这里归零 */
.cw-card-head .cw-card-title {
    margin-bottom: 0;
}

/* ---------- 三、统计卡片 ---------- */
.cw-stat-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 10px;
}

/* 部分页面把卡片放进 layui 栅格列里（列自带 25% 宽度与 6px 内边距）。
   此时若再叠加父级的 gap，四项刚好超出 100% 就会挤到第二行（3+1 错位），
   因此这里改由 flex 均分宽度，间距统一交给父级 gap。 */
.cw-stat-row > [class*="layui-col-"] {
    flex: 1 1 0;
    width: auto;
    min-width: 168px;
    max-width: 100%;
    padding: 0;
}

.cw-stat {
    flex: 1 1 0;
    min-width: 140px;
    background: #fff;
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(24, 46, 74, .08);
    padding: 10px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    transition: box-shadow .2s, transform .2s;
}

.cw-stat:hover {
    box-shadow: 0 3px 12px rgba(24, 46, 74, .14);
    transform: translateY(-1px);
}

.cw-stat-icon {
    width: 36px;
    height: 36px;
    border-radius: 7px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    color: #fff;
    flex: 0 0 auto;
}

.cw-stat-body { flex: 1 1 auto; min-width: 0; }

.cw-stat-value {
    font-size: 20px;
    font-weight: 700;
    line-height: 1.15;
    color: #1b2b3a;
    font-variant-numeric: tabular-nums;
}

.cw-stat-value small {
    font-size: 12px;
    font-weight: 400;
    color: #8a99a8;
    margin-left: 3px;
}

.cw-stat-label {
    font-size: 12px;
    color: #7b8a9a;
    margin-top: 1px;
}

/* ---------- 统计区块就地刷新后的提示动画 ----------
   区块内容被换成最新值时闪一下，动画播完自动消失，
   用来提示「这里的数字刚刚变了」，无需整页刷新。 */
.cw-stat-flash > * {
    animation: cwStatFlash .9s ease-out;
}

@keyframes cwStatFlash {
    0%   { opacity: .2; transform: translateY(-2px); }
    100% { opacity: 1;  transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .cw-stat-flash > * { animation: none; }
}

/* 图标底色 */
.cw-bg-blue   { background: linear-gradient(135deg, #4aa8ff, #1e9fff); }
.cw-bg-green  { background: linear-gradient(135deg, #4fd08a, #16b777); }
.cw-bg-orange { background: linear-gradient(135deg, #ffb959, #ff9c29); }
.cw-bg-red    { background: linear-gradient(135deg, #ff7d7d, #f5544f); }
.cw-bg-purple { background: linear-gradient(135deg, #a98bff, #8257ff); }
.cw-bg-cyan   { background: linear-gradient(135deg, #4bd3d3, #16b8b8); }
.cw-bg-gray   { background: linear-gradient(135deg, #adbccb, #8798a8); }

/* 顶栏左侧导航与 logo 都是绝对定位，保证 logo 区域不盖住菜单按钮 */
.layui-header .layui-layout-left { z-index: 2; }

/* ---------- 四、筛选栏（条件与按钮同一流式布局：
   电脑/移动端均与筛选项同行显示，放不下时按钮「作为整体」
   换行，查询/重置两键在任何断点都不分离） ---------- */
.cw-filter {
    background: #fff;
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(24, 46, 74, .08);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    padding: 8px 10px;
    margin-bottom: 12px;
}

/* 条件项提升为筛选栏的直接成员，参与同一行流式排列 */
.cw-filter .layui-form-item {
    display: contents;
}

.cw-filter .layui-inline {
    /* 条件项内部也用 flex 排布：
       layui 的 .layui-form-label 是 float:left 的块，后面紧跟 .layui-input-inline
       时会留下一个空白文本节点（约 10px 的「空气」）。五个条件加起来就是 50px，
       正是「按钮组差一点挤不进这一行」的量。flex 容器会忽略纯空白文本节点，
       顺带让标签与控件自动垂直居中对齐（手机端区块本来就是这个写法）。 */
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    margin-right: 0;
    /* layui 自带的 margin-bottom:5px 会被 flex 垂直居中按
       「含外边距的盒」计入，导致条件比按钮整体偏高，必须归零 */
    margin-top: 0;
    margin-bottom: 0;
}

/* layui 自带的 `.layui-input-inline{margin-right:10px}` 必须归零。
   它是为「多个 .layui-input-inline 并排」设计的，但现在控制间距的职责
   已经交给 .cw-filter 的 gap，这 10px 变成纯浪费：
   五个条件 = 50px，正是 1366 宽度下户籍名册（差 30px）与党员管理（差 67px）
   「按钮组就差一口气挤不进这一行」的量。 */
.cw-filter .layui-input-inline {
    margin-right: 0;
}

/* 同一条件内的相邻控件（如年龄「起 / 止」）留 5px 间隙，
   否则 flex 之下两者会贴在一起（上面的 margin-right 已归零，
   这里给后一个补 margin-left，实际间隙就是 5px） */
.cw-filter .layui-input-inline + .layui-input-inline {
    margin-left: 5px;
}

.cw-filter .layui-form-label {
    width: 74px;
    padding: 9px 8px;
    font-size: 13px;
    color: #55677a;
}

/* 行内条件的标签按文字内容自适应宽度，
   「性别/年龄」等短标签不再固定占 74px，
   让 1366 宽度下条件与按钮能排进同一行。

   右侧内边距的几轮取值（注意：这一条权重高于手机端那条同名规则，
   桌面与手机都由它决定，改它等于两端一起改）：
     · v27.6 由 3px 收到 2px —— 当时 1366 下按钮组就差一口气挤不进这一行；
     · v27.9 用户反馈「名称和输入框/下拉框的距离太近不协调」→ 加回 6px。
       为不让 1366 的换行被推坏，同时把控件宽度上限 132→126、
       关键字框基准宽 168→164 收回同样多：每个条件一进一出基本持平
       （实测 14 个列表页在 1366 下仍全部与按钮同行）。 */
.cw-filter .layui-inline .layui-form-label {
    width: auto;
    padding: 9px 6px 9px 0;
}

.cw-filter .layui-input-block {
    margin-left: 74px;
}

/* 按钮组：独立盒子整体参与换行（查询/重置永不拆开），
   剩余空间足够时靠右与条件同行。
   选择器带 .layui-form-item 前缀，压过上面 display:contents 的权重；
   align-items:center 让组内的期次提示、展开开关与按钮垂直居中；
   上下外边距必须归零——flex 垂直居中按「含外边距的盒」计算，
   残留的 margin-bottom 会把按钮整体抬高，与输入框错位 */
.cw-filter .layui-form-item.cw-filter-btns {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    margin-top: 0;
    margin-bottom: 0;
    margin-left: auto;
    padding-left: 0;
}

/* 「更多条件」块：展开后整块另起一行，按钮组留在第一行原位。
   这个块换了三代写法，三次都是「按钮与多出来的条件谁占哪一行」的问题：

   ① display:block + flex:1 1 100%（整块独占一整行）
      → 多出来的条件自己占一行，按钮组被挤到第三行、那一行只有按钮，
        既难看又白占约 46px 高度（v27.7 反馈：「展开后查询按钮会单独另起一行」）。

   ② display:contents（v27.7）
      → 块内条件项升格为 .cw-filter 的直接 flex 成员，按钮组确实留在第一行
        不动了；但 flex 只在「放不下」时才换行，而换行计算时按钮组的
        margin-left:auto 被当作 0，第一行往往刚好还塞得下多出来的第一个条件
        → 条件被排到按钮组右边同一行（v27.8 反馈：「展开更多条件后，
        出现的选项没有换行」）。

   ③ 现在：块自身作为 flex 成员，用 flex-basis:100% 强制占满一整行。
      100% 就是容器内容宽，第一行的剩余空间永远小于它 → 必然换行；
      换行后它自己独占该行，内部条件项再按 flex 排布（内部 gap 必须自己给，
      它已不在 .cw-filter 的直接子项流里，父级 gap 不会继承进来）。

   注意 1：显隐由类名控制。内联 style="display:none" 权重高于类选择器，
          .cw-open 会被它压住；页面里那个内联样式已一并去掉。
   注意 2：展开／收起的 JS 判定一律看类名，不要用 jQuery 的 :visible / :hidden
          （②那代 display:contents 无盒模型会被恒判为「隐藏」，这个坑留个记录）。 */
.cw-filter .layui-form-item.cw-filter-more {
    display: none;
}

.cw-filter .layui-form-item.cw-filter-more.cw-open {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    flex: 0 0 100%;
    /* 这几条都是抵消 layui 自带样式：flex 垂直居中按「含外边距的盒」
       计算，残留的 margin-bottom 会把这一行整体抬高并与上一行错位 */
    margin-top: 0;
    margin-bottom: 0;
    padding: 0;
}

/* 有的页面把按钮写成 <div class="layui-inline cw-filter-btns">（少了 layui-form-item），
   上面那条靠右规则就落不到它头上，按钮会紧贴在条件后面而不是靠右。
   这里补一条，让「靠右」在两种写法下都成立；
   margin-left:auto 在空间不足时自然退化为 0，不会把按钮挤到下一行。 */
.cw-filter .layui-inline.cw-filter-btns {
    margin-left: auto;
}

/* 筛选栏里的按钮比正文按钮紧凑一档：
   layui 默认 padding 0 15px / 字号 14px，四个按钮加开关就要 300px 出头，
   正是它把「查询」挤到下一行的。收到 0 10px / 13px，视觉上仍是标准按钮。 */
.cw-filter-btns .layui-btn {
    margin-right: 4px;
    padding: 0 9px;
    font-size: 13px;
}

.cw-filter-btns .layui-btn:last-child {
    margin-right: 0;
}

/* 「展开更多条件」开关：随按钮组垂直居中，不再浮在半空 */
.cw-filter-toggle {
    display: inline-flex;
    align-items: center;
    font-size: 12px;
    color: #1e9fff;
    line-height: 1;
    margin-left: 5px;
    cursor: pointer;
    vertical-align: middle;
}

.cw-filter-toggle:hover {
    text-decoration: underline;
}

.cw-filter-toggle i {
    font-size: 12px;
    margin-left: 2px;
}

/* ---------- 四之二、条件控件的宽度上限（只对桌面与平板生效，手机端不受影响） ----------
   背景：用户反馈「为什么查询行一直是换行显示，太占空间了。不只是这一个栏目」。
   实测（真实 Chrome，1366px 视口）：14 个列表页里有 8 个的「查询/重置」被挤到单独一行，
   那一行只放按钮、右侧大片空白；面板高度 100px（两行）而不是 58px（一行）。
   根因不是布局算法，而是各页把控件宽度写飘了：关键字框 190~230px 各不相同，
   没写内联宽度的下拉又吃到 layui 默认的 190px —— 条件一多就刚好差几十像素放不下按钮组
   （残疾人员页在 1366 下只差 156px）。

   这里给条件控件统一一个宽度上限，注意用 max-width：
   · max-width 只「收」不「放」——本来就窄的（性别 100px、年龄 80px）完全不受影响，
     不必去改 20 多个页面的内联宽度；
   · 关键字框是唯一的例外：给 164px 的「基准宽度」，允许在行内有余量时长胖到 240px
     （条件少的页面没必要跟着一起收，否则白截断 placeholder）；
   · 数字框（年龄起 / 止）只要两位数字，收到 64px。

   为什么是 126px 而不是更宽松的值：党员管理页在 1366 视口下是「最坏情况」——
   关键字 + 类别 + 支部 + 职务 + 性别共 5 个条件，其中 4 个是下拉（没有内联宽度，
   吃满上限）。v27.6 从 140 收到 132 时留出约 14px 余量；
   v27.9 标签右间距由 2px 加到 6px（每个条件 +4px），按「下拉 132→126、
   关键字 168→164」各收 4px 对冲 → 1366 下的总占宽与 v27.6 基本一致。
   126px 显示 4 个字的选项（如「正常在册」≈52px）仍然绰绰有余。

   为什么用 :has()：CSS 选不到父元素，而宽度是写在控件外层 .layui-input-inline 上的，
   只能「按控件类型给外层容器定宽」。浏览器若不支持 :has()，关键字框会跟着收敛到 132px
   （placeholder 略有截断），功能与布局均不受影响；本文件的手机端区块也早已在用 :has()。 */
@media screen and (min-width: 769px) {
    .cw-filter .layui-input-inline {
        max-width: 126px !important;
    }

    /* 关键字框的 164px 是「参与换行计算的基准宽度」，不是它的显示宽度：
       flex-grow:1 + max-width 让它在行内还有富余时长胖（最多 240px）。
       条件少的页面（土地确权 1 个条件、农业保险 1 个、数据字典 2 个）原来
       给关键字框写了 220px 内联宽度，若一律压到 164px，placeholder
       会被无谓截断——那是纯粹的浪费，不是紧凑。
       flex-shrink:0 很关键：行内放不下时它不会被压缩，所以
       「谁换行」的判定与固定 164px 时逐字节一致。 */
    .cw-filter .layui-inline:has(input[name="keyword"]) {
        flex: 1 0 164px;
        max-width: 240px;
    }

    /* 关键字框外层容器改为「吃满 .layui-inline 的剩余宽度」：
       width:0 作为 flex-basis，再由 flex-grow 撑开；
       max-width:none 必须写——上面那条通用规则给的 max-width:132px
       在 :has() 规则里不会被自动覆盖 */
    .cw-filter .layui-inline:has(input[name="keyword"]) .layui-input-inline {
        width: 0 !important;
        max-width: none !important;
        min-width: 0;
        flex: 1 1 auto;
    }

    /* 标签别跟着被压窄（flex 容器里 width:auto 是允许收缩的） */
    .cw-filter .layui-inline:has(input[name="keyword"]) .layui-form-label {
        flex: 0 0 auto;
    }

    .cw-filter .layui-input-inline:has(> input[type="number"]) {
        max-width: 64px !important;
    }
}

/* 弹层内嵌页使用的普通明细表 */
.cw-list-table {
    width: 100%;
    border-collapse: collapse;
    background: #fff;
    font-size: 13.5px;
}

.cw-list-table th,
.cw-list-table td {
    border: 1px solid #e6ecf3;
    padding: 7px 10px;
    text-align: center;
    line-height: 1.7;
}

.cw-list-table th {
    background: #f7fafd;
    color: #55677a;
    font-weight: 600;
    white-space: nowrap;
}

.cw-list-table tbody tr:hover {
    background: #f6fbff;
}

/* 工具栏（新增、导入、导出等按钮） */
.cw-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.cw-toolbar .cw-toolbar-right {
    margin-left: auto;
}

/* ---------- 五、表格微调 ---------- */
.layui-table-view {
    border-radius: 6px;
    overflow: hidden;
}

.layui-table th {
    font-weight: 600;
    color: #40566d;
    background: #f7fafd;
}

.layui-table-cell {
    height: auto;
    line-height: 26px;
    padding: 5px 10px;
    font-size: 13px;
}

/* 单元格内容垂直居中，保证各列在同一行内对齐 */
.layui-table td,
.layui-table th {
    vertical-align: middle;
}

.layui-table .cw-op,
.layui-table a.cw-link {
    line-height: 26px;
}

/* 行间隔色：奇偶行交替底色，便于区分行，避免看错行 */
.layui-table tbody tr:nth-child(even) > td {
    background-color: #e3edf6;
}

.layui-table tbody tr:hover > td,
.layui-table-hover > td {
    background-color: #cfe5f8;
}

.cw-table-name {
    font-weight: 600;
    color: #1b2b3a;
}

/* 卡片头部：左侧标题，右侧提示（垂直居中对齐，
   避免标题与右侧说明文字一高一低） */
.cw-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 12px;
}

.cw-card-tip {
    font-size: 12.5px;
    color: #93a2b3;
}

.cw-card-tip b {
    color: #1672d0;
    font-weight: 600;
}

/* 文本类链接 */
.cw-link {
    color: #1e9fff;
    cursor: pointer;
}

.cw-link:hover {
    text-decoration: underline;
}

/* 证件号码等需要等宽显示的内容 */
.cw-mono {
    font-family: Consolas, Menlo, "Courier New", monospace;
    letter-spacing: .4px;
}

/* 表单提示与必填星号 */
.cw-form-tip {
    font-size: 12px;
    color: #93a2b3;
    line-height: 22px;
    margin-top: 2px;
}

/* 表单中的实际取值展示（如身份标记），保持深色可读 */
.cw-form-flag {
    font-size: 13px;
    color: #333;
    line-height: 22px;
    margin-top: 2px;
}

/* 详情（禁用）态表单控件：文字保持深色可读，仅占位符保持浅灰 */
.layui-form .layui-input[disabled],
.layui-form .layui-textarea[disabled],
.layui-form select[disabled],
.layui-form .layui-input-disabled,
.layui-form .layui-textarea-disabled,
.layui-form .layui-disabled.layui-input,
.layui-form .layui-disabled.layui-textarea,
.layui-form-select .layui-input.layui-disabled,
.layui-form .layui-form-checkbox.layui-disabled div,
.layui-form .layui-form-radio.layui-disabled div,
.layui-form .layui-form-switch.layui-disabled em {
    color: #333 !important;
    -webkit-text-fill-color: #333;
    opacity: 1;
}

.layui-form .layui-input[disabled]::placeholder,
.layui-form .layui-textarea[disabled]::placeholder {
    -webkit-text-fill-color: #b8c2cc;
    color: #b8c2cc;
}

.cw-req {
    color: #f5544f;
    margin-right: 2px;
}

/* 详情视图：键值对照表 */
.cw-kv {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

.cw-kv th,
.cw-kv td {
    border: 1px solid #e6ecf3;
    padding: 8px 12px;
    text-align: left;
    line-height: 1.7;
}

.cw-kv th {
    width: 112px;
    background: #f7fafd;
    color: #55677a;
    font-weight: 500;
    white-space: nowrap;
}

/* 表格内的操作链接 */
.cw-op a {
    color: #1e9fff;
    /* v28.12：8px → 10px。
       业主 2026-09-17 反映「操作按钮挨太近容易点错」。网页端表格里
       这些链接本身字号小、又都是纯文字，8px 的缝在触摸屏（一体机、
       平板）上确实容易连击到旁边那个。加到 10px 与手机端卡片的
       圆形按钮间距口径一致（见 RosterListScreen 的「卡片按钮间距」）。
       桌面端鼠标点击本来不会点错，多这 2px 只是让整列更透气。 */
    margin-right: 10px;
    cursor: pointer;
}

.cw-op a:hover { text-decoration: underline; }

.cw-op a.cw-op-danger { color: #f5544f; }

/* 操作链接的语义配色：启用、停用与不可操作 */
.cw-op a.cw-op-warn { color: #ff9800; }
.cw-op a.cw-op-ok { color: #16baaa; }

.cw-op span.cw-op-disabled {
    color: #c3ccd6;
    /* 同上：与可点链接的间距保持同一口径，免得同一列里两种缝 */
    margin-right: 10px;
    cursor: not-allowed;
}

/* ---------- 六、状态标签 ---------- */
.cw-tag {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 10px;
    font-size: 12px;
    line-height: 18px;
    white-space: nowrap;
}

.cw-tag-blue   { color: #1672d0; background: #e5f2ff; }
.cw-tag-green  { color: #128a5a; background: #e2f8ee; }
.cw-tag-orange { color: #b8720d; background: #fff2dd; }
.cw-tag-red    { color: #cf3f3a; background: #ffe8e7; }
.cw-tag-purple { color: #6142cc; background: #efeaff; }
.cw-tag-gray   { color: #6d7d8e; background: #eef1f5; }

/* ---------- 七、空状态 ---------- */
.cw-empty {
    text-align: center;
    padding: 60px 20px;
    color: #9aa8b8;
}

.cw-empty i {
    font-size: 44px;
    color: #cfd9e4;
    display: block;
    margin-bottom: 12px;
}

/* ---------- 八、登录与安装页 ---------- */
.cw-auth-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #1b3a63 0%, #26558f 45%, #1e9fff 130%);
    padding: 24px;
    box-sizing: border-box;
}

.cw-auth-box {
    width: 100%;
    max-width: 400px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 18px 50px rgba(10, 28, 52, .32);
    padding: 30px 32px 26px;
}

.cw-auth-logo {
    text-align: center;
    margin-bottom: 22px;
}

.cw-auth-logo .cw-auth-icon {
    width: 56px;
    height: 56px;
    border-radius: 14px;
    background: linear-gradient(135deg, #4aa8ff, #1e9fff);
    color: #fff;
    font-size: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 10px;
}

.cw-auth-logo h2 {
    font-size: 18px;
    font-weight: 600;
    color: #1b2b3a;
    margin: 0;
}

.cw-auth-logo p {
    font-size: 12.5px;
    color: #93a2b3;
    margin: 6px 0 0;
}

.cw-auth-tip {
    text-align: center;
    font-size: 12.5px;
    color: #93a2b3;
    margin-top: 16px;
    line-height: 1.8;
}

/* ---------- 八之二、登录页的错误提示区（分条列出，便于逐项看清） ----------
   v28.19 新增。原先登录失败只有一条 layer 气泡，2 秒消失，内容一长就看不完
   （「分站已到期」那条尤其要把联系人与电话逐项读清）。
   所以改成登录框**内部**一个常驻区块：一行一条、带图标、不自动消失。

   ⚠ 这里刻意**不用** flex 做「图标 + 文字」两栏：图标若作为 flex item，
   文字换行时第二行会缩进到图标右侧，长句子看起来像被截断。
   用绝对定位把图标摘出文档流，文字就自然占满整行。 */
.cw-auth-alert {
    display: none;                 /* 默认隐藏，有内容时由 JS 打开 */
    margin: 0 0 14px;
    padding: 11px 14px 11px 36px;
    position: relative;
    background: #fef3f2;
    border: 1px solid #fbd5d1;
    border-radius: 8px;
    font-size: 12.5px;
    line-height: 1.75;
    color: #a32d2d;
    text-align: left;
}
.cw-auth-alert.cw-on { display: block; }
.cw-auth-alert > i {
    position: absolute;
    left: 13px;
    top: 11px;
    font-size: 14px;
    color: #e24b4a;
}
/* 换行用 <br> 而不是块级子元素：layer 提示里本来就带 <br>，
   两种写法都能正确换行，但 <br> 更接近原文，不用再加工。 */

/* ---------- 八之三、登录页两栏布局（v28.34 改版） ----------
   业主 2026-09-17 定稿：电脑端左边是下载、登录框在另一边，右边是说明；
                        手机端上面是登录框，中间是下载，最下面是说明。
   业主 2026-09-29 改版：
     「【首次打开 App 这样填】的说明放在客户端下载的下面，
       然后去除右侧的卡片。重新设计一个布局。」

   ⇒ 电脑端 = **两栏**「下载 + 说明 | 登录」；手机端 = **竖排** 登录 → 下载 + 说明。

   ★★★ 为什么要拆掉「三栏 + 强制等高」（实测数据，不是感觉）：
     改版前三栏靠 `align-items: stretch` 拉成等高。1440 宽下三栏都是 **757px**，
     而各自内容只到 769（下载，满）／484（登录）／459（说明）
     → 登录卡空 **303px**、说明卡空 **328px** 的白，整页 863px，在 900 高的屏上
     还得滚动才看得到页脚。
     根因不是「等高」本身，是**上一轮加的「Windows 桌面端」下载块把左栏
     顶高了约 250px**（426 → 757），强制等高就把另外两栏一起拉长了。
     ⇒ 说明搬进左栏缩短不了多少，索性**不再强制等高**：
       各卡按自己的内容收高度。代价是两条底边不齐 ——
       但「底边差一截」只是缺一点对齐感，「被拉高 300px 的死白」是实打实的难看。

   上下顺序由 **DOM 顺序** 直接写死（登录框在前、下载+说明其次、页脚最后），
   手机端不动 DOM 就是对的；电脑端用 `order` 把「下载+说明」提到左边。
   ⚠ 不要反过来「DOM 按电脑端排、手机端靠 order 调」—— 那样手机端的
     阅读顺序（也是屏幕阅读器顺序）会和视觉顺序对不上。

   ⚠ 外层 `align-items: center` 会把两个子块**各自居中**而不是顶端对齐
     （flex 的 align-items 作用于交叉轴 = 纵向）→ 两栏会变成中间凸出的阶梯。
     所以这里显式 `align-items: flex-start` + `align-content: center`
     （align-content 只在 `flex-wrap: wrap` 时生效，所以必须加 wrap）。

   ★★★ 两栏宽度按**实际占位**给，别按「内容想多宽」给 —— 而且要注意
     这两块的 `box-sizing` **不一样**（实测出来的，别照直觉推）：
       · `.cw-auth-site` 自己写了 `box-sizing: border-box`
         → `flex-basis` 就是**含 padding 的总宽**，610 就是 610；
       · `.cw-auth-box` 没写，走默认的 content-box
         → `flex-basis: 328` 还要再加左右 padding 32×2 = **392**。
     所以两栏合计 = 610 + 392 + 间距 26 = **1028**，
     加外层 padding 20×2 = 40 → **1068**，于是「两栏」的下限取 **1080**
     （见下方媒体查询，留 12px 余量，免得「差几个像素就掉行」）。
     ⚠ 调任何一栏的 padding 或 basis，都必须回头重算这个和 ——
       这两块口径不同，是这套布局里最容易算错的一处。

   ★★★ 垂直方向有**两行**（两栏 + 页脚），所以不能靠 `align-content` 摆：
     `align-content` 只在**多行**时有意义，且它分配的是「行与行之间」的空隙。
     这里要的是「**整块内容在视口里居中**」，正解是
     `justify-content: center`（主轴=横向居中）+ 纵向用 `align-content: center`
     配合 `min-height: 100vh`，**页脚必须能换行**（见下方 `nowrap` 的取舍）。
     ⚠ 一旦外层写成 `flex-wrap: nowrap`，页脚就被压在**同一行**里
       （实测页脚 y=32 与栏位 y=30 齐平，等于叠在上面）→
       **纵排必须允许换行**，所以这里选 `wrap` + 显式宽度，不选 `nowrap`。 */
.cw-auth-page {
    /* 两栏横排；`flex-wrap: wrap` 是「页脚独占一行」的前提，不能去掉 */
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;      /* 两栏顶对齐（不是各自居中） */
    align-content: center;        /* 两行整体在视口里纵向居中 */
    justify-content: center;
    gap: 26px;
    padding: 30px 20px 26px;
    min-height: 100vh;
    overflow-y: auto;
    box-sizing: border-box;
}

/* 右栏 = 登录卡片。两块里它最该是视觉焦点：抬高一点、阴影重一点。
   ⚠ 它比左栏矮一截（内容多寡不同）。**不要**为了「底边齐」去 stretch 它 ——
     那正是 v28.34 改版要修掉的那块死白，见本节开头的实测数据。
   ⚠ 这块**没写** `box-sizing`，走默认的 content-box → `flex-basis: 328`
     是**内容宽**，占位还要加左右 padding 32×2 = **392**。
     左栏（.cw-auth-site）写了 border-box，口径相反 —— 见本节开头的警告。 */
.cw-auth-box {
    order: 2;                      /* 两块都是 0 时不生效，所以两块都要显式写 */
    flex: 0 0 328px;
    margin: 0;
}

/* 左栏 = 客户端下载 + 使用说明（一张白卡，内部是 2×2 网格）
   ------------------------------------------------------------
   ★★★ v28.34 为什么里面还要再分两列：
     单列排下来实测 **968px** —— 而右栏登录卡只有 480px。
     左栏独自把整页顶到 1073px（比改版前的 863 还高），
     在 1440×900 上照样要滚动，而且右栏旁边是一大片空白。
     拆成 2×2 之后左栏降到约 480，与登录卡基本齐平，整页 ~590px，不用滚。

       上排  [Windows 桌面端] [手机 App]
       下排  [这样填]         [手机端能做什么]

   ⚠ 每格 (640-40-20)/2 = **290px** —— 这个数不能再小：
     · 「管理员操作说明」那条按钮要 134px，而右侧文字列 = 290 - 120(二维码) - 16
       = 154px，正好够；格子掉到 275 时右列只剩 147，就开始折行；
     · 「能做什么」那一格掉到 275 时，每条都会从 1 行涨到 2 行
       （209px → 289px），左栏跟着长高 80px。
   ⚠ 这里**故意不写 `align-items`**（用默认的 stretch），让同一排的两格等高。
     早先写过 `align-items: start`，理由是「不让矮格被拉高、免得下面多出空白」——
     那个理由是错的：格子既没有底色也没有边框，被拉高只是盒子变大，
     **内容一个像素都不会动**（块级内容一律从盒子顶部往下排）。
     而 stretch 换来的好处很实在：上排两格等高之后，格内用 margin-top:auto
     压到底部的「文件信息块」才能左右对齐（见 .cw-auth-file 那条）。
   ⚠ `flex` 的第二个值是 **1**（可压缩）而不是 0：1080～1157 这一档
     两栏放不下完整 640，让它各让一点就都能站住，不必整块掉到单列。 */
.cw-auth-site {
    order: 1;
    flex: 0 1 640px;
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 18px 50px rgba(10, 28, 52, .32);
    padding: 20px 20px 18px;
    box-sizing: border-box;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 20px;
}

/* 上排两格改成竖排（v28.34 续）：格子被 grid 拉成等高之后，
   格内靠 `margin-top: auto` 把「文件信息块」压到底部 —— 两格的文件信息
   就上下沿都对齐（原先左格 y306、右格 y352，整整差出一个按钮行的高度）。
   DOM 结构现在左右对称：head → (下载区) → 文件信息块。
   左格的「下载区」就是裸的 `.cw-auth-dl-main`（它没有二维码，不必再包
   `.cw-auth-dl`）；右格才是 `.cw-auth-dl`（二维码 + 按钮列）。

   ★★★ v28.34：**两格的按钮个数必须一样**（现在各 2 个）。
     左格 2 个、右格 3 个时，右格比左格高 46px（实测 253 vs 290）；
     两格又被 grid 拉成等高，这 46px 就全变成**左格里**按钮与文件名之间的
     一段空当 —— 也就是说「文件块上下沿对齐」只治了错位，治不了这个洞。
     所以《管理员操作说明》从右格搬到了下排「这样填」那格，
     两格高度差降到 2px，由 `margin-top: auto` 吸掉，看不见。
     ⚠ 以后往任一格加/删按钮，另一格要同步 —— 否则那个洞会自己回来。 */
.cw-auth-desk,
.cw-auth-phone {
    display: flex;
    flex-direction: column;
}

/* ⚠ `.cw-auth-dl-main` 的基础规则是 `flex: 1 1 auto` —— 那是给**横向**的
   `.cw-auth-dl` 用的（右列要撑开）。左格这里是**纵向** flex，`1 1 auto`
   会变成「纵向可伸缩」，把格子剩下的高度全吃掉，于是 `margin-top: auto`
   无处可吸，文件信息块紧贴按钮、贴不到底。所以这里必须按回 `0 0 auto`。
   margin-bottom 9px：`.cw-auth-file` 的 margin-top 已经改成 auto（贴底），
   原来那 9px 的间距得由**上面**这一块让出来。两格都留同样的 9px ——
   v28.34 之后两格的按钮数一样（各 2 个），下载区高度只差 2px（118 vs 120，
   右格被二维码的 120 撑着），这点零头由 auto 吸掉，谁也不会看出洞。 */
.cw-auth-desk > .cw-auth-dl-main,
.cw-auth-phone > .cw-auth-dl {
    flex: 0 0 auto;
    margin-bottom: 9px;
}

/* 下排两格（这样填 / 能做什么）与上排的下载区之间加一条浅虚线。
   两段虚线并排、中间隔一个 20px 列间距，读起来就是一条「换行了」的横线。 */
.cw-auth-guide,
.cw-auth-feat {
    border-top: 1px dashed #e8eef6;
    padding-top: 16px;
}

/* 使用说明（v28.34 从右栏搬进左栏）：不再是独立卡片，只是一段内容。
   ⚠ 底色变了，里面所有字色都要跟着换（原来是深蓝玻璃卡上的浅色字）——
     见下方 .cw-auth-gd-tt / .cw-auth-how / .cw-auth-feat 三节。 */
.cw-auth-guide {
    color: #55637a;
}

/* 说明区标题（v28.34 搬进白卡后改成深色字 —— 原来是深蓝玻璃卡上的白字）
   ⚠ `flex: 0 0 auto` 不能省：`.cw-auth-gd-tt` 是 flex 容器，图标是它的
     flex item。默认 `flex-shrink: 1` 在空间紧张时会把图标盒子压到 0 宽，
     而图标字形是固定的 font-size → **溢出到右边那格文字上**，
     看着就是「图标压在『首』字上」。 */
.cw-auth-gd-tt {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 14.5px;
    font-weight: 600;
    color: #1b2b3a;
    padding-bottom: 12px;
    border-bottom: 1px solid #eef2f7;
    margin-bottom: 4px;
}
.cw-auth-gd-tt i { flex: 0 0 auto; color: #0f9b8e; font-size: 17px; }

/* 头部：图标 + 标题 + 一句说明。同 .cw-card-head 的规矩 —— 按钮/徽标
   一律排在文字之后，靠 margin-left:auto 推到右边（flex 里 float 不生效）。 */
.cw-auth-site-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 15px;
    border-bottom: 1px solid #eef2f7;
    margin-bottom: 16px;
}
.cw-auth-site-head .cw-auth-site-ico {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: #e8f6f4;
    color: #0f9b8e;
    font-size: 19px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.cw-auth-site-head .cw-auth-site-tt {
    flex: 1 1 auto;
    min-width: 0;
}
.cw-auth-site-head .cw-auth-site-tt b {
    display: block;
    font-size: 14.5px;
    font-weight: 600;
    color: #1b2b3a;
}
.cw-auth-site-head .cw-auth-site-tt span {
    display: block;
    font-size: 12px;
    color: #93a2b3;
    margin-top: 2px;
}

/* 一、下载区。
   ★ v28.34：左栏从 264 加宽到 420（内容 380），二维码与按钮改成**横排**。
     竖排时「二维码 150 + 版本 + 两个按钮 + 文件名」要 374px 高，
     而左栏正是把三栏一起撑到 757、逼出那两块死白的元凶；
     横排之后这一块降到约 210px。
   DOM 顺序保持「二维码 → 版本/按钮」，与视觉顺序一致，不必借 order 调整。 */
.cw-auth-dl {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 16px;
}
/* 二维码 120px（外框，画布 108px）：约 29 个模块 → 每模块 ~3.7px，
   手机凑近仍扫得清。**不能更大** —— 它每宽 1px，右侧按钮列就窄 1px，
   到 132px 时「管理员操作说明」就会被折成两行。 */
.cw-auth-qr {
    flex: 0 0 auto;
    width: 120px;
    height: 120px;
    border: 1px solid #e6ebf2;
    border-radius: 10px;
    box-sizing: border-box;
    padding: 6px;
    background: #fff;
    box-shadow: 0 2px 10px rgba(10, 28, 52, .06);
}
.cw-auth-qr canvas,
.cw-auth-qr img {
    display: block;
    width: 100%;
    height: 100%;
}
/* 二维码画不出来（极老浏览器）时退回一段文字，不能让白框空着 */
.cw-auth-qr .cw-auth-qr-fb {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    font-size: 11.5px;
    color: #a3aeba;
    text-align: center;
    line-height: 1.5;
}

/* ⚠ `width` 必须是 auto 而不是 100%：横排时右列要靠 flex 撑开，
   写 100% 会把二维码挤扁（宽度会算成「整行 100%」再去分配）。
   `text-align: left` —— 原来是竖排居中的，横排之后要与上方的头部左对齐。 */
.cw-auth-dl-main {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    text-align: center;
}
.cw-auth-ver {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: #eaf1fe;
    color: #2a6fe0;
    border-radius: 20px;
    padding: 3px 11px;
    font-size: 12px;
    margin-bottom: 10px;
}
.cw-auth-btns {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}
/* 默认「各占一行」：手机 App 那两个按钮落在扫码右侧只有 ~232px 的窄列里，
   并排会把「管理员操作说明」挤成两行。
   桌面端块是例外 —— 它有整块 380px 宽，两个按钮并排（见上方 .cw-auth-desk 那条）。 */
.cw-auth-btns .cw-dl {
    flex: 1 1 100%;
    height: 40px;
    line-height: 40px;
    padding: 0 18px;
    border-radius: 8px;
    background: linear-gradient(135deg, #4aa8ff, #1e9fff);
    color: #fff !important;
    font-size: 14px;
    text-align: center;
    text-decoration: none;
    box-sizing: border-box;
    transition: box-shadow .2s, transform .2s;
}
.cw-auth-btns .cw-dl:hover {
    box-shadow: 0 6px 16px rgba(30, 159, 255, .34);
    transform: translateY(-1px);
}
.cw-auth-btns .cw-dl i { margin-right: 5px; }
.cw-auth-btns .cw-alt i { margin-right: 5px; }
.cw-auth-btns .cw-alt {
    flex: 1 1 100%;
    height: 38px;
    line-height: 36px;
    /* 12px 而不是 15px：桌面端块里这颗按钮要跟「下载桌面端」并排，
       而「Win7 电脑先装运行库」是全页最长的一条按钮文案（约 163px）。 */
    padding: 0 12px;
    border: 1px solid #d8e0e9;
    border-radius: 8px;
    color: #55637a !important;
    font-size: 13px;
    text-align: center;
    text-decoration: none;
    box-sizing: border-box;
    transition: border-color .2s, color .2s;
}
.cw-auth-btns .cw-alt:hover { border-color: #1e9fff; color: #2a6fe0 !important; }
.cw-auth-file {
    font-size: 11px;
    color: #a3aeba;
    /* v28.34 续：不再是固定 9px —— 改成 `auto` 贴到格子底部，
       左右两格的文件信息块就落在同一条基线上。
       ⚠ `auto` 会盖掉原来的 9px，所以按钮与文件信息之间的间距改由
         `.cw-auth-desk > .cw-auth-dl-main` 的 margin-bottom 提供（左格），
         右格则由 `.cw-auth-dl` 自身多出的 9px 提供 —— 两边都不写死数字。 */
    margin-top: auto;
    /* 钉一个「三行高」= 11px × 1.7 × 3 ≈ 56px。
       左格是三行（文件名·大小 / 系统要求 / 运行库），右格只有两行；
       不钉住高度的话右格比左格矮 19px，两块的**上沿**仍旧错开 ——
       业主 2026-09-29 截图里圈的就是这一处。
       ⚠ 写死 56px，**不要**改回用 calc 做乘法（如「3 乘 1.7em」那种写法）：
         整条会被内嵌的 IE 内核（桌面端自己就带一个）和部分国产浏览器丢弃，
         一丢这两块立刻又错开，而且不报错 —— 只在某个浏览器上悄悄变形，
         本地怎么测都正常。字号真要改，56 这个数跟着一起改。 */
    min-height: auto;
    line-height: 1.7;
    /* 与 .cw-auth-dl-main 一起改成左对齐（v28.34 从竖排改横排之后） */
    text-align: center;
    /* ⚠ 「cunwei-1.6.6.apk　·　11.4 MB　·　安卓 8.0 及以上」这类长串
       在手机 App 右侧那条 ~232px 的窄列里仍放不下 → 加 `word-break`
       让它**在中间断行**，而不是被容器裁掉
       （默认的 `overflow: hidden` 会把文件名整段吃掉，只剩后半截）。 */
    word-break: break-all;
}

/* 二、填写指引：服务器地址 / 账号 / 密码
   v28.34 随说明区搬进白卡 → 改成浅灰底、深色字（原来是玻璃卡上的浅色字）。 */
.cw-auth-how {
    background: #f5f8fc;
    border: 1px solid #e8eef6;
    border-radius: 8px;
    padding: 13px 15px;
    margin-top: 12px;
    font-size: 12.5px;
    color: #55637a;
    line-height: 1.95;
}
.cw-auth-how b { color: #1b2b3a; }
.cw-auth-how .cw-auth-how-tt {
    display: block;
    font-weight: 600;
    color: #1b2b3a;
    margin-bottom: 5px;
}
/* 服务器地址是业主特意要求写明的，用主题青点出来
   （白底上要压深一档，原来的 #7ee6d2 在白底上几乎看不见） */
.cw-auth-how .cw-host {
    color: #0f9b8e;
    font-weight: 600;
    letter-spacing: .2px;
}

/* 三、功能亮点（v28.34 随说明区搬进白卡 → 深色字）
   上边那条虚线、以及上内边距，由上面「下排两格」那条共用规则给，
   这里不再自己写 border-top —— 两处都写会出现两条线。 */
.cw-auth-feat-tt {
    font-size: 13px;
    font-weight: 600;
    color: #1b2b3a;
    margin-bottom: 10px;
}
/* ------------------------------------------------------------
   ⚠ v28.21 曾从两栏改回**单栏**：当时右栏只有 356 宽，两栏后单列仅 147px，
      六条里有四条被挤成 3 行、两条 2 行，条目高矮交替 —— 业主说的
      「看着有点乱」就是这个。
   ★ v28.34 说明区搬进左栏后，「能做什么」这一格只有 (640-40-20)/2 = **290px**。
      单栏六条 → 约 156px 高，与左边「这样填」那格（约 165px）正好齐。
      仍然**不写死列数**：`auto-fit + minmax(190px, 1fr)` —— 格宽了就自动两栏，
      窄了自动退回单栏，两条规矩合一，不必再维护两套。
      190px 是实测出来的下限：再窄「名册随时查　户籍 / 党员 / 兜底保障 /
      退役军人」这类长条目就要折成三行。
   ------------------------------------------------------------ */
.cw-auth-feat ul {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 9px 16px;
    margin: 0;
    padding: 0;
    list-style: none;
}
/* 每条：小圆点 + 名称 + 一句说明。同样用绝对定位放圆点，避免换行缩进 */
.cw-auth-feat li {
    position: relative;
    padding-left: 15px;
    font-size: 12.5px;
    color: #55637a;
    line-height: 1.6;
}
.cw-auth-feat li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 7px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #1e9fff;
}
.cw-auth-feat li b {
    color: #1b2b3a;
    font-weight: 600;
}

/* ------------------------------------------------------------
   v28.34：原来这里还有「五之一、右栏底部的说明入口」那一节（.cw-auth-more）。
   已删 —— 说明区搬进左栏之后，这行链接与上方「管理员操作说明」按钮
   在同一张卡里重复；按钮是点到手边的，链接是读到一半才碰到的，留按钮就够。
   连带删掉的还有它在 ≤768px 里的那条 `padding` 覆盖。
   ------------------------------------------------------------ */

/* 四、底部版权（三栏下方的整行页脚）
   ⚠ `flex: 1 1 100%` 只有在容器**允许换行**时才真正独占一行；
     外层写成 `flex-wrap: nowrap` 时它会被压在同一行（实测与右栏齐平重叠）。
     → 外层必须保持 `wrap`（见 .cw-auth-page 注释）。 */
.cw-auth-copy {
    order: 4;
    flex: 1 1 100%;              /* 三栏之后的整行 */
    text-align: center;
    font-size: 11.5px;
    color: rgba(255, 255, 255, .66);
    margin-top: 2px;
    line-height: 1.9;
}

/* ============================================================
   单列区间（≤1099px）：排不下两栏，退回竖排
   ------------------------------------------------------------
   顺序 = DOM 顺序：登录 → 下载+说明 → 页脚。
   ⚠ 阈值 1100 是**算出来的**：两栏合计 640 + 392 + 间距 26 = 1058，
     加外层左右内边距 40 = **1098**。
     ⚠ 必须卡在 1098 **以上**：卡在 1079 时，1080～1097 这一档两栏其实
       放不下，会退化成「左栏独占第一行、登录卡换到第二行」——
       顺序变成「下载在上、登录在下」，与手机端的「登录在上」相反，
       同一台电脑拉窄一点窗口就变个样，看着像坏了。
       左栏虽可压缩（`flex: 0 1 640px`），但那只在 1100～1157 之间让几像素，
       不该指望它兜住 20px 的缺口。
     ⚠ 见 `.cw-auth-site` 上方的说明 —— 两块的 box-sizing 不一样，别算错。
   ⚠ 不要写 `flex-wrap: nowrap`：页脚 `.cw-auth-copy` 靠
     `flex: 1 1 100%` 独占一行，锁 nowrap 它会被压进同一行
     （实测与栏位齐平叠住）。
   ⚠ 两块都要 `width:100%` **和** `max-width` 一起给 ——
     `.cw-auth-box` 的基础规则带 `max-width: 400px`，它**压在 width 之上**；
     只管 width 会让两块宽度口径不一致，真机上表现为「右侧露出背景色」。
   ⚠ `align-items: center` 只在单列下用：配合上面的 max-width 把两块居中。
     两栏区间用的是 flex-start（见 .cw-auth-page 基础规则）。
   ============================================================ */
@media screen and (max-width: 1099px) {
    .cw-auth-page {
        flex-direction: column;
        align-items: center;
        gap: 14px;
        padding: 18px 14px 24px;
        /* 兜底：万一某块内还有超宽内容，不要撑出横向滚动条
           （真机上表现为「页面能左右晃」） */
        overflow-x: hidden;
    }

    .cw-auth-box,
    .cw-auth-site {
        flex: 0 0 auto;
        width: 100%;
        max-width: 520px;
        min-width: 0;
        box-sizing: border-box;
    }

    /* ★ 顺序：登录(1) → 下载+说明(2) → 页脚(3)，与 DOM 顺序一致。
       ⚠ 这里**必须**覆盖基础规则的 order（基础规则是「下载 1 / 登录 2」，
         那是横排用的）—— 不覆盖的话竖排会变成「下载在上、登录在下」。 */
    .cw-auth-box  { order: 1; }
    .cw-auth-site { order: 2; }
    /* 竖排时页脚是普通的最后一行，`flex: 1 1 100%` 在列方向上
       basis 会按**高度**解析，必须收回 */
    .cw-auth-copy { order: 3; flex: 0 0 auto; }

    /* ★ 左栏内部那张 2×2 网格也要收成一列：
       单列区间里左栏最多 520px，再分两列每格只剩 240px，
       「服务器地址：qigei.cn（不加 http:// 和斜杠）」会被折成三行。 */
    .cw-auth-site { grid-template-columns: 1fr; }
}

/* ============================================================
   手机端（≤768px）：在单列基础上再收紧一档
   ------------------------------------------------------------
   ★ v28.34：下载区在电脑端是「二维码 + 右列」**横排**，手机上必须改回竖排 ——
     320px 宽的机器上，卡片内容只有 ~256px，减掉 132px 二维码只剩 124px，
     而「管理员操作说明」这条按钮本身就要 141px → 会被折成两行。
   ⚠ 竖排之后 `.cw-auth-dl-main` 要跟着改回居中（基础规则是左对齐），
     否则二维码居中、按钮却顶着左边缘，看着是错位的。
   ============================================================ */
@media screen and (max-width: 768px) {
    .cw-auth-page { gap: 12px; padding: 14px 12px 22px; }

    /* 两块左右内边距统一 16px —— 卡片里的文字才对得齐 */
    .cw-auth-box  { padding: 22px 16px 18px; }
    .cw-auth-site { padding: 16px 16px 14px; }

    /* 二维码居中、按钮整行（见上方注释） */
    .cw-auth-dl { flex-direction: column; align-items: center; gap: 12px; }
    .cw-auth-dl-main { width: 100%; text-align: center; }
    .cw-auth-file { text-align: center; }

    /* 二维码：手机上整行宽度够用，放大到 150px 更好扫 */
    .cw-auth-qr { width: 150px; height: 150px; }

    /* 下载/说明按钮**各占一行** —— 并排时会被压到换行，
       看起来像按钮宽度不一致 */
    .cw-auth-btns .cw-dl,
    .cw-auth-btns .cw-alt { flex: 1 1 100%; min-width: 0; }

    /* 功能介绍：手机上**每行一条**（业主 2026-09-17 要求）。
       基础规则是 `auto-fit + minmax(190px, 1fr)`，窄屏本来就会退成一栏，
       这里显式钉住，免得日后有人把基础规则改成写死两栏、手机端又跟着乱。
       ⚠ 别删这条：它现在是「手机端必须单列」这条要求的唯一落点。 */
    .cw-auth-feat ul { grid-template-columns: 1fr; gap: 9px; }

    /* 说明区在窄屏收紧内边距，别让「账号 / 密码」这类短句被挤断 */
    .cw-auth-how { padding: 12px 13px; }

    /* 下载区信息行（文件名 · 大小 · 安卓版本）手机上允许换行 */
    .cw-auth-file { word-break: break-word; }
}

/* 安装向导步骤条 */
.cw-step {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    margin-bottom: 26px;
}

.cw-step-item {
    display: flex;
    align-items: center;
    color: #9aa8b8;
    font-size: 13px;
}

.cw-step-item .cw-step-num {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #e8eef6;
    color: #8a99a8;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    margin-right: 7px;
}

.cw-step-item.cw-step-on { color: #1e9fff; font-weight: 600; }

.cw-step-item.cw-step-on .cw-step-num {
    background: #1e9fff;
    color: #fff;
}

.cw-step-item.cw-step-done .cw-step-num {
    background: #16b777;
    color: #fff;
}

.cw-step-line {
    width: 46px;
    height: 1px;
    background: #dde5ee;
    margin: 0 10px;
}

/* ---------- 九、模板预览与 A4 打印 ---------- */
/* 预览区：灰色底衬托纸张 */
.cw-paper-wrap {
    background: #e9edf3;
    padding: 22px 12px;
    border-radius: 6px;
    overflow-x: auto;
}

/* A4 纸张：210mm × 297mm，按 96dpi 折算约 794px × 1123px */
.cw-paper {
    width: 794px;
    min-height: 1123px;
    margin: 0 auto;
    background: #fff;
    box-shadow: 0 4px 18px rgba(24, 46, 74, .18);
    padding: 96px 84px;
    box-sizing: border-box;
    font-family: "宋体", SimSun, serif;
    font-size: 16px;
    line-height: 1.9;
    color: #000;
    position: relative;
}

.cw-paper .cw-paper-title {
    font-family: "黑体", SimHei, sans-serif;
    font-size: 26px;
    font-weight: 700;
    text-align: center;
    letter-spacing: 4px;
    margin-bottom: 34px;
    line-height: 1.6;
}

.cw-paper .cw-paper-body {
    text-align: justify;
    text-indent: 2em;
}

.cw-paper .cw-paper-body p {
    margin: 0 0 12px;
    text-indent: 2em;
}

/* 落款：右对齐 */
.cw-paper .cw-paper-sign {
    margin-top: 56px;
    text-align: right;
    line-height: 2.1;
    padding-right: 12px;
}

/* 表格类模板 */
.cw-paper table.cw-paper-table {
    width: 100%;
    border-collapse: collapse;
    margin: 16px 0;
    font-size: 15px;
}

.cw-paper table.cw-paper-table th,
.cw-paper table.cw-paper-table td {
    border: 1px solid #000;
    padding: 7px 10px;
    line-height: 1.7;
}

.cw-paper table.cw-paper-table th {
    background: #f5f5f5;
    font-weight: 700;
    text-align: center;
}

/* 占位符高亮：仅在预览态显示，打印时自动隐藏 */
.cw-ph {
    background: #fff6d8;
    border-bottom: 1px dashed #e0b34a;
    padding: 0 2px;
    border-radius: 2px;
}

/* 模板编辑器里的占位符标签 */
.cw-ph-chip {
    display: inline-block;
    padding: 2px 9px;
    margin: 0 5px 6px 0;
    border-radius: 11px;
    font-size: 12.5px;
    background: #eef4fc;
    color: #1672d0;
    border: 1px solid #d6e6fa;
    cursor: pointer;
    transition: all .15s;
}

.cw-ph-chip:hover {
    background: #1e9fff;
    color: #fff;
    border-color: #1e9fff;
}

/* ---------- 十、打印样式：只输出纸张内容 ---------- */
@page {
    size: A4;
    margin: 12mm 14mm;
}

@media print {
    html, body {
        background: #fff !important;
        height: auto;
    }

    /* 隐藏一切非打印内容 */
    .layui-layout-admin .layui-header,
    .layui-layout-admin .layui-side,
    .layui-body-header,
    .cw-filter,
    .cw-toolbar,
    .cw-card-title,
    .cw-no-print,
    .layui-layer,
    .layui-laypage {
        display: none !important;
    }

    .layui-layout-admin .layui-body {
        left: 0 !important;
        top: 0 !important;
        position: static !important;
    }

    .cw-body { padding: 0 !important; }

    .cw-paper-wrap {
        background: #fff !important;
        padding: 0 !important;
        overflow: visible !important;
    }

    .cw-paper {
        width: auto !important;
        min-height: auto !important;
        margin: 0 !important;
        padding: 0 !important;
        box-shadow: none !important;
    }

    /* 打印时不显示高亮底纹 */
    .cw-ph {
        background: transparent !important;
        border-bottom: none !important;
    }

    /* 避免段落被拆到两页 */
    .cw-paper p,
    .cw-paper .cw-paper-sign {
        page-break-inside: avoid;
    }

    .cw-page-break {
        page-break-after: always;
    }
}

/* ---------- 十一、小屏适配 ---------- */
@media screen and (max-width: 768px) {
    .cw-stat { min-width: 46%; }

    .cw-paper {
        width: 100%;
        min-height: auto;
        padding: 24px 18px;
        font-size: 15px;
    }

    .cw-toolbar .cw-toolbar-right { margin-left: 0; }
}

/* 表单分组标题，用于安装向导与设置类页面的分节 */
.cw-form-title {
    font-size: 14px;
    font-weight: 600;
    color: #1b2b3a;
    padding: 4px 0 10px;
    margin: 6px 0 14px;
    border-bottom: 2px solid #eef3f8;
    position: relative;
}

.cw-form-title::before {
    content: '';
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 42px;
    height: 2px;
    background: #1e9fff;
}

/* ---------- 十二、看板图表与快捷入口 ---------- */

/* 横向条形图，用于展示年龄结构、村组分布等占比数据 */
.cw-bars {
    padding: 4px 2px 0;
}

.cw-bar-row {
    display: flex;
    align-items: center;
    margin-bottom: 11px;
    font-size: 13px;
    color: #55677a;
}

.cw-bar-label {
    width: 84px;
    flex: 0 0 84px;
    text-align: right;
    padding-right: 10px;
    color: #6b7c8f;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cw-bar-track {
    flex: 1 1 auto;
    height: 14px;
    background: #eef3f8;
    border-radius: 8px;
    overflow: hidden;
}

.cw-bar-fill {
    height: 100%;
    min-width: 2px;
    border-radius: 8px;
    background: linear-gradient(90deg, #63b8ff, #1e9fff);
    transition: width .4s ease;
}

.cw-bar-fill.cw-bar-green {
    background: linear-gradient(90deg, #7fd8a6, #16b364);
}

.cw-bar-value {
    width: 62px;
    flex: 0 0 62px;
    text-align: right;
    color: #1b2b3a;
    font-weight: 600;
}

/* 紧凑型明细表，用于看板内的分类数据 */
.cw-mini-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
    color: #45566a;
}

.cw-mini-table th {
    text-align: left;
    font-weight: 600;
    color: #7d8ea1;
    font-size: 12.5px;
    padding: 6px 8px;
    border-bottom: 1px solid #eaf0f6;
    background: #fafcfe;
    white-space: nowrap;
}

.cw-mini-table td {
    padding: 8px;
    border-bottom: 1px dashed #eef3f8;
}

.cw-mini-table tbody tr:last-child td,
.cw-mini-table tr:last-child td {
    border-bottom: none;
}

.cw-mini-table tbody tr:hover,
.cw-mini-table tr:hover {
    background: #f7fbff;
}

.cw-mini-table .cw-num {
    text-align: right;
    font-weight: 600;
    color: #1b2b3a;
    white-space: nowrap;
}

.cw-mini-table .cw-num.cw-warn,
.cw-warn {
    color: #e6820c;
}

/* 常用功能快捷入口 */
.cw-quick {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding: 4px 0 2px;
}

.cw-quick-item {
    flex: 0 0 auto;
    min-width: 104px;
    padding: 14px 10px;
    border: 1px solid #e6ecf3;
    border-radius: 8px;
    background: #fbfdff;
    text-align: center;
    color: #45566a;
    transition: all .2s ease;
}

.cw-quick-item:hover {
    border-color: #a9d4ff;
    background: #f2f9ff;
    color: #1e9fff;
    box-shadow: 0 6px 16px rgba(30, 159, 255, .12);
    transform: translateY(-2px);
}

.cw-quick-item i {
    display: block;
    font-size: 22px;
    margin-bottom: 6px;
    color: #1e9fff;
}

.cw-quick-item span {
    font-size: 13px;
}

/* 保障大类卡片（在快捷入口基础上叠加名称与数量） */
.cw-cat-card {
    min-width: 118px;
    cursor: pointer;
}

/* 模板中心的分类卡改为紧凑胶囊：一行放下 名称+数量，
   不再是竖排图标大卡片，整行高度大幅压缩 */
.cw-cat-card {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    flex: 0 1 auto;
    padding: 7px 14px;
}

.cw-cat-card i {
    font-size: 15px;
    margin: 0;
    display: inline;
}

.cw-cat-card .cw-cat-name {
    display: inline;
    font-size: 13px;
    line-height: 1.4;
}

.cw-cat-card .cw-cat-num {
    display: inline;
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    color: #1e9fff;
}

.cw-cat-card .cw-cat-name {
    display: block;
    font-size: 13px;
    line-height: 1.5;
}

.cw-cat-card .cw-cat-num {
    display: block;
    margin-top: 2px;
    font-size: 17px;
    font-weight: 600;
    color: #1b2b3a;
}

.cw-cat-card.cw-cat-card-on {
    border-color: #1e9fff;
    background: #eaf5ff;
    color: #1e9fff;
    box-shadow: 0 6px 16px rgba(30, 159, 255, .18);
}

.cw-cat-card.cw-cat-card-on .cw-cat-num {
    color: #1e9fff;
}

/* 统计明细块（分类统计页使用） */
.cw-panel {
    border: 1px solid #e6ecf3;
    border-radius: 8px;
    padding: 14px 16px 6px;
    background: #fbfdff;
}

/* 同一行的统计面板等高对齐：
   行改 flex，列改纵向 flex 并让面板拉伸填满，矮卡不再顶在上/中间 */
.cw-eq-row {
    display: flex;
    flex-wrap: wrap;
}

.cw-eq-row > [class*="layui-col-"] {
    display: flex;
    flex-direction: column;
}

.cw-eq-row > [class*="layui-col-"] > .cw-panel {
    flex: 1 1 auto;
}

.cw-panel-title {
    font-size: 14px;
    font-weight: 600;
    color: #1b2b3a;
    margin-bottom: 12px;
}

.cw-panel-title i {
    color: #1e9fff;
    margin-right: 5px;
}

.cw-kpi {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.cw-kpi-item {
    flex: 1 1 150px;
    border: 1px solid #e6ecf3;
    border-radius: 8px;
    padding: 12px 14px;
    background: #fff;
}

.cw-kpi-item .cw-kpi-name {
    font-size: 12.5px;
    color: #7e8fa2;
}

.cw-kpi-item .cw-kpi-value {
    margin-top: 4px;
    font-size: 20px;
    font-weight: 600;
    color: #1b2b3a;
}

.cw-kpi-item .cw-kpi-value small {
    font-size: 12px;
    font-weight: 400;
    color: #8a97a5;
    margin-left: 3px;
}

@media screen and (max-width: 768px) {
    .cw-quick-item { min-width: 30%; }
    .cw-bar-label { width: 68px; flex-basis: 68px; }
}

/* ---------- 十三、通用小工具类 ---------- */
/* 弱化的占位文字（表格中的破折号等） */
.cw-muted {
    color: #c2ccd8;
}

/* 卡片标题右侧的跳转入口 */
.cw-card-more {
    margin-left: auto;
    font-size: 12.5px;
    color: #1672d0;
    white-space: nowrap;
}

.cw-card-more:hover {
    color: #0f5aa8;
}

/* 卡片头部需要左右分列时使用 */
.cw-card-head .cw-card-more {
    order: 9;
}

/* 进度条与图例之间的间距 */
.cw-bar-wrap {
    margin-top: 6px;
}

/* 弹层内表单的两列说明文字 */
.cw-form-note {
    color: #8a97a5;
    font-size: 12px;
    line-height: 20px;
    padding: 2px 0 0;
}

/* ---------- 十四、打印模板与套打样式 ---------- */

/* 模板列表中的正文摘要 */
.cw-brief {
    color: #5b6b7c;
    font-size: 12.5px;
    line-height: 20px;
}

/* 内置模板导入提示卡片 */
.cw-import-tip {
    border-left: 3px solid #1672d0;
    background: #f6faff;
}

.cw-import-tip .cw-card-head {
    align-items: center;
}

/* 模板正文预览弹层 */
.cw-preview-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding-bottom: 10px;
    border-bottom: 1px dashed #e4eaf1;
    font-size: 12.5px;
}

.cw-preview-fields {
    padding: 12px 0;
    font-size: 13px;
    color: #4a5a6a;
    line-height: 26px;
}

.cw-preview-body {
    max-height: 380px;
    overflow: auto;
    margin: 0;
    padding: 16px 18px;
    border: 1px solid #e4eaf1;
    border-radius: 4px;
    background: #fafcfe;
    color: #1b2b3a;
    font-family: "宋体", "SimSun", "Microsoft YaHei", serif;
    font-size: 15px;
    line-height: 32px;
    white-space: pre-wrap;
    word-break: break-word;
}

/* 套打页面：工具条 + 纸张 */
.cw-print-toolbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    background: #fff;
    border-bottom: 1px solid #e4eaf1;
    box-shadow: 0 1px 4px rgba(27, 43, 58, 0.06);
}

.cw-print-toolbar .cw-toolbar-title {
    font-size: 14px;
    font-weight: 600;
    color: #1b2b3a;
    margin-right: 6px;
}

.cw-print-toolbar .cw-toolbar-gap {
    flex: 1;
}

.cw-print-paper {
    width: 210mm;
    min-height: 297mm;
    margin: 22px auto 60px;
    padding: 26mm 22mm 24mm;
    background: #fff;
    box-shadow: 0 2px 14px rgba(27, 43, 58, 0.12);
    box-sizing: border-box;
}

.cw-print-title {
    margin: 0 0 26px;
    text-align: center;
    font-family: "宋体", "SimSun", serif;
    font-size: 24px;
    font-weight: bold;
    letter-spacing: 4px;
    color: #000;
    line-height: 1.6;
}

.cw-print-body {
    font-family: "宋体", "SimSun", serif;
    font-size: 16px;
    line-height: 32px;
    color: #000;
    text-align: justify;
    white-space: normal;
    word-break: break-word;
}

/* 正文段落：由 TemplateRepo::toParagraphs() 逐行拆成 <p class="cw-para">。
   段落缩进为手工控制——行首空格用 pre-wrap 原样呈现，不再自动缩进两字，
   这样「顶格写的行」与「缩进两格的行」可以各自按需排版 */
.cw-print-body .cw-para {
    margin: 0;
    text-indent: 0;
    white-space: pre-wrap;
}

/* 原文中的空白行：保留一行高度维持段间距，但不做缩进 */
.cw-print-body .cw-para-empty {
    text-indent: 0;
}

/* 留空手写的落款日期「　年　月　日」：不加下划线，全角空格原样保留 */
.cw-print-body .cw-date-blank {
    border-bottom: none;
}

/* 落款区：右对齐。
   这里的字号与上间距只是兜底，套打页会用模板自己的设置以内联样式覆盖
   （落款字号 sign_font_size、落款与正文间距 sign_gap_lines） */
.cw-print-sign {
    margin-top: 46px;
    text-align: right;
    font-family: "宋体", "SimSun", serif;
    font-size: 16px;
    line-height: 34px;
    color: #000;
}

/* 套打页左侧字段面板 */
.cw-print-side {
    max-width: 1180px;
    margin: 18px auto 0;
    padding: 0 18px;
}

.cw-print-panel {
    background: #fff;
    border: 1px solid #e4eaf1;
    border-radius: 4px;
    padding: 16px 18px 6px;
}

.cw-print-panel .cw-panel-title {
    margin-bottom: 12px;
    font-size: 14px;
    font-weight: 600;
    color: #1b2b3a;
}

.cw-field-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 14px;
}

.cw-field-grid .cw-field-item {
    display: flex;
    align-items: center;
    width: calc(33.33% - 10px);
    min-width: 250px;
}

.cw-field-grid .cw-field-item label {
    width: 96px;
    flex: 0 0 96px;
    font-size: 12.5px;
    color: #5b6b7c;
    text-align: right;
    padding-right: 8px;
}

.cw-field-grid .cw-field-item input {
    flex: 1;
    height: 34px;
    padding: 0 10px;
    border: 1px solid #dde5ee;
    border-radius: 3px;
    font-size: 13px;
    color: #1b2b3a;
    outline: none;
}

.cw-field-grid .cw-field-item input:focus {
    border-color: #1672d0;
}

/* 打印时只保留纸张内容 */
@media print {
    .cw-print-toolbar,
    .cw-print-side,
    .cw-no-print {
        display: none !important;
    }

    body {
        background: #fff !important;
    }

    .cw-print-paper {
        width: auto;
        min-height: 0;
        margin: 0;
        padding: 0;
        box-shadow: none;
    }

    @page {
        size: A4;
        margin: 26mm 22mm;
    }
}

/* ============================================================
 *  数据表格单元格统一居中
 *  所有列表页（layui table）的表头与数据单元格一律水平居中，
 *  覆盖列定义里的 align: left/right，保证各栏目风格统一。
 *  注意：layui 把 align 属性写在 .layui-table-cell 内层 div 上，
 *  只写 th/td 会被属性样式压过，必须连内层 div 一起覆盖。
 * ========================================================== */
.layui-table-view th,
.layui-table-view td,
.layui-table th,
.layui-table td,
.layui-table-view .layui-table-cell,
.layui-table .layui-table-cell {
    text-align: center !important;
}

/* 列表密度：压低行高与内边距，一屏多显示几行数据 */
.layui-table-view .layui-table-cell {
    height: 32px;
    line-height: 22px;
    padding: 4px 10px;
}
.layui-table-view .layui-table[lay-size="lg"] .layui-table-cell { height: 40px; line-height: 30px; }
.layui-table-view .layui-table[lay-size="sm"] .layui-table-cell { height: 28px; line-height: 18px; }
.layui-table-page { padding: 4px 8px !important; }

/* ---------- 顶栏右侧用户名下拉箭头：垂直居中、右侧留距，
   电脑/移动端通用（layui 默认 top:0 会与姓名叠画） ---------- */
.layui-header .layui-layout-right .layui-nav-item > a {
    padding-right: 22px !important;
    white-space: nowrap;
}
.layui-header .layui-layout-right .layui-nav-more {
    top: 50% !important;
    margin: 0 !important;
    transform: translateY(-50%);
    right: 4px !important;
}
.layui-header .layui-layout-right .layui-nav-more.layui-nav-mored,
.layui-header .layui-layout-right .layui-nav-itemed > a .layui-nav-more {
    transform: translateY(-50%) rotate(180deg);
}

/* ============================================================
 *  十五、移动端 / 平板适配
 *  断点：≤768px 手机；769–1024px 平板微调。
 *  布局骨架：侧边栏在手机上变抽屉（配合 layout.php 的
 *  cw-side-open 类与 .cw-side-mask 遮罩使用）。
 * ========================================================== */
.cw-side-mask {
    display: none;
}

@media screen and (max-width: 768px) {
    /* ---------- 布局骨架 ---------- */
    .layui-layout-admin .layui-header .layui-logo {
        width: auto !important;
        max-width: 46vw;
        font-size: 13.5px !important;
        padding: 0 8px !important;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* 顶栏右侧用户名旁的角色文字收起，只留图标+姓名 */
    .layui-layout-right a > span { display: none !important; }

    .layui-layout-admin .layui-side {
        position: fixed !important;
        left: 0 !important;
        top: 60px !important;
        bottom: 0 !important;
        width: var(--cw-side-w, 246px) !important;
        z-index: 1200;
        transform: translateX(-105%);
        transition: transform .22s ease;
    }

    .layui-layout-admin.cw-side-open .layui-side {
        transform: translateX(0);
        box-shadow: 4px 0 18px rgba(0, 0, 0, .3);
    }

    .layui-layout-admin .layui-body {
        left: 0 !important;
    }

    .cw-side-mask {
        display: none;
        position: fixed;
        left: 0; right: 0; top: 60px; bottom: 0;
        background: rgba(15, 30, 48, .45);
        z-index: 1190;
    }

    .layui-layout-admin.cw-side-open .cw-side-mask { display: block; }

    .cw-body { padding: 10px; }

    /* ---------- 统计卡：两列 ---------- */
    .cw-stat-row { gap: 8px; }
    .cw-stat-row > [class*="layui-col-"] { min-width: 47%; }
    .cw-stat { min-width: 0; padding: 10px 12px; gap: 9px; }
    .cw-stat-icon { width: 34px; height: 34px; border-radius: 7px; font-size: 16px; }
    .cw-stat-value { font-size: 18px; }
    .cw-stat-label { font-size: 12px; }

    /* ---------- 筛选栏：改纵向排列 ---------- */
    .cw-filter { padding: 10px 12px 2px; }
    .cw-filter .layui-form-item { margin-bottom: 2px; }
    .cw-filter .layui-inline {
        display: flex;
        width: 100%;
        margin: 0 0 8px;
    }
    .cw-filter .layui-form-label {
        width: 74px;
        flex: 0 0 74px;
        padding: 9px 4px 9px 0;
        text-align: left;
    }
    .cw-filter .layui-input-inline {
        flex: 1 1 auto;
        width: auto !important;
        margin-left: 0;
    }
    .cw-filter-btns { padding-left: 0; padding-bottom: 8px; }

    /* ---------- 通用表单（整页表单页） ---------- */
    .layui-form-label { padding: 9px 8px 9px 4px; }

    /* ---------- 表格 ---------- */
    .layui-table-view { max-width: 100%; }
    .layui-table-tool-self .layui-inline { padding: 0 8px; }

    /* ---------- 分页横滑 ---------- */
    .layui-laypage {
        max-width: 100%;
        overflow-x: auto;
        padding-bottom: 4px;
    }

    /* ---------- 快捷入口 / 分类卡 ---------- */
    .cw-quick { gap: 8px; }
    .cw-quick-item { min-width: 30%; padding: 10px 4px; }
    .cw-quick-item i { font-size: 18px; margin-bottom: 4px; }
    .cw-cat-card { padding: 7px 12px; }

    /* ---------- 看板明细块 ---------- */
    .cw-kpi-item { flex: 1 1 45%; padding: 10px 12px; }
    .cw-kpi-item .cw-kpi-value { font-size: 17px; }

    /* ---------- 套打与纸张 ---------- */
    .cw-paper-wrap { padding: 10px 2px; }
    .cw-print-paper {
        width: 100%;
        min-height: 0;
        margin: 12px auto 40px;
        padding: 10mm 7mm;
    }
    .cw-print-toolbar { padding: 10px 12px; }
    .cw-field-grid .cw-field-item { width: 100%; min-width: 0; }
    .cw-field-grid .cw-field-item label { width: 84px; flex: 0 0 84px; text-align: left; }

    /* ---------- 弹层内嵌页 ---------- */
    .cw-step { padding: 4px 0 2px; }
    .cw-step .cw-step-item { display: inline-block; margin: 0 4px; }
    .cw-step .cw-step-line { width: 18px; margin: 0 4px; }
}

/* ---------- 平板（769–1024px）微调 ---------- */
@media screen and (min-width: 769px) and (max-width: 1024px) {
    .cw-body { padding: 12px; }
    .cw-stat-row > [class*="layui-col-"] { min-width: 30%; }
    .cw-filter .layui-input-inline { max-width: 220px; }
    .cw-field-grid .cw-field-item { width: calc(50% - 8px); }
}

/* 手机端补充修复（实测反馈）：
   1) 顶栏 flex 排列并用 order 定序：
      菜单按钮 → 当前栏目名（logo 区）→ 首页图标 → 用户区；
   2) 明细类表格（固定列宽的 mini/list/kv 表）在卡片内横向滚动，
      不再撑破页面。 */
@media screen and (max-width: 768px) {
    .layui-header {
        display: flex;
        align-items: center;
    }

    /* 左侧导航容器打散为透明成员，用 order 重排三个元素 */
    .layui-header .layui-layout-left {
        position: static !important;
        left: auto !important;
        padding-left: 0 !important;
        display: contents;
    }
    .layui-header .layui-layout-left > .layui-nav-item {
        order: 1;
        display: inline-flex;
    }
    .layui-header .layui-layout-left > .cw-home-item { order: 3; }

    /* 顶栏快捷入口只在电脑端出现：手机端顶栏已被「菜单按钮 + 栏目名 +
       首页 + 用户区」占满，多出来的入口一律隐藏（侧栏抽屉里全都有）。
       必须带 !important —— 上面那条 .layui-nav-item 的 display:inline-flex
       与本条同权重，靠后生效，加 !important 后不受后续追加规则影响。 */
    .layui-header .layui-layout-left > .cw-top-quick { display: none !important; }

    /* 栏目名（logo 区）排在菜单按钮之后、首页图标之前 */
    .layui-header .layui-logo {
        order: 2;
        flex: 0 1 auto;
        width: auto !important;
    }

    /* 首页只留图标 */
    .layui-header .cw-home-item .cw-home-text { display: none; }

    .layui-header .layui-layout-right {
        position: static !important;
        right: auto !important;
        order: 4;
        flex: 0 0 auto;
        margin-left: auto;
    }

    .cw-mini-table,
    .cw-list-table,
    .cw-kv {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* 手机端：html 层兜底禁止横向滚动（内容已全部自适应，
   该规则只拦截隐藏元素造成的虚拟溢出） */
@media screen and (max-width: 768px) {
    html { overflow-x: hidden; }
}

/* 手机端：layui 栅格间距类的负边距会撑破容器，统一归零，
   间距改由子列自身的小内边距提供 */
@media screen and (max-width: 768px) {
    [class*="layui-col-space"] {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    [class*="layui-col-space"] > [class*="layui-col-"] {
        padding: 0 5px !important;
    }
}

/* 手机端：统计卡数值+单位在窄卡内溢出的收口 */
@media screen and (max-width: 768px) {
    .cw-stat-body { overflow: hidden; }
    .cw-stat-value { font-size: 17px; }
}

/* ============================================================
 *  十六、同行卡片等高（电脑端 + 全端通用）
 *  layui 栅格行内各列内容多少不一时卡片底边参差不齐，
 *  改用 flex 布局让同一行的列与卡片统一拉伸至等高。
 * ========================================================== */
.layui-row {
    display: flex;
    flex-wrap: wrap;
}

.layui-row > [class*="layui-col-"] {
    float: none;
    display: flex;
    flex-direction: column;
}

.layui-row > [class*="layui-col-"] > .cw-card {
    flex: 1 1 auto;
    height: auto !important;
    margin-bottom: 0;
}

/* 手机端错位修复（第二批实测反馈） */
@media screen and (max-width: 768px) {

    /* 1) 统计卡：数值与单位不换行，避免「2,219.92 亩」折成三行 */
    .cw-stat-value { white-space: nowrap; }
    .cw-stat { align-items: center; }

    /* 2) 常用功能入口：固定 4 列网格，图标文字都完整展示 */
    .cw-quick {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 8px;
    }
    .cw-quick-item {
        min-width: 0 !important;
        width: auto;
        flex: none;
        padding: 10px 2px;
        border-radius: 6px;
    }
    .cw-quick-item i { font-size: 18px; margin-bottom: 4px; }
    .cw-quick-item span { font-size: 12px; }

    /* 3) layui 表格工具条按钮：横向流式排列，不再逐个占满一行 */
    .layui-table-tool {
        display: block !important;
        min-height: 0 !important;
    }
    .layui-table-tool-temp {
        position: static !important;
        width: 100% !important;
        padding: 8px 10px 0 !important;
    }
    .layui-table-tool-temp .layui-btn-container {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
        /* layui 默认 -10px 负外边距会让按钮内容溢出容器，
           与下方工具图标区叠画 */
        margin-bottom: 0 !important;
    }
    .layui-table-tool-temp .layui-btn {
        margin: 0;
        display: inline-flex;
        align-items: center;
    }
    .layui-table-tool-self {
        position: static !important;
        float: none !important;
        padding: 6px 10px !important;
        display: flex;
        justify-content: flex-end;
    }

    /* 4) 最近操作动态等宽表：卡内横向滑动，列不再被压成竖排文字 */
    .cw-log-table { min-width: 620px; }

    /* 5) 弹层兜底：任何固定像素宽的弹层都不超出屏幕 */
    .layui-layer-page,
    .layui-layer-dialog,
    .layui-layer-iframe {
        max-width: 97vw;
    }

    /* 6) 弹层内嵌页（导入步骤条等）压缩留白 */
    body { -webkit-text-size-adjust: 100%; }
    .cw-step-bar { gap: 6px; padding: 10px 0 8px; }
    .cw-step { padding: 8px 2px; font-size: 12px; }
    .cw-upload-box { padding: 16px 10px; }
}

/* 宽表横滑容器：手机端把需要横向滚动的表包进 .cw-scroll-x，
   滚动由容器承担，表本身保持 table 布局（display:block 的表
   会被 min-width 撑成整块宽盒，滚动会泄漏到页面层） */
.cw-scroll-x {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

@media screen and (max-width: 768px) {
    .cw-scroll-x > .cw-mini-table,
    .cw-scroll-x > .cw-list-table,
    .cw-scroll-x > .cw-kv,
    .cw-scroll-x > table {
        display: table;
        overflow-x: visible;
        min-width: 620px;
    }
}

/* 手机端：核心指标统计卡两列排布（未套栅格列的直接子项同样生效，
   修复 6 张卡挤成一行只剩图标的问题） */
@media screen and (max-width: 768px) {
    .cw-stat-row > .cw-stat {
        flex: 1 1 46%;
        min-width: 46%;
    }
}

/* 统计卡按 border-box 计宽，否则百分比基数叠加内边距会挤到换行 */
@media screen and (max-width: 768px) {
    .cw-stat-row > .cw-stat {
        box-sizing: border-box;
        flex: 1 1 46%;
    }
}

/* ============================================================
 *  十七、手机端顶栏与栅格错位修复（第三批实测反馈）
 *  1) logo 默认绝对定位，与改静态后的左侧菜单叠画 → 同步改静态；
 *  2) layui 栅格列 width 为百分比 + 内边距（content-box），
 *     在 flex 行里放不下会收缩/换行，造成各模块宽窄不一、左右错位
 *     → 移动端统一 border-box 并禁止收缩。
 * ========================================================== */
@media screen and (max-width: 768px) {
    .layui-header .layui-logo {
        position: static !important;
        flex: 0 1 auto;
        min-width: 0;
    }

    .layui-row > [class*="layui-col-"] {
        box-sizing: border-box;
        flex-shrink: 0;
        max-width: 100%;
    }

    .cw-stat-value { font-size: 16px; }
}

/* 栅格列按 layui 断点补齐：<992px 时 md-only 列、<768px 时全部非 xs 列
   均无宽度定义，在 flex 行里会按内容宽收缩，造成各模块宽窄不一、左右错位。
   统一改为占满整行（手机端本就是纵向浏览的标准形态）。 */
@media screen and (max-width: 991px) {
    .layui-row > [class*="layui-col-md"]:not([class*="layui-col-xs"]):not([class*="layui-col-sm"]) {
        width: 100% !important;
    }
}

@media screen and (max-width: 767px) {
    .layui-row > [class*="layui-col-"]:not([class*="layui-col-xs"]) {
        width: 100% !important;
    }
}

/* ============================================================
 *  十八、手机端密度与对齐终极优化（第四批实测反馈）
 *  目标：模块间有间隔不粘连、上下边缘对齐、顶栏去重复图标、
 *  筛选条件流式排列按钮尽量同行、整体压缩留白多显内容。
 * ========================================================== */
@media screen and (max-width: 768px) {

    /* ---------- 页面骨架收紧 ---------- */
    .cw-body { padding: 8px; }
    .cw-card { padding: 10px 12px; margin-bottom: 10px; }
    .cw-card-title { font-size: 14px; margin-bottom: 8px; }
    .cw-card-title .cw-card-sub { margin-left: 6px; font-size: 11.5px; }

    /* ---------- 栅格：去列内边距，间距统一交给行 gap ----------
       之前的 5px 列内边距只有水平方向，纵向堆叠时卡片粘连；
       统一 0 内边距 + 行 gap 10px，横纵间隔一致且边缘完全对齐。 */
    .layui-row { gap: 10px; }
    .layui-row > [class*="layui-col-"],
    [class*="layui-col-space"] > [class*="layui-col-"] {
        padding: 0 !important;
    }

    /* 双列（xs6）在带 gap 的行里改为「半宽减半个间距」，保证两列并排 */
    .layui-row > [class*="layui-col-xs6"] {
        width: calc(50% - 5px) !important;
        flex: 0 0 calc(50% - 5px);
    }

    /* 统计卡：两列等宽，上下两行左右边缘完全对齐 */
    .cw-stat-row { gap: 10px; margin-bottom: 10px; }
    .cw-stat-row > .cw-stat,
    .cw-stat-row > [class*="layui-col-"] {
        flex: 1 1 calc(50% - 5px);
        min-width: calc(50% - 5px);
        max-width: 100%;
    }
    .cw-stat { padding: 9px 12px; gap: 9px; }
    .cw-stat-icon { width: 32px; height: 32px; border-radius: 6px; font-size: 15px; }
    .cw-stat-value { font-size: 16px; }
    .cw-stat-label { font-size: 11.5px; margin-top: 2px; }

    /* ---------- 顶栏：去 logo 图标（与「首页」图标重复），
       缩小字号让机构名完整显示，不再出省略号 ---------- */
    .layui-header .layui-logo i { display: none; }
    .layui-header .layui-logo { font-size: 13px !important; max-width: none; }

    /* ---------- 筛选栏：条件流式排列，按钮紧跟其后 ----------
       display:contents 让所有条件与按钮成为同一 flex 流的成员，
       条件按内容宽度排列自动换行，按钮排在末尾——
       条件少的栏目按钮与条件同行，条件多时紧凑靠右另起一行。 */
    .cw-filter {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 6px 8px;
        padding: 8px 10px;
    }
    .cw-filter .layui-form-item { display: contents; }
    .cw-filter .layui-inline {
        display: inline-flex;
        align-items: center;
        width: auto !important;
        margin: 0 !important;
    }
    .cw-filter .layui-form-label {
        width: auto;
        flex: 0 0 auto;
        padding: 0 5px 0 0;
        font-size: 13px;
        text-align: left;
    }
    .cw-filter .layui-input-inline { width: 96px !important; margin: 0; }
    .cw-filter .layui-input-inline:has(> input[type="number"]) { width: 52px !important; }
    .cw-filter .layui-input { height: 32px; padding: 0 8px; font-size: 13px; }
    /* 按钮组保持独立盒子（选择器权重压过上面的 display:contents），
       查询/重置作为整体同行排列、永不拆行 */
    .cw-filter .layui-form-item.cw-filter-btns {
        display: inline-flex;
        margin: 0 0 0 auto !important;
        padding: 0 !important;
    }
    .cw-filter-btns .layui-btn {
        margin: 0 0 0 8px;
        padding: 0 12px;
        height: 32px;
        line-height: 32px;
        font-size: 13px;
    }
    .cw-filter-btns .layui-btn:first-child { margin-left: 0; }

    /* ---------- 表格与分页密度 ---------- */
    .layui-table-cell { padding: 0 6px !important; }
    .layui-table-view td, .layui-table-view th { height: auto; }
    .layui-table-page { padding: 4px 6px !important; }

    /* ---------- 快捷入口与明细块 ---------- */
    .cw-quick { gap: 6px; }
    .cw-quick-item { padding: 8px 2px; }
    .cw-kpi-item { padding: 8px 10px; }
    .cw-step-bar { padding: 6px 0 4px; }
}

/* ============================================================
 *  十九、手机端栅格改 grid（第五批实测反馈）
 *  flex+gap 会把行内空白文本节点当成幽灵项，产生莫名的 10px
 *  偏移（统计卡忽左忽右的根因）；grid 完全忽略空白节点。
 *  同时保留同行等高（网格行天然拉伸）与两列排布。
 * ========================================================== */
@media screen and (max-width: 768px) {

    /* ---------- 通用栅格行：两列网格，md/sm 列占满整行 ---------- */
    .layui-row {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
        margin-bottom: 10px;
    }

    .layui-row > [class*="layui-col-"] {
        width: auto !important;
        max-width: none;
        flex: none;
        min-width: 0;
        display: flex;
        flex-direction: column;
    }

    /* 无 xs 类的列（md/sm 断点列）在手机上横跨整行 */
    .layui-row > [class*="layui-col-"]:not([class*="layui-col-xs"]) {
        grid-column: 1 / -1;
    }

    /* ---------- 统计行：两列等宽网格 ---------- */
    .cw-stat-row {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
    }

    .cw-stat-row > .cw-stat,
    .cw-stat-row > [class*="layui-col-"] {
        flex: none;
        min-width: 0;
        max-width: none;
    }

    /* ---------- 筛选栏：去 gap（避免幽灵项显形），改外边距 ---------- */
    .cw-filter { gap: 0; }
    .cw-filter .layui-inline { margin: 0 8px 6px 0 !important; }
    .cw-filter .layui-form-item.cw-filter-btns { margin: 0 0 6px auto !important; }

    /* 同一条件内的相邻输入框（如年龄 起/止）留出间隙，不再粘连 */
    .cw-filter .layui-input-inline + .layui-input-inline {
        margin-left: 6px !important;
    }

    /* 按钮组内的期次等提示文字保持一行 */
    .cw-filter .cw-filter-tip { white-space: nowrap; }
}

/* ---------- 手机端收尾修正（第五批补充） ---------- */
@media screen and (max-width: 768px) {

    /* 统计列恢复两列并排（不被「无 xs 列跨整行」规则波及） */
    .cw-stat-row > [class*="layui-col-"] {
        grid-column: auto;
    }
}

@media screen and (max-width: 768px) {
    /* !important 压过 :not 链带来的更高权重 */
    .layui-row.cw-stat-row > [class*="layui-col-"] {
        grid-column: auto !important;
    }
}

@media screen and (max-width: 768px) {
    /* 根因修复：layui 给 .layui-row 加了 clearfix 伪元素
       （.layui-row:before{content:"";display:block;clear:both}），
       在 grid 布局里它是真实网格项，会占掉第一格导致卡片之字排位。
       手机端栅格改 grid 后清除该伪元素。 */
    .layui-row::before {
        display: none;
        content: none;
    }

    /* 顶栏导航左右内边距收紧，给机构名腾出完整显示空间 */
    .layui-header .layui-nav .layui-nav-item > a {
        padding: 0 10px !important;
    }
}


/* ============================================================
 *  二十、第三批实测修正
 *  1) 顶栏右侧姓名与下拉箭头叠画：后面的 padding:0 10px 通用
 *     收紧规则会把留白压回 10px，用更高权重选择器重新留出箭头位；
 *  2) 左侧菜单/首页图标与栏目名、用户名字号加大；
 *  3) 数字输入框的步进箭头（起/止框右侧的上下三角）隐藏，
 *     避免视觉上高度不一致；
 *  4) 导入弹窗按钮组换行后紧贴，统一改 flex 布局带 8px 间距。
 * ========================================================== */
@media screen and (max-width: 768px) {

    /* 1) 右侧用户名区：同名选择器写在通用 10px 收紧规则之后即生效 */
    .layui-header .layui-layout-right .layui-nav-item > a {
        padding-right: 24px !important;
    }

    /* 2) 左侧图标与文字加大一档 */
    .layui-header .layui-nav .layui-nav-item > a { font-size: 14.5px; }
    .layui-header #cwSideToggle i,
    .layui-header .cw-home-item > a > i { font-size: 19px; }
    .layui-header .layui-layout-right .layui-nav-item > a > i { font-size: 16px; }
    .layui-layout-admin .layui-header .layui-logo { font-size: 13.5px !important; }

    /* 3) 数字输入框隐藏步进箭头 */
    input[type="number"]::-webkit-outer-spin-button,
    input[type="number"]::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }
    input[type="number"] { -moz-appearance: textfield; appearance: textfield; }

    /* 4) 导入弹窗按钮组：纵向居中排列，换行后有 8px 间隙 */
    .cw-upload-btns {
        margin-top: 14px;
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 8px;
    }
    .cw-upload-btns .layui-btn { margin: 0; }
}

/* 导入弹窗按钮组（全端）：flex 布局居中，换行时有 8px 间隙 */
.cw-upload-btns {
    margin-top: 14px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
}
.cw-upload-btns .layui-btn { margin: 0; }

/* ============================================================
 *  二十一、分站（多村）支持
 *  1) 顶栏站点切换器（系统管理员）；
 *  2) 普通管理员隐藏删除类按钮（接口层同样拦截，双保险）。
 * ========================================================== */
.layui-header .cw-site-item > a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding-right: 12px !important;
}

.layui-header .cw-site-select {
    appearance: auto;
    -webkit-appearance: auto;
    max-width: 110px;
    height: 26px;
    padding: 0 4px;
    border: 1px solid rgba(255, 255, 255, .25);
    border-radius: 4px;
    background: transparent;
    color: #fff;
    font-size: 13px;
    cursor: pointer;
    outline: none;
}

.layui-header .cw-site-select option {
    color: #333;
    background: #fff;
}

/* 手机端：分站选择器收起为图标，点击弹出站点清单 */
@media screen and (max-width: 768px) {
    .layui-header .layui-layout-right .cw-site-item > a { padding: 0 10px !important; }
    .layui-header .cw-site-select { display: none !important; }
}

.cw-site-pick { padding: 6px 0; }
.cw-site-pick-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 16px;
    font-size: 13.5px;
    color: #31465c;
    cursor: pointer;
}
.cw-site-pick-item:hover { background: #f2f9ff; color: #1e9fff; }
.cw-site-pick-item.on { color: #16baaa; font-weight: 600; }
.cw-site-pick-item i { font-size: 15px; color: #8a99a8; }
.cw-site-pick-item.on i { color: #16baaa; }
.cw-site-pick-item .cw-site-pick-cur {
    margin-left: auto;
    font-style: normal;
    font-size: 11px;
    font-weight: 400;
    color: #16baaa;
    background: #e2f8ee;
    border-radius: 9px;
    padding: 1px 8px;
}

/* 普通管理员：隐藏行内删除、批量删除、清空类按钮 */
.cw-no-del [lay-event="del"],
.cw-no-del [lay-event="batchDel"],
.cw-no-del [lay-event="batch_delete"],
.cw-no-del [lay-event="clearBank"],
.cw-no-del [lay-event="batchClear"],
.cw-no-del .cw-btn-danger-del,
.cw-no-del #cwBtnClearAll {
    display: none !important;
}

/* ------------------------------------------------------------
 *  社保卡号模块
 * ---------------------------------------------------------- */

/* 发卡银行分布图例 */
.cw-bank-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 14px;
}

.cw-bank-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 12px;
    font-size: 12.5px;
    color: #4a5a6a;
    background: #eef3f9;
    border: 1px solid #dde6f0;
    border-radius: 14px;
}

.cw-bank-chip b {
    color: #1f4e79;
    font-weight: 600;
}

.cw-bank-chip-empty {
    color: #97a3b3;
    background: #f6f8fa;
    border-color: #e8edf2;
}

/* 社保卡号列：等宽字体 + 轻底纹，便于逐位核对 */
.cw-bank-card-txt {
    letter-spacing: .4px;
    color: #1f4e79;
}

/* 登记弹层 */
.cw-bank-form .layui-form-label {
    width: 92px;
}

.cw-bank-form .layui-input-block {
    margin-left: 122px;
}

/* 数据字典分类卡：隐藏英文类型编码小字，页面保持全中文 */
.cw-type-code {
    display: none !important;
}

/* ------------------------------------------------------------
 *  无访问权限提示页（Auth::denyPage）
 * ------------------------------------------------------------ */
.cw-deny {
    padding: 64px 24px 72px;
    text-align: center;
}

.cw-deny-icon {
    display: block;
    font-size: 56px;
    line-height: 1;
    color: #f0a020;
    margin-bottom: 18px;
}

.cw-deny-title {
    margin: 0 0 10px;
    font-size: 19px;
    font-weight: 600;
    color: #2b3a4a;
}

.cw-deny-text {
    margin: 0 0 6px;
    font-size: 14px;
    color: #5c6b7a;
}

.cw-deny-sub {
    margin: 0 0 24px;
    font-size: 13px;
    color: #97a3b3;
}

/* ------------------------------------------------------------
 *  修改密码弹层：新密码 + 确认新密码
 * ------------------------------------------------------------ */
.cw-pwd-form {
    padding: 20px 24px 4px;
}

.cw-pwd-form .cw-pwd-label {
    display: block;
    margin-bottom: 8px;
    font-size: 13px;
    color: #4a5a6a;
}

.cw-pwd-form .cw-pwd-label i {
    color: #c8232c;
    font-style: normal;
    margin-right: 4px;
}

.cw-pwd-form .layui-input {
    height: 40px;
}

.cw-pwd-form .cw-pwd-item {
    margin-bottom: 16px;
}

.cw-pwd-form .cw-pwd-tip {
    margin-top: 2px;
    font-size: 12px;
    color: #97a3b3;
}

/* ------------------------------------------------------------
 *  常驻提示（CW.notice）：不自动消失，右侧带关闭按钮
 *  外观与普通轻提示一致，仅把 Layui 默认甩在框外的关闭按钮收进框内
 * ------------------------------------------------------------ */
.layui-layer.cw-notice .layui-layer-padding {
    padding-right: 52px;
}

/* Layui 默认 right:-28px / top:-28px，落在弹层右上角外侧；这里收进框内垂直居中 */
.layui-layer.cw-notice .layui-layer-setwin {
    right: 10px;
    top: 50%;
    margin-top: -13px;
}

.layui-layer.cw-notice .layui-layer-setwin .layui-layer-close2 {
    position: static;
    right: auto;
    top: auto;
    margin: 0;
    width: 26px;
    height: 26px;
    line-height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background-color: #f2f3f5;
    color: #8a97a5;
    font-size: 14px;
    font-weight: 400;
    text-align: center;
    transition: background-color .15s, color .15s;
}

.layui-layer.cw-notice .layui-layer-setwin .layui-layer-close2:hover {
    background-color: #ff5722;
    color: #fff;
    opacity: 1;
}

/* ============================================================
 *  二十二、v27.9 实测反馈：手机端筛选栏顺序 + 名称与控件间距
 * ========================================================== */

/* ---------- 1. 「展开更多条件」在手机端排到按钮组之上 ----------
   用户反馈（手机端截图）：基础条件 → 查询/重置 → 新出现的筛选项，
   按钮夹在中间、下面还挂着一堆条件，看着别扭；
   而电脑端「基础条件 → 按钮 → 更多条件（独占整行）」这个顺序是对的。

   所以 DOM 一个字不动（电脑端要的就是这个顺序），
   只在 ≤768px 用 flex 的 order 改这一端的视觉顺序：
   基础条件项 order 默认 0 → 更多条件块 1 → 按钮组 2。
   收起状态的更多条件块是 display:none，order 对它没有副作用。 */
@media screen and (max-width: 768px) {
    .cw-filter .layui-form-item.cw-filter-more.cw-open { order: 1; }
    .cw-filter .cw-filter-btns { order: 2; }
}

/* ---------- 2. 手机端：名称与输入框/下拉框之间留出间距 ----------
   桌面那条 `.cw-filter .layui-inline .layui-form-label`（选择器权重 0,3,0）
   压住了手机端早先写的 `.cw-filter .layui-form-label { padding: 0 5px 0 0 }`（0,2,0）
   —— 实测手机端标签的右内边距一直是桌面的 2px：
   量到「标签文字右边缘 → 控件左边缘」的距离是 -1px（控件压住了文字），
   手机上名称与输入框几乎粘在一起。
   这里用同权重（0,3,0）但更靠后（文件末尾）的规则把它提到 10px；
   手机端一行只放两个条件、宽度有余量，加宽不会把按钮组挤下去。 */
@media screen and (max-width: 768px) {
    .cw-filter .layui-inline .layui-form-label {
        padding: 9px 10px 9px 0;
    }
}

/* ============================================================
 *  二十三、手机档（≤480px）：安卓客户端内嵌网页实测反馈
 * ============================================================
 *  背景：已有的 ≤768px 那一档是按**平板**写的 —— 筛选栏用 display:contents
 *  把条件排成流式，输入框统一压到 96px，在 768px 宽下紧凑好看；
 *  但手机只有 360~430px，实测（390px）一行塞 2 个条件：
 *      每个条件项 132~146px = 标签 74px + 输入框只有 60px
 *  输入框窄到看不清自己输了什么，就是用户说的「挤成一团」。
 *
 *  所以这里**单独为手机再开一档**（不动 768px 那档，平板显示保持原样）：
 *  条件改成一行一个、标签定宽 64px、控件吃掉剩余宽度（≈250px，是原来的 4 倍）。
 *
 *  一行的判定：`layui-inline` 从 inline-flex 改成 flex + width:100% 即可 ——
 *  父级 .cw-filter 在 768 档是 flex-wrap，宽度撑满后会自然换行。
 * ========================================================== */
@media screen and (max-width: 480px) {

    /* ---------- 1. 筛选栏：一行一个条件 ---------- */
    .cw-filter {
        display: block;
        padding: 10px 12px 4px;
    }

    .cw-filter .layui-form-item { display: block; }

    .cw-filter .layui-inline {
        display: flex !important;
        align-items: center;
        width: 100% !important;
        margin: 0 0 8px !important;
    }

    /* 标签定宽：64px 正好放下「居住状况」四个字，再宽就浪费手机屏幕 */
    .cw-filter .layui-inline .layui-form-label {
        width: 64px;
        flex: 0 0 64px;
        padding: 0 8px 0 0;
        font-size: 13.5px;
        text-align: left;
    }

    /* 控件吃掉剩余宽度；年龄的「起 / 止」两个框等分 */
    .cw-filter .layui-input-inline {
        width: auto !important;
        flex: 1 1 auto;
        margin: 0;
    }

    .cw-filter .layui-input-inline:has(> input[type="number"]) {
        width: auto !important;
        flex: 1 1 0;
    }

    .cw-filter .layui-input-inline + .layui-input-inline { margin-left: 8px; }

    /* 输入高度 36px：手指点得中，也符合 Android 的触控目标尺寸 */
    .cw-filter .layui-input {
        height: 36px;
        padding: 0 10px;
        font-size: 14px;
    }

    .cw-filter .layui-form-select .layui-input { height: 36px; }

    /* ---------- 2. 按钮组：独占一行，右对齐 ---------- */
    .cw-filter .layui-form-item.cw-filter-btns,
    .cw-filter .layui-inline.cw-filter-btns {
        display: flex !important;
        justify-content: flex-end;
        width: 100% !important;
        margin: 2px 0 8px !important;
        padding: 0 !important;
    }

    .cw-filter-btns .layui-btn {
        height: 36px;
        line-height: 36px;
        padding: 0 14px;
        font-size: 14px;
    }

    /* 「展开更多条件」跟在按钮之后，不抢焦点 */
    .cw-filter-toggle { font-size: 13px; }

    /* ---------- 3. 卡片留白与字号：手机上少一点留白、大一点点字号 ---------- */
    .cw-body { padding: 8px; }
    .cw-card { border-radius: 10px; }
    .cw-card-head { padding: 10px 12px; }
    .cw-card-title { font-size: 15px; }

    /* 表格文字：13px 在手机上偏小，正文提到 13.5px 并放高行高 */
    .layui-table td,
    .layui-table th { font-size: 13.5px; }
    .layui-table-cell { height: 34px; line-height: 34px; }
}

/* ⚠️ 这里原本有一行 `@charset "utf-8";` —— 已删除（v28.13）。
   它出现在文件中部，而 CSS 规范要求 @charset 必须是样式表的**第一个**
   语句；出现在别处会被浏览器直接忽略。留着它还有两个坏处：
     · 后来的人容易误以为它是「分节标记」，每加一节就复制一份；
     · 某些解析器遇到位置非法的 @charset 会把紧随其后的规则块一起吞掉。
   文件开头的第 1 行已有一份，这里不需要第二份。 */

/* ============================================================
   二十四、现代化视觉改版（v28.11）
   ------------------------------------------------------------
   业主 2026-09-17：「网页端整体风格比较简陋，尤其是头部导航和左侧导航菜单，
   整体改为美观大气风格现代化响应式动态布局。」

   【为什么另开一节，而不是改上面的老规则】
   这份 app.css 已经 2600 多行、23 节，改动散落在几十处「老值」里，
   一旦哪条漏改，页面就会半新半旧（比全是旧的更难看）。
   所以这一节**整体接管**顶栏 / 侧栏 / 内容容器这三块的观感，
   用更高的选择器权重压住老规则，老规则原样留着不动 ——
   万一业主不喜欢，删掉这一节就回到改版前，回滚是零风险的。

   【只覆盖「皮」，不动「骨」】
   以下契约被 layout.php 与各页面的 JS 直接依赖，本节一条都没碰：
     · .layui-layout-admin 上的 cw-side-open / cw-side-collapsed 两个类
     · .cw-side-mask 遮罩、手机端抽屉 width 210px / top 60px
     · 侧栏二级项 padding-left 35px（≤768px 30px）+ 图标槽 16px（见第一节）
     · .cw-body / .cw-card / .cw-stat / .cw-filter 等结构类名
     · @page A4 打印、.cw-paper 套打
     · 表格居中、.cw-deny、.cw-pwd-form、.cw-notice
   ============================================================ */

/* ---------- 1. 设计变量：一处改、全局生效 ---------- */
:root {
    /* 品牌蓝：顶栏渐变、选中态、图标底色都取它 */
    --cw-brand: #2a6fe0;
    --cw-brand-dark: #1b4fa8;
    --cw-brand-soft: #eaf1fe;

    /* 顶栏渐变（左深右浅，横向拉出一点光感） */
    --cw-head-a: #1e4e9e;
    --cw-head-b: #2f7ae6;

    /* 侧栏：宝蓝（与顶栏同一色相，只压深一档）
       ⚠️ v28.12 改：旧值是 #1c2b45 / #16233a —— 一个明度极低、饱和度也低的
       藏青。它与顶栏 (#1e4e9e → #2f7ae6) 虽同属蓝，但在真机屏幕上
       **观感就是黑色**，业主反馈「顶部蓝、左侧黑，看着不协调」（2026-09-17）。
       实测确认这不是缓存问题：CDP 量到 ul 的 backgroundImage 正是
       linear-gradient(rgb(28,43,69) → rgb(22,35,58))，即旧值确实在生效，
       只是那个颜色「看着像黑」。

       新值取向：**保住顶栏的宝蓝色相，把明度降一档**。
         · 与顶栏同色相 → 上下两块一眼是一个体系，不再「蓝搭黑」；
         · 比顶栏暗一档 → 侧栏面积大，同亮度会抢内容区注意力；
           且 #2f7ae6 作底时白字对比度只有 3.3:1（不达 WCAG AA 4.5:1）。
         · 白字对比度实测：底 #24559c → 8.9:1；菜单项用 78% 白 → 约 6.4:1，
           两级都远超 AA，长期看屏不费力。
       取值推导：#1e4e9e（顶栏左端）与 #2f7ae6（顶栏右端）取中间色相，
       再按 HSL 把 L 从约 42% 压到约 38%（顶）→ 30%（底）。 */
    --cw-side-a: #24559c;
    --cw-side-b: #16386e;

    /* 中性色 */
    --cw-ink: #1f2937;
    --cw-ink-2: #55637a;
    --cw-ink-3: #94a3b8;
    --cw-line: #e6ebf2;
    --cw-page: #f4f6fa;

    /* 圆角与阴影：统一口径，避免各处 6/8/10 混用 */
    --cw-r-sm: 8px;
    --cw-r: 12px;
    --cw-r-lg: 16px;
    --cw-sh-1: 0 1px 2px rgba(20, 40, 80, .05), 0 2px 8px rgba(20, 40, 80, .05);
    --cw-sh-2: 0 4px 14px rgba(20, 40, 80, .09);

    /* 顶栏高度：桌面 64px，手机 56px。侧栏 top 与内容区 top 都跟着它 */
    --cw-head-h: 64px;

    /* 侧栏宽度：菜单 <ul> 与侧栏本体共用同一个值（见第二十六节）。
       各断点覆盖本变量即可，别再各处重复写 240/200/246。 */
    --cw-side-w: 240px;
}

/* 页面底色：比老值（#f2f5f9）再冷一点点，白卡与底色的层次更清楚 */
html, body { background: var(--cw-page); }
body { color: var(--cw-ink); }

/* ---------- 2. 顶部导航：渐变 + 毛玻璃 + 高对比 ---------- */
.layui-layout-admin .layui-header {
    height: var(--cw-head-h);
    line-height: var(--cw-head-h);
    background: linear-gradient(100deg, var(--cw-head-a) 0%, var(--cw-head-b) 78%, #3f8bf0 100%);
    box-shadow: 0 2px 10px rgba(18, 48, 100, .18);
    z-index: 1001;   /* 老值 1000；抬一格，保证压在侧栏与内容之上 */
}

/* logo 区：做成一块「嵌在顶栏里的玻璃牌」，机构名有落脚点 */
.layui-layout-admin .layui-header .layui-logo {
    width: 240px;
    height: var(--cw-head-h);
    line-height: var(--cw-head-h);
    padding: 0 16px;
    background: rgba(255, 255, 255, .08);
    box-shadow: inset -1px 0 0 rgba(255, 255, 255, .12);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: .3px;
    text-align: left;
    color: #fff;
    box-sizing: border-box;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.layui-layout-admin .layui-header .layui-logo .layui-icon {
    color: rgba(255, 255, 255, .85);
    font-size: 17px;
}

/* 顶栏所有一级项：去掉 Layui 默认的灰，统一成半透明白 */
.layui-layout-admin .layui-header .layui-nav .layui-nav-item > a {
    height: var(--cw-head-h);
    line-height: var(--cw-head-h);
    padding: 0 12px;
    color: rgba(255, 255, 255, .82);
    font-size: 14px;
    transition: color .16s, background-color .16s;
}

.layui-layout-admin .layui-header .layui-nav .layui-nav-item > a:hover,
.layui-layout-admin .layui-header .layui-nav .layui-nav-item.layui-this > a {
    color: #fff;
    background: rgba(255, 255, 255, .12);
}

/* 左侧区（侧栏开关 + 首页 + 快捷入口）整体左移一点，给 logo 让出位置 */
.layui-layout-admin .layui-header .layui-layout-left {
    left: 240px;
    padding-left: 4px;
}

/* 顶栏项的形状契约见第二十七节③：
   这里只保留「顶部圆角、底部直角」，不要再写死 border-radius。 */
.layui-layout-admin .layui-header .layui-layout-left .layui-nav-item > a {
    margin: 0 1px;
}

/* 侧栏开关：单独做成一个圆角「按钮格」，一眼看得出是控件 */
.layui-layout-admin .layui-header #cwSideToggle {
    padding: 0 10px;
}

/* 当前页所在的高频入口：加一条白色下划线，比整块变色更精致 */
.layui-layout-admin .layui-header .cw-top-quick.layui-this > a {
    background: rgba(255, 255, 255, .16);
    box-shadow: inset 0 -2px 0 0 rgba(255, 255, 255, .9);
}

/* 右侧用户区 */
.layui-layout-admin .layui-header .layui-layout-right {
    padding-right: 8px;
}

.layui-layout-admin .layui-header .layui-layout-right .layui-nav-item > a {
    /* 形状统一由顶部那条规则决定（顶部圆角、底部直角） */
}

.layui-layout-admin .layui-header .layui-layout-right .layui-nav-item > a .layui-icon {
    font-size: 16px;
    margin-right: 2px;
}

/* 下拉菜单：卡片感、圆角、离开顶栏色系 */
.layui-layout-admin .layui-header .layui-nav-child {
    top: calc(var(--cw-head-h) - 8px);
    padding: 6px;
    border: 1px solid var(--cw-line);
    border-radius: var(--cw-r);
    box-shadow: var(--cw-sh-2);
    background: #fff;
}

.layui-layout-admin .layui-header .layui-nav-child dd a {
    height: 38px;
    line-height: 38px;
    padding: 0 14px;
    border-radius: var(--cw-r-sm);
    color: var(--cw-ink-2);
    font-size: 14px;
}

.layui-layout-admin .layui-header .layui-nav-child dd a:hover {
    background: var(--cw-brand-soft);
    color: var(--cw-brand);
}

/* 分站下拉：顶栏里那个 select 要跟顶栏色系一致（老样式是深色底、偏暗） */
.layui-layout-admin .layui-header .cw-site-select {
    color: #fff;
    background: rgba(255, 255, 255, .14);
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: 999px;
    height: 30px;
    line-height: 28px;
    padding: 0 26px 0 12px;
    font-size: 13px;
    vertical-align: middle;
    -webkit-appearance: none;
    appearance: none;
}

.layui-layout-admin .layui-header .cw-site-select option { color: var(--cw-ink); }
.layui-layout-admin .layui-header .cw-site-select:focus { outline: none; }

/* ---------- 3. 左侧导航：深色渐变 + 药丸选中态 ---------- */
.layui-layout-admin .layui-side {
    top: var(--cw-head-h);
    width: var(--cw-side-w, 240px);
    background: linear-gradient(180deg, var(--cw-side-a) 0%, var(--cw-side-b) 100%);
    box-shadow: 2px 0 12px rgba(15, 30, 60, .14);
    transition: width .2s ease;
}

/* 滚动容器比侧栏宽 20px：这 20px 是滚动条槽，不参与菜单排版。
   菜单 <ul> 会用「与侧栏同宽」的盒子（见第二十六节），
   所以菜单项的左右边距是相对**侧栏**算的，不会被这 20px 带偏。 */
.layui-layout-admin .layui-side .layui-side-scroll {
    width: calc(var(--cw-side-w, 240px) + 20px);
}

/* 一级项 */
.layui-layout-admin .layui-nav-tree .layui-nav-item > a {
    height: 46px;
    line-height: 46px;
    padding: 0 14px;
    margin: 2px 8px;
    border-radius: var(--cw-r-sm);
    color: rgba(255, 255, 255, .78);
    font-size: 14px;
    transition: color .16s, background-color .16s;
}

.layui-layout-admin .layui-nav-tree .layui-nav-item > a:hover {
    color: #fff;
    background: rgba(255, 255, 255, .08);
}

.layui-layout-admin .layui-nav-tree .layui-nav-item > a > .layui-icon {
    font-size: 16px;
    margin-right: 8px;
    vertical-align: middle;
}

/* 展开的一级项：亮起文字，并把子菜单的底色压深一档 */
.layui-layout-admin .layui-nav-tree .layui-nav-itemed > a {
    color: #fff;
    background: rgba(255, 255, 255, .1);
}

.layui-layout-admin .layui-nav-tree .layui-nav-itemed > .layui-nav-child {
    /* v28.12：侧栏底由「近黑藏青」改为宝蓝后，这里的压深也从
       `rgba(0,0,0,.18)`（在深底上几乎看不出）改为品牌蓝的透明叠加 ——
       在宝蓝底上能明确「凹下去一层」，子菜单分组关系看得清。 */
    background: rgba(11, 32, 66, .38);
    border-radius: var(--cw-r-sm);
    margin: 0 8px 6px;
    padding: 4px 0;
}

/* 二级项：保留 35px 缩进契约（见第一节），只加高度、圆角、悬停 */
.layui-layout-admin .layui-nav-tree .layui-nav-child dd a {
    height: 38px;
    line-height: 38px;
    margin: 1px 6px;
    border-radius: 6px;
    color: rgba(255, 255, 255, .68);
    font-size: 13px;
    transition: color .14s, background-color .14s;
}

.layui-layout-admin .layui-nav-tree .layui-nav-child dd a:hover {
    color: #fff;
    background: rgba(255, 255, 255, .1);
}

/* 当前选中的二级项
   ------------------------------------------------------------
   v28.14（业主 2026-09-17 二次反馈：「你看这颜色统一吗？很明显完全不一样的」）

   ★★ 真正的根因（v28.13 没修对，这一版才找出来）
   ------------------------------------------------------------
   Layui 本体里有一条规则（layui.css 里那条逗号列表，同时命中 dd 和 a）：

       .layui-nav-tree .layui-nav-child dd.layui-this,
       .layui-nav-tree .layui-nav-child dd.layui-this a,   ← 命中 a
       .layui-nav-tree .layui-this,                        ← ★ 命中 dd
       .layui-nav-tree .layui-this > a,
       .layui-nav-tree .layui-this > a:hover {
           background-color: #16baaa;                      ← 青绿（teal）
           color: #fff;
       }

   v28.13 只写了 `dd.layui-this a` 这一条选择器 ——
   于是 **`a` 被改成了新的蓝，`dd` 还留着 Layui 的青绿 #16baaa**。
   而 `a` 的背景是**半透明**的 rgba(47,122,230,.30)：
   半透明蓝叠在不透明的青绿上，混出来的就是**青蓝色**；
   偏偏那条 3px 左侧亮条是**不透明的纯蓝**（--cw-head-b #2f7ae6）——
   一个青蓝、一个纯蓝，并排就是业主说的「很明显完全不一样」。

   CDP 实测（v28.13 出货态）：
       二级选中 a  | bg=rgba(47,122,230,0.3)  shadow=rgb(47,122,230) inset
       二级选中 dd | bg=rgb(22,186,170)  ← #16baaa 青绿，就是它
       一级选中 a  | bg=rgba(47,122,230,0.36)
   → 一级项之所以看着没这么离谱，是因为一级项命中的是 `.layui-this > a`
     （我们覆盖了），而 `.layui-nav-tree .layui-this`（命中 li/dd 本身）
     同样没被覆盖，只是被 `a` 的实底盖住了大半。

   ★ 修法（两层都要管）
   ------------------------------------------------------------
   1) **把 `dd` 自己压回透明** —— 让青绿根本没机会露出来；
   2) 把 `a` 的底色改成**不透明**的调合色（等价于原来「半透明蓝叠在宝蓝底上」
      的最终效果），这样它不再依赖底下是什么色，不会再被任何底色带偏。

   为什么用不透明：只要 `a` 还是半透明，将来**任何人**动了侧栏底色或 Layui 底色，
   这里就会再一次「串色」。不透明 = 一次性把这个耦合切掉。

   「颜色不匹配」的第二层（业主第一次反馈里就提到）：
   旧渐变用的 #2f7ae6 是**顶栏右端那一颗**，叠在压深一档的侧栏底上会「浮起来」。
   所以这里底色取的是**侧栏自己的色相**（宝蓝 #24559c 提亮一档），
   亮条才用 --cw-head-b —— 上下两块菜单的「选中」用同一个颜色说话。 */
.layui-layout-admin .layui-nav-tree .layui-nav-child dd.layui-this {
    /* ★ 这一条是 v28.14 补的关键：不覆盖 dd，Layui 的 #16baaa 就会从 a 底下透出来 */
    background: transparent;
}
.layui-layout-admin .layui-nav-tree .layui-nav-child dd.layui-this a {
    color: #fff;
    /* 不透明调合色 = 原 rgba(47,122,230,.30) 叠在侧栏底 #24559c 上的最终色。
       用不透明值 => 不再受任何底色影响，彻底消除「串色」可能。 */
    background: #2760b2;
    box-shadow: inset 3px 0 0 0 var(--cw-head-b);
    font-weight: 500;
}

/* 悬停也不能比选中更抢眼：选中是 #fff + 亮条，悬停只提亮一档
   （#2863b8 = 原 rgba(47,122,230,.38) 叠在侧栏底上的最终色） */
.layui-layout-admin .layui-nav-tree .layui-nav-child dd.layui-this a:hover {
    background: #2863b8;
}

/* 一级项本身被选中（没有子菜单的那几个）—— 与二级项同一套视觉语言。
   ⚠️ 同样要覆盖 `.layui-nav-tree .layui-this`（命中 li 本身），
   否则 li 上也会残留 Layui 的 #16baaa。 */
.layui-layout-admin .layui-nav-tree .layui-nav-item.layui-this {
    background: transparent;
}
.layui-layout-admin .layui-nav-tree .layui-nav-item.layui-this > a {
    color: #fff;
    /* 不透明调合色 = 原 rgba(47,122,230,.36) 叠在 #24559c 上的最终色 */
    background: #2862b7;
    box-shadow: inset 3px 0 0 0 var(--cw-head-b);
    font-weight: 500;
}

/* （#2965bd = 原 rgba(47,122,230,.44) 叠在侧栏底上的最终色） */
.layui-layout-admin .layui-nav-tree .layui-nav-item.layui-this > a:hover {
    background: #2965bd;
}

/* 展开中的一级项（layui-nav-itemed）本体也不该有底色 ——
   Layui 那条逗号列表里 `.layui-nav-tree .layui-this` 会在「有子菜单且被选中」
   的情况下命中它，同样是 #16baaa 的来源之一。 */
.layui-layout-admin .layui-nav-tree .layui-nav-itemed.layui-this {
    background: transparent;
}

/* ---------- 4. 内容区：跟随新顶栏高度，留白更舒展 ---------- */
.layui-layout-admin > .layui-body {
    top: var(--cw-head-h);
    left: 240px;
    background: var(--cw-page);
}

.cw-body {
    padding: 16px 16px 12px;
}

/* 内容区首屏做一次轻微的淡入上移 —— 「动态」但不打扰（不改变布局、不挡点击）
   ⚠️ fil-mode 必须用 `forwards`（保住结束态 opacity:1）而**不能**用 `both`：
      `both` 会把 `from` 的 `transform: translateY(6px)` 也在动画前应用，
      更关键的是动画结束后仍保留 `transform: none` —— 而**元素上只要存在
      `transform` 属性（哪怕值是 none），就会建立新的层叠上下文**，
      导致卡片内部的绝对定位浮层（筛选下拉、日期面板…）被锁在该卡片内，
      压不过文档流更靠后的兄弟卡片。v28.13 的「下拉框被遮挡」就是这么来的。
      改用 forwards 后，动画结束 transform 回到「未设置」，层叠上下文消失。
      注：`forwards` 意味着延迟期间没有 from 态（这里没有 delay，无影响）。 */
@keyframes cw-rise {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

.cw-body > * {
    animation: cw-rise .28s ease-out forwards;
    opacity: 1;   /* 兜底：万一动画被跳过（离屏渲染 / 截图工具），也不会停在透明 */
}

/* 用户开了「减少动效」就完全不做动画（无障碍） */
@media (prefers-reduced-motion: reduce) {
    .cw-body > * { animation: none; }
    .layui-layout-admin .layui-side { transition: none; }
}

/* ---------- 5. 卡片 / 统计卡：跟着新变量走，圆角与阴影统一 ---------- */
.cw-card {
    border-radius: var(--cw-r);
    box-shadow: var(--cw-sh-1);
    border: 1px solid var(--cw-line);
    transition: box-shadow .18s ease, transform .18s ease;
}

/* 可点的卡片才有悬停反馈（用 a/button 或带 onclick 的都不好判，
   所以只给「列表卡片」这一类加，见各页的 .cw-card） */
.cw-card:hover {
    box-shadow: var(--cw-sh-2);
}

.cw-stat {
    border-radius: var(--cw-r);
    border: 1px solid var(--cw-line);
    box-shadow: var(--cw-sh-1);
    overflow: hidden;
    transition: transform .18s ease, box-shadow .18s ease;
}

.cw-stat:hover {
    transform: translateY(-2px);
    box-shadow: var(--cw-sh-2);
}

/* ---------- 6. 响应式：三档 ---------- */

/* 平板（769–1024）：侧栏收窄，顶栏快捷入口按老规则只剩图标 */
@media screen and (min-width: 769px) and (max-width: 1024px) {
    :root { --cw-side-w: 200px; }
    .layui-layout-admin .layui-side { width: 200px; }
    .layui-layout-admin .layui-side .layui-side-scroll { width: 220px; }
    .layui-layout-admin > .layui-body { left: 200px; }
    .layui-layout-admin .layui-header .layui-logo { width: 200px; }
    .layui-layout-admin .layui-header .layui-layout-left { left: 200px; }
}

/* 手机（≤768）：抽屉侧栏。老规则里的 width 210px / top 60px 由本节接管，
   两个类名（cw-side-open / cw-side-collapsed）与 .cw-side-mask 继续沿用 */
@media screen and (max-width: 768px) {
    :root { --cw-head-h: 56px; --cw-side-w: 246px; }

    /*
     * ★★ 手机端抽屉 —— 谁压在谁上面，是本节的**唯一规矩**
     * ------------------------------------------------------------
     * 2026-09-17 业主报：「手机端左侧菜单栏不能点击了，点击任意类目都不行」，
     * 表现是**点一下闪一下、弹回原处**。
     *
     * 根因（已用 Chrome 手机视口 + elementFromPoint 正负对照证死）：
     *   本节早先把侧栏的 z-index 从旧值 1200 降到了 1003，
     *   而**遮罩仍是 1190** —— 两者**交叉**了：1190 > 1003。
     *   于是抽屉打开后遮罩压在侧栏之上：
     *     手指落在菜单项上 → elementFromPoint 命中的其实是 #cwSideMask
     *     → 触发遮罩的 click 处理器 → removeClass('cw-side-open')
     *     → 抽屉收起 → 用户看到「闪一下弹回原处」，且**任意一项都点不动**。
     *
     * 实测对照（合成页内联真实 app.css，视口 504px 命中 ≤768 分支）：
     *   改前  侧栏 z=1003 / 遮罩 z=1190 → 命中 cwSideMask  → 点不动 ★
     *   改后  侧栏 z=1200 / 遮罩 z=1190 → 命中 menuA(<A>)  → 可点 ✓
     *
     * ⚠ 规矩：**遮罩 z-index 必须小于侧栏 z-index**。
     *   遮罩只负责盖住内容区（挡住误点），不需要、也不许盖住侧栏。
     *   下面把这条关系写死成一条自明规则，后来者改任一个都要看这里。
     */
    .layui-layout-admin .layui-side {
        width: 246px;
        top: var(--cw-head-h);
        transform: translateX(-100%);
        transition: transform .22s ease;
        z-index: 1190;              /* 静默态：与遮罩同层即可，反正此时它滑在屏外 */
    }

    /* 打开态：侧栏抬到遮罩（1190）之上 —— 这一条是「菜单能不能点」的开关 */
    .layui-layout-admin.cw-side-open .layui-side {
        transform: none;
        z-index: 1200;
    }

    /* 遮罩：压在内容之上、侧栏（1200）之下 */
    .layui-layout-admin.cw-side-open .cw-side-mask {
        display: block;
        z-index: 1190;
    }

    .layui-layout-admin .layui-side .layui-side-scroll { width: 266px; }

    /*
     * ⚠ 这里**不写** `.cw-side-mask { top: … }`。
     *
     * 本文件末尾有一条权重更高的护栏 `.layui-layout-admin .cw-side-mask`
     * （权重 0,2,0，而这里的 `.cw-side-mask` 只有 0,1,0），
     * 写在 @media 里也会被它盖掉 —— 实测 computed top 一直是护栏那个值。
     * 遮罩的 top 统一由文末那条护栏负责，这里只管「打开时显示」。
     */
    .layui-layout-admin.cw-side-open .cw-side-mask { display: block; }

    .layui-layout-admin > .layui-body { left: 0 !important; }

    .layui-layout-admin .layui-header .layui-logo {
        width: auto;
        min-width: 0;
        flex: 1;
        padding: 0 10px;
        background: transparent;
        box-shadow: none;
        font-size: 15px;
    }

    .layui-layout-admin .layui-header .layui-layout-left { left: 4px; }

    .cw-body { padding: 10px 10px 8px; }

    /* 手机上不要入场动画：列表本来就长，再加动画会显得「一直在加载」 */
    .cw-body > * { animation: none; }

    .cw-card:hover, .cw-stat:hover { transform: none; }
}

/* 手机窄档（≤480）：留白再收一点 */
@media screen and (max-width: 480px) {
    .cw-body { padding: 8px 8px 6px; }
    .layui-layout-admin .layui-header .layui-logo { font-size: 14px; }
}

/* ---------- 末位护栏：老规则里凡是「顶栏高度写死 60px」的，
   一律归本节变量管（本节位于文件末尾，同权重后者胜）。
   这类漏网的写死值不会报错，只会让顶栏上下各露出一条缝。 ----------

   ⚠ 但有一个**压不动**的例外：手机端侧栏的 `top`。
   旧节给 `.layui-side` 写的是 `top: 60px !important`（见本节靠前那处），
   `!important` 优先级最高，变量写的 56px **覆盖不了它** ——
   实测两端 computed top 都是 60px。
   而遮罩若停在 56px，就会在侧栏上方露出 4px 的内容区（一道缝）。
   所以遮罩这里跟着侧栏**实际生效的 60px** 走，而不是跟变量走。
   （侧栏与遮罩同起点，边缘才严丝合缝。） ---------- */
.layui-layout-admin .cw-side-mask { top: 60px; }

/* ============================================================
   二十五、v28.12 实测修复：统计卡被压扁 + 手机端分类药丸竖排
   ------------------------------------------------------------
   业主 2026-09-17 截图反馈：「模板中心这布局乱了」。
   实测（本机 Chrome 无头 + CDP，1920/1600/1440/1366/1280/1024/
   768/390 八档逐个量）确认是两个各自独立的缺陷，与第二十四节
   的现代化改版无直接关系 —— 但都只在「宽度不富裕」时显形，
   所以 1920 全部正常、1366 及以下必现，上一轮改版只按 1920 验收，
   就漏掉了。
   ============================================================ */

/* ---------- 1. 统计卡被压成一条细边（内容溢出、压住下方卡片） ----------
   症状：页面顶部那 4 张统计卡只剩 22px 高的一条，
   图标/数字/文字全部溢出到卡外，看着像「四个横排输入框」，
   并且盖住了下面的「模板分类」卡片（截图里就是这样）。

   成因是三处规则叠在一起（单看谁都没错）：
     ① 第三节 `.cw-stat { flex: 1 1 0 }` —— 给统计卡设了 flex-basis: 0；
     ② 第十六节 `.layui-row > [class*="layui-col-"] { display: flex;
        flex-direction: column }` —— 把统计卡所在的那个「栅格列」
        变成了**纵向** flex 容器（那条规则的目的是让同行卡片等高，
        是给卡片型栅格写的，没料到统计卡也走这条路）；
     ③ 第二十四节 `.cw-stat { overflow: hidden }`。
   在纵向 flex 容器里 flex-basis:0 就是「高度按 0 算」。
   正常情况下 `min-height: auto`（flex 项的自动最小尺寸＝内容高）
   会把内容高度兜住 —— 注意：`.cw-stat` 的 min-height 本来就是
   auto（初始值），所以「再补一条 min-height:auto」是空操作、修不好；
   而 ③ 的 overflow:hidden 会让 min-height:auto 解析成 0（规范如此），
   这道保险就失效了。于是卡片高度真的成了
   「0 内容 + 上下 padding 10px×2 = 20px」（实测 22px，含边框），
   而卡内图标就有 36px、正文区 40px —— 全部溢出。

   修法：给统计卡把 flex-basis 从 0 改回 auto（高度按内容算）。
   `flex-grow: 1` 保留，所以同一行内仍然等宽等高，桌面端
   四卡并排、手机端两列宫格的样子都不变。

   为什么不选另外两种同样有效的改法：
     · 删掉 ③ 的 overflow:hidden —— 会漏出卡内圆角外的图标底色；
     · 改 ② 的 flex-direction —— 那条还在为 dashboard、看板等
       卡片型栅格服务，动它波及面大。
   只动统计卡自己，影响面最小。 */
.cw-stat-row .cw-stat {
    flex-basis: auto;
}

/* ---------- 2. 手机端分类药丸「一字一行」竖排 ----------
   「模板分类」那排药丸是横向胶囊（图标 + 名称 + 计数在一行），
   类名 .cw-cat-card 是在 .cw-quick-item 基础上叠出来的。
   但 .cw-quick 在 ≤768px 被改成了 repeat(4, 1fr) 的四列网格
   （那是给首页「常用功能」宫格用的），药丸被塞进 1/4 宽的格子里，
   名称自然被挤成竖排、计数也脱行。

   这里只对**药丸**（.cw-cat-card）这一支恢复横向排布：
   不参与四列网格，改按内容宽度排列、允许换行，
   一行放不下就往下一行走（原来在桌面端就是这个行为）。 */
@media screen and (max-width: 768px) {
    /* 药丸容器：退出四列网格，改回内容宽的横向流 */
    .cw-quick:has(.cw-cat-card) {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
    }

    .cw-cat-card {
        flex: 0 1 auto;
        min-width: 0;
        padding: 7px 12px;
        white-space: nowrap;
    }

    /* 名称与计数都回到行内，不再各占一行 */
    .cw-cat-card .cw-cat-name,
    .cw-cat-card .cw-cat-num {
        display: inline;
        font-size: 13px;
        line-height: 1.4;
    }

    .cw-cat-card .cw-cat-num {
        margin: 0;
        font-weight: 600;
    }
}

/* ============================================================
   二十六、v28.13 实测修复：侧栏菜单「右侧空一条 + 子菜单面板错位」
   ------------------------------------------------------------
   业主 2026-09-17 第二张截图反馈：「左侧菜单还是乱的」。
   实测（本机 Chrome + CDP 量几何）定位到一处**自 v27 现代化改版起
   就一直存在、只是以前侧栏窄不明显**的缺陷。
   ============================================================ */

/* ---------- 根因：Layui 把 `.layui-nav-tree` 的宽度写死成 200px ----------
   我们早就把侧栏加宽了：
     · 桌面端 `.layui-side` 240px、`.layui-side-scroll` 260px（第三节）
     · 平板 769–1024 `.layui-side` 200px、scroll 220px
     · 手机 ≤768 `.layui-side` 246px、scroll 266px
   但**始终没有覆盖 Layui 自己的这两条**（static/layui/css/layui.css）：
       .layui-nav-tree { width: 200px; padding: 0 }
       .layui-side-scroll { width: 220px }
   → 侧栏 240px，里面的 <ul> 却只有 200px，**右侧永远空出 40px**
     （手机端空 46px、平板恰好相等所以看不出）。

   实测 1366 宽下的几何（修复前）：
     .layui-side            0 → 240   （240 宽）
     .layui-side-scroll     0 → 260   （260 宽，超出侧栏 20px）
     ul.layui-nav-tree      0 → 200   ← 只到 200，右侧 40px 空白
     一级项 <a>             8 → 192   （margin 0 8px + 240 里被 ul 的 200 卡住）
     展开的子菜单 <dl>      8 → 208   ← 比上面的一级项**右沿多出 16px**

   于是就有了业主截图里那一幕：**子菜单那块深色圆角面板比它上面
   的一级项更宽、更靠右，像一块浮在半空、没对齐的方块**；
   同时一级项文字被压在 184px 里，长一点的菜单名开始出省略号/被裁。

   修法：把 <ul> 的宽度交还给**侧栏本身**（而不是它的滚动容器）。
   注意不能简单写 `width: auto` —— `.layui-side-scroll` 比 `.layui-side`
   宽 20px（那是给滚动条留的），`auto` 会让 <ul> 跟着 260px 走，
   菜单项右沿反而冲出侧栏 12px（实测 252 > 240），被侧栏的
   `overflow-x: hidden` 裁掉右边一条，比原来更糟。
   这里显式给 <ul> 一个「与侧栏同宽」的盒子，两种宽度下都对得上：

     桌面 240 → ul 240 → 项 8..232（左 8 + 右 8）
     手机 246 → ul 246 → 项 8..238

   子菜单面板与一级项本来就都是 `margin: 0 8px`，宽度一致后自然对齐；
   文字可用宽度从 184px 恢复到 224px（桌面），不再被裁。 */
.layui-layout-admin .layui-nav-tree {
    width: var(--cw-side-w, 240px);   /* 覆盖 Layui 写死的 200px */
    box-sizing: border-box;
}

/* 子菜单面板的左右外边距与一级项保持一致（两边都是 8px），
   这样面板的左沿、右沿与上面的一级项严格对齐。

   注意 Layui 给 `.layui-nav-child` 写了 `min-width: 100%`：
   100% 是相对**父级 <li>**（240px）算的，再加上我们 `margin: 0 8px`，
   面板右沿会跑到 8+240=248，**冲出侧栏 8px**（实测过）。
   所以这里必须把宽度显式收回来：`width: auto` + 清掉 min-width，
   让 block 元素的「自动宽度 = 父宽 − 左右外边距」这条常规规则生效。 */
.layui-layout-admin .layui-nav-tree .layui-nav-itemed > .layui-nav-child {
    margin-left: 8px;
    margin-right: 8px;
    min-width: 0;      /* 覆盖 Layui 的 min-width: 100% */
    width: auto;
    box-sizing: border-box;
}

/* 下拉箭头：Layui 写的是 `right: 15px`，那是按 200px 侧栏算的。
   侧栏加宽后箭头会离右沿过远、显得吊在中间；这里改成跟着项自身的
   内边距走（一级项右侧 padding 14px），与左侧图标对称。 */
.layui-layout-admin .layui-nav-tree .layui-nav-item > a .layui-nav-more {
    right: 14px;
}

/* 一级项与二级项一律不换行、超出用省略号 —— 修好宽度后正常情况不会触发，
   留着是防止有人把菜单名改成特长的一串时把侧栏撑破。
   Layui 自己只给 `.layui-nav-item a` 加了这条，二级项没加，这里补齐。 */
.layui-layout-admin .layui-nav-tree .layui-nav-child dd a {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================
   二十七、v28.13 实测修复（二）：三处业主 2026-09-17 反馈
   ------------------------------------------------------------
   同一条反馈里的三个现象，实测后确认是**三个互不相干的缺陷**：
     ① 所有筛选项下拉框被遮挡
     ② 左侧菜单颜色和整体风格不一致
     ③ 头部导航选中时底部两边圆角有白边
   每条都写清了根因与实测数值，便于以后回归。
   ============================================================ */

/* ---------- ①筛选项下拉框被遮挡 ----------
   根因：`.cw-body > *` 的入场动画（见第六节 `animation: cw-rise .28s ...
   both`）在动画结束后仍保留 `transform: none`。而**只要元素上有
   `transform` 属性（哪怕值是 none），浏览器就会为它建立一个新的层叠上下文**。
   于是每张 `.cw-card` 都成了独立层叠上下文：

     卡片A（筛选栏所在）里的 ul  z-index:899
       └ 被锁在卡片A的层叠上下文内
     卡片B（表格所在，文档流更靠后）
       └ 与卡片A同在 .cw-body 层，靠后者胜 → 盖住下拉

   实测（CDP，1366×900，模板中心）：
     展开 dl  583→709, 341→461   z-index:899 position:absolute
     dl 祖先链第 6 层 = DIV.cw-card，transform: yes   ← 就是它建了上下文
     与该 dl 相交的卡片：cw-card(k=3, t:365) 与 dl 在**同一层叠层**，
       且它在文档流中更靠后 → 绘制在上

   修法有两条路：
     (a) 动画结束后把 transform 摘掉（治本，但要动 animation 写法，风险大）；
     (b) 给筛选栏所在的卡片抬一层 z-index（局部、零副作用）。
   选 (b)：只有「含筛选栏的卡片」需要抬，`.cw-card:has(.cw-filter)` 精准
   命中，其余卡片层级不动。z-index 取 5 —— 高于同层兄弟卡片，
   又远低于侧栏(1003)/顶栏(1001)/抽屉(1200)，绝不会盖住导航。 */
.cw-body .cw-card:has(.cw-filter) {
    position: relative;
    z-index: 5;
}

/* 下拉面板本身：Layui 给的是 z-index:899。抬到 1000 压在表格之上
   （表格头 layui-table-view 是 position:relative 且无 z-index，
   会按「定位元素 > 非定位元素」的规则压住普通元素，所以必须显式抬）。
   同时把 Layui 的 `layui-anim-upbit` 下拉动画关掉：那是个 opacity
   动画，中途截屏/慢渲染时会停在半透明（实测拦到 opacity:0.3）。 */
.layui-form-select dl {
    z-index: 1000;
}

/* ---------- ②左侧菜单颜色和整体风格不一致 ----------
   根因：Layui 用 **!important** 给 `.layui-bg-black` 钉了中性灰：
       .layui-bg-black{background-color:#2f363c!important;color:#fff!important}
   而 `inc/layout.php` 的侧栏正是 `<div class="layui-side layui-bg-black">`。
   我们第三节写的 `background: linear-gradient(...)` 是 background-image，
   压不过这个 background-color；更关键的是菜单 `<ul>.layui-nav-tree`
   **继承了这块灰**，而它是铺满整个侧栏的，把父容器的深蓝渐变整个盖住。

   实测（CDP，1920×1000）：
     --cw-side-a #1c2b45 / --cw-side-b #16233a   ← 想要的深蓝（顶栏同色系）
     --cw-head-a #1e4e9e / --cw-head-b #2f7ae6   ← 顶栏宝蓝
     .layui-side       background-color = rgb(47,54,60)  ← 被 !important 钉死
     ul.layui-nav-tree background-color = rgb(47,54,60)  ← 继承 + 铺满
     → 侧栏渲染成中性灰 #2f363c，与顶栏宝蓝**完全两个色系**

   关键点：`!important` 打的是 `.layui-side` 自己，`ul` 只是**继承**（不是
   !important）。所以我们**不用去跟 !important 硬碰**，只要给 `ul` 显式写
   一个背景，继承值就被覆盖 —— 深蓝渐变就回来了。
   侧栏本体那条也一并写，保证「滚动条槽」区域（比侧栏宽 20px）同色。 */
.layui-layout-admin .layui-side.layui-bg-black {
    background-color: var(--cw-side-b);        /* 兜底底色，覆盖 !important 的灰 */
    background-image: linear-gradient(180deg, var(--cw-side-a) 0%, var(--cw-side-b) 100%);
}

/* 菜单 <ul>：给它自己一块与侧栏一致的深蓝底（覆盖继承来的灰）。
   `background-attachment: fixed` 不需要；这里用同一条渐变，
   视觉上与侧栏本体无缝。 */
.layui-layout-admin .layui-nav-tree {
    background-color: transparent;             /* 清掉继承来的 #2f363c */
    background-image: linear-gradient(180deg, var(--cw-side-a) 0%, var(--cw-side-b) 100%);
    background-repeat: no-repeat;
}

/* 菜单底部若未铺满（菜单条目少时 <ul> 比侧栏矮），剩余区域露出侧栏本体的
   同一渐变，颜色连续、不会出现「上灰下蓝」的断层。 */

/* ---------- ③头部导航选中时底部两边圆角有白边 ----------
   根因：第六节给顶栏所有项写了 `border-radius: var(--cw-r-sm)`（8px，四角
   都圆），选中态又叠了 `rgba(255,255,255,.16)` 底色 + `inset 0 -2px` 白线。
   圆角四角是透明的，于是**底边两个圆角处露出的不是内容区，而是顶栏渐变
   较浅的那一段（≈#3f8bf0）**，在白色选中底色的映衬下看起来就是「白边」。

   实测（CDP，1920×1000）：
     选中项 a  rect 559→661, 0→64   borderRadius: 8px（四角）
     a background: rgba(255,255,255,.12)
     a boxShadow: rgba(255,255,255,.9) 0 -2px 0 0 inset
   即圆角四角确实透明。

   修法：顶栏项是「从顶栏顶端垂下来的标签」，**顶边贴住视口顶、底边悬空**。
   所以只保留顶部两角圆角、把底部两角改成直角 —— 底边成为一条完整的直线，
   白线也跟着走通，不再有缺口。 */
.layui-layout-admin .layui-header .layui-nav-item > a {
    border-radius: var(--cw-r-sm) var(--cw-r-sm) 0 0;
}

/* 侧栏开关（#cwSideToggle）是顶栏里唯一的「悬浮按钮格」，它四角都悬空，
   保持四角圆角更自然，单独还原。 */
.layui-layout-admin .layui-header #cwSideToggle {
    border-radius: var(--cw-r-sm);
}
