/* ==========================================================================
   CyberStrikeAI — Mobile UI Layer
   --------------------------------------------------------------------------
   目标：在不改动 style.css（1.1MB）与既有桌面布局的前提下，用一层独立的
   响应式样式把平台改造成"手机优先可用"的形态。

   设计语言参考 QuantumNous/new-api 的移动端实现：
     - 断点 768px（useIsMobile: innerWidth < 768）
     - 底部滑出式面板（rounded sheet + backdrop-blur 遮罩 + spring 动画）
     - 100svh/dvh 视口单位、--app-header-height 变量驱动的布局高度
     - 抽屉式导航 + 卡片化列表

   本文件只在 max-width: 767.98px（以及平板/横屏区间）生效，
   桌面端与 ≥768px 的既有表现完全不受影响。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 设计令牌
   -------------------------------------------------------------------------- */
:root {
    --m-appbar-h: 52px;
    --m-tabbar-h: 58px;
    --m-safe-top: env(safe-area-inset-top, 0px);
    --m-safe-bottom: env(safe-area-inset-bottom, 0px);
    --m-safe-left: env(safe-area-inset-left, 0px);
    --m-safe-right: env(safe-area-inset-right, 0px);
    --m-drawer-w: min(84vw, 320px);
    --m-touch: 44px;
    --m-radius-sheet: 18px;
    --m-radius-card: 14px;
    --m-gutter: 14px;
    /* 24 节「按钮 / 控件视觉体系」的度量：全站按钮只有这一组尺寸口径。
       改造前 style.css 里没有 .btn 基类，圆角 11 种、字号 9 种、字重 7 档、
       同一个 .btn-secondary 出现 12 种签名（_mbtn.mjs 实测 645 个控件）。 */
    --m-r-ctl: 12px;
    /* 图标按钮一律正圆、文字按钮一律胶囊：24 节那批 !important 规则读的就是这两个
       令牌，改令牌一处生效全站，不要再往下补选择器或跟 !important 对轰 */
    --m-r-icon: 50%;
    --m-r-btn: 999px;
    --m-r-pill: 999px;
    --m-ctl-h: var(--m-touch);
    --m-ctl-pad-x: 16px;
    --m-ctl-pad-x-sm: 12px;
    --m-ctl-fs: 14px;
    --m-ctl-fs-sm: 13px;
    --m-ctl-fw: 500;
    --m-ctl-fw-strong: 600;
    --m-ctl-gap: 8px;
    --m-ease: cubic-bezier(0.32, 0.72, 0, 1);
    --m-scrim: rgba(15, 23, 42, 0.5);
    --m-z-tabbar: 800;
    --m-z-scrim: 1200;
    --m-z-drawer: 1201;
    --m-z-sheet: 1202;
    --m-z-toast: 1300;
    /* 运行时由 mobile-ui.js 写入，作为 100dvh 不可用时的兜底 */
    --m-app-height: 100vh;
    /* 贴底固定件（底栏 / 面板）的抬升量：iOS Safari 工具栏展开时，可见视口比
       100dvh 矮一截，bottom:0 的固定件会被 Safari 底栏压住。JS 每次 resize 都会
       重写 --m-app-height，所以这里能实时算出那一截是多少。默认 0，桌面与
       不支持 dvh 的环境都不动。 */
    --m-bar-bottom: 0px;
}

/* --------------------------------------------------------------------------
   2. 视口与滚动基础
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    html {
        height: 100%;
        overflow: hidden;
    }

    body {
        height: 100vh;
        height: 100dvh;
        height: var(--m-app-height, 100dvh);
        overflow: hidden;
        overscroll-behavior: none;
        -webkit-text-size-adjust: 100%;
        text-size-adjust: 100%;
    }

    .container {
        height: 100%;
        max-height: 100%;
        border-radius: 0;
        box-shadow: none;
        overflow: hidden;
    }

    /* 触摸设备：去掉 300ms 点击延迟与高亮块 */
    a,
    button,
    .nav-item-content,
    .nav-submenu-item,
    [onclick],
    [role="button"] {
        -webkit-tap-highlight-color: transparent;
        touch-action: manipulation;
    }

    /* 双击缩放整体抑制（仍保留双指缩放），替代原先的全局 JS touchend 拦截 */
    body {
        touch-action: manipulation;
    }

    /* iOS 输入聚焦自动放大：所有表单控件至少 16px */
    input,
    select,
    textarea {
        font-size: 16px;
    }

    /* 滚动容器统一惯性滚动与边界收敛 */
    .page-content,
    .main-sidebar-nav,
    .chat-messages,
    .conversation-list,
    .notification-list,
    .m-sheet-body {
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }

    /* 触控目标下限 */
    button,
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-small,
    .nav-item-content,
    .nav-submenu-item,
    .user-menu-item {
        min-height: var(--m-touch);
    }

    button,
    .btn-primary,
    .btn-secondary,
    .btn-danger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
    }

    /* 桌面专属元素在手机上隐藏 */
    .m-desktop-only {
        display: none !important;
    }
}

/* 手机专属元素默认隐藏，避免桌面端闪现 */
.m-mobile-only {
    display: none;
}

@media (max-width: 767.98px) {
    .m-mobile-only {
        display: block;
    }

    .m-mobile-only.m-flex {
        display: flex;
    }

    .m-mobile-only.m-inline-flex {
        display: inline-flex;
    }
}

/* --------------------------------------------------------------------------
   3. 顶部应用栏
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    header {
        height: var(--m-appbar-h);
        min-height: var(--m-appbar-h);
        padding: 0 var(--m-gutter);
        padding-top: var(--m-safe-top);
        height: calc(var(--m-appbar-h) + var(--m-safe-top));
        min-height: calc(var(--m-appbar-h) + var(--m-safe-top));
        display: flex;
        align-items: center;
        flex-shrink: 0;
        position: relative;
        z-index: 20;
        background: var(--bg-primary);
        border-bottom: 1px solid var(--border-color);
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    }

    .header-content {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
        height: 100%;
    }

    .header-logo-link {
        flex: 1;
        min-width: 0;
        gap: 8px;
        display: flex;
        align-items: center;
    }

    .header-logo-link .brand-logo {
        width: 28px;
        height: 28px;
        flex-shrink: 0;
    }

    .header-logo-link .brand-wordmark--lg {
        font-size: 1.05rem;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .version-badge {
        display: none;
    }

    .header-right {
        gap: 4px;
        flex-shrink: 0;
    }

    .header-actions {
        gap: 4px;
        align-items: center;
    }

    /* 桌面端的次要操作（API 文档 / GitHub / 主题 / 语言）收进"更多"面板 */
    .header-actions > .openapi-doc-btn,
    .header-actions > .lang-switcher,
    .header-actions > .theme-toggle,
    .header-actions > #theme-toggle-btn,
    .header-actions > .theme-toggle-btn {
        display: none !important;
    }

    .header-actions > .notification-menu-container,
    .header-actions > .user-menu-container {
        display: flex;
    }

    /* 汉堡按钮 / 关闭按钮 */
    .m-menu-btn,
    .m-more-btn,
    .m-close-btn {
        width: var(--m-touch);
        height: var(--m-touch);
        min-height: var(--m-touch);
        padding: 0;
        border: none;
        border-radius: 10px;
        background: transparent;
        color: var(--text-primary);
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }

    .m-menu-btn:active,
    .m-more-btn:active,
    .m-close-btn:active {
        background: var(--bg-tertiary);
    }

    .m-menu-btn svg,
    .m-more-btn svg,
    .m-close-btn svg {
        width: 22px;
        height: 22px;
    }

    /* 通知与用户菜单是本层唯一漏掉 44px 下限的常驻控件：38px 在手指下是
       「看得见但点不准」，与上面 --m-touch 的口径必须一致 */
    .notification-btn,
    .user-avatar-btn {
        width: var(--m-touch);
        height: var(--m-touch);
        min-height: var(--m-touch);
        padding: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

/* --------------------------------------------------------------------------
   4. 侧边栏 → 抽屉导航
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .main-layout {
        position: relative;
        overflow: hidden;
        min-height: 0;
        flex: 1;
    }

    .main-sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: var(--m-drawer-w) !important;
        max-width: 86vw;
        height: 100%;
        height: 100dvh;
        height: var(--m-app-height, 100dvh);
        z-index: var(--m-z-drawer);
        transform: translateX(-102%);
        visibility: hidden;
        transition: transform 0.3s var(--m-ease), visibility 0.3s linear;
        box-shadow: none;
        border-right: 1px solid var(--border-color);
        border-radius: 0 var(--m-radius-sheet) var(--m-radius-sheet) 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .main-sidebar.m-open {
        transform: translateX(0);
        visibility: visible;
        box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
    }

    /* 折叠态在手机上无意义，强制展开 */
    .main-sidebar.collapsed {
        width: var(--m-drawer-w) !important;
    }

    .main-sidebar.collapsed .nav-item-content span,
    .main-sidebar.collapsed .nav-submenu-item {
        display: revert;
    }

    /* 桌面折叠按钮由抽屉头部关闭按钮取代 */
    .sidebar-collapse-btn {
        display: none !important;
    }

    /* 抽屉头部（由 mobile-ui.js 注入） */
    .m-drawer-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        padding: 10px 10px 10px 14px;
        padding-top: calc(10px + var(--m-safe-top));
        border-bottom: 1px solid var(--border-color);
        flex-shrink: 0;
    }

    .m-drawer-brand {
        display: flex;
        align-items: center;
        gap: 8px;
        min-width: 0;
    }

    .m-drawer-brand img {
        width: 26px;
        height: 26px;
        flex-shrink: 0;
    }

    .m-drawer-brand .brand-wordmark {
        font-size: 1.02rem;
        white-space: nowrap;
    }

    .m-drawer-search {
        padding: 8px 12px;
        border-bottom: 1px solid var(--border-color);
        flex-shrink: 0;
    }

    .m-drawer-search input {
        width: 100%;
        box-sizing: border-box;
        height: 38px;
        padding: 0 12px;
        border-radius: 10px;
        border: 1px solid var(--border-color);
        background: var(--input-bg);
        color: var(--text-primary);
        font-size: 15px;
        outline: none;
    }

    .m-drawer-search input:focus {
        border-color: var(--accent-color);
    }

    .m-nav-empty {
        padding: 10px 4px 2px;
        font-size: 13px;
        color: var(--text-muted);
        text-align: center;
    }

    .m-nav-empty[hidden] {
        display: none;
    }


    /* 抽屉内的导航项：更大、更好点 */
    .main-sidebar-nav {
        flex: 1;
        overflow-y: auto;
        padding: 6px 8px calc(12px + var(--m-safe-bottom));
    }

    .nav-section-label {
        padding: 12px 10px 6px;
        font-size: 0.7rem;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--text-muted);
    }

    .nav-item-content {
        padding: 11px 12px;
        min-height: 46px;
        font-size: 0.95rem;
        border-radius: 10px;
        gap: 12px;
    }

    .nav-item-content svg {
        width: 20px;
        height: 20px;
        flex-shrink: 0;
    }

    .nav-submenu-item {
        padding: 10px 12px 10px 44px;
        /* 原来是 42px——本层自己定的 --m-touch(44px) 下限被自己漏掉了一处 */
        min-height: var(--m-touch);
        font-size: 0.9rem;
        border-radius: 8px;
    }

    .nav-item.active > .nav-item-content,
    .nav-item-content.active {
        background: color-mix(in srgb, var(--accent-color) 14%, transparent);
        color: var(--accent-color);
    }

    .nav-submenu-item.active {
        background: color-mix(in srgb, var(--accent-color) 12%, transparent);
        color: var(--accent-color);
    }

    /* 菜单搜索命中的项 */
    .m-nav-hit > .nav-item-content,
    .nav-submenu-item.m-nav-hit {
        outline: 1px solid color-mix(in srgb, var(--accent-color) 45%, transparent);
    }

    .m-nav-hidden {
        display: none !important;
    }

    /* 遮罩 */
    .m-scrim {
        position: fixed;
        inset: 0;
        z-index: var(--m-z-scrim);
        /* 全屏 backdrop-filter 在无 GPU 加速环境代价极高，用不透明度替代 */
        background: var(--m-scrim);
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.24s ease, visibility 0.24s linear;
    }

    .m-scrim.m-show {
        opacity: 1;
        visibility: visible;
    }
}

/* --------------------------------------------------------------------------
   5. 底部标签栏
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .content-area {
        padding-bottom: calc(var(--m-tabbar-h) + var(--m-safe-bottom));
        background: var(--bg-secondary);
    }

    #m-tabbar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: var(--m-bar-bottom);
        z-index: var(--m-z-tabbar);
        display: flex;
        align-items: stretch;
        height: calc(var(--m-tabbar-h) + var(--m-safe-bottom));
        padding-bottom: var(--m-safe-bottom);
        padding-left: var(--m-safe-left);
        padding-right: var(--m-safe-right);
        /* 固定底栏带 backdrop-filter 时，软件渲染每帧都要重算模糊，是移动端掉帧主因 */
        background: var(--bg-primary);
        border-top: 1px solid var(--border-color);
        box-shadow: 0 -2px 14px rgba(0, 0, 0, 0.06);
        transition: transform 0.24s var(--m-ease);
    }

    #m-tabbar.m-hidden {
        transform: translateY(110%);
    }

    .m-tab {
        flex: 1 1 0;
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        padding: 6px 2px 4px;
        border: none;
        background: transparent;
        color: var(--text-muted);
        /* 原 0.66rem = 10.56px，是本层自己漏掉的"小字号下限 12px"（见 18.2），
           底部标签栏是主导航，字号必须达标 */
        font-size: 12px;
        line-height: 1.15;
        position: relative;
        border-radius: var(--m-r-ctl);
        transition: color 0.16s ease, transform 0.16s ease;
        -webkit-tap-highlight-color: transparent;
        touch-action: manipulation;
    }

    .m-tab svg {
        width: 23px;
        height: 23px;
        flex-shrink: 0;
    }

    .m-tab span {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .m-tab.m-active {
        color: var(--accent-color);
    }

    .m-tab.m-active svg {
        transform: translateY(-1px) scale(1.06);
    }

    .m-tab:active {
        transform: scale(0.94);
    }

    .m-tab-badge {
        position: absolute;
        top: 3px;
        left: 50%;
        margin-left: 6px;
        min-width: 18px;
        height: 18px;
        padding: 0 5px;
        border-radius: 9px;
        background: var(--error-color, #ef4444);
        color: #fff;
        font-size: 11px;
        line-height: 18px;
        text-align: center;
        font-weight: 600;
        box-sizing: border-box;
    }

    .m-tab-dot {
        position: absolute;
        top: 6px;
        left: 50%;
        margin-left: 8px;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: var(--error-color, #ef4444);
    }

    /* 键盘弹出时让出空间 */
    body.m-keyboard #m-tabbar {
        transform: translateY(110%);
    }

    body.m-keyboard .content-area {
        padding-bottom: 0;
    }
}

/* --------------------------------------------------------------------------
   6. 底部滑出面板（更多 / 快捷操作）
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    #m-sheet {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: var(--m-z-sheet);
        width: 95%;
        margin: 0 auto;
        bottom: calc(8px + var(--m-safe-bottom) + var(--m-bar-bottom));
        background: var(--bg-primary);
        border: 1px solid var(--border-color);
        border-radius: var(--m-radius-sheet);
        box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.32);
        transform: translateY(calc(100% + 24px));
        opacity: 0;
        visibility: hidden;
        transition: transform 0.32s var(--m-ease), opacity 0.2s ease, visibility 0.32s linear;
        max-height: 78vh;
        max-height: 78dvh;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    #m-sheet.m-show {
        transform: translateY(0);
        opacity: 1;
        visibility: visible;
    }

    .m-sheet-grip {
        width: 38px;
        height: 4px;
        border-radius: 2px;
        background: var(--border-color);
        margin: 8px auto 2px;
        flex-shrink: 0;
    }

    .m-sheet-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 6px 16px 10px;
        flex-shrink: 0;
    }

    .m-sheet-title {
        font-size: 0.95rem;
        font-weight: 600;
        color: var(--text-primary);
    }

    .m-sheet-body {
        overflow-y: auto;
        padding: 0 10px 12px;
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 4px;
    }

    .m-sheet-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 6px;
        padding: 12px 4px;
        border: none;
        background: transparent;
        border-radius: 12px;
        color: var(--text-secondary);
        font-size: 0.72rem;
        text-align: center;
        line-height: 1.2;
        min-height: 74px;
    }

    .m-sheet-item:active {
        background: var(--bg-tertiary);
    }

    .m-sheet-item svg {
        width: 22px;
        height: 22px;
    }

    .m-sheet-item.m-on {
        color: var(--accent-color);
        background: color-mix(in srgb, var(--accent-color) 10%, transparent);
    }

    .m-sheet-sep {
        grid-column: 1 / -1;
        height: 1px;
        background: var(--border-color);
        margin: 8px 6px;
    }
}

/* --------------------------------------------------------------------------
   7. 页面头 / 内容区
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .page-header {
        padding: 10px var(--m-gutter);
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 8px;
        align-items: stretch;
        border-radius: 0;
    }

    /* 标题独占一行，操作按钮区满宽换到下一行（避免 space-between 把按钮挤窄、
       主按钮右端出屏被截）。按钮区内部仍可横向滚动，但占满整行、左对齐平齐。 */
    .page-header h1,
    .page-header h2,
    .page-header h3 {
        font-size: 1.05rem;
        line-height: 1.3;
        width: 100%;
    }

    .page-header-actions {
        display: flex;
        align-items: center;
        gap: 6px;
        width: 100%;
        padding-bottom: 2px;
        flex-wrap: wrap;
    }

    .page-header-actions > * {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    .page-content {
        padding: var(--m-gutter) var(--m-gutter) calc(var(--m-gutter) + 8px);
        overflow-x: hidden;
    }

    /* 页面切换的轻量过渡 */
    .page.active {
        animation: m-page-in 0.22s var(--m-ease);
    }

    @keyframes m-page-in {
        from {
            opacity: 0;
            transform: translateY(6px);
        }

        to {
            opacity: 1;
            transform: none;
        }
    }

    /* 卡片化：常见容器统一圆角与内边距 */
    .card,
    .stat-card,
    .metric-card,
    .dashboard-card,
    .panel,
    .settings-section,
    .info-card {
        border-radius: var(--m-radius-card);
    }
}

/* --------------------------------------------------------------------------
   8. 表格 → 横向滚动 + 边缘渐隐
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .m-table-scroll {
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        margin-left: calc(-1 * var(--m-gutter));
        margin-right: calc(-1 * var(--m-gutter));
        padding: 0 var(--m-gutter);
        /* 左右渐隐阴影（Lea Verou 滚动阴影） */
        background:
            linear-gradient(to right, var(--bg-primary) 30%, rgba(255, 255, 255, 0)) left / 32px 100% no-repeat local,
            linear-gradient(to left, var(--bg-primary) 30%, rgba(255, 255, 255, 0)) right / 32px 100% no-repeat local,
            radial-gradient(farthest-side at 0 50%, rgba(15, 23, 42, 0.16), rgba(15, 23, 42, 0)) left / 12px 100% no-repeat scroll,
            radial-gradient(farthest-side at 100% 50%, rgba(15, 23, 42, 0.16), rgba(15, 23, 42, 0)) right / 12px 100% no-repeat scroll;
    }

    .m-table-scroll > table {
        min-width: 560px;
    }

    .m-table-scroll.m-tight > table {
        min-width: 0;
    }

    table,
    .data-table {
        font-size: 0.82rem;
    }

    table th,
    table td,
    .data-table thead th,
    .data-table tbody td {
        padding: 9px 10px;
        white-space: nowrap;
    }

    /* 表格内的按钮别撑破行 */
    table .btn-primary,
    table .btn-secondary,
    table .btn-danger,
    .data-table .btn-primary,
    .data-table .btn-secondary,
    .data-table .btn-danger {
        min-height: 34px;
        padding: 4px 10px;
        font-size: 0.78rem;
    }

    /* 单元格里的长文本允许换行 */
    .data-table td .m-wrap,
    td.m-wrap {
        white-space: normal;
        min-width: 160px;
    }
}

/* --------------------------------------------------------------------------
   9. 表单与按钮
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .form-group,
    .form-row {
        margin-bottom: 12px;
    }

    .form-group label {
        font-size: 0.85rem;
        margin-bottom: 6px;
    }

    input[type="text"],
    input[type="search"],
    input[type="password"],
    input[type="number"],
    input[type="email"],
    input[type="url"],
    input[type="date"],
    input[type="datetime-local"],
    select,
    textarea {
        width: 100%;
        box-sizing: border-box;
        min-height: var(--m-touch);
        padding: 10px 12px;
        border-radius: 10px;
    }

    textarea {
        min-height: 96px;
        resize: vertical;
    }

    /* 一行多列的表单在手机上堆叠 */
    .form-grid,
    .form-row.multi,
    .settings-grid {
        grid-template-columns: 1fr !important;
        display: grid;
        gap: 12px;
    }

    .form-actions,
    .page-header-actions.m-stack {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
    }

    .form-actions > button,
    .modal-footer > button {
        flex: 1 1 auto;
    }
}

/* --------------------------------------------------------------------------
   10. 弹窗 / 下拉 / 浮层
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .modal {
        padding: 0;
    }

    .modal-content {
        width: 100%;
        max-width: 100%;
        height: 100%;
        max-height: 100%;
        margin: 0;
        border-radius: 0;
        border: none;
        animation: m-sheet-up 0.26s var(--m-ease);
        padding-top: var(--m-safe-top);
        padding-bottom: var(--m-safe-bottom);
        box-sizing: border-box;
    }

    @keyframes m-sheet-up {
        from {
            transform: translateY(16px);
            opacity: 0.4;
        }

        to {
            transform: none;
            opacity: 1;
        }
    }

    .modal-header {
        padding: 12px var(--m-gutter);
        flex-shrink: 0;
        position: sticky;
        top: 0;
        background: var(--bg-primary);
        z-index: 2;
        border-bottom: 1px solid var(--border-color);
    }

    .modal-header h2,
    .modal-header h3 {
        font-size: 1.02rem;
    }

    .modal-body {
        padding: var(--m-gutter);
        flex: 1;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .modal-footer {
        padding: 10px var(--m-gutter);
        padding-bottom: calc(10px + var(--m-safe-bottom));
        flex-shrink: 0;
        position: sticky;
        bottom: 0;
        background: var(--bg-primary);
        border-top: 1px solid var(--border-color);
        display: flex;
        gap: 8px;
        flex-wrap: wrap;
    }

    .modal-close,
    .modal .close {
        width: var(--m-touch);
        height: var(--m-touch);
        min-height: var(--m-touch);
    }

    /* 头部下拉：贴边全宽 */
    .notification-dropdown,
    .user-menu-dropdown,
    .lang-dropdown {
        position: fixed !important;
        left: 8px !important;
        right: 8px !important;
        top: calc(var(--m-appbar-h) + var(--m-safe-top) - 4px) !important;
        width: auto !important;
        max-width: none !important;
        max-height: 70vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        border-radius: var(--m-radius-card);
        z-index: 1210;
    }

    /* 角色 / 项目 / 对话模式选择面板在手机上统一为底部抽屉，但**不盖输入框**：
       YG 反馈「输入框和这三个功能点重叠」，实测面板 bottom:66px 恰好盖住输入条
       （.chat-input-container 占据视口底部 186px）。现在 bottom 用 JS 测得的
       --m-panel-offset（输入条顶部到视口底 + 8px 间距），面板始终弹在输入条正上方，
       微信输入面板同款行为：输入条全程可见可点，点输入条即收起面板。
       对话模式面板原先漏在这一组之外，仍按桌面的 position:absolute + left:0 定位，
       在 320–412px 视口下以按钮包裹层为基准取全屏宽度，右边缘实测越界 198px。 */
    .role-selection-panel,
    .chat-project-panel,
    .agent-mode-panel {
        position: fixed !important;
        left: 8px !important;
        right: 8px !important;
        bottom: var(--m-panel-offset, calc(var(--m-tabbar-h) + var(--m-safe-bottom) + 8px)) !important;
        top: auto !important;
        width: auto !important;
        max-width: none !important;
        max-height: var(--m-panel-maxh, 62vh);
        border-radius: var(--m-radius-sheet);
        z-index: 1210;
        /* 面板与背景同色，上向投影把抽屉与聊天区明确分开 */
        box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.16), 0 -1px 0 rgba(0, 0, 0, 0.06);
    }

    /* 轻提示 */
    #m-toast {
        position: fixed;
        left: 50%;
        /* 底栏按 --m-bar-bottom 抬升时提示条要一起抬，否则会压在底栏上 */
        bottom: calc(var(--m-tabbar-h) + var(--m-safe-bottom) + 16px + var(--m-bar-bottom));
        transform: translate(-50%, 12px);
        z-index: var(--m-z-toast);
        max-width: 88vw;
        padding: 10px 16px;
        border-radius: 999px;
        background: rgba(15, 23, 42, 0.92);
        color: #fff;
        font-size: 0.82rem;
        line-height: 1.35;
        text-align: center;
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.2s ease, transform 0.24s var(--m-ease), visibility 0.24s;
        pointer-events: none;
    }

    #m-toast.m-show {
        opacity: 1;
        visibility: visible;
        transform: translate(-50%, 0);
    }
}

/* --------------------------------------------------------------------------
   11. 对话页
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .chat-page-layout {
        flex-direction: row;
    }

    /* 会话列表 → 左侧抽屉 */
    .conversation-sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: var(--m-drawer-w) !important;
        max-width: 86vw;
        height: 100%;
        height: 100dvh;
        height: var(--m-app-height, 100dvh);
        z-index: var(--m-z-drawer);
        transform: translateX(-102%);
        visibility: hidden;
        transition: transform 0.3s var(--m-ease), visibility 0.3s linear;
        border-radius: 0 var(--m-radius-sheet) var(--m-radius-sheet) 0;
        box-shadow: none;
        padding-top: var(--m-safe-top);
    }

    .conversation-sidebar.m-open {
        transform: translateX(0);
        visibility: visible;
        box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
    }

    .conversation-sidebar.collapsed {
        width: var(--m-drawer-w) !important;
    }

    /* 桌面语义的「折叠」在手机上只会加一个无效 class，隐藏掉，让位给关闭按钮 */
    .conversation-sidebar-collapse-btn {
        display: none !important;
    }

    /* 抽屉只盖住左侧 320px，右侧露出的工具条按钮会误触，打开时整体隐藏 */
    body.m-chat-drawer-open .m-chat-bar {
        visibility: hidden;
    }

    .m-chat-drawer-close {
        margin-left: auto;
        flex-shrink: 0;
    }

    .m-chat-drawer-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        padding: 8px 10px 8px var(--m-gutter);
        border-bottom: 1px solid var(--border-color);
        background: var(--bg-primary);
        flex-shrink: 0;
    }

    .m-chat-drawer-title {
        font-size: 0.9375rem;
        font-weight: 600;
        color: var(--text-primary);
    }

    .conversation-header {
        padding: 6px var(--m-gutter);
    }

    .chat-messages {
        padding: 12px 12px 12px 12px;
    }

    /* 消息气泡占满宽度 */
    .chat-messages .message,
    .chat-messages .message-row,
    .chat-messages .conversation-message {
        max-width: 100%;
    }

    /* 轮次导航条在窄屏上太挤，直接收起 */
    #chat-turn-rail {
        display: none !important;
    }

    #chat-return-latest {
        right: 10px;
        bottom: 12px;
    }

    .chat-input-container {
        padding: 8px 10px;
        gap: 6px;
        border-top: 1px solid var(--border-color);
    }

    .chat-input-primary-row {
        gap: 6px;
    }

    .chat-input-leading {
        gap: 6px;
    }

    /* 输入区里的次要按钮收成图标 */
    .chat-input-container .role-selector-text {
        max-width: 88px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* 三个选择面板的关闭按钮桌面是 32×32，手机端放大到 44×44 满足触控 */
    .role-selection-panel-close {
        width: var(--m-touch) !important;
        height: var(--m-touch) !important;
        min-width: var(--m-touch) !important;
        min-height: var(--m-touch) !important;
    }

    /* 发送按钮桌面是 40×40 圆形，手机端补足到 44×44（触控最小命中区） */
    .chat-input-container .send-btn,
    #chat-send-btn {
        width: var(--m-touch) !important;
        min-width: var(--m-touch) !important;
        height: var(--m-touch) !important;
        min-height: var(--m-touch) !important;
    }

    .chat-input-container .send-btn svg {
        width: 20px;
        height: 20px;
    }

    /* ------------------------------------------------------------------
       19.1 触摸命中区统一补齐到 44×44（WCAG 2.5.8 / iOS HIG 最小可点区）
       依据 _mtouch.mjs 实测：顶部栏图标 38×38、通用按钮高 40、
       .btn-small 高 38、设置页导航项高 37、对话工具条高 40 —— 均低于 44。
       只提升命中区高度/宽度，不改字号与配色。
       ------------------------------------------------------------------ */
    .header-logo-link,
    #notification-bell-btn,
    #user-avatar-btn,
    .m-chat-bar-btn,
    .chat-upload-btn,
    .btn-secondary,
    .btn-primary,
    .btn-small,
    .btn-danger,
    .settings-nav-item,
    .settings-custom-select-trigger,
    .page-header-actions button,
    .page-header-actions a {
        min-height: var(--m-touch) !important;
    }

    #notification-bell-btn,
    #user-avatar-btn,
    .chat-upload-btn {
        width: var(--m-touch) !important;
        min-width: var(--m-touch) !important;
    }

    /* 设置页导航 chip「C2」是最短项，实测只有 41px 宽 */
    .settings-nav-item {
        min-width: var(--m-touch) !important;
    }

    /* 复选框/单选框的尺寸见 24.11（已并入按钮体系，避免两处各说一套） */

    .chat-input-field textarea,
    .chat-input-field .chat-textarea {
        max-height: 132px;
        font-size: 16px;
    }

    #chat-hitl-approval-dock {
        border-radius: var(--m-radius-card);
    }

    /* 附件列表横向滚动 */
    .chat-file-list {
        overflow-x: auto;
        flex-wrap: nowrap;
        -webkit-overflow-scrolling: touch;
    }

    /* 对话页移动端工具条（由 mobile-ui.js 注入到 .chat-container 首位） */
    #m-chat-bar {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-shrink: 0;
        padding: 6px 10px;
        background: var(--bg-primary);
        border-bottom: 1px solid var(--border-color);
    }

    .m-chat-bar-spacer {
        flex: 1;
    }

    .m-chat-bar-btn {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        min-height: 36px;
        padding: 0 13px;
        border-radius: 999px;
        border: 1px solid var(--border-color);
        background: var(--bg-tertiary);
        color: var(--text-primary);
        font-size: 0.8125rem;
        font-weight: 500;
        line-height: 1;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
        transition: transform 0.12s var(--m-ease), background 0.15s;
    }

    .m-chat-bar-btn svg {
        width: 16px;
        height: 16px;
        flex-shrink: 0;
    }

    .m-chat-bar-btn:active {
        transform: scale(0.95);
    }

    .m-chat-bar-btn.m-primary {
        background: var(--accent-color);
        border-color: var(--accent-color);
        color: #ffffff;
    }

    /* _mchat12.mjs 实测：会话抽屉条目 38px、会话设置折叠头 39px、
       HITL 审批人开关仅 30px——都藏在抽屉/折叠区，之前全站扫描扫不到。
       这些是可点交互控件，统一提到 44px。 */
    #conversation-sidebar .conversation-item,
    #conversation-sidebar .project-conversation-item,
    #conversation-reasoning-toggle,
    .hitl-reviewer-toggle-btn,
    .hitl-config-select,
    .hitl-config-field .hitl-config-label {
        min-height: var(--m-touch) !important;
    }

    .hitl-reviewer-toggle-btn {
        display: inline-flex;
        align-items: center;
    }
}

/* --------------------------------------------------------------------------
   12. 终端 / WebShell / C2
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .webshell-layout,
    .c2-layout,
    .terminal-layout {
        flex-direction: column !important;
    }

    .webshell-sidebar,
    .c2-sidebar,
    .terminal-sidebar {
        width: 100% !important;
        max-width: none !important;
        max-height: 40vh;
        border-right: none;
        border-bottom: 1px solid var(--border-color);
    }

    .terminal-container,
    .xterm {
        font-size: 12px;
    }

    .xterm-viewport {
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }

    /* 终端工具条横向滚动 */
    .terminal-toolbar,
    .webshell-toolbar,
    .c2-toolbar {
        overflow-x: auto;
        flex-wrap: nowrap;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    .terminal-toolbar::-webkit-scrollbar,
    .webshell-toolbar::-webkit-scrollbar,
    .c2-toolbar::-webkit-scrollbar {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   13. 登录页
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .login-overlay {
        padding: 16px;
        padding-top: calc(16px + var(--m-safe-top));
        padding-bottom: calc(16px + var(--m-safe-bottom));
        align-items: center;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .login-card {
        width: 100%;
        max-width: 420px;
        padding: 22px 18px;
        border-radius: var(--m-radius-sheet);
        margin: auto;
    }

    .login-title {
        font-size: 1.25rem;
    }

    .login-submit {
        min-height: 48px;
        font-size: 1rem;
        width: 100%;
    }
}

/* --------------------------------------------------------------------------
   14. 网格 / 统计卡 / 图表
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .stats-grid,
    .kpi-grid,
    .cards-grid,
    .metrics-grid,
    .dashboard-grid,
    .overview-grid {
        grid-template-columns: 1fr !important;
        gap: 10px;
    }

    .stats-grid.m-two,
    .kpi-grid.m-two {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }

    /* 图表容器限高，避免 canvas 撑出屏幕 */
    canvas {
        max-width: 100% !important;
    }

    .chart-container,
    .graph-container,
    #fact-graph,
    #asset-graph {
        min-height: 260px;
        max-height: 62vh;
    }

    /* 标签 / 徽章不换行溢出 */
    .badge,
    .tag,
    .status-badge,
    .pill {
        white-space: nowrap;
    }
}

/* --------------------------------------------------------------------------
   15. 平板区间（768–1023.98px）：保留桌面结构，仅做收敛
   -------------------------------------------------------------------------- */
@media (min-width: 768px) and (max-width: 1023.98px) {
    .main-sidebar {
        width: 190px;
    }

    .page-content {
        padding: 14px 16px;
    }

    .chat-messages {
        padding: 16px 16px 16px 24px;
    }

    .conversation-sidebar {
        width: 264px;
    }
}

/* --------------------------------------------------------------------------
   16. 横屏手机：把底部栏压薄，让出纵向空间
   -------------------------------------------------------------------------- */
@media (max-width: 900px) and (orientation: landscape) and (max-height: 500px) {
    :root {
        --m-tabbar-h: 46px;
        --m-appbar-h: 44px;
    }

    #m-tabbar .m-tab span {
        display: none;
    }

    #m-tabbar .m-tab svg {
        width: 21px;
        height: 21px;
    }

    .main-sidebar {
        width: min(70vw, 300px) !important;
    }
}

/* --------------------------------------------------------------------------
   17. 无障碍与性能
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    @media (prefers-reduced-motion: reduce) {

        .main-sidebar,
        .conversation-sidebar,
        #m-tabbar,
        #m-sheet,
        .m-scrim,
        #m-toast {
            transition-duration: 0.01ms !important;
        }

        .page.active {
            animation: none !important;
        }
    }

    /* 焦点可见性（键盘 / 辅助设备） */
    a:focus-visible,
    button:focus-visible,
    input:focus-visible,
    select:focus-visible,
    textarea:focus-visible,
    [tabindex]:focus-visible {
        outline: 2px solid var(--accent-color);
        outline-offset: 2px;
    }
}

/* 抽屉/面板打开时锁定背景滚动 */
body.m-locked {
    overflow: hidden !important;
}

/* --------------------------------------------------------------------------
   17.6 选择面板层级修正（关键）
   --------------------------------------------------------------------------
   .chat-input-container 带 container-type: inline-size，会创建独立的层叠
   上下文，导致内部 position:fixed 的 .chat-project-panel / .role-selection-panel
   / .agent-mode-panel 的 z-index:1210 只在容器内部比较，无法与 body 级
   #m-scrim(z-index:1200) 竞争 —— 实测 elementFromPoint 命中 .m-scrim，
   面板收不到任何触摸事件，下滑关闭失效。
   面板打开期间把容器提升到 1215（高于 scrim 1200 / drawer 1201 / sheet 1202，
   低于 toast 1300），容器本身无 position，故需显式 position: relative。
   -------------------------------------------------------------------------- */
body.m-panel-open .chat-input-container {
    position: relative;
    z-index: 1215;
}

/* --------------------------------------------------------------------------
   18. 可读性 / 对比度 / 溢出修复
   --------------------------------------------------------------------------
   依据 _mvisual.mjs 实测：light 主题 --text-muted(#adb5bd) 在白底上只有
   2.07:1，--text-secondary(#6c757d) 4.69:1，均不满足 WCAG AA(4.5:1)；
   11px 标签在手机上不可读；WebShell 工作区比视口宽 5px；设置页下拉选中值
   与 AI 通道 chip 被 flex 压缩到 6~22px 宽。
   以下仅在移动端生效，桌面端保持原样。
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {

    /* 18.1 文本色令牌提到 AA 级 */
    html:not([data-theme="dark"]) {
        --text-secondary: #525d6c;
        /* 白底 6.6:1，灰底(≥#f8fafc)仍 ≥6.2:1 */
        --text-muted: #5b6472;
        /* 白底 6.0:1，浅灰底(#f1f3f5) 5.5:1 —— 原 #adb5bd 仅 2.07:1 */
        /* 原 #3b82f6 作正文色在白底仅 3.68:1，深一档后 5.2:1 */
        --accent-color: #2563eb;
    }

    html[data-theme="dark"] {
        --text-muted: #9ca3af;
        /* #111827 底 7.2:1 */
    }

    /* 18.2 小字号下限 12px */
    .dashboard-severity-insight-score-label,
    .dashboard-severity-insight-urgent-label,
    .dashboard-severity-center-label,
    .dashboard-severity-status-label,
    .mcp-stats-kpi__label,
    .mcp-stats-kpi__chip,
    .pagination-info,
    .pagination-page,
    .hitl-tab-badge,
    .version-badge,
    /* 补漏（_mprobe.mjs 实测仍为 11px）：projects 页的状态胶囊、统计 chip、
       事实筛选标签，以及分页的「每页」标签 */
    .projects-status-pill,
    .projects-stat-chip,
    .projects-fact-filter-label,
    .pagination-page-size {
        font-size: 12px !important;
    }

    /* 18.2b 第九轮（审计覆盖从假 14 页修成真实 29 页后）新暴露的小字。
       asset-overview 的资产类型统计标签 11px、协议表头 9px；
       agents-management 的角色徽章 11px；platform-rbac 的状态胶囊 11px。
       图标字符（如 .tool-expand-icon 的 ▶ 10px）不属于文本，不在此列。 */
    .asset-type-item span,
    .asset-protocol-compact__header p,
    .asset-panel-meta,
    .asset-protocol-columns span,
    .agent-role-badge,
    .rbac-pill {
        font-size: 12px !important;
    }

    /* 18.3 语义色徽章/数值加粗，补偿配色本身的低对比 */
    .dashboard-severity-insight-risk-badge,
    .dashboard-severity-status-value,
    .dashboard-severity-insight-score-value {
        font-weight: 700;
    }

    /* 18.4 WebShell / C2 / 终端工作区横向溢出 */
    .webshell-main,
    .webshell-workspace,
    .c2-main,
    .terminal-main {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box;
        overflow-x: hidden;
    }

    /* 18.5 设置页自定义下拉：选中值不再被压扁 */
    *:has(> .settings-custom-select-value) {
        min-width: 0;
    }

    .settings-custom-select-value {
        flex: 1 1 max-content !important;
        min-width: 0 !important;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* 18.6 AI 通道 chip：容器占满整行并允许换行，chip 不再被压到不可读 */
    *:has(> .ai-channel-editor-chip) {
        flex: 1 1 100% !important;
        flex-wrap: wrap !important;
        width: 100%;
        min-width: 0;
        row-gap: 6px;
    }

    .ai-channel-editor-chip {
        flex: 0 0 auto !important;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* 18.7 对话页人工审批标签：原思路是"缩小 1px 就能完整显示"，实测不成立
       —— 见 24.14 的真实根因（max-width:142px 才是瓶颈，缩字号只是把裁切推迟）。 */

    /* 18.8 dashboard 残留 11px 标签 */
    .dashboard-batch-side-stat-label,
    .dashboard-severity-progress-legend-item span,
    .dashboard-severity-status-text span:not([id]) {
        font-size: 12px !important;
    }

    /* 18.9 硬编码浅灰文本（不随令牌走）逐个纠正 */
    #c2-sessions-count,
    #page-knowledge-management .empty-state p,
    #page-knowledge-management .empty-state div {
        color: var(--text-secondary) !important;
    }

    /* 18.10 语义色徽章 / 状态数值：加深到 AA 级 */
    .role-card-badge.enabled {
        color: #157347;
        background: rgba(40, 167, 69, 0.16);
    }

    #dashboard-status-fp {
        color: #64748b !important;
    }

    /* 18.10b 第七轮补：语义色**文字**再次加深（原 2.09~2.88:1）
       重算方式不是拿白底硬套，而是用 `_mcontrast.mjs` 逐层合成真实有效背景
       （徽章自己还叠了 rgba(34,197,94,0.12)+0.04 两层底 → #dcf6e6），再对
       "保持色相与饱和度、只压亮度"做二分求解，目标 5.0:1（比 AA 的 4.5 留一点
       余量，避免不同背景合成算法得出不同结论）。
       最要紧的是 dashboard 的「安全」徽章与四个状态计数——它们是页面主数据，
       2.09:1 在手机户外基本读不出来。原则：**只动亮度，不动色相**，所以
       「红=高危 / 绿=已修复 / 琥珀=待确认 / 灰=已忽略」的语义完整保留，
       纠正的只是「把填充色直接当文字色用」这个反模式。
       深色主题不受影响（同 18.14 的做法，见 23.4 的对称处理）。 */
    html:not([data-theme="dark"]) #dashboard-severity-risk-level {
        color: #107636 !important;
    }

    html:not([data-theme="dark"]) #dashboard-status-open {
        color: #d81212 !important;
    }

    html:not([data-theme="dark"]) #dashboard-status-confirmed {
        color: #986206 !important;
    }

    html:not([data-theme="dark"]) #dashboard-status-fixed {
        color: #167e3c !important;
    }

    html:not([data-theme="dark"]) #dashboard-status-ignored {
        color: #5a6d88 !important;
    }

    html:not([data-theme="dark"]) .dashboard-recommend-arrow {
        color: #67707f !important;
    }

    html:not([data-theme="dark"]) .projects-fact-filter-label {
        color: #5d718c !important;
    }

    /* 18.10c 必填项星号：样式表里有 4 种写法（`.required-mark` / `.form-required` /
       `.required` / 内联 `style="color: red;"`），同一种语义 4 套颜色。
       其中内联那种是纯 #ff0000，在白底上只有 4.0:1（星号也是文字，归 AA）。
       统一到 18.11 已经在用的 #b02a37（≈6.0:1），一个语义一个颜色。
       内联样式优先级高于普通规则，必须 !important 才压得住。 */
    html:not([data-theme="dark"]) label > span[style*="color: red"],
    html:not([data-theme="dark"]) label > span[style*="color:red"],
    html:not([data-theme="dark"]) label > span.form-required,
    html:not([data-theme="dark"]) label > span.required,
    html:not([data-theme="dark"]) label > span.required-mark {
        color: #b02a37 !important;
    }

    /* 18.11 白底红字按钮：原 #dc3545 仅 4.0:1 */
    .btn-secondary.btn-danger,
    .btn-secondary.btn-delete {
        color: #b02a37 !important;
    }

    /* 18.12 C2 工具栏文字型按钮（无类名，继承 accent 色）；
       排除带内联背景的按钮，避免文字色与底色撞车 */
    #page-c2-sessions button:not(.btn-primary):not(.btn-secondary):not(.btn-danger):not([style*="background"]) {
        color: #1d4ed8 !important;
    }

    /* 18.13 dashboard / HITL / 知识库残留的低对比文本（原 3.3~4.5:1） */
    #dashboard-fix-rate,
    .dashboard-feed-tab {
        color: var(--text-secondary) !important;
    }

    .dashboard-feed-tab.active {
        color: var(--accent-color) !important;
    }

    .dashboard-empty-action,
    #page-knowledge-management .empty-state button,
    #page-knowledge-management .empty-state .btn,
    #hitl-pending-count {
        background-color: #2563eb !important;
        border-color: #2563eb !important;
        color: #ffffff !important;
        font-weight: 600;
    }

    /* 18.14 硬编码灰/蓝文本再深一档（实测 4.0~4.34:1）
       注意：这个深灰只在亮色主题下成立，深色主题下由区块 23.4 覆写。 */
    html:not([data-theme="dark"]) #chat-hitl-shortcut-text,
    html:not([data-theme="dark"]) #page-hitl .hitl-reviewer-toggle-btn,
    html:not([data-theme="dark"]) #page-hitl .hitl-reviewer-toggle-btn span {
        color: #4a5462 !important;
    }

    #projects-list-count {
        color: #0052cc !important;
    }

    #page-settings .required-mark {
        color: #b02a37 !important;
    }
}

/* ==========================================================================
   19. 设置页两栏布局在移动端塌陷（实测正文区仅剩 98px 宽）
   --------------------------------------------------------------------------
   根因：.page-content.settings-layout 是 flex-direction:row，
   .settings-sidebar 固定 200px。390px 视口下 .settings-content 只剩 162px，
   再扣 32px×2 内边距 → 正文 98px，下拉选中值与 AI 通道 chip 被压到 6~22px。
   方案：移动端改单列，左侧导航变成顶部横向滚动的胶囊标签条。
   ========================================================================== */
@media (max-width: 767.98px) {

    #page-settings .page-content.settings-layout {
        flex-direction: column !important;
        padding: 0 0 16px !important;
    }

    #page-settings .settings-sidebar {
        width: 100% !important;
        max-width: 100% !important;
        height: auto !important;
        flex: 0 0 auto !important;
        border-right: 0 !important;
        border-bottom: 1px solid var(--border-color);
        background: var(--bg-primary);
        position: sticky;
        top: 0;
        z-index: 5;
    }

    #page-settings .settings-nav {
        display: flex !important;
        flex-direction: row !important;
        width: 100% !important;
        height: auto !important;
        min-height: 0 !important;
        overflow-x: auto !important;
        overflow-y: hidden !important;
        gap: 6px;
        padding: 8px 10px;
        box-sizing: border-box;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    #page-settings .settings-nav::-webkit-scrollbar {
        display: none;
    }

    #page-settings .settings-nav-item {
        flex: 0 0 auto !important;
        width: auto !important;
        max-width: none !important;
        white-space: nowrap;
        padding: 8px 13px;
        border-radius: 999px;
        font-size: 13px;
        border-left: 0 !important;
        border-bottom: 0 !important;
    }

    #page-settings .settings-nav-item.active {
        background: var(--accent-color);
        color: #ffffff;
    }

    #page-settings .settings-content {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        flex: 1 1 auto !important;
        padding: 14px 12px 24px !important;
        box-sizing: border-box;
        overflow-x: hidden;
    }

    /* 19.1 设置页内所有可伸缩容器放开宽度，禁止再被压缩 */
    #page-settings .settings-section-content,
    #page-settings .settings-subsection,
    #page-settings .ai-channel-manager,
    #page-settings .ai-channel-manager-body,
    #page-settings .ai-channel-editor,
    #page-settings .ai-channel-editor-head,
    #page-settings .ai-channel-editor-meta,
    #page-settings .ai-channel-switcher,
    #page-settings .ai-channel-switcher-field,
    #page-settings .settings-custom-select,
    #page-settings .settings-custom-select-trigger {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        box-sizing: border-box;
    }

    /* 19.2 通道选择区原为 grid，移动端改为单列堆叠 */
    #page-settings .ai-channel-switcher-field {
        display: block !important;
    }

    /* 19.3 设置页宽表（审计日志 / 存储明细）自带 min-width:560px，
       在 390px 视口直接撑破页面 → 改为容器内横向滚动 */
    #page-settings *:has(> table.audit-log-table) {
        overflow-x: auto !important;
        max-width: 100% !important;
        box-sizing: border-box;
        -webkit-overflow-scrolling: touch;
    }

    #page-settings table.audit-log-table {
        max-width: none;
    }

    /* 19.4 审计筛选区：.audit-field 固定 min-width:150px，
       320px 视口下第二个字段被挤出屏幕 → 允许压缩 + 整行换行 */
    #page-settings .audit-field {
        min-width: 0 !important;
        flex: 1 1 140px !important;
    }

    #page-settings .audit-datetime-field,
    #page-settings .audit-datetime-btn {
        min-width: 0 !important;
    }

    #page-settings *:has(> .audit-field) {
        flex-wrap: wrap !important;
    }
}

/* --------------------------------------------------------------------------
   20. 页面头功能按钮布局 / 工具条触控 / 底部安全区
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {

    /* 20.1 页面头功能按钮位置
       根因：style.css:19132 的 @media (max-width: 768px) 把 .page-header-actions
       设为 flex-direction: column; align-items: stretch;。本文件此前只覆盖了
       align-items / flex-wrap / width，没有覆盖 flex-direction，于是
       「刷新 / 批量导入 / 新增资产」这类按钮在手机上各占一行、各自居中。
       改为横向换行自适应排列：能一行就一行（宽度 ≥444 左右），放不下自动换行，
       任何设备宽度下按钮都完整可见、无需横向滑动。
       注意：不要改回 nowrap + overflow-x —— 那会让主按钮（保存/新建）被推到
       视口外需横滑才能看到，违背"自适应"诉求。 */
    .page-header-actions,
    .page-header > .page-header-actions,
    .platform-rbac-page .page-header-actions,
    .mcp-monitor-page .page-header-actions {
        flex-direction: row !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        justify-content: flex-start !important;
        gap: 8px !important;
        width: 100%;
        padding-bottom: 0;
    }

    /* 20.1b「已与服务端同步」状态块（tool-guard）84px 太占宽，会把主按钮挤出
       一行。允许它在窄容器里收缩省略，留出空间给按钮。 */
    .page-header-actions > .tool-guard-save-state {
        flex: 0 1 auto;
        min-width: 0;
        max-width: 96px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 11px;
    }

    .page-header-actions > * {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* 头部文字按钮统一到可点尺寸并留出横向内边距 */
    .page-header-actions > button,
    .page-header-actions > a.btn,
    .page-header-actions > .btn-primary,
    .page-header-actions > .btn-secondary,
    .page-header-actions > .btn-danger {
        min-height: var(--m-touch) !important;
        min-width: 64px;
        padding-left: 14px !important;
        padding-right: 14px !important;
    }

    /* 20.2 图标型按钮（分页 ‹ › 等）原本只有 20~32px 宽，点不中 */
    .btn-icon-pagination,
    .btn-icon,
    .table-icon-btn,
    .page-size-select {
        min-width: var(--m-touch) !important;
        min-height: var(--m-touch) !important;
    }

    /* 20.3 工作流画布工具条：5 个按钮挤在 32px 宽里，文字被截断 */
    .workflow-toolbar,
    .workflow-toolbar-actions,
    .workflow-canvas-toolbar,
    .workflow-toolbar-group {
        flex-wrap: wrap !important;
        gap: 6px !important;
    }

    .workflow-toolbar-button,
    .workflow-save-button {
        min-width: 72px !important;
        min-height: var(--m-touch) !important;
        padding: 0 10px !important;
        font-size: 12px;
    }

    /* 20.4 小号按钮保底触控高度（原 .btn-small 只有 30~36px 高） */
    .btn-small {
        min-height: var(--m-touch) !important;
        padding: 0 12px !important;
    }

    /* 20.5 底部安全区：在标签栏之上再留 10px，
       避免滚到底后最后一行控件仍贴住标签栏 */
    .content-area {
        padding-bottom: calc(var(--m-tabbar-h) + var(--m-safe-bottom) + 10px);
    }

    /* 20.6 页面内自定义下拉触发器高度不足 44px */
    .settings-custom-select-trigger,
    .monitor-filter-select-trigger,
    .projects-filter-select-trigger {
        min-height: var(--m-touch) !important;
    }

    /* 20.7 对话页顶部工具条按钮原为 36px 高 */
    .m-chat-bar-btn {
        min-height: var(--m-touch) !important;
        padding: 0 12px !important;
    }

    /* 20.8 上传等纯图标按钮宽高都不足 */
    .chat-upload-btn {
        min-width: var(--m-touch) !important;
        min-height: var(--m-touch) !important;
    }
}

/* ==========================================================================
   21. 内容区滚动模型修复（手机端局部滚动容器塌陷）
   --------------------------------------------------------------------------
   桌面端这些页面用「固定高度容器 + 内部 overflow:hidden」把滚动锁在局部，
   例如 .asset-list-card 自己滚分页。390x664 的手机视口下父级 flex 空间不足，
   这些局部滚动容器被压到 16~48px 高，内部控件被 overflow:hidden 裁掉，
   而且无论怎么滑动都露不出来。改成「内容区整页滚动 + 内部容器按内容展开」。
   ========================================================================== */
@media (max-width: 767.98px) {

    /* 21.1 资产库：.asset-list-card 实测仅 48px 高，里面的分页控件 183px 全被裁 */
    .page-content.asset-content {
        display: block !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        -webkit-overflow-scrolling: touch;
    }

    .asset-list-card {
        display: block !important;
        flex: none !important;
        height: auto !important;
        max-height: none !important;
        min-height: 0 !important;
        overflow: visible !important;
    }

    #asset-pagination,
    .pagination-container.pagination-fixed {
        position: static !important;
        height: auto !important;
        min-height: 0 !important;
    }

    /* 21.2 技能管理：#skills-list 实测仅 16px 高，5483px 内容挤成一条缝 */
    .page-content.page-content-with-pagination {
        display: block !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        -webkit-overflow-scrolling: touch;
    }

    #skills-list,
    .skills-grid {
        flex: none !important;
        height: auto !important;
        max-height: none !important;
        min-height: 0 !important;
        overflow: visible !important;
    }

    #skills-pagination {
        position: static !important;
        height: auto !important;
    }

    /* 21.3 平台 RBAC：.rbac-panel-detail 实测 2px、#rbac-tab-roles 28px */
    .platform-rbac-page .page-content {
        display: block !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        -webkit-overflow-scrolling: touch;
    }

    #rbac-view-users,
    .rbac-layout {
        display: block !important;
        height: auto !important;
        min-height: 0 !important;
        overflow: visible !important;
    }

    .rbac-panel,
    .rbac-tab-panel,
    #rbac-tab-roles,
    #rbac-tab-permissions,
    #rbac-tab-resources,
    #rbac-tab-audit {
        flex: none !important;
        height: auto !important;
        max-height: none !important;
        min-height: 0 !important;
        overflow: visible !important;
    }

    /* 21.4 工作流：侧栏节点列表与画布工具条被 overflow:hidden 裁掉 */
    .page-content.workflow-page-content {
        display: block !important;
        min-height: 0 !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        -webkit-overflow-scrolling: touch;
    }

    .workflow-sidebar {
        height: auto !important;
        max-height: none !important;
        overflow: visible !important;
    }

    /* 画布本身需要一块固定高度，不能被内容压成 0 */
    .workflow-main {
        height: auto !important;
        min-height: 380px !important;
        max-height: none !important;
        overflow: visible !important;
    }

    /* 21.5 C2 会话「重置」按钮实测 24x44，横向点不中 */
    #page-c2-sessions button,
    .c2-sessions-page button {
        min-width: 44px !important;
    }
}

/* --------------------------------------------------------------------------
   22. 平板竖屏（768–1023.98px）：对话页三个选择面板同样贴底
   桌面规则 style.css:29402 的 @media (max-width:768px) 把 .role-selection-panel /
   .agent-mode-panel 改成 width:calc(100vw - 16px) + left:-8px，但仍是
   position:absolute，定位基准是各自在 100–200px 处的按钮包裹层；实测 768x1024
   下两者右边缘分别越界 563px 与 654px，面板完全落在屏幕之外。
   -------------------------------------------------------------------------- */
@media (min-width: 768px) and (max-width: 1023.98px) {
    .role-selection-panel,
    .chat-project-panel,
    .agent-mode-panel {
        position: fixed !important;
        left: 16px !important;
        right: 16px !important;
        bottom: var(--m-panel-offset, 16px) !important;
        top: auto !important;
        width: auto !important;
        max-width: none !important;
        max-height: var(--m-panel-maxh, 62vh);
        border-radius: var(--m-radius-sheet);
        z-index: 1210;
        box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.16), 0 -1px 0 rgba(0, 0, 0, 0.06);
    }
}

/* --------------------------------------------------------------------------
   22.2 触摸型横屏平板（1024–1439.98px + pointer:coarse）：模式面板仍会越界
   _mchat11.mjs 实测 1024x768 下 .agent-mode-panel 右边缘 1035 > 1024（offR=11）。
   桌面鼠标保持原样（_mdesktop.mjs 已证明 1024x768 的桌面溢出为既有问题，不归本层管）。
   -------------------------------------------------------------------------- */
@media (min-width: 1024px) and (max-width: 1439.98px) and (pointer: coarse) {
    .role-selection-panel,
    .chat-project-panel,
    .agent-mode-panel {
        position: fixed !important;
        left: 16px !important;
        right: 16px !important;
        bottom: var(--m-panel-offset, 16px) !important;
        top: auto !important;
        width: auto !important;
        max-width: none !important;
        max-height: var(--m-panel-maxh, 62vh);
        border-radius: var(--m-radius-sheet);
        z-index: 1210;
        box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.16), 0 -1px 0 rgba(0, 0, 0, 0.06);
    }
}

/* --------------------------------------------------------------------------
   23. 深色主题对比度修正（_mdark.mjs 全站实测出 4 类违规）
   深色令牌里 --accent-color 是 #60a5fa（浅蓝），配白字只有 2.54:1；
   语义绿 #15803d 在 #111f29 底上 3.33:1；危险红 #b02a37 在 #111827 底上 2.73:1。
   统一只改文字色、不动背景，保证亮色主题与桌面端完全不受影响。
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {

    /* 23.1 浅蓝底(#60a5fa)上的白字 → 深墨蓝 #0b1120，实测 9.4:1 */
    html[data-theme="dark"] .btn-primary,
    html[data-theme="dark"] .btn-primary:hover,
    html[data-theme="dark"] .btn-primary:focus,
    html[data-theme="dark"] .m-chat-bar-btn.m-primary,
    html[data-theme="dark"] .settings-nav-item.active,
    html[data-theme="dark"] .chat-input-container .send-btn,
    html[data-theme="dark"] .ai-channel-save-btn,
    html[data-theme="dark"] #hitl-pending-count,
    html[data-theme="dark"] .dashboard-empty-action,
    html[data-theme="dark"] #page-knowledge-management .empty-state button,
    html[data-theme="dark"] #page-knowledge-management .empty-state .btn {
        color: #0b1120 !important;
    }

    html[data-theme="dark"] .btn-primary svg,
    html[data-theme="dark"] .m-chat-bar-btn.m-primary svg,
    html[data-theme="dark"] .chat-input-container .send-btn svg,
    html[data-theme="dark"] .settings-nav-item.active svg {
        color: #0b1120 !important;
        fill: currentColor;
        stroke: currentColor;
    }

    /* 23.2 语义绿在深底上提亮：#15803d → #4ade80，实测 8.9:1 */
    html[data-theme="dark"] .is-success,
    html[data-theme="dark"] .dashboard-kpi-sub-text.is-success,
    html[data-theme="dark"] .mcp-stats-kpi__value--rate.is-success,
    html[data-theme="dark"] .mcp-stats-kpi__status.is-success,
    html[data-theme="dark"] .mcp-stats-tool-item__rate.is-success,
    html[data-theme="dark"] .mcp-stats-rate.is-success {
        color: #4ade80 !important;
    }

    /* 刷新闪烁态「上次更新」徽章同样是硬编码 #15803d */
    html[data-theme="dark"] .dashboard-last-updated.is-flash {
        color: #4ade80 !important;
        background: rgba(74, 222, 128, 0.14);
    }

    /* 23.3 危险红在深底上提亮：#b02a37 → #f87171，实测 6.4:1 */
    html[data-theme="dark"] {
        --danger-color: #f87171;
        --success-color: #4ade80;
    }

    html[data-theme="dark"] .required-mark,
    html[data-theme="dark"] .btn-danger,
    html[data-theme="dark"] .btn-secondary.btn-small.danger,
    html[data-theme="dark"] .text-danger,
    html[data-theme="dark"] .is-danger {
        color: #f87171 !important;
    }

    /* 23.4 18.14 的硬编码深灰只对亮色成立，深色下交回 --text-muted(#9ca3af) */
    html[data-theme="dark"] #chat-hitl-shortcut-text,
    html[data-theme="dark"] #page-hitl .hitl-reviewer-toggle-btn,
    html[data-theme="dark"] #page-hitl .hitl-reviewer-toggle-btn span {
        color: var(--text-muted) !important;
    }
}

/* ==========================================================================
   24. 按钮 / 控件视觉体系统一
   --------------------------------------------------------------------------
   _mbtn.mjs 在 27 页上实测 645 个可点控件，改造前的客观问题：

     · style.css 里**没有 .btn 基类**（`^\s*\.btn\s*\{` 零命中），因此没有尺寸
       基准：.btn-danger 是唯一 10px 20px / 15px 的"大一号"按钮，.btn-search 与
       .pagination-btn 固定 height:32px，.btn-icon-pagination 只有 20x20，
       .settings-custom-select-trigger 同一页存在 32/38/42/48px 四种高度。
     · 类语义被打破：.btn-secondary 一个类出现 **12 种签名**（205 个实例）——
       高度 44/52/71、圆角 6px/8px、字号 13px/14px、横内边距 12/14/16/18px；
       .btn-primary 6 种、.btn-small 4 种。
     · 度量发散：圆角 11 种（0/4/5/6/7/8/10/12/14/999px/50%）、字号 9 种
       （10.56~16px）、字重 7 档（400/500/520/560/600/650/700）。
     · 同一行内尺寸互不相同（39 处容器）：mcp-management 分页「上一页/下一页」
       被 style.css:11867 的 `flex:1 + max-width:120px` 压到 53px 宽、中文换行
       撑高成 53x71，而同行「首页/末页」是 44x52；资产库工具条三个按钮的横内边距
       是 16/16/6；工作流工具条的圆角是 7px 与 0px。
     · 手机主导航（底部标签栏）字号 10.56px、角标 9.6px，低于本层 18.2 自己
       定的 12px 下限。

   本节只做"收敛"，不改任何布局结构与配色（配色仍由 18/23 节负责）：
     按钮高度  -> 44px（触控下限，也是唯一档）
     圆角      -> 矩形控件 10px / 方形图标按钮 12px / 标签胶囊 999px
     字号      -> 标准 14px、小号与胶囊 13px
     字重      -> 常规 500、主要行动与选中态 600
     横内边距  -> 标准 16px、小号 12px
     分组间距  -> 8px

   两条刻意不碰：`.btn-compact`（style.css:32833 显式 `min-height:0`，它是侧栏
   分页的紧凑按钮，抬到 44px 会把侧栏撑破）与 `.chat-files-dropdown-item`
   （是左对齐的菜单行，不是按钮，单独定义）。
   ========================================================================== */
@media (max-width: 767.98px) {

    /* 24.1 基底：所有"按钮化控件"共用同一套度量，取代原先散落在
       20.1 / 20.2 / 20.4 / 20.6 / 20.7 / 20.8 的逐类补丁。
       只设左右内边距，不动上下——保持 style.css 里各族的垂直视觉重心。 */
    :is(.btn-primary, .btn-secondary, .btn-danger, .btn-ghost,
        .btn-small, .btn-sm, .btn-filter, .btn-search,
        .mcp-detail-btn, .btn-delete, .btn-loading,
        .page-header-actions > button, .page-header-actions > a.btn,
        .tools-actions button, .attack-chain-action-btn,
        .attack-chain-filters button, .robot-manager-toolbar button,
        .robot-command-entry button, .asset-batch-menu button,
        .workflow-toolbar-button, .workflow-save-button,
        .m-chat-bar-btn, .chat-session-shortcut, .role-selector-btn,
        .new-chat-btn, .ai-channel-save-btn, .dashboard-empty-action,
        .dashboard-severity-status-filter-btn, .empty-state button,
        .workflow-node-palette button, .c2-sessions-quick-links button,
        .syntax-guide-toggle) {
        min-height: var(--m-ctl-h) !important;
        padding-left: var(--m-ctl-pad-x) !important;
        padding-right: var(--m-ctl-pad-x) !important;
        font-size: var(--m-ctl-fs) !important;
        font-weight: var(--m-ctl-fw) !important;
        border-radius: var(--m-r-btn) !important;
        line-height: 1.25 !important;
        box-sizing: border-box;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* 24.2 小号档：横内边距收到 12px，字号 13px（高度仍是 44px 触控下限） */
    :is(.btn-small, .btn-sm, .btn-filter, .btn-search,
        .btn-icon-pagination, .mcp-detail-btn,
        .tools-actions button, .workflow-toolbar-button,
        .workflow-save-button, .m-chat-bar-btn, .chat-session-shortcut,
        .workflow-node-palette button, .c2-sessions-quick-links button,
        .syntax-guide-toggle, .robot-command-entry button) {
        padding-left: var(--m-ctl-pad-x-sm) !important;
        padding-right: var(--m-ctl-pad-x-sm) !important;
        font-size: var(--m-ctl-fs-sm) !important;
    }

    /* 24.3 图标档：纯图标按钮一律 44x44 正方形，圆角略大于文字按钮，
       让"图标块"与"文字条"在一起时不显单薄。
       （原来 .chat-upload-btn 36x36/圆角 10、.btn-icon-pagination 20x20、
       顶部图标 38x38，三种口径并存） */
    :is(.btn-icon, .btn-icon-pagination, .chat-upload-btn,
        .m-menu-btn, .m-more-btn, .m-close-btn, .projects-list-item-menu,
        #notification-bell-btn, #user-avatar-btn, .header-actions .btn-icon) {
        width: var(--m-ctl-h) !important;
        min-width: var(--m-ctl-h) !important;
        height: var(--m-ctl-h) !important;
        min-height: var(--m-ctl-h) !important;
        padding: 0 !important;
        border-radius: var(--m-r-icon) !important;
        font-size: var(--m-ctl-fs-sm) !important;
        font-weight: var(--m-ctl-fw) !important;
    }

    :is(.btn-icon, .chat-upload-btn, .m-menu-btn, .m-more-btn, .m-close-btn,
        #notification-bell-btn, #user-avatar-btn) svg {
        width: 20px;
        height: 20px;
    }

    /* 24.4 行内文字按钮（.btn-link）：原来只有 32px 宽、圆角 0、横内边距 6px，
       和旁边 6px 圆角按钮排在一行时基线都不齐。给它按钮的位置感，但保持无底无框。 */
    .btn-link {
        min-width: var(--m-touch) !important;
        min-height: var(--m-ctl-h) !important;
        padding-left: var(--m-ctl-pad-x-sm) !important;
        padding-right: var(--m-ctl-pad-x-sm) !important;
        font-size: var(--m-ctl-fs-sm) !important;
        font-weight: var(--m-ctl-fw) !important;
        border-radius: var(--m-r-btn) !important;
        background: transparent !important;
        box-shadow: none !important;
    }

    /* 24.5 标签 / 胶囊档：凡是"一组里选一个"的控件统一胶囊形，
       原来 .rbac-tab 是 0 圆角 + 1px 内边距、.projects-tab 是 8px、
       .hitl-page-tab 是 0 圆角、.asset-period-switch 是 11px 字号、
       .c2-tasks-time-preset-btn 是 12px 字号。 */
    :is(.rbac-tab, .projects-tab, .dashboard-feed-tab, .hitl-page-tab,
        .rbac-workspace-tab, .settings-nav-item, .preset-chip,
        .asset-period-switch button, .c2-tasks-time-preset-btn,
        .hitl-reviewer-toggle-btn) {
        min-height: var(--m-ctl-h) !important;
        padding-left: 14px !important;
        padding-right: 14px !important;
        font-size: var(--m-ctl-fs-sm) !important;
        font-weight: var(--m-ctl-fw) !important;
        border-radius: var(--m-r-pill) !important;
        line-height: 1.25 !important;
        white-space: nowrap;
        box-sizing: border-box;
    }

    :is(.rbac-tab, .projects-tab, .dashboard-feed-tab, .hitl-page-tab,
        .rbac-workspace-tab, .settings-nav-item, .preset-chip,
        .asset-period-switch button, .c2-tasks-time-preset-btn,
        .hitl-reviewer-toggle-btn).is-active,
    :is(.rbac-tab, .projects-tab, .dashboard-feed-tab, .hitl-page-tab,
        .rbac-workspace-tab, .settings-nav-item, .preset-chip,
        .asset-period-switch button, .c2-tasks-time-preset-btn,
        .hitl-reviewer-toggle-btn).active {
        font-weight: var(--m-ctl-fw-strong) !important;
    }

    /* 分段控件（周期切换）容器跟着胶囊化，3px 内衬保留 */
    .asset-period-switch {
        border-radius: var(--m-r-pill) !important;
        padding: 3px !important;
        gap: 2px !important;
        display: inline-flex !important;
        align-items: center;
    }

    /* 24.5b rbac-summary-count 是"查看明细 70"的**虚线文字按钮**，style.css 设计为
       border-radius:0 + 虚线底边 + color:secondary。上面把它误纳入胶囊档，被强制
       成全圆角、无背景的怪圈（实测 42×44、border-radius:999px）。排除它并还原
       虚线文字按钮本义，仅给移动端 44px 命中高。 */
    .rbac-summary-count--interactive {
        border-radius: 0 !important;
        background: none !important;
        min-height: var(--m-touch) !important;
        padding: 0 2px 1px !important;
        display: inline-flex !important;
        align-items: flex-end;
    }

    /* 24.6 下拉触发器：与按钮同高同圆角，但文字左对齐、右端留给箭头。
       原来同一类在资产库有 32/38/42/48px 四种高度、在内距 9/11/12 之间跳动。 */
    :is(.settings-custom-select-trigger, .monitor-filter-select-trigger,
        .projects-filter-select-trigger, .vuln-filter-select-trigger,
        .tasks-filter-select-trigger, .chat-files-filter-select-trigger,
        .c2-form-select-trigger, .asset-custom-select .settings-custom-select-trigger) {
        min-height: var(--m-ctl-h) !important;
        padding-left: var(--m-ctl-pad-x-sm) !important;
        padding-right: var(--m-ctl-pad-x-sm) !important;
        font-size: var(--m-ctl-fs) !important;
        font-weight: var(--m-ctl-fw) !important;
        border-radius: var(--m-r-ctl) !important;
        line-height: 1.25 !important;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
    }

    /* 24.7 分页结构修复
       实测：mcp-management 分页里「上一页/下一页」53x71（中文被挤成两行），
       同行「首页/末页」44x52 —— style.css:11867 在 ≤768px 给
       `.pagination-fixed .pagination-controls .btn-secondary` 设了
       `flex:1; min-width:60px; max-width:120px`，按钮被压窄后文字换行撑高。
       这里取消伸缩、禁止换行、允许整行折行，四个按钮回到同一高度。 */
    :is(.pagination-controls, .pagination-fixed .pagination-controls,
        .pagination) {
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        gap: 6px !important;
    }
    :is(.pagination-controls, .pagination-fixed .pagination-controls) > :is(button, .btn-secondary, .btn-primary) {
        flex: 0 0 auto !important;
        max-width: none !important;
        min-width: var(--m-touch) !important;
        min-height: var(--m-ctl-h) !important;
        padding-left: var(--m-ctl-pad-x-sm) !important;
        padding-right: var(--m-ctl-pad-x-sm) !important;
        font-size: var(--m-ctl-fs-sm) !important;
        border-radius: var(--m-r-ctl) !important;
        white-space: nowrap !important;
    }

    /* 24.8 分组间距统一：控件成组出现时一律 8px，原来 6/8/10/12/16 混用 */
    :is(.page-header-actions, .tools-actions, .rbac-tabs, .projects-tabs,
        .dashboard-feed-tabs, .attack-chain-filters, .asset-toolbar-main,
        .workflow-toolbar, .workflow-toolbar-group, .workflow-node-palette,
        .chat-composer-context, .chat-composer-footer-leading,
        .c2-tasks-time-presets, .c2-sessions-quick-links, .settings-nav,
        .asset-saved-views, .header-actions, .hitl-reviewer-toggle,
        .syntax-guide-actions, .rbac-summary-permissions, .empty-state) {
        gap: var(--m-ctl-gap) !important;
    }

    /* 24.9 可点卡片 / 行的圆角归一到卡片档（原为 0/4/8/10/12 五种混用） */
    :is(.dashboard-resource-item, .dashboard-severity-legend-item,
        .dashboard-severity-status-cell, .dashboard-access-stat,
        .dashboard-recommend-item, .tool-guard-rule-summary,
        .rbac-user-row, .stat-card, .dashboard-kpi-card) {
        border-radius: var(--m-radius-card) !important;
    }

    /* 24.10 层级：主要行动与选中态用 600，其余 500。
       原来同一个界面里并存 400/500/520/560/600/650 六档字重。 */
    :is(.btn-primary, .new-chat-btn, .ai-channel-save-btn,
        .rbac-summary-count, .empty-state button,
        .role-selector-btn.m-primary) {
        font-weight: var(--m-ctl-fw-strong) !important;
    }

    .chat-input-container .send-btn {
        font-weight: var(--m-ctl-fw-strong) !important;
    }

    /* 24.11 表单勾选类控件：视觉 24px，命中面 44x44（由整行 label 提供）
       实测结论（_mchk2.mjs，运行时注入对照实验）：Chrome 对
       input[type=checkbox]/radio 这类替换元素**不采纳作者的 padding**——连运行时
       注入 `input[type=checkbox]{padding:10px !important}` 都不生效（computed
       padding 恒为 0、外框恒为 24x24）。按 CSS 层叠规范，!important 的优先级是
       反的：UA 的 !important 高于作者的 !important，而 Blink 的 UA 样式表对勾选框
       强制了内衬。所以"把本体撑到 44px"这条路在本平台上不成立（真撑大了视觉上也
       是个巨大方框）。正确做法是：本体保持 24px 视觉，把 44px 命中面交给整行
       label —— 实测该行 68x44，点行内任意位置都能切换。 */
    input[type="checkbox"],
    input[type="radio"] {
        width: 30px !important;
        height: 30px !important;
        min-width: 30px !important;
        min-height: 30px !important;
        /* 仍需 !important：style.css 的 `.auto-refresh-toggle input[type=checkbox]`
           （18871）等后代选择器特异性更高，会把它按回 18px */
    }

    label:has(> input[type="checkbox"]),
    label:has(> input[type="radio"]) {
        min-height: var(--m-touch);
        display: inline-flex;
        align-items: center;
        gap: 8px;
    }

    /* 24.12 胶囊标签条：横向滚动，不换行、不裁切
       _mprobe.mjs 实测 `.hitl-page-tabs` 在 320px 视口 clientW=292 / scrollW=371，
       且 overflow-x 是 visible —— 第 4 个页签右边缘 385 > 视口 320，被祖先
       `.page-content{overflow-x:hidden}` 直接切掉，**手指也滑不出来**：一个点不到
       的页签。390px 下也已溢出 9px。这里沿用文件里既有的"横向滚动 + nowrap"惯例
       （见 6.x 终端工具条、19.3 宽表），把溢出交还给标签条自己滚动。
       只列真正单行排布的胶囊条，工作流工具条这类靠换行展示全部的容器不动。 */
    :is(.hitl-page-tabs, .projects-tabs, .dashboard-feed-tabs, .rbac-tabs,
        .rbac-workspace-tabs, .c2-tasks-time-presets) {
        flex-wrap: nowrap !important;
        overflow-x: auto !important;
        overflow-y: hidden !important;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
    }

    :is(.hitl-page-tabs, .projects-tabs, .dashboard-feed-tabs, .rbac-tabs,
        .rbac-workspace-tabs, .c2-tasks-time-presets)::-webkit-scrollbar {
        display: none;
    }

    /* 条目不许被压扁（否则"横向滚动"会退化成"每个页签都被挤成省略号"） */
    :is(.hitl-page-tabs, .projects-tabs, .dashboard-feed-tabs, .rbac-tabs,
        .rbac-workspace-tabs, .c2-tasks-time-presets) > * {
        flex: 0 0 auto !important;
        scroll-snap-align: start;
    }

    /* 24.13 projects 页残留小字号已并入 18.2 的下限清单（保持单一出处） */

    /* 24.14 对话页「人工审批：关闭」按钮：文字不再被截断
       实测根因（_mprobe.mjs）：按钮被 style.css 的 max-width:142px 钉死，而内衬
       16px 在图标+间距之外只剩 69px 给标签，标签实际需要 84px → 恒显省略号
       （iPhone SE 上只剩 49px）。原 18.7 用"字号缩 1px"绕，属于治标。
       底部这一行总宽 368px，上传键 44 + 发送键 44 之后仍有富余，放宽即可完整显示。 */
    #chat-hitl-shortcut {
        max-width: none !important;
        padding-left: var(--m-ctl-pad-x-sm) !important;
        padding-right: var(--m-ctl-pad-x-sm) !important;
        font-size: var(--m-ctl-fs-sm) !important;
        overflow: hidden !important;
    }

    /* 24.9 会话快捷按钮的文本由 JS 动态写入（如「Agent 审查：关闭 · OpenAI 协议模型 · qwen3-max」），
       实测比按钮宽 30px+。原来强制 nowrap + visible 会被按钮容器裁掉尾部；
       改为在按钮内收缩，超出显示省略号（回到 style.css:44875 的初衷）。 */
    #chat-hitl-shortcut-text {
        flex: 1 1 auto !important;
        min-width: 0 !important;
        font-size: var(--m-ctl-fs-sm) !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
        text-align: left;
    }

    /* 24.15 自制开关：**不得**套用 24.11 的原生勾选框尺寸
       （必须排在 24.11 之后，靠层叠接管）
       tool-guard 页「调用拦截」把复选框做成了开关：tool-guard.css:68 定义
       30×18 胶囊轨道 + 12px 圆形滑块（::after，left:2，选中 translateX(12)）；
       tool-guard.js:205-218 同时还给这个 input 挂了 `.theme-checkbox` 类。
       24.11 是 `input[type=checkbox]{width/height:24px !important}`——特异性
       (0,1,1) 低于 `.tool-guard-page .tool-guard-switch input[type=checkbox]`
       (0,2,1)，但一加 !important 就反超，于是：
         · 轨道被压成 24×24 方块（本该是 30×18 的胶囊）
         · 滑块仍是 left2 + 12 + 位移12 = 右缘 26，**越出轨道**
         · 未选中态：24 宽轨道里左侧一个 12px 圆点、右侧空 10px → 坏掉的控件
       这里按原设计还原轨道与滑块，并用更高特异性接管两态位移。 */
    .tool-guard-page .tool-guard-switch input[type="checkbox"] {
        width: 30px !important;
        height: 18px !important;
        min-width: 30px !important;
        min-height: 18px !important;
        border-radius: 999px !important;
        padding: 0 !important;
        position: relative !important;
    }

    /* 未选中态：滑块归位。transform 必须显式声明，否则会从 24.16 的命中区
       规则里继承 `translate(-50%,-50%)`，把滑块挪到轨道外 */
    .tool-guard-page .tool-guard-switch input[type="checkbox"]::after {
        content: '' !important;
        position: absolute !important;
        top: 2px !important;
        left: 2px !important;
        width: 12px !important;
        height: 12px !important;
        border-radius: 50% !important;
        background: #fff !important;
        transform: none !important;
    }

    /* 选中态：left2 + 滑块12 + 位移12 = 右缘 26，轨道内宽 28（30 减 1px 边框），
       右侧留 2px —— 与未选中态左侧留 2px 对称 */
    .tool-guard-page .tool-guard-switch input[type="checkbox"]:checked::after {
        transform: translateX(12px) !important;
    }

    /* 裸开关：label 内只有 input、没有文字时宽度只有 24px，给它 44 命中面。
       `justify-content` 在 auto 宽度下无副作用（内容即容器），所以对带文字的
       「启用调用拦截」那行（104×44）不产生影响。 */
    .tool-guard-page .tool-guard-switch {
        min-height: var(--m-touch);
        min-width: var(--m-touch);
        justify-content: center;
    }

    /* 24.16 勾选框（.theme-checkbox）：等比圆角 + 44px 命中面
       (a) 等比圆角：24.11 把本体放大到 24px，但 `.theme-checkbox` 自己的
           border-radius 是 4px（为默认 16px 设计），24px 下显得方。按钮体系是
           10px/44px ≈ 23%，这里取 6px/24px = 25%——**按尺寸等比**才叫协调。
       (b) 44px 命中面：24.11 的注释写着"命中面交给整行 label"，但全站有 22 个
           勾选框并没有可点的 label（mcp-management 工具列表 20 个、
           asset-library 表头全选、info-collect 全选），本体 24×24 在手机上
           很难点中。`.theme-checkbox` 是 appearance:none 的，此时 input 会渲染
           伪元素、**且伪元素参与命中测试**；原生外观下则被 UA 样式表锁死——
           这正是 24.11 里"padding 撑不开"的原因，两者是同一个机制的两面。
           所以用一个透明 44×44 ::after 撑开命中面：不占布局、不改视觉。 */
    .theme-checkbox {
        position: relative !important;
        border-radius: 6px !important;
    }

    .theme-checkbox::after {
        content: '' !important;
        position: absolute !important;
        top: 50% !important;
        left: 50% !important;
        width: 44px !important;
        height: 44px !important;
        transform: translate(-50%, -50%) !important;
        background: transparent !important;
    }

    /* 24.17 开关型隐形 input 必须排除在 24.11 之外
       项目里其实有**三套**勾选/开关机制，24.11 只能套第一套：
         1. `.theme-checkbox`（style.css:43032）——真·勾选框，appearance:none、
            可见可点，24.16 已给它等比圆角与 44px 命中面；
         2. `.modern-checkbox` + `.checkbox-custom`（style.css:11011）——开关，
            input 本体是 `position:absolute; opacity:0; width:0; height:0;
            pointer-events:none`，**根本不接收点击**，点击由外层 `.checkbox-label`
            代收，视觉交给兄弟元素 `.checkbox-custom`（44×24 胶囊 + 16px 滑块，
            选中 translateX(20)：2+16+20 = 38 ≤ 40，左右各留 2px，设计本身正确）；
         3. `.tool-guard-page .tool-guard-switch input`——30×18 开关，见 24.15。
       24.11 给第 2 套的 input 强推 24×24，等于在页面上多出一层 24×24 的隐形盒子
       （因为 pointer-events:none 所以不拦点击，但没有任何存在理由，也会让
       审计脚本把它误判成"点不中的勾选框"）。这里恢复它的 0×0。 */
    input.modern-checkbox {
        width: 0 !important;
        height: 0 !important;
        min-width: 0 !important;
        min-height: 0 !important;
    }

    /* 第 2 套开关的真实点击接收者是 `.checkbox-label`（实测 150×40，差 4px）。
       这才是"点不中"的正确修复点——修 label，而不是修那个不可见的 input。
       必须 !important：info-collect 有一条
       `#info-collect-full-option .checkbox-label{min-height:40px}`（特异性 1,2,0）
       压着这里的 (0,1,0)；基础规则那边的 40px 则是 `padding:8px 0` + 24px 内容得来的。 */
    .checkbox-label {
        min-height: var(--m-touch) !important;
    }
}

/* ==========================================================================
   区块 25：审计覆盖被修正后（假 14 页 → 真实 29 页）新暴露的问题收口
   --------------------------------------------------------------------------
   起因：`_mtouch.mjs` / `_mdark.mjs` 的页表里有 6 个并不存在的页面 id，而
   `switchPage()` 对无效 id 是静默 no-op —— 那 6 页一直在重复测上一页，
   于是「14 页全 0」是假覆盖。修好页表（共用 `_pages.mjs` 的 29 个真实 id，
   切换后回读 `.page.active` 断言）再测，下面这些问题才第一次被看见。
   ========================================================================== */
@media (max-width: 767.98px) {

    /* 25.1 info-collect 表单在手机上仍是 4 列栅格。
       基础规则（style.css:30644）的
           grid-template-columns: minmax(160px,.7fr) 同 ×2
                                 + minmax(150px,.45fr) + minmax(280px,1fr)
       最小合计 750px，390px 屏上第 3/4 列被直接推出视口；而
       `@media (max-width:980px)` 里改为单列的那条（style.css:30627）被写在
       **它之后**且特异性同为 (0,1,0) —— 顺序错误让这个覆盖永久失效。
       实测「完整模式」选项 left=390 right=540（vw=390），整块不在屏内。 */
    .info-collect-form-row {
        grid-template-columns: 1fr !important;
    }

    /* 25.2 mcp-management 统计条用 flex-wrap:nowrap，
       「📌 常驻: 49」right=409、「🔗 已连接: 0」right=468，都越过屏幕右缘。 */
    #tools-stats,
    .external-mcp-stats {
        flex-wrap: wrap !important;
    }

    /* 25.3 语义色文字：沿用 18.10b 的同一套体系（一个语义一个色，只压亮度、
       冻结色相与饱和度，目标 ≥4.5:1），限定亮色主题。注释里是修复前的实测值。 */

    /* 中性灰 —— 与 .projects-fact-filter-label 取同值，全站灰标签一色到底 */
    .c2-tasks-stat-label,                 /* 2.56 on #fff */
    .c2-events-stat-label,
    .c2-tasks-time-preset-btn,            /* 2.45 on #f8fafc */
    .c2-events-time-preset-btn {
        color: #5d718c !important;
    }

    /* 信息蓝 */
    #c2-events-stat-info,                 /* 3.68 */
    .c2-tasks-time-preset-btn.is-active,  /* 3.36 on #eff5fe */
    .c2-events-time-preset-btn.is-active,
    .agent-role-badge--orchestrator,      /* 4.36 on #e0edff */
    #rbac-metric-users,                   /* 4.34 on #e5ecf9，strong 是本体的 id */
    .rbac-metric-users,
    .rbac-metric-users span {
        color: #1557e7 !important;
    }

    /* 待处理琥珀 */
    #c2-tasks-stat-pending,               /* 2.15 */
    #c2-events-stat-warn {
        color: #986206 !important;
    }

    /* 失败 / 严重 红 */
    #c2-tasks-stat-failed,                /* 3.76 */
    #c2-events-stat-critical {
        color: #d81212 !important;
    }

    /* 成功绿（.monitor-stat-value 是 28.8px 大字号，标准线是 3.0，实测 2.97 差 0.03） */
    #c2-tasks-stat-success,               /* 2.54 */
    .monitor-stat-value.is-success {
        color: #167e3c !important;
    }

    /* 授权橙 */
    #rbac-metric-assignments,             /* 3.00 on #f7e9e2，strong 是本体的 id */
    .rbac-metric-assignments,
    .rbac-metric-assignments span {
        color: #ad4109 !important;
    }

    /* 浅粉底上的危险按钮文字：同属危险语义，但底色 #f6e9ec 比 dashboard 那处的
       #fef8f8 更深，沿用同一个 #d81212 只有 4.42:1，所以按底色单独压暗。 */
    #c2-tasks-batch-delete span,          /* 3.84 */
    #c2-events-batch-delete span {
        color: #c22231 !important;
    }

    /* 25.4 c2 的主行动按钮：c2.css 拿 --c2-accent(#3b82f6)（c2.css:8）当按钮底色，
       白字只有 3.68:1。同一个 #3b82f6 作正文色时已在 18.x 处理过，作按钮底色这条漏了。
       压深到 #2563eb → 5.17:1。
       **必须限定亮色主题**：深色主题下 `--c2-accent` 会变成浅蓝，按钮是"浅底+深字"，
       在深色里改背景会直接把文字对比度打下来（实测 3.64:1）。 */
    html:not([data-theme="dark"]) .c2-payload-card .btn-primary,
    html:not([data-theme="dark"]) #c2-build-btn {
        background: #2563eb !important;
        border-color: #2563eb !important;
    }

    /* 25.5 第九轮第二遍：新暴露页面里剩下的文本类小字也纳入 12px 下限。
       `.tool-expand-icon` 的 ▶（10px）是图标字符、`svg text`（9px）是图表内标注，
       两者属图形元素，不受文本字号下限约束，保持原尺寸。 */
    .skill-card-tags span,        /* 11.52px 技能标签 */
    .c2-tasks-field span,         /* 11px 筛选字段标题 */
    .c2-events-field span,
    #tools-stats strong,          /* 11.2px 工具统计数字 */
    .asset-protocol-empty p,      /* 11px「暂无数据」 */
    .asset-recent-badge,          /* 10px「7 天」 */
    .asset-recent-caption {       /* 11px「占当前资产总量的 0%」 */
        font-size: 12px !important;
    }

    /* 25.6 iPhone SE（320px 视口）下 info-collect 的结果工具栏被推出屏幕：
       「列 / 导出 CSV / 导出 JSON」right=386 > 320。让它换行而不是溢出。
       （同屏 `span.rbac-context-stat` 的 right=326 也越界 6px，但它的父容器
        尚未定位，属边缘情况，先记录不动。） */
    .info-collect-results-toolbar,
    #fofa-selected-meta {
        flex-wrap: wrap !important;
    }

    /* 25.6b header 是单行 space-between，左栏 min-width:240px 仍会把工具栏挤出；
       改为上下两行：左栏占满一行，工具栏换到下一行右对齐。 */
    .info-collect-results-header {
        flex-wrap: wrap !important;
    }
    .info-collect-results-header-left {
        min-width: 0 !important;
        flex: 1 1 100% !important;
    }

    /* 25.6c rbac context 胶囊：max-width:min(25%,360px) 在 320px 下只有 80px，
       两个统计（"1个角色·3项授权"）放不下，第二个 right=326 越界 6px。
       窄屏放行换行且取消 25% 上限。 */
    .rbac-metric-context {
        max-width: none !important;
        flex-wrap: wrap !important;
    }

    /* 25.7 输入控件高度兜底：区块 7 的 input/select{min-height:var(--m-touch)}
       特异性 (0,1,1) 不够，被专项规则覆盖成 36/38/40/42px。
       - c2.css `#page-c2-events .c2-events-field .form-control`(1,2,1) 锁 36px
       - knowledge 的 `.knowledge-filters .search-box`(0,2,0) -> 38px
       - rbac 的 `.rbac-search .form-input` -> 40px
       - settings 的 `.form-group input`(settings 页) -> 42px
       这里用 `#page-*` 前缀 + !important 压过，同时保留原 box-sizing/padding。
       （form-control 设 height+min-height 都要改；.search-box input 与裸 input
         走 min-height 即可。） */
    #page-c2-tasks .c2-tasks-field .form-control,
    #page-c2-events .c2-events-field .form-control,
    #page-knowledge-management .knowledge-search-field input,
    #page-platform-rbac .rbac-search .form-input,
    #page-settings .form-group input,
    #page-settings input[type="text"],
    #page-settings input[type="password"],
    #page-settings input[type="url"] {
        height: var(--m-ctl-h) !important;
        min-height: var(--m-ctl-h) !important;
    }
}

/* ==========================================================================
   区块 26：深色主题（html[data-theme="dark"]）
   --------------------------------------------------------------------------
   这批违规同样是"审计覆盖修正后才被看见"的：`_mdark.mjs` 的页表此前含 6 个
   不存在的页面 id，14 页里那 6 页一直在重复测上一页，所以"深色 0 违规"是假覆盖。

   39 处的推荐色用 `_mcontrast.mjs` 的新 OFFLINE 模式离线求出 —— 它刻意复用与
   在页面里跑时**同一份 solveFor()**，避免"离线一套算法、在线一套算法"分叉。
   方向与亮色相反：深色下要**提亮**前景（搜索方向由前景/背景的明暗关系自动决定，
   无须人工指定）。取值同样遵循"一个语义一个色"，括号内是修复前的实测比值。

   两处结论经**像素裁决**（`_mpixel.mjs` + THEME=dark）确认可信：CSS 计算的
   `.mcp-stats-kpi__chip.is-ok` = #166534 与像素真值完全吻合（2.04:1），
   `.role-card-badge.enabled` = #157347 同样吻合（2.43:1）——不是建模误差。
   ========================================================================== */
html[data-theme="dark"] {

    /* 26.1 【已回滚的误判，留作记录】深色主题下 `.btn-primary` 的常规形态是
       "浅蓝底 #60a5fa + 深墨蓝文字"，实测 9.4:1 —— 与亮色主题的"深蓝底 + 白字"
       互为反色，这是**有意设计**（正是 23.1 区块处理过的那套写法）。
       我最初把它误判成"深字压蓝底"，统一改成浅色文字，结果把 18 个页面里
       可见的主按钮从 9.4:1 一次性压到 2.21:1 —— `_mdark.mjs` 重测后立刻暴露。
       结论：**不要动 `.btn-primary` 的文字色**。

       真正有问题的是登录按钮：`#login-overlay .btn-primary.login-submit` 上叠了
       background-image: linear-gradient(135deg,#2563eb,#1d4ed8) 的深蓝渐变，
       把浅蓝底盖掉了，文字仍是深墨蓝 → 实测 1:1 ~ 3.64:1。只修这一处。 */
    #login-overlay .btn-primary,
    #login-overlay .login-submit {
        color: #eceff8 !important;
    }

    /* 26.2 中性灰 —— 深色下一律提亮到同一色：取各元素解里最亮的一档
       （#848fa0 是"筛选按钮 / #1f2937 底"的解，对更暗的底只会比值更高）。
       `.btn-secondary` 的分页按钮这里必须带上 `*`：按钮自身的文字其实是
       子元素承载的，只改按钮本体会看不到任何变化（实测过）。 */
    .c2-tasks-stat-label,                 /* 3.49 on #131a27 */
    .c2-events-stat-label,
    .c2-tasks-time-preset-btn,            /* 3.75 on #0c1220 */
    .c2-events-time-preset-btn,
    #projects-detail-meta-time,           /* 3.72 */
    button.btn-secondary,                 /* 2.48 */
    button.btn-secondary * {
        color: #8c97a8 !important;
    }

    /* 26.3 信息蓝 */
    #c2-events-stat-info,                 /* 2.95 */
    .c2-tasks-time-preset-btn.is-active,  /* 2.33 on #1e2d45 */
    .c2-events-time-preset-btn.is-active,
    .agent-role-badge--orchestrator,      /* 2.69 */
    .rbac-metric-users,
    .rbac-metric-users span {             /* 2.77 */
        color: #6591f1 !important;
    }

    /* 26.4 紫 */
    .rbac-metric-roles,
    .rbac-metric-roles span {             /* 2.90 */
        color: #9c6af1 !important;
    }

    /* 26.5 绿 —— #24a655 是"启用徽章 / #142f2c 底"的解（对更暗的 chip 底只会更高） */
    #c2-tasks-stat-success,               /* 3.39 */
    .mcp-stats-kpi__chip.is-ok,           /* 2.04 ← 像素裁决过 */
    .rbac-pill.is-ok,                     /* 2.27 */
    .role-card-badge.enabled {            /* 2.42 ← 像素裁决过 */
        color: #24a655 !important;
    }
    /* dashboard 的「安全」徽章底色更亮（#163a36），需要更亮的绿 */
    #dashboard-severity-risk-level {
        color: #18b351 !important;        /* 3.77 */
    }

    /* 26.6 红 —— #f04a4a 是"失败 chip / #271c2a 底"的解（#ef3e3e 对 #211a29 只有 4.35:1） */
    #c2-tasks-stat-failed,                /* 3.33 */
    #c2-events-stat-critical,
    #c2-tasks-batch-delete span,          /* 2.86 */
    #c2-events-batch-delete span,
    .btn-secondary.btn-delete,            /* 2.73 */
    .mcp-stats-kpi__chip.is-fail {        /* 1.97 */
        color: #f25858 !important;
    }
    #dashboard-status-open {
        color: #ef4646 !important;        /* 4.45，差 0.05，单独按解取值 */
    }

    /* 26.7 琥珀 */
    #c2-tasks-stat-pending,               /* 3.39 */
    #c2-events-stat-warn {
        color: #b47407 !important;
    }

    /* 26.8 橙 */
    .rbac-metric-assignments,
    .rbac-metric-assignments span {       /* 2.72 */
        color: #e9580c !important;
    }

    /* 26.9 知识库「未启用」提示（rgb(102,102,102) 在深底上只有 3.28:1） */
    #page-knowledge-management h3 {
        color: #7c7c7c !important;
    }

    /* 26.10 mcp-management 的「全部」筛选按钮是白字压在浅蓝 #60a5fa 上：
       冻结色相与饱和度后**无解**（白色没有可提亮的余量，求解器原样返回 #ffffff），
       所以只能压深底色。 */
    .btn-filter.active {
        background: #2563eb !important;
        border-color: #2563eb !important;
    }

    /* 26.11 c2 会话工具栏的文字型按钮：18.12 给的 #1d4ed8 在深底上只有 2.84:1。
       那条规则的特异性是 (1,4,1)——四个 `:not()` 里的类与属性**都要计入**特异性，
       所以这里必须原样带上同一个选择器才压得住（4 个 `:not()` 里的类与属性都要计入特异性）。

       **踩过的坑**：这条规则原先我写成了 `html[data-theme="dark"][data-theme="dark"] #page-...`，
       而它所在的位置是本文件末尾 `html[data-theme="dark"] { ... }` 块的**内部** ——
       CSS 嵌套会把它解释成 `html[data-theme="dark"] html[data-theme="dark"][data-theme="dark"] #page-...`，
       也就是"`html` 是 `html` 的后代"，**结构性永不匹配**。表现为"改了毫无反应"，
       而且**连把特异性翻倍都毫无反应**——因为根本没有参与匹配。
       块内规则已经自带 `html[data-theme="dark"]` 前缀，这里反而不能再写。 */
    #page-c2-sessions button:not(.btn-primary):not(.btn-secondary):not(.btn-danger):not([style*="background"]) {
        color: #6591f1 !important;
    }

    /* 26.12 空状态行动按钮：18.13 给它们铺了实心 #2563eb 底，
       23.1 又按"浅蓝底(#60a5fa)"的假设把文字改成深墨蓝 —— 两轮修复前提不一致，
       结果成了"深蓝底上的深蓝字"（实测 3.64:1）。底色既然固定是 #2563eb，
       深色下文字就必须回转浅色（5.17:1）。前缀由所属的 `html[data-theme="dark"]` 块提供，
       这里**不能**再手写一遍（原因见 26.11 的注释）。 */
    .dashboard-empty-action,
    #page-knowledge-management .empty-state button,
    #page-knowledge-management .empty-state .btn,
    #hitl-pending-count {
        color: #eceff8 !important;
    }

    /* 26.13 未修项：asset-library 分页的「首页/上一页/下一页/尾页」在首页时是
       `:disabled` 态，取 #475569 浅灰属有意设计 —— WCAG 1.4.3 明确豁免禁用控件，
       不计入对比度要求。`_mdark.mjs` 会照报，属工具侧尚未过滤 `:disabled`。 */
}

/* --------------------------------------------------------------------------
   27. C2 会话管理页移动端布局修正（第十轮）
   实测（390x664 视口，登录 mtester）：
   - c2.css:4371 的 @media (max-width:768px) 给 .c2-session-layout 设
     min-height:calc(100vh - 140px) —— 移动端该页可用内容区实测只有 445px 高，
     而 100vh-140px = 524px，硬撑出 81px 垂直溢出 → .page-content 出现滚动条，
     布局底部 B676 伸到 #m-tabbar(顶 T606) 之下 70px，内容被底部标签栏盖住；
   - c2.css:4473 的 @media (max-width:1100px) 在样式表里位于 768px 断点**之后**，
     同特异性下后声明胜 → .c2-session-sidebar-wrap 被卡回 width:280px，
     390px 视口下会话列表只占 72% 宽，右侧直接露出深色背景；
   - 会话主区 .c2-session-main 被 layout 的 auto 高度压到 266px，空态卡片
     底部越界，下端内容被切。
   修复方向：高度交给内容区实际算（flex:1 + min-height:0），侧栏手机占满全宽、
   最高 260px 内部滚动，主区接管剩余空间并内部滚动。只作用于 ≤767.98px。
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    #page-c2-sessions .c2-session-layout {
        min-height: 0 !important;
        height: 100% !important;
        max-height: none !important;
        overflow: hidden !important;
    }

    #page-c2-sessions .c2-session-sidebar-wrap {
        width: 100% !important;
        min-width: 0 !important;
        max-width: none !important;
        max-height: 260px !important;
        flex-shrink: 0 !important;
        border-right: none !important;
    }

    #page-c2-sessions .c2-session-sidebar,
    #page-c2-sessions #c2-session-list {
        overflow-y: auto !important;
        min-height: 0 !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }

    #page-c2-sessions .c2-session-main {
        flex: 1 1 auto !important;
        min-height: 0 !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        padding: 12px 14px 18px !important;
    }
}

/* --------------------------------------------------------------------------
   25. iOS 观感修订：材质 / 圆角 / 按压反馈
   --------------------------------------------------------------------------
   口径：
   - 材质一律用 color-mix 从主题自己的 --bg-primary / --border-color 派生，
     浅色与暗色自动跟随；写死 rgba 会在暗色下糊成一块白雾。
   - backdrop-filter 只在浏览器支持时启用，不支持就退回实心背景（观感一致，
     只是没有透出）。固定栏的模糊是软件渲染掉帧主因（见 5 节），所以全站只给
     顶栏与底栏各一层 blur(20px)，抽屉/面板用不透明材质不再加模糊。
   - 圆角收成一个阶梯：控件胶囊、图标按钮正圆、卡片 18、面板顶角 22。
     本层原有的 10/12/14/18 四种混用在手机上读起来是"没对齐"，不是"设计过"。
   - 按压反馈用 scale，且在 prefers-reduced-motion 下整体关掉。
   - 所有改动只碰观感：44px 触控下限、层级、滚动容器一概不动。
   -------------------------------------------------------------------------- */
:root {
    --m-r-card: 18px;
    --m-r-panel: 22px;
    --m-material: color-mix(in srgb, var(--bg-primary) 82%, transparent);
    --m-material-solid: color-mix(in srgb, var(--bg-primary) 96%, transparent);
    --m-hairline: color-mix(in srgb, var(--border-color) 55%, transparent);
    --m-fill-quaternary: color-mix(in srgb, var(--text-primary) 6%, transparent);
    --m-fill-press: color-mix(in srgb, var(--text-primary) 10%, transparent);
    --m-ring: color-mix(in srgb, var(--accent-color) 30%, transparent);
    --m-shadow-panel: 0 -12px 40px rgba(0, 0, 0, 0.22);
    --m-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04);
}

@media (max-width: 767.98px) {
    /* 25.1 顶栏 / 底栏：透出材质 + 发丝分隔线。
       顶栏必须写成 html[data-theme] header：style.css 用同一条特异性给暗色塞了
       不透明渐变，只写 header 会在暗色下丢掉材质（实测 background 被压成渐变）。 */
    header,
    html[data-theme] header {
        background: var(--m-material-solid);
        border-bottom: 1px solid var(--m-hairline);
        box-shadow: none;
    }

    #m-tabbar {
        background: var(--m-material-solid);
        border-top: 1px solid var(--m-hairline);
        box-shadow: none;
    }

    @supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
        header,
        html[data-theme] header {
            background: var(--m-material);
            -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
        }

        #m-tabbar {
            background: var(--m-material);
            -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
        }
    }

    /* 25.2 圆角阶梯：卡片、面板、控件、图标按钮 */
    .card,
    .stat-card,
    .metric-card,
    .dashboard-card,
    .panel,
    .settings-section,
    .info-card {
        border-radius: var(--m-r-card);
        box-shadow: var(--m-shadow-card);
    }

    #m-sheet {
        border-radius: var(--m-r-panel) var(--m-r-panel) 0 0;
        box-shadow: var(--m-shadow-panel);
    }

    .main-sidebar {
        border-radius: 0 var(--m-r-panel) var(--m-r-panel) 0;
        border-right: none;
    }

    input:not([type=checkbox]):not([type=radio]),
    select,
    textarea {
        border-radius: 12px;
    }

    button,
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-small,
    .btn-sm,
    .m-chat-bar-btn {
        border-radius: var(--m-r-pill);
    }

    /* 图标按钮去底去框：桌面用的是 .header-actions button（类+元素）两条特异性，
       本层只写类名会被压住（实测 border 仍是 1px），所以这里必须同形写 */
    .header-actions :is(.m-more-btn, .m-close-btn, .notification-btn, .user-avatar-btn, .btn-icon),
    .m-menu-btn {
        border: none;
        background: transparent;
    }

    /* 次要按钮：iOS 的"填充"样式，去掉描边不再和主按钮抢层次 */
    .btn-secondary,
    .btn-small,
    .btn-sm {
        background: var(--m-fill-quaternary);
        border-color: transparent;
    }

    /* 25.3 发丝线：抽屉 / 面板 / 会话条的内部分隔 */
    .m-drawer-head,
    .m-drawer-search,
    .m-sheet-head,
    .m-chat-bar {
        border-bottom-color: var(--m-hairline);
    }

    .m-sheet-sep {
        background: var(--m-hairline);
    }

    .m-sheet-grip {
        width: 36px;
        height: 5px;
        border-radius: 999px;
        background: color-mix(in srgb, var(--text-muted) 45%, transparent);
    }

    /* 25.4 按压反馈：可见的"点到了"，不改变布局尺寸 */
    .m-tab,
    .m-sheet-item,
    .m-chat-bar-btn,
    .m-menu-btn,
    .m-more-btn,
    .m-close-btn,
    .notification-btn,
    .user-avatar-btn,
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-small,
    .nav-item-content,
    .nav-submenu-item {
        transition: transform 0.12s ease, background-color 0.12s ease, color 0.16s ease, opacity 0.12s ease;
    }

    .m-tab:active,
    .m-sheet-item:active,
    .m-chat-bar-btn:active,
    .btn-primary:active,
    .btn-secondary:active,
    .btn-danger:active,
    .btn-small:active {
        transform: scale(0.96);
        background-color: var(--m-fill-press);
    }

    .btn-primary:active {
        /* 主按钮按压时保持强调色，只压暗，不变成灰底 */
        background-color: color-mix(in srgb, var(--accent-color) 88%, #000);
    }

    /* 当前标签：图标后面一枚圆形底色，比整格变色更接近系统底栏 */
    .m-tab.m-active {
        color: var(--accent-color);
        background: transparent;
    }

    .m-tab.m-active svg {
        background: color-mix(in srgb, var(--accent-color) 12%, transparent);
        border-radius: 50%;
        padding: 2px;
        box-sizing: content-box;
    }

    /* 25.5 焦点环：从 2px 硬描边换成 3px 柔光环，键盘可达性不降级 */
    a:focus-visible,
    button:focus-visible,
    input:focus-visible,
    select:focus-visible,
    textarea:focus-visible,
    [tabindex]:focus-visible {
        outline: none;
        box-shadow: 0 0 0 3px var(--m-ring);
    }

    .m-drawer-search input:focus {
        border-color: color-mix(in srgb, var(--accent-color) 55%, transparent);
    }

    /* 强制高对比下柔光环会被抹掉，这里把硬描边还给它 */
    @media (forced-colors: active) {
        a:focus-visible,
        button:focus-visible,
        input:focus-visible,
        select:focus-visible,
        textarea:focus-visible,
        [tabindex]:focus-visible {
            outline: 2px solid Highlight;
            outline-offset: 2px;
        }
    }

    /* 工具条里的 <a> 按钮（查看全部 / 拉取模型列表 / 视觉测试）：它们是操作控件而不是
       正文链接，桌面写成 21-29px 高的行内块，手指点不中。给到本层的触控下限，
       字号与颜色不动。正文里的链接（.markdown-body 内）不在这些容器里，不受影响。 */
    :is(.page-header-actions, .dashboard-section-actions, .dashboard-section-header,
         .model-pick-row, .asset-toolbar, .settings-toolbar, .settings-form,
         .form-group, .info-collect-toolbar, .settings-advanced-block > div)
        a:not(.btn-primary):not(.btn-secondary):not(.btn-danger) {
        display: inline-flex;
        align-items: center;
        min-height: var(--m-touch);
        padding: 0 8px;
        box-sizing: border-box;
    }

    /* 会话抽屉：本层把它做成全屏抽屉，里面的行就必须按 44 触控口径来
       （实测搜索框 42、分组按钮 24 宽、项目行 38、"最近对话"折叠头 30） */
    :is(#conversation-sidebar .conversation-search-box input,
        #conversation-sidebar .add-group-btn,
        #conversation-sidebar .project-folder-item,
        #conversation-sidebar .recent-conversations-toggle,
        #conversation-sidebar .project-folder-header) {
        min-height: var(--m-touch);
    }

    #conversation-sidebar .add-group-btn {
        min-width: var(--m-touch);
    }

    /* 调用拦截的开关：input 是 30x18 的滑块，命中区其实是包着它的 label。
       把 label 撑到触控下限，手指点的就是整块开关而不是那条 18px 的芯。 */
    .tool-guard-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: var(--m-touch);
        min-height: var(--m-touch);
    }

    /* RBAC 概览里的计数胶囊：20px 宽点不中，补足到下限（文字居中，不改视觉密度） */
    .rbac-summary-count {
        min-width: var(--m-touch);
    }

    /* 桌面把 .ai-channel-manager 设成 overflow:hidden（style.css:4796，靠固定高度自截），
       手机上它的内容比盒子高，超出的一截被裁掉——实测 4 个通道选择按钮 scrollIntoView
       也拉不进视口，属于「看得见点不到」。这里交还给页面滚动容器。 */
    .ai-channel-manager {
        overflow: visible;
    }

    /* 25.6 遮罩与轻提示：遮罩不加模糊（全屏模糊是掉帧主因），提示条用材质 */
    .m-scrim {
        background: color-mix(in srgb, var(--m-scrim) 88%, transparent);
    }

    /* 提示条保持基底的深色 HUD 胶囊（1023 行）：这里曾把它改成浅色材质，
       但字色仍是 #fff，结果白底白字——用户看到的就是"屏幕中间一块白的"。
       只补一层投影，底色与字色不动。 */
    #m-toast {
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    }
}

@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
    /* 关掉按压缩放，只保留颜色反馈 */
    .m-tab,
    .m-sheet-item,
    .m-chat-bar-btn,
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-small {
        transition: background-color 0.12s ease, color 0.16s ease;
    }

    .m-tab:active,
    .m-sheet-item:active,
    .m-chat-bar-btn:active,
    .btn-primary:active,
    .btn-secondary:active,
    .btn-danger:active,
    .btn-small:active {
        transform: none;
    }
}

@supports (height: 100dvh) {
    :root {
        --m-bar-bottom: max(0px, calc(100dvh - var(--m-app-height, 100dvh)));
    }
}

/* --------------------------------------------------------------------------
   26. 密度与表面：对齐 new-api 的卡片体系 + iOS 的分组列表与填充式表单
   --------------------------------------------------------------------------
   这一节只管"看起来挤不挤、齐不齐"，不改配色语言：KPI 卡那套按 nth-child 分的
   淡彩渐变是产品自己的身份（style.css:23789-23793），不跟它抢。
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    /* 26.1 KPI：桌面在 ≤480px 把 5 张卡拍成一列 116px 高的长条，手机上要滚
       两屏才看完四个数字。改成两列紧凑网格，数字才是主角。 */
    .dashboard-kpi-row {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
        gap: 10px;
        margin-bottom: 16px;
    }

    /* 奇数张时末卡通栏，右下角不留空洞 */
    .dashboard-kpi-row > .dashboard-kpi-card:last-child:nth-child(odd) {
        grid-column: 1 / -1;
    }

    .dashboard-kpi-card {
        padding: 12px 13px !important;
        min-height: 0 !important;
        gap: 0 !important;
    }

    .dashboard-kpi-label {
        font-size: 12px;
        line-height: 1.35;
        font-weight: 500;
        color: var(--text-muted);
    }

    .dashboard-kpi-value {
        font-size: 26px;
        line-height: 1.15;
        font-weight: 600;
        letter-spacing: -0.02em;
        font-variant-numeric: tabular-nums;
        margin-top: 6px;
    }

    .dashboard-kpi-sub,
    .dashboard-kpi-sub-text {
        font-size: 12px;
        line-height: 1.4;
    }

    .dashboard-kpi-icon {
        width: 28px;
        height: 28px;
        border-radius: 9px;
        flex-shrink: 0;
    }

    .dashboard-kpi-icon svg {
        width: 15px;
        height: 15px;
    }

    .dashboard-access-strip {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
        gap: 10px;
    }

    /* 26.2 卡片表面统一：发丝边 + 16 圆角 + 几乎看不见的投影。
       桌面的 0 2px 8px 双层阴影在小屏上会把每张卡都"抬起来"，一屏四张就散了。 */
    :is(.card, .stat-card, .metric-card, .dashboard-card, .panel,
         .settings-section, .info-card) {
        border: 1px solid var(--m-hairline);
        border-radius: var(--m-r-card);
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
    }

    /* 26.3 页面头：标题与操作行收成一组，不再各占一段空白 */
    .page-header h2,
    .page-header h1 {
        font-size: 20px;
        font-weight: 600;
        letter-spacing: -0.01em;
    }

    .page-header {
        gap: 8px;
        margin-bottom: 12px;
    }

    /* 26.4 填充式表单（iOS 的写法：字段靠底色区分，不靠一圈灰边框） */
    :is(.form-group, .settings-form, .modal-body, .m-drawer-search) :is(input, select, textarea) {
        background: var(--m-fill-quaternary);
        border-color: transparent;
        border-radius: 12px;
    }

    /* 聚焦：只留一圈柔光环。再改 border 颜色会与 25.5 的环叠成两圈（登录框实测如此）*/
    :is(.form-group, .settings-form, .modal-body, .m-drawer-search) :is(input, select, textarea):focus {
        background: var(--bg-primary);
        border-color: transparent;
        box-shadow: 0 0 0 3px var(--m-ring);
    }

    /* 26.5 登录卡：满宽卡片 + 填充式字段 + 胶囊主按钮 */
    .login-card {
        border-radius: 20px;
        box-shadow: 0 18px 40px rgba(0, 0, 0, 0.12);
    }

    .login-form .btn-primary,
    .login-card .btn-primary {
        width: 100%;
        border-radius: var(--m-r-pill);
    }

    /* 26.6 分组列表：卡片内的行之间只留发丝线，行高按触控下限走 */
    :is(.settings-section, .card, .panel, .info-card) :is(.form-group, .settings-row, .list-row) + :is(.form-group, .settings-row, .list-row) {
        border-top: 1px solid var(--m-hairline);
    }
}

/* --------------------------------------------------------------------------
   28. 玻璃质感：环境光画布 + 玻璃表面 + 顶缘高光
   --------------------------------------------------------------------------
   目标：把手机端从"平面灰底 + 分隔线"推进到 Apple 的玻璃材质语言。
   玻璃要读得出来，前提是材料后面有东西可透，所以这一节先做两件事：

   - 画布：.container 铺一层极淡的环境光（浅色 = 近白底 + 右上 accent / 左下紫的
     柔光；暗色 = 深底 + 同色更亮的柔光），再把 .content-area / .chat-messages 的
     实心底色交还给这层画布。此后所有半透明表面都有色可透，各页面自身的内容背景
     一律不动。
   - 表面分三档：模糊（backdrop-filter）只给"小面积或瞬时"的件 —— 顶栏、底栏
     （25 节已有）、底部面板、抽屉、登录卡、弹窗；它们要么面积小，要么只在被打开
     时才绘制，不挂在常驻滚动内容上。常驻卡片（.card/.stat-card/... 一列）只做
     半透明 + 发丝边 + 顶缘高光，不挂模糊 —— 固定栏的大面积模糊是移动端掉帧
     主因（25 节实测），这条口径不动。
   - 浅色与暗色全部经 color-mix 从主题令牌派生；只有"顶缘高光"必须换向
     （浅色 = 白线，暗色 = 极淡白线），单独覆写。
   - prefers-reduced-transparency: reduce 时不问浏览器支持与否，全部退回实心。
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    :root {
        /* 栏体材质从 82% 提到 62%：有模糊托底，透出的是画布而不是一块灰板 */
        --m-material: color-mix(in srgb, var(--bg-primary) 62%, transparent);
        /* 玻璃卡（常驻，不挂模糊）：透出画布的一点色 */
        --m-glass-card: color-mix(in srgb, var(--card-bg) 66%, transparent);
        /* 玻璃面板（瞬时件，配模糊）：抽屉 / 底部面板 / 登录卡 / 弹窗 */
        --m-glass-panel: color-mix(in srgb, var(--bg-primary) 72%, transparent);
        --m-glass-blur: saturate(180%) blur(20px);
        /* 顶缘高光：玻璃的"口沿"。浅色下是白线，暗色下换极淡白（见下方覆写） */
        --m-bevel: inset 0 1px 0 rgba(255, 255, 255, 0.55);
    }

    html[data-theme="dark"] {
        --m-bevel: inset 0 1px 0 rgba(255, 255, 255, 0.07);
    }

    /* 28.1 环境光画布：整块 app 换底，卡片与栏体从这层透色 */
    .container {
        background:
            radial-gradient(120% 88% at 88% -12%,
                color-mix(in srgb, var(--accent-color) 14%, transparent), transparent 58%),
            radial-gradient(95% 72% at -12% 106%,
                color-mix(in srgb, #8b5cf6 11%, transparent), transparent 60%),
            var(--bg-secondary);
    }

    html[data-theme="dark"] .container {
        background:
            radial-gradient(120% 88% at 88% -12%,
                color-mix(in srgb, var(--accent-color) 18%, transparent), transparent 58%),
            radial-gradient(95% 72% at -12% 106%,
                color-mix(in srgb, #8b5cf6 13%, transparent), transparent 60%),
            var(--bg-secondary);
    }

    /* 交还底色：画布负责"底"，卡片负责"面" */
    .content-area,
    .chat-messages {
        background: transparent;
    }

    /* 28.2 底栏补一道顶缘高光，顶栏保持 25 节的发丝线 */
    #m-tabbar {
        border-top-color: var(--m-hairline);
        box-shadow: var(--m-bevel);
    }

    /* 28.3 卡片玻璃：半透明表面 + 发丝边 + 顶缘高光；投影保持 26 节的"几乎看不见" */
    :is(.card, .stat-card, .metric-card, .dashboard-card, .panel,
         .settings-section, .info-card) {
        background: var(--m-glass-card);
        border-color: var(--m-hairline);
        box-shadow: var(--m-bevel), 0 1px 2px rgba(0, 0, 0, 0.03);
    }

    /* 28.4 底部面板：真玻璃（透色 + 模糊），只在打开时绘制 */
    #m-sheet {
        background: var(--m-glass-panel);
        border-color: color-mix(in srgb, var(--border-color) 50%, transparent);
        box-shadow: var(--m-bevel), var(--m-shadow-panel);
    }

    /* 28.5 抽屉（主导航 / 会话列表）：同面板材质的真玻璃。
       两套选择器：不带属性的管浅色与初始绘制，html[data-theme] 的管暗色
       （style.css 的暗色抽屉是 (0,2,0) 特异性的不透明渐变，必须同形压回）。 */
    .main-sidebar,
    .conversation-sidebar,
    html[data-theme] .main-sidebar,
    html[data-theme] .conversation-sidebar {
        background: var(--m-glass-panel);
    }

    .m-chat-drawer-head {
        background: transparent;
    }

    .m-drawer-search input {
        background: color-mix(in srgb, var(--input-bg) 78%, transparent);
    }

    /* 对话页顶部工具条：在流内、滚动内容不会跑到它后面，纯透色不挂模糊 */
    #m-chat-bar {
        background: color-mix(in srgb, var(--bg-primary) 66%, transparent);
        border-bottom-color: var(--m-hairline);
    }

    /* 28.6 弹窗：与面板同档的玻璃 */
    .modal-content {
        background-color: var(--m-glass-panel);
        border: 1px solid var(--m-hairline);
    }

    /* 28.7 登录：遮罩本身得先有"画布"（否则卡片后面只有一块灰），卡片是真玻璃 */
    .login-overlay {
        background:
            radial-gradient(120% 88% at 85% -10%,
                color-mix(in srgb, var(--accent-color) 13%, transparent), transparent 60%),
            radial-gradient(95% 72% at -12% 108%,
                color-mix(in srgb, #8b5cf6 10%, transparent), transparent 62%),
            color-mix(in srgb, var(--bg-secondary) 92%, transparent);
    }

    html[data-theme="dark"] .login-overlay {
        background:
            radial-gradient(120% 88% at 85% -10%,
                color-mix(in srgb, var(--accent-color) 17%, transparent), transparent 60%),
            radial-gradient(95% 72% at -12% 108%,
                color-mix(in srgb, #8b5cf6 12%, transparent), transparent 62%),
            color-mix(in srgb, #0b1120 92%, transparent);
    }

    .login-card {
        background: var(--m-glass-panel);
        border-color: var(--m-hairline);
        box-shadow: var(--m-bevel), 0 18px 44px rgba(0, 0, 0, 0.14);
    }

    /* 28.8 模糊：只给上述瞬时件。@supports 兜底逻辑与 25 节一致 */
    @supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
        #m-sheet,
        html[data-theme] .main-sidebar,
        html[data-theme] .conversation-sidebar,
        .login-card,
        .modal-content {
            -webkit-backdrop-filter: var(--m-glass-blur);
            backdrop-filter: var(--m-glass-blur);
        }
    }

    /* 28.9 降低透明度环境：退回实心材质（含画布） */
    @media (prefers-reduced-transparency: reduce) {
        .container,
        .content-area,
        .chat-messages,
        .login-overlay {
            background: var(--bg-secondary);
        }

        #m-sheet {
            background: var(--bg-primary);
        }

        .main-sidebar,
        .conversation-sidebar,
        html[data-theme] .main-sidebar,
        html[data-theme] .conversation-sidebar,
        .login-card,
        .modal-content {
            background: var(--bg-primary);
        }

        #m-chat-bar {
            background: var(--bg-primary);
        }

        :is(.card, .stat-card, .metric-card, .dashboard-card, .panel,
             .settings-section, .info-card) {
            background: var(--card-bg);
        }

        #m-sheet,
        html[data-theme] .main-sidebar,
        html[data-theme] .conversation-sidebar,
        .login-card,
        .modal-content {
            -webkit-backdrop-filter: none;
            backdrop-filter: none;
        }
    }
}
