/* ==========================================================================
   ui-refine.css — 界面统一优化层（加载顺序：app.css → theme.css → promo.css → 本文件）
   --------------------------------------------------------------------------
   目标（对应本次「整理 / 优化 / 美化」需求）：
     1. 统一：圆角、留白、描边、字号与强调色收敛到一套令牌，不再各处写死像素；
     2. 简洁：去掉多余的深色色块与厚重边框，靠「底色分层 + 细描边 + 一点强调色」建立层次；
     3. 多彩提示：状态色保持原有语义（绿=正常 / 琥珀=提醒 / 玫红=异常），
        另外新增 3 个「分类色」只用于图标底色（蓝 / 青 / 紫），不与状态色抢语义；
     4. 弹窗分层：手机 = 100% 宽、贴底、大圆角、带拖动条；电脑 = 居中、20px 圆角、弹入；
     5. 小动效：全部只用 transform / opacity（走合成层，不触发重排与重绘），
        且不使用无限循环动画；统一受 prefers-reduced-motion 约束；
     6. 性能：手机端关闭顶栏 / Tab 栏 / 弹窗的 backdrop-filter（低端安卓最贵的一项），
        改为高不透明度实色，观感几乎不变、滚动更稳。

   说明：本文件只覆盖「外观」，不改变任何页面结构、类名与交互逻辑，
        因此可整份删除回退，不影响功能。
   ========================================================================== */

/* ==========================================================================
   R1. 令牌（圆角 / 动效 / 阴影 / 分类色 / 弹窗标题）
   ========================================================================== */
:root {
    /* 圆角梯度：把 app.css 里 6 / 7 / 8 / 10 / 12 / 16 的混用收敛成 4 档 */
    --radius-sm: 10px;      /* 输入框 / 选择器 / 小控件 */
    --radius: 14px;         /* 常规卡片 */
    --radius-card: 14px;    /* 卡片族统一入口（手机端在 R9 放大到 16px） */
    --radius-lg: 20px;      /* 弹窗 / 面板 */
    --r-xl: 24px;           /* 手机端贴底弹窗的上圆角 */

    /* 动效：短、快、只用合成属性 */
    --t-1: 110ms;
    --t-2: 180ms;
    --t-3: 280ms;
    --ease: cubic-bezier(.22, .61, .36, 1);
    --ease-spring: cubic-bezier(.34, 1.32, .64, 1);

    /* 阴影：平面化风格下只给「浮起来的东西」用（弹窗 / 面板 / Toast） */
    --shadow-1: 0 1px 2px rgba(16, 24, 40, .05);
    --shadow-2: 0 10px 30px -12px rgba(16, 24, 40, .22);
    --shadow-3: 0 24px 64px -24px rgba(16, 24, 40, .38);

    /* 分类色（只用于图标底色，不参与「状态」语义）
       蓝 = 排课/数据，青 = 学员/成长，紫 = 财务/报表，主色 = 核心操作 */
    --a-blue: #2563eb;
    --a-blue-soft: #e7effd;
    --a-teal: #0d8a70;
    --a-teal-soft: #e0f4ee;
    --a-violet: #7452c6;
    --a-violet-soft: #f0ebfa;

    /* 弹窗标题行：品牌色渐变（替代原来的纯色实底，多一层质感但不刺眼） */
    --modal-head-bg: linear-gradient(135deg, #37795c 0%, #1f5240 100%);

    /* 弹窗遮罩：比抽屉的 --overlay 再深一点，弹窗浮起来时背景要退得下去 */
    --scrim-modal: rgba(16, 56, 40, .52);
}

html[data-theme="classic"] {
    --a-blue: #007aff;
    --a-blue-soft: #e5f1ff;
    --a-teal: #0f8a72;
    --a-teal-soft: #e2f5ef;
    --a-violet: #7c4dff;
    --a-violet-soft: #f0eaff;
    --modal-head-bg: linear-gradient(135deg, #2b8cff 0%, #0066d6 100%);
    --scrim-modal: rgba(0, 0, 0, .44);
}

html[data-theme="spring"] {
    --a-blue: #2c6fb7;
    --a-blue-soft: #eaf4ff;
    --a-teal: #0d8a70;
    --a-teal-soft: #e2f5ef;
    --a-violet: #7a5ab5;
    --a-violet-soft: #f1edfa;
    --modal-head-bg: linear-gradient(135deg, #11b76a 0%, #068a3f 100%);
    --scrim-modal: rgba(0, 0, 0, .46);
}

html[data-theme="rustic"] {
    --a-blue: #4a6b8a;
    --a-blue-soft: #e8eef4;
    --a-teal: #50796b;
    --a-teal-soft: #e6f0eb;
    --a-violet: #7b6288;
    --a-violet-soft: #efe8f0;
    --modal-head-bg: linear-gradient(135deg, #8a7353 0%, #5d4a35 100%);
    --scrim-modal: rgba(49, 42, 31, .5);
}

html[data-theme="romance"] {
    --a-blue: #93c5fd;
    --a-blue-soft: rgba(59, 130, 246, .16);
    --a-teal: #5eead4;
    --a-teal-soft: rgba(20, 184, 166, .16);
    --a-violet: #c4a4ff;
    --a-violet-soft: rgba(167, 92, 255, .18);
    --modal-head-bg: linear-gradient(120deg, #7c3aed 0%, #a21caf 55%, #be185d 100%);
    --scrim-modal: rgba(5, 3, 12, .74);

    /* 深底上阴影要更沉，否则弹窗和背景糊在一起 */
    --shadow-2: 0 12px 34px -14px #000;
    --shadow-3: 0 30px 80px -30px #000;
}

/* ==========================================================================
   R2. 基础排版 / 聚焦
   ========================================================================== */
body {
    text-rendering: optimizeLegibility;
}

/* 家长端购课：付款是高频手机操作，抽屉内始终保持单列、无横向滚动。 */
.parent-purchase-modal { width: min(620px, calc(100vw - 28px)); min-width: 0; overflow: hidden; }
.parent-purchase-modal .modal-head { background: var(--primary); }
.parent-purchase-modal .modal-body { min-width: 0; overflow-x: hidden; }
.purchase-section { display: grid; min-width: 0; gap: 8px; }
.purchase-section > .field-label { margin: 4px 0 2px; color: var(--text); font-size: calc(13px * var(--jx-fs)); font-weight: 700; }
.purchase-option { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 10px; width: 100%; min-width: 0; min-height: 68px; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); text-align: left; font: inherit; cursor: pointer; }
.purchase-option.selected { border-color: var(--primary); background: var(--primary-light); }
.purchase-option.disabled { opacity: .55; cursor: not-allowed; }
.purchase-option-main { min-width: 0; display: grid; gap: 4px; }
.purchase-option-main strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: calc(14px * var(--jx-fs)); }
.purchase-option-main small { overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); line-height: 1.45; text-overflow: ellipsis; white-space: nowrap; }
.purchase-option-price { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.purchase-discount { color: var(--ok-text); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.purchase-option .ico { color: var(--text-3); }
.purchase-option.selected .ico { color: var(--primary); }
.purchase-summary { display: grid; grid-template-columns: 1fr auto; gap: 8px 14px; margin-top: 12px; padding: 12px; border-top: 1px solid var(--line); color: var(--text-muted); font-size: calc(13px * var(--jx-fs)); }
.purchase-summary strong { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: baseline; padding-top: 8px; border-top: 1px dashed var(--line); color: var(--text); font-size: calc(14px * var(--jx-fs)); }
.purchase-summary b { color: var(--primary-text); font-size: calc(21px * var(--jx-fs)); font-variant-numeric: tabular-nums; }
.payment-state { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 8px; padding: 12px; border: 1px solid var(--ok); border-radius: var(--radius-sm); background: var(--ok-light); color: var(--ok-text); font-size: calc(13px * var(--jx-fs)); line-height: 1.45; }
.payment-state .ico { flex: 0 0 auto; }
.payment-state > span { min-width: 0; overflow-wrap: anywhere; }
.payment-state .form-actions { display: grid; grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; width: 100%; margin: 2px 0 0; }
.payment-state .form-actions .btn { display: inline-flex; min-width: 0; min-height: 42px; justify-content: center; padding: 0 10px; white-space: nowrap; }
/* 第二个按钮是“重新发起支付”，把它明确放成当前流程的唯一主操作。 */
.payment-state .form-actions .btn:nth-child(2) { grid-column: 1 / -1; order: -1; }

@media (max-width: 767px) {
    .modal.parent-purchase-modal { width: 100vw; max-width: 100vw; max-height: 88vh !important; max-height: min(88dvh, 720px) !important; box-sizing: border-box; }
    .parent-purchase-modal .modal-head { padding-right: 14px; }
    .parent-purchase-modal .modal-body { padding: 14px 16px 16px; }
    .parent-purchase-modal .modal-foot { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 10px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); }
    .parent-purchase-modal .modal-foot .btn { width: 100%; min-width: 0; margin: 0; padding: 0 10px; font-size: calc(14px * var(--jx-fs)); }
    .purchase-option { min-height: 76px; padding: 12px; gap: 8px; }
    .purchase-option-main small { display: -webkit-box; overflow: hidden; white-space: normal; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
    .purchase-option-price, .purchase-discount { font-size: calc(15px * var(--jx-fs)); }
    .purchase-summary { margin-top: 8px; padding: 12px 0 0; }
    .purchase-summary b { font-size: calc(24px * var(--jx-fs)); }
    .locked-tip { align-items: flex-start; line-height: 1.5; }
    .payment-state { margin-top: 10px; }
    .payment-state .form-actions .btn { font-size: calc(13px * var(--jx-fs)); }
}

/* 待支付状态的操作已在订单卡片内给出，底栏只保留关闭，避免出现第二个灰色支付按钮。 */
@supports selector(.parent-purchase-modal:has(.payment-state)) {
    @media (max-width: 767px) {
        .parent-purchase-modal:has(.payment-state .form-actions) .modal-foot { grid-template-columns: 1fr; }
        .parent-purchase-modal:has(.payment-state .form-actions) .modal-foot .btn-primary { display: none; }
    }
}

/* 数字一律等宽：课时、金额、人数在列表里上下对齐，扫读更快 */
.stat-num,
.home-stat-copy strong,
.student-balance strong,
.pending-count,
.key-value,
.hours-input,
.lesson-stat strong {
    font-variant-numeric: tabular-nums;
}

/* 标题轻微收紧字距，中文大字号的默认字距偏松 */
.page-title,
.card-title,
.modal-title,
.sheet-title,
.settings-panel-title strong,
.wx-settings-title strong {
    letter-spacing: -.01em;
}

/* 键盘焦点：统一成品牌色细环；输入框自身有 ring，避免双层 */
:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.input:focus-visible,
.select:focus-visible,
.textarea:focus-visible,
.select-field:focus-visible {
    outline: none;
}

/* ==========================================================================
   R3. 表面：卡片 / 统计 / 列表
   ========================================================================== */
.card {
    border-color: var(--line);
    transition: border-color var(--t-2) var(--ease), background-color var(--t-2) var(--ease);
}

.card-head {
    padding: 12px 14px;
}

.card-title {
    font-weight: 650;
}

/* 卡片头里的图标统一给一点主色，避免整块头全是灰字 */
.card-title .ico {
    color: var(--primary-text);
}

.card-foot {
    background: var(--surface-2);
}

/* 列表行：手机上给足触控高度；分隔线弱化，避免「表格感」 */
.list-item {
    min-height: 50px;
    border-bottom-color: var(--line);
}

.list-item-title {
    font-weight: 600;
}

@media (hover: hover) and (pointer: fine) {
    .list-item.pointer:hover {
        background: var(--surface-2);
    }
}

/* 空态：图标放进一个浅色圆角方块，比原来「一个灰图标 + 灰字」更有落点 */
.empty {
    padding: 34px 18px;
}

.empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin: 0 auto 10px;
    border-radius: 18px;
    background: var(--surface-2);
    color: var(--text-3);
    opacity: 1;
}

.empty-text {
    color: var(--text-2);
}

/* 学员卡底栏：与班级卡底栏统一成同一条「归属信息条」
   · 同一高度（46px）、同一内边距（9px 14px，手机 13px）、同一 12px 字级；
   · 课时余额不再用 19px 大数字压在日期旁边（一条细底栏撑不住这么大的字号，
     视觉重心也从「这个人是谁」被拽到「剩几节课」），收成一枚小胶囊，
     规格与班级卡的老师标签一致：3px 8px 内边距 + 描边 + 圆角；
   · 语义色保留：课时充足=绿，课时不足/为零=玫红；数字等宽对齐。 */
.student-card-foot {
    flex-wrap: nowrap;
    min-height: 46px;
    padding: 9px 14px;
    gap: 8px;
}

.student-card-date {
    flex: 1 1 auto;
    min-width: 0;
    font-size: calc(12px * var(--jx-fs));
}

.student-card .student-balance {
    flex: 0 0 auto;
    align-items: baseline;
    min-width: 0;
    gap: 5px;
    padding: 3px 8px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.5;
    white-space: nowrap;
}

.student-card .student-balance strong {
    display: inline;
    font-size: calc(13.5px * var(--jx-fs));
    line-height: 1;
}

.student-card .student-balance > span {
    display: inline;
    margin-top: 0;
    font-size: calc(11.5px * var(--jx-fs));
}

@media (max-width: 767px) {
    .student-card-foot {
        padding-right: 13px;
        padding-left: 13px;
    }
}

/* ==========================================================================
   R4. 控件：按钮 / 输入 / 分段 / 标签 / 勾选
   ========================================================================== */

/* 按钮：按下缩一点（合成层），悬停只提亮一点，不做位移 */
.btn {
    transition: transform var(--t-1) var(--ease),
                background-color var(--t-2) var(--ease),
                border-color var(--t-2) var(--ease),
                color var(--t-2) var(--ease),
                box-shadow var(--t-2) var(--ease);
}

.btn:active:not([disabled]) {
    transform: scale(.97);
    opacity: .92;
}

.btn-primary {
    /* 顶部一道极淡的高光，纯色按钮看起来不再是一块塑料片 */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
}

.btn-plain {
    background: var(--surface);
}

@media (hover: hover) and (pointer: fine) {
    .btn:hover:not([disabled]) {
        filter: brightness(1.04);
    }

    .btn-plain:hover:not([disabled]),
    .btn-outline:hover:not([disabled]) {
        background: var(--surface-2);
        border-color: var(--line-2);
        filter: none;
    }

    .btn-ghost:hover:not([disabled]) {
        background: var(--primary-light);
    }
}

.btn[disabled] {
    opacity: .42;
    filter: saturate(.6);
}

/* 输入类：统一 40px 高、10px 圆角，聚焦时描边 + 柔光环 */
.input,
.select,
.textarea {
    min-height: 40px;
    border-color: var(--line);
    transition: border-color var(--t-2) var(--ease), box-shadow var(--t-2) var(--ease);
}

.input:focus,
.select:focus,
.textarea:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-light);
}

.input[disabled],
.select[disabled],
.textarea[disabled] {
    background: var(--surface-2);
    border-color: var(--line);
}

/* 选择器（ui-select 的触发器）：与输入框同高同圆角 */
.select-field {
    min-height: 40px;
    border-radius: var(--radius-sm);
    transition: border-color var(--t-2) var(--ease), background-color var(--t-2) var(--ease);
}

/* 分段控件：选中态有颜色过渡，不再「啪」地跳过去 */
.subtab,
.seg-pill,
.seg-item,
.theme-seg-item,
.settings-tabs button {
    transition: background-color var(--t-2) var(--ease),
                color var(--t-2) var(--ease),
                border-color var(--t-2) var(--ease),
                transform var(--t-1) var(--ease);
}

.subtab:active,
.seg-pill:active {
    transform: scale(.96);
}

/* 勾选胶囊：开启时轻微弹一下，给「点到了」的确认感 */
.check {
    transition: background-color var(--t-2) var(--ease),
                border-color var(--t-2) var(--ease),
                color var(--t-2) var(--ease);
}

.check.on .ico {
    animation: jxPopIn var(--t-2) var(--ease-spring);
}

.check-plain input[type="checkbox"] {
    width: 19px;
    height: 19px;
    border-radius: 5px;
}

/* 标签：字重加一点，深浅底都不容易糊 */
.tag {
    padding: 2px 9px;
    font-size: calc(11.5px * var(--jx-fs));
    font-weight: 600;
    line-height: 1.6;
}

/* 图标按钮：按下回弹（已在 app.css 有 .icon-btn:active，这里补过渡曲线） */
.icon-btn {
    transition: background-color var(--t-2) var(--ease),
                color var(--t-2) var(--ease),
                border-color var(--t-2) var(--ease),
                transform var(--t-1) var(--ease);
}

/* ==========================================================================
   R5. 导航：侧栏 / 顶栏 / 面包屑 / 底部 Tab
   ========================================================================== */

/* 品牌名过长时省略，不再折行把侧栏挤成两行（桌面 196px 下的真实问题） */
.brand-name,
.drawer-head .drawer-id strong {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.brand-name {
    font-size: calc(14px * var(--jx-fs));
    font-weight: 700;
    letter-spacing: 0;
}

.brand {
    gap: 9px;
    padding: 0 12px;
}

.brand .brand-logo {
    width: 28px;
    height: 28px;
    border-radius: 9px;
}

/* 桌面侧栏：条目改成圆角块 + 选中时左侧短竖条，整栏不再是「一列文字」 */
@media (min-width: 1024px) {
    /* 侧栏品牌区始终留在顶部；只有菜单区滚动，避免滚动时品牌也被带走。 */
    .sidebar {
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .sidebar .brand {
        flex: 0 0 var(--topbar-h);
    }

    .sidebar .nav {
        flex: 1 1 auto;
        min-height: 0;
        padding: 8px 0 18px;
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
        scrollbar-color: transparent transparent;
    }

    /* 桌面端日常以鼠标滚轮浏览；滚动条仅在需要拖动时以极细轨道出现。 */
    .sidebar .nav:hover {
        scrollbar-color: var(--side-line) transparent;
    }

    .sidebar .nav::-webkit-scrollbar {
        width: 4px;
    }

    .sidebar .nav::-webkit-scrollbar-track {
        background: transparent;
    }

    .sidebar .nav::-webkit-scrollbar-thumb {
        background: transparent;
        border-radius: 999px;
    }

    .sidebar .nav:hover::-webkit-scrollbar-thumb {
        background: var(--side-line);
    }

    .sidebar .nav-item {
        min-height: 36px;
        margin: 1px 8px;
        padding: 0 10px;
        border-left: 0;
        border-radius: 10px;
        transition: background-color var(--t-2) var(--ease), color var(--t-2) var(--ease);
    }

    .sidebar .nav-item.active {
        position: relative;
        font-weight: 600;
    }

    .sidebar .nav-item.active::before {
        content: "";
        position: absolute;
        top: 50%;
        left: -8px;
        width: 3px;
        height: 18px;
        margin-top: -9px;
        border-radius: 0 3px 3px 0;
        background: var(--side-fg);
        opacity: .9;
    }

    .sidebar .nav-group-title {
        padding: 10px 16px 3px;
        letter-spacing: .6px;
    }
}

/* 顶栏：标题更实，面包屑更淡，右侧入口不抢视线 */
.topbar {
    border-bottom-color: var(--line);
    transition: background-color var(--t-2) var(--ease);
}

.topbar-title {
    letter-spacing: -.01em;
}

.topbar-menu,
.topbar-user {
    transition: background-color var(--t-2) var(--ease), color var(--t-2) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
    .topbar-menu:hover,
    .topbar-theme:hover,
    .topbar-user:hover,
    .topbar-font:hover {
        background: var(--nav-fg-soft);
    }
}

/* 底部 Tab：选中项顶部一条短指示条 + 图标弹一下 */
.tab-item {
    transition: color var(--t-2) var(--ease);
}

.tab-item.active::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 18px;
    height: 3px;
    margin-left: -9px;
    border-radius: 0 0 3px 3px;
    background: currentColor;
    opacity: .85;
}

.tab-item.active .tab-icon {
    animation: jxTabPop var(--t-3) var(--ease-spring);
}

/* 角标：进场脉冲只播 3 次（不常驻动画，省电） */
.badge,
.tab-badge {
    font-variant-numeric: tabular-nums;
    animation: jxBadgePulse 2.2s var(--ease) 3;
}

/* ==========================================================================
   R6. 反馈：Toast / 确认框 / 加载
   ========================================================================== */
.jx-toast {
    padding: 11px 16px;
    border-radius: 14px;
    font-size: calc(13.5px * var(--jx-fs));
    font-weight: 500;
    line-height: 1.5;
    box-shadow: var(--shadow-3);
    animation: jxToastIn var(--t-3) var(--ease) both;
}

/* 错误提示多一个很轻的左右抖动：视线更容易被错误抓住，但不夸张 */
.jx-toast-err {
    animation: jxToastIn var(--t-3) var(--ease) both,
               jxToastShake .42s .18s ease-in-out;
}

.jx-confirm {
    width: 100%;
    max-width: min(340px, 86vw);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-3);
    animation: jxPop var(--t-2) var(--ease) both;
}

.jx-confirm-title {
    padding: 18px 18px 4px;
    letter-spacing: -.01em;
}

.jx-confirm-body {
    padding: 6px 18px 18px;
    color: var(--text-2);
}

.jx-confirm-foot {
    border-top-color: var(--line);
}

.jx-confirm-foot .btn {
    min-height: 48px;
    font-size: calc(14px * var(--jx-fs));
    transition: background-color var(--t-2) var(--ease), color var(--t-2) var(--ease);
}

.jx-confirm-foot .btn:active {
    transform: none;
}

@media (hover: hover) and (pointer: fine) {
    .jx-confirm-foot .btn:hover {
        background: var(--surface-2);
    }

    .jx-confirm-foot .btn-primary:hover {
        background: var(--primary-light);
    }
}

.jx-loading {
    animation: jxFade var(--t-2) var(--ease);
}

.jx-spinner {
    width: 30px;
    height: 30px;
    border-width: 2.5px;
    border-top-color: var(--primary-text);
}

/* ==========================================================================
   R7. 浮层：弹窗（手机贴底 / 电脑居中）、面板、抽屉
   --------------------------------------------------------------------------
   统一排除整屏编辑器类弹窗（它们有自己的宽度与直角规则）：
     .activity-page-editor / .form-page-editor / .growth-form-modal
     .public-poster-modal / .public-signup-modal / .submissions-modal
   —— 这些类在 app.css 里用「单类选择器」给了 width/max-width，
      若不排除，本文件后加载的 .modal 规则会覆盖掉它们的尺寸。
   ========================================================================== */
.modal-mask {
    background: var(--scrim-modal, var(--overlay));
    animation: jxFade var(--t-2) var(--ease);
}

.modal-head {
    /* 品牌渐变标题行：比纯色多一点层次，仍然只占一条窄带 */
    background: var(--modal-head-bg);
    color: var(--on-accent);
    border-bottom-color: var(--side-line);
    font-weight: 650;
}

.modal-head .close,
.modal-head .icon-btn {
    border-radius: var(--radius-pill);
    transition: background-color var(--t-2) var(--ease), color var(--t-2) var(--ease);
}

.modal-body {
    background: var(--surface);
}

.modal-foot {
    background: var(--surface-2);
    border-top-color: var(--line);
}

/* ---- 手机：100% 宽、贴底、24px 上圆角、顶部拖动条 ---- */
@media (max-width: 767px) {
    .modal-mask {
        padding: 0;
        align-items: flex-end;
    }

    .modal:not(.activity-page-editor):not(.form-page-editor):not(.growth-form-modal):not(.public-poster-modal):not(.public-signup-modal):not(.submissions-modal) {
        width: 100%;
        max-width: 100%;
        max-height: 92vh;
        max-height: 92dvh;
        border: 0;
        border-top: 1px solid var(--line);
        border-radius: var(--r-xl) var(--r-xl) 0 0;
        background: var(--surface);
        box-shadow: var(--shadow-3);
        animation: jxSheetUp var(--t-3) var(--ease) both;
        /* 底部安全区由 .modal-foot 统一补，这里不能再补一次，否则 iPhone 上会多出一条空白 */
    }

    .modal-head {
        position: relative;
        padding: 19px 14px 11px;
        border-radius: var(--r-xl) var(--r-xl) 0 0;
    }

    /* 拖动条：纯装饰，告诉用户「这是一张可以往下推的卡片」 */
    .modal-head::before {
        content: "";
        position: absolute;
        top: 7px;
        left: 50%;
        width: 36px;
        height: 4px;
        margin-left: -18px;
        border-radius: 99px;
        background: rgba(255, 255, 255, .5);
    }

    .modal-title {
        font-size: calc(15.5px * var(--jx-fs));
    }

    .modal-body {
        padding: 16px 16px 18px;
        overscroll-behavior: contain;
    }

    .modal-foot {
        padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
        box-shadow: 0 -1px 0 var(--line);
    }

    .modal-foot .btn {
        min-height: 46px;
    }
}

/* ---- 电脑 / 平板：居中、20px 圆角、轻微弹入 ---- */
@media (min-width: 768px) {
    .modal-mask {
        padding: 24px;
        align-items: center;
    }

    .modal:not(.activity-page-editor):not(.form-page-editor):not(.growth-form-modal):not(.public-poster-modal):not(.public-signup-modal):not(.submissions-modal) {
        width: 100%;
        max-width: 600px;
        max-height: 86vh;
        border: 1px solid var(--line);
        border-radius: var(--radius-lg);
        background: var(--surface);
        box-shadow: var(--shadow-3);
        animation: jxPop var(--t-2) var(--ease) both;
    }

    .modal.modal-sm {
        max-width: 440px;
    }

    .modal-head {
        padding: 14px 16px;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    }

    .modal-body {
        padding: 18px 20px;
    }

    .modal-foot {
        padding: 12px 20px;
    }

    .modal-foot .btn {
        flex: 0 1 auto;
        min-width: 104px;
    }

    .modal-foot .btn-block {
        flex: 1;
    }
}

/* 底部面板（日期 / 选择器）：与弹窗同一套圆角语言，手机贴底、电脑居中 */
.sheet {
    background: var(--surface);
    border-color: var(--line);
    box-shadow: var(--shadow-3);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    transition: none;
}

.sheet-head {
    padding: 13px 14px 11px;
}

@media (max-width: 767px) {
    .sheet {
        max-width: 100%;
        border-radius: var(--r-xl) var(--r-xl) 0 0;
        animation: jxSheetUp var(--t-3) var(--ease) both;
    }
}

@media (min-width: 768px) {
    .sheet {
        max-width: 460px;
        border-radius: var(--radius-lg);
        animation: jxPop var(--t-2) var(--ease) both;
    }
}

/* 手机抽屉：从左侧滑入、右侧圆角，宽度放宽到 64%（原 58% 略窄） */
@media (max-width: 767px) {
    .drawer {
        animation: jxFade var(--t-2) var(--ease);
    }

    .drawer-panel {
        width: 64%;
        min-width: 232px;
        max-width: 272px;
        border-radius: 0 var(--radius) var(--radius) 0;
        animation: jxSlideRight var(--t-3) var(--ease) both;
    }

    .drawer-panel .nav-item {
        min-height: 42px;
        border-radius: 11px;
    }

    /* 底部面板也补一条拖动条，与手机弹窗保持同一种「可推下去」的语言 */
    .sheet-head {
        position: relative;
        padding-top: 18px;
    }

    .sheet-head::before {
        content: "";
        position: absolute;
        top: 7px;
        left: 50%;
        width: 36px;
        height: 4px;
        margin-left: -18px;
        border-radius: 99px;
        background: var(--line-2);
        opacity: .9;
    }
}

/* ==========================================================================
   R8. 色彩：只给「图标底」加分类色，状态色语义保持不变
   ========================================================================== */

/* 首页概览条：四格分别对应 待办 / 排课 / 学员 / 班级，各自一个浅色底 */
.home-stat-icon,
.home-stat-icon.primary,
.home-stat-icon.ok,
.home-stat-icon.danger,
.core-icon {
    border-radius: 11px;
}

.home-stat:nth-child(1) .home-stat-icon {
    background: var(--danger-light);
    color: var(--danger-text);
}

.home-stat:nth-child(2) .home-stat-icon {
    background: var(--a-blue-soft);
    color: var(--a-blue);
}

.home-stat:nth-child(3) .home-stat-icon {
    background: var(--a-teal-soft);
    color: var(--a-teal);
}

.home-stat:nth-child(4) .home-stat-icon {
    background: var(--a-violet-soft);
    color: var(--a-violet);
}

/* 快捷入口：去掉每格描边，只留浅底 + 图标，格子多的时候不再像表格 */
.quick-card .quick-item,
.quick-card .quick-item:hover,
.quick-card .quick-item:active {
    border-color: transparent;
}

.quick-card .quick-item:active {
    background: var(--primary-light);
}

/* 快捷入口：保留「重点 / 常规」两级层次，只把重点项的图标底做得更实一点 */
.quick-item .quick-icon.tone-accent {
    background: var(--primary-light);
    color: var(--primary-text);
}

.quick-item .quick-icon.tone-plain {
    background: var(--surface-2);
    color: var(--text-2);
}

/* 设置 / 微信对接分区图标：两套色系，扫读时先分区再找条目 */
.wx-settings-icon {
    background: var(--a-teal-soft);
    color: var(--a-teal);
}

.settings-panel-icon {
    background: var(--primary-light);
    color: var(--primary-text);
}

/* 设置项图标按行循环三种色（蓝 / 青 / 紫）：
   只做识别性着色，不代表状态；比原来一整列同色更容易「按位置记住」某一项。
   刻意不引入琥珀 / 玫红——那两个在本系统里是「提醒 / 异常」的专用色。 */
.settings-general-panel .settings-row .settings-icon {
    border-radius: 10px;
}

.settings-general-panel .settings-row:nth-child(3n+1) .settings-icon {
    background: var(--a-blue-soft);
    color: var(--a-blue);
}

.settings-general-panel .settings-row:nth-child(3n+2) .settings-icon {
    background: var(--a-teal-soft);
    color: var(--a-teal);
}

.settings-general-panel .settings-row:nth-child(3n) .settings-icon {
    background: var(--a-violet-soft);
    color: var(--a-violet);
}

/* 核心入口卡（班级 / 学员 / 核销 / 活动）：图标去掉描边，靠底色区分 */
.core-icon {
    background: var(--surface-2);
    color: var(--text-2);
}

.core-card-primary .core-icon {
    background: var(--primary-light);
    color: var(--primary-text);
}

/* ==========================================================================
   R9. 手机端专属：更短的顶栏、更大的触控面、更松的卡片间距
   ========================================================================== */
@media (max-width: 767px) {
    :root {
        --radius-card: 16px;
        --tabbar-h: 54px;
    }

    .main {
        padding: 10px 12px calc(var(--tabbar-h) + 18px + env(safe-area-inset-bottom));
    }

    .page-head {
        margin-bottom: 10px;
    }

    /* 卡片间距：原来 12px，在长列表里两两之间显得松、首屏能看到的条目少，收到 10px */
    .card {
        margin-bottom: 10px;
    }

    .card-head {
        padding: 11px 14px;
    }

    .card-body {
        padding: 13px 14px;
    }

    /* 触控：列表行、按钮、输入框统一 44px 下限（分段控件 40px 更紧凑） */
    .list-item {
        min-height: 54px;
        padding: 12px 14px;
    }

    .btn,
    .btn-sm {
        min-height: 44px;
    }

    .input,
    .select,
    .select-field {
        min-height: 42px;
    }

    /* 顶栏：实色替代毛玻璃（低端安卓上 blur 是滚动掉帧的主因） */
    .topbar {
        background: var(--surface);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        padding: 4px 10px;
        box-shadow: 0 1px 0 var(--line);
        border-bottom: 0;
    }

    .topbar-title {
        font-size: calc(16px * var(--jx-fs));
        font-weight: 700;
    }

    /* 底部 Tab / 提交条同理，实色不闪、滚动更稳 */
    .tabbar {
        background: var(--surface);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        border-top-color: var(--line);
        box-shadow: 0 -1px 0 rgba(0, 0, 0, .02);
    }

    .submit-bar {
        background: var(--surface);
        border-top-color: var(--line);
        border-radius: var(--radius) var(--radius) 0 0;
        padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
        box-shadow: 0 -8px 24px -18px rgba(16, 24, 40, .45);
    }

    .submit-bar .btn {
        min-height: 44px;
        padding: 0 18px;
    }

    /* 学员 / 班级列表页的控制条：与卡片同圆角，内部控件不再套两层边框 */
    .student-control-bar {
        border-radius: var(--radius-card);
        padding: 8px;
        border-color: var(--line);
        background: var(--surface);
    }

    .student-search-row .student-search-input {
        border-radius: var(--radius-pill);
        background: var(--surface-2);
        border-color: transparent;
    }

    .student-search-row .student-search-input:focus-within {
        background: var(--surface);
        border-color: var(--primary);
        box-shadow: 0 0 0 3px var(--primary-light);
    }

    /* 过滤用的胶囊按钮 / 选择器统一 38px，一行放得下三个 */
    .student-filter-select .select-field,
    .student-filter-row .class-status-tabs .seg-pill.sm {
        min-height: 38px;
        height: 38px;
        border-radius: var(--radius-pill);
    }

    /* 「新增班级」与旁边的「搜索」同高，避免一行里 40 / 44 / 48 三种高度并存 */
    .class-create-btn {
        height: auto;
        min-height: 44px;
        padding: 0 14px;
    }

    /* 学员卡：整卡可点，按下有反馈（比 hover 更符合触屏）。
       卡片本身不再设内边距 —— 与班级卡同构，留白交给卡片头 / 卡片底栏各自负责，
       底栏才能整条贴到卡片底边、下缘跟着卡片圆角走。
       （原来这里补了 13px，底栏被内边距顶起来，四周露出白边、四角还是直角，
       看起来像"贴"在卡片上的一块灰条，接不上卡片。） */
    .student-card {
        padding: 0;
        border-radius: var(--radius-card);
    }

    .student-card:active {
        background: var(--surface-2);
        transform: scale(.995);
    }

    /* 设置页：整块面板贴边更彻底，条目之间用底色差分组 */
    .settings-general-panel,
    .wx-settings-panel {
        border-radius: var(--radius-card);
    }

    .settings-page .settings-tabs {
        border-radius: var(--radius-pill);
        padding: 3px;
    }

    .settings-tabs button {
        border-radius: var(--radius-pill);
        min-height: 40px;
    }

    .settings-tabs button.on {
        box-shadow: var(--shadow-1);
    }

    /* 弹窗里的表单：底部保存条不再被键盘顶掉 */
    .modal-foot {
        position: sticky;
        bottom: 0;
        z-index: 2;
    }
}

/* 超窄屏（320-380）：搜索框独占一行。
   原来「状态 + 搜索框 + 搜索 + 新增」挤在一行，输入框会被压到 80px 左右，
   只剩一个放大镜图标，根本没法输入 —— 换行比缩小更有用。 */
@media (max-width: 380px) {
    .class-filter-row:not(.student-filter-row),
    .student-search-row {
        flex-wrap: wrap;
        row-gap: 6px;
    }

    .class-filter-row:not(.student-filter-row) .class-search-input,
    .student-search-row .student-search-input {
        order: 1;
        flex: 1 1 100%;
        min-height: 42px;
    }

    .class-filter-row:not(.student-filter-row) .class-status-tabs {
        order: 2;
    }

    .class-filter-row:not(.student-filter-row) .class-search-btn {
        order: 3;
        margin-left: auto;
    }

    .class-filter-row:not(.student-filter-row) .class-create-btn {
        order: 4;
    }

    .student-search-row .student-search-submit {
        order: 2;
        margin-left: auto;
    }

    .student-search-row .student-create-btn {
        order: 3;
    }
}

/* ==========================================================================
   R10. 电脑端专属：更舒展的版心、更紧凑的行高、悬停反馈
   ========================================================================== */
@media (min-width: 768px) {
    :root {
        --topbar-h: 52px;
    }
}

@media (min-width: 1024px) {
    :root {
        --sidebar-w: 208px;
    }

    .main {
        padding: 20px 24px 36px;
    }

    .topbar {
        padding: 0 18px;
        gap: 12px;
    }

    .topbar-title {
        font-size: calc(16px * var(--jx-fs));
        font-weight: 700;
    }

    .brand {
        padding: 0 14px;
    }

    .card-head {
        padding: 13px 16px;
    }

    .card-body {
        padding: 16px;
    }

    .list-item {
        padding: 12px 16px;
    }

    /* 桌面卡片网格稍微放宽，4 列不再挤成 200px */
    .student-card-grid {
        grid-template-columns: repeat(auto-fill, minmax(246px, 1fr));
        gap: 10px;
    }

    /* 设置页是「一行一项」的表单型页面：版心收窄，视线不必横跨 1200px 找控件 */
    .settings-page {
        max-width: 1040px;
    }

    /* 列表页搜索框：不再拉满整行（1400px 宽的输入框既难读也浪费横向空间），
       与右侧「高级」按钮组成一个紧凑工具条 */
    .filter-bar > .searchbar {
        max-width: 560px;
    }

    /* 悬停：只抬 1px + 描边变色，不用阴影（保持平面化） */
    @media (hover: hover) {
        .student-card:hover {
            transform: translateY(-1px);
            border-color: var(--primary);
            background: var(--surface);
        }

        .core-card:hover,
        .quick-card .quick-item:hover {
            border-color: var(--line-2);
        }

        .core-card,
        .quick-card .quick-item,
        .student-card {
            transition: transform var(--t-2) var(--ease),
                        border-color var(--t-2) var(--ease),
                        background-color var(--t-2) var(--ease);
        }
    }
}

/* ==========================================================================
   R11. 小动效关键帧（全部 transform / opacity）
   ========================================================================== */
@keyframes jxFade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes jxPop {
    from { opacity: 0; transform: scale(.965) translateY(6px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes jxPopIn {
    0% { transform: scale(.7); }
    60% { transform: scale(1.12); }
    100% { transform: scale(1); }
}

@keyframes jxSheetUp {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

@keyframes jxSlideRight {
    from { transform: translateX(-100%); }
    to { transform: translateX(0); }
}

@keyframes jxTabPop {
    0% { transform: translateY(0) scale(1); }
    45% { transform: translateY(-2px) scale(1.14); }
    100% { transform: translateY(0) scale(1); }
}

@keyframes jxBadgePulse {
    0%, 100% { transform: scale(1); }
    12% { transform: scale(1.18); }
    24% { transform: scale(1); }
}

@keyframes jxToastIn {
    from { opacity: 0; transform: translateX(-50%) translateY(12px) scale(.96); }
    to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

@keyframes jxToastShake {
    0%, 100% { transform: translateX(-50%); }
    25% { transform: translateX(calc(-50% - 4px)); }
    75% { transform: translateX(calc(-50% + 4px)); }
}

/* ==========================================================================
   R12. 性能与无障碍
   --------------------------------------------------------------------------
   1) 触屏（无 hover）不加载任何悬停样式，避免「点一下停在悬停态」；
   2) 系统开启「减弱动态效果」时，动画与过渡全部瞬时完成（保留状态变化）。
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   R13. 页首工具条：形状统一为「全圆角」
   --------------------------------------------------------------------------
   原来同一排里混着三种形状：搜索框 10px、搜索/新增按钮 10px、状态胶囊 999px，
   换一台设备（断点不同）同一颗按钮还会从胶囊变方角，看成两套设计。
   这里只统一「工具条里的可点控件」，表单里的输入框仍保持 10px 的克制感：
     · 搜索框、搜索/新增按钮、状态下拉、日期框 → 999（胶囊）
     · 分段器（全部/启用/停用、周次、星期）→ 999（本来就是）
     · 分组外壳（周次导航三合一）→ 999 + 溢出裁切，组内按钮继续贴合
   ========================================================================== */
.class-filter-panel .class-status-tabs .seg-pill.sm,
.class-filter-panel .class-search-input,
.class-filter-panel .class-search-btn,
.class-filter-panel .class-create-btn,
.class-filter-row .class-search-input,
.class-filter-row .class-search-btn,
.class-filter-row .btn,
.student-control-bar .searchbar-input,
.student-control-bar .btn,
.student-filter-row .class-status-tabs .seg-pill.sm,
.student-filter-row .student-filter-select .select-field,
.week-toolbar-nav,
.week-toolbar-date .date-field,
.page-head .btn,
.filter-bar .searchbar-input,
.filter-adv-btn {
    border-radius: var(--radius-pill);
}

/* 独立搜索栏（公告页等）：外层不再画框，输入区自身就是一颗胶囊，
   与带「高级」按钮的筛选条同一套外观，避免同一种控件两种框法 */
.searchbar {
    padding: 0;
    border: 0;
    background: transparent;
}

.searchbar .searchbar-input {
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
}

/* 承载胶囊的那层「托盘」：班级页原来是灰底方角（10px），学员页是白底 14px，
   同一位置的容器两种样子；统一成白底 14px 卡片，胶囊浮在卡片里 */
.class-filter-panel > .class-filter-row {
    padding: 6px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

/* 营销 / 活动页的页签轨道：9px 外壳 + 6px 内块，是全站最后一块方角，
   和旁边的胶囊搜索框并排时尤其明显，一并改成胶囊 */
.marketing-tabs-wrap {
    border-radius: var(--radius-pill);
}

.marketing-tabs-wrap::before,
.marketing-tabs-wrap .seg-pill {
    border-radius: var(--radius-pill);
}

/* 工具条上的「+」：方形图标按钮改成正圆，和状态胶囊同一种语言 */
.marketing-create {
    border-radius: 50%;
}

/* 周次导航是「上一页 / 本周 / 下一页」三合一：外壳做胶囊，内部按钮贴合，不留缝 */
.week-toolbar-nav {
    overflow: hidden;
}

/* 手机端取消周工具条外层那层「方盒子」：里面已经是两颗胶囊，再套一层边框只会显脏 */
@media (max-width: 767px) {
    .week-toolbar-wrap {
        padding: 0;
        border: 0;
        background: transparent;
    }

    .searchbar .searchbar-input {
        min-height: 42px;
        padding: 0 12px;
    }
}

/* ==========================================================================
   R14. 老带新工作台：筛选区重排
   --------------------------------------------------------------------------
   原实现把 4 个页签、搜索框、状态下拉全塞进一行，手机上：
     · 工具条是 grid 但列宽是 auto，页签轨道只拿到内容宽度（266px / 364px），
       每个页签被压到 61px，「待我处理」「试听安排」直接折成两行；
     · 搜索框被挤到 154px，占位文字显示成「家长、孩子」半句；
     · 搜索按钮是个 30px 的高饱和圆形，视觉重量超过主操作。
   改为「页签一行、搜索一行」，两级信息各占一行，宽度全部用满。
   ========================================================================== */
.referral-toolbar {
    gap: 12px;
    padding: 12px;
    border-bottom: 1px solid var(--line);
    background: var(--surface-2);
}

.referral-tabs {
    flex: 0 1 460px;
    max-width: 460px;
}

.referral-tabs .slide-tabs-item {
    white-space: nowrap;
}

.referral-filter {
    flex: 1 1 auto;
    min-width: 0;
    gap: 8px;
    justify-content: flex-end;
}

/* 搜索框吃满页签之外的空间，但留 170px 下限，占位文字不会被截半句 */
.referral-filter .marketing-search {
    flex: 1 1 220px;
    min-width: 170px;
    max-width: 340px;
    border-radius: var(--radius-pill);
}

.referral-filter .select-wrap {
    flex: 0 0 146px;
    min-width: 146px;
}

/* 顶部四个指标卡：与全站卡片同一档圆角，内容垂直居中（原来贴顶，卡片下半截空着） */
.referral-kpi {
    align-content: center;
    gap: 3px;
    border-radius: var(--radius);
}

.referral-kpi b {
    line-height: 1.15;
}

/* 搜索框里的确认键全站统一：灰图标，不再是主色小圆点（主操作留给右侧的「新增」） */
.marketing-search .icon-btn {
    border: 0;
    background: transparent;
    color: var(--text-3);
}

.marketing-search .icon-btn:hover {
    background: var(--surface-3);
    color: var(--primary-text);
}

/* 搜索确认键退成「工具条里的次级图标」：不再是一颗抢眼的主色圆点 */
.referral-filter .marketing-search .icon-btn {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--text-3);
}

.referral-filter .marketing-search .icon-btn:hover {
    background: var(--surface-3);
    color: var(--primary-text);
}

.referral-filter .select-wrap,
.referral-filter .select-field {
    border-radius: var(--radius-pill);
}

@media (max-width: 767px) {
    /* 关键：单列 1fr，页签轨道才能吃到整行宽度 */
    .referral-toolbar {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        gap: 8px;
        padding: 10px;
    }

    .referral-tabs {
        width: 100%;
    }

    .referral-tabs .slide-tabs-item {
        min-height: 38px;
        font-size: calc(13.5px * var(--jx-fs));
    }

    .referral-filter {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
    }

    .referral-filter .marketing-search {
        flex: 1 1 auto;
        width: auto;
        min-height: 40px;
        padding: 0 4px 0 12px;
    }

    .referral-filter .marketing-search .input {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
        font-size: calc(13px * var(--jx-fs));
    }

    .referral-filter .select-wrap {
        flex: 0 0 clamp(96px, 27vw, 116px);
        width: auto;
        min-width: 0;
    }

    .referral-filter .select-field {
        min-height: 40px;
        padding: 0 10px;
    }
}
