/* finesse · register=product · shell=sidebar+tabbar / stacked-core-cards
 * pages=home(guest 系统名片 · member 工作台) · SOUL=5 SPECTACLE=1 DENSITY=7
 * 约定：只改调色/外壳/密度/表面；导航位置、交互 affordance、状态色语义保持不变 */
/* ==========================================================================
   培训机构课时核销系统 — 全局样式
   移动优先；断点：<=767 手机（底部 Tab）/ 768-1023 平板 / >=1024 桌面（左侧菜单）
   ========================================================================== */

/* --------------------------------------------------------------------------
   尺寸令牌（与主题无关）；颜色令牌统一由 theme.css 提供，支持亮/暗双主题
   -------------------------------------------------------------------------- */
:root {
    --radius-sm: 7px;
    --radius: 10px;
    --radius-lg: 16px;   /* 弹窗 / 底部面板 / 登录卡等大块面 */
    --radius-pill: 999px; /* 胶囊：按钮 / 图标按钮 / 分段控件（与 .tag/.chip 一致） */

    /* ★ 卡片族统一圆角（学员卡 / 班级卡 / 日志卡 / 首页统计卡 / 搜索框 / 提示条 …）
       全部指向这一个令牌，别再给某一张卡片单独写 6px / 8px —— 那样就会和别的卡片对不齐。
       手机端在 §26 里统一放大到 12px。 */
    --radius-card: var(--radius);

    /* 字号系数：1 = 原有字号。全站 font-size 都写成 calc(<原值>px * var(--jx-fs))，
       只有手机 / 平板（<=1023px）会由 html[data-font="md|lg"] 改写它，见 §28。 */
    --jx-fs: 1;

    /* 「降一档」字号系数：给本身基准字号就偏大的两类元素用——页面搜索框与菜单。
       md 档与 --jx-fs 相同（不降），lg 档固定停在 md 的 1.08；
       最小档 sm 仍是 1（菜单最小时已经很小，不再往下调）。见 §28.4。 */
    --jx-fs-sub: 1;

    --sidebar-w: 196px;
    --topbar-h: 48px;
    --tabbar-h: 52px;
    --submit-bar-h: 57px;
}

* {
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

html, body {
    margin: 0;
    padding: 0;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    font-size: calc(14px * var(--jx-fs));
    line-height: 1.55;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    overscroll-behavior-y: none;
}

a {
    color: var(--primary-text);
    text-decoration: none;
}

button {
    font-family: inherit;
    font-size: inherit;
}

input, select, textarea {
    font-family: inherit;
    font-size: calc(14px * var(--jx-fs));
    color: var(--text);
}

img {
    max-width: 100%;
    display: block;
}

/* --------------------------------------------------------------------------
   启动占位
   -------------------------------------------------------------------------- */
.splash {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: var(--surface);
    gap: 12px;
}

.splash-logo {
    font-size: calc(22px * var(--jx-fs));
    font-weight: 700;
    color: var(--primary-text);
    letter-spacing: 2px;
}

.splash-tip {
    color: var(--text-muted);
    font-size: calc(13px * var(--jx-fs));
}

/* --------------------------------------------------------------------------
   布局
   -------------------------------------------------------------------------- */
.shell {
    min-height: 100vh;
}

.sidebar {
    display: none;
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--sidebar-w);
    background: var(--bg-side);
    border-right: 1px solid var(--line);
    overflow-y: auto;
    z-index: 50;
}

/* 品牌块并入左侧栏底色（不再单独铺一条主色横带），让侧栏成为一整块干净的面；
   强调交给图标徽标与名称本身 */
.brand {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 16px;
    background: var(--bg-side);
    color: var(--text);
    border-bottom: 1px solid var(--line);
    font-weight: 700;
    font-size: calc(16px * var(--jx-fs));
}

.brand .brand-logo {
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: var(--grad-brand);
    color: var(--on-accent);
}

.brand-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--primary);
    box-shadow: 0 0 0 4px var(--primary-light);
}

.nav {
    padding: 6px 0 16px;
}

.nav-group-title {
    padding: 7px 12px 3px;
    font-size: calc(11px * var(--jx-fs));
    color: var(--text-muted);
    letter-spacing: 1px;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 3px 12px;
    color: var(--text-2);
    font-size: calc(13.5px * var(--jx-fs));
    border-left: 3px solid transparent;
    cursor: pointer;
    user-select: none;
}

.nav-item:hover {
    background: var(--info-light);
    color: var(--text);
}

.nav-item.active {
    background: var(--primary-light);
    color: var(--primary-text);
    border-left-color: var(--primary-text);
    font-weight: 600;
}

.nav-icon {
    width: 20px;
    text-align: center;
    font-size: calc(15px * var(--jx-fs));
}

.nav-text {
    flex: 1;
}

/* --------------------------------------------------------------------------
   深底导航面：左侧栏 / 品牌块 / 手机端抽屉
   这几块底色都是 --bg-side，默认的 --text-2 / --text-muted
   是给浅底用的深色，落上去读不出来，所以统一改用 --side-* 前景令牌
   （亮色白字 6.1:1；暗色主题各自的 --side-* 也是浅色，观感不变）。
   悬停/选中改用半透明白，避免亮色的浅绿底 + 浅绿字这种「看不清」的组合。
   -------------------------------------------------------------------------- */
.brand {
    color: var(--side-fg);
    border-bottom-color: var(--side-line);
}

.brand-name {
    color: var(--side-fg);
}

.sidebar .nav-group-title,
.drawer-panel .nav-group-title {
    color: var(--side-fg-3);
}

.sidebar .nav-item,
.drawer-panel .nav-item {
    color: var(--side-fg-2);
}

/* 导航图标独立于条目文字，始终使用侧栏图标令牌。 */
.sidebar .nav-icon,
.drawer-panel .nav-icon {
    color: var(--side-icon);
}

.sidebar .nav-item:hover,
.drawer-panel .nav-item:hover {
    background: var(--side-hover);
    color: var(--side-fg);
}

.sidebar .nav-item.active,
.drawer-panel .nav-item.active {
    background: var(--side-active);
    color: var(--side-fg);
    border-left-color: var(--side-accent);
}

/* 抽屉标题行与抽屉面同色；侧栏上沿不再需要一条硬线（与顶栏同深色，分隔交给色块本身） */
.drawer-head {
    background: var(--bg-side);
    color: var(--side-fg);
    border-bottom-color: var(--side-line);
}

/* 抽屉身份卡的第二行（角色 · 分校）默认是浅底用的 --text-muted，深底上读不出来 */
.drawer-head .drawer-id small {
    color: var(--side-fg-3);
}

.body {
    min-height: 100vh;
}

.topbar {
    position: sticky;
    top: 0;
    z-index: 40;
    width: 100%;
    min-height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 12px;
    background: var(--glass-nav);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    border-bottom: 1px solid var(--line);
    color: var(--nav-fg);
}

/* 左：侧边栏菜单入口 */
.topbar-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
}

/* 顶栏常用操作采用紧凑按钮；主题按钮单独使用图标入口。 */
.topbar-menu,
.topbar-theme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    min-height: 40px;
    padding: 0 12px;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--nav-fg);
    font-family: inherit;
    font-size: calc(13px * var(--jx-fs));
    line-height: 1;
    opacity: .86;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s, opacity .15s;
}

/* 主题按钮是纯图标入口：尺寸与图标按钮一致；颜色见文件后段「模式只由图标表达」那条。 */
.topbar-theme {
    width: 36px;
    min-width: 36px;
    min-height: 36px;
    padding: 0;
    border-radius: 0;
    background: transparent;
}

/* 顶栏路径条（单行）：分校名 > 首页 > 分组 > 当前页
   全部同一字号字重；可点的段用链接色，当前页只做位置区分 */
.topbar-breadcrumb {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.topbar-breadcrumb::-webkit-scrollbar {
    display: none;
}

.topbar-crumb {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    max-width: 132px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--nav-fg);
    opacity: .68;
    font-family: inherit;
    font-size: calc(12px * var(--jx-fs));
    font-weight: 400;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}

.topbar-crumb.label {
    max-width: 168px;
    opacity: .84;
    cursor: default;
}

.topbar-crumb.group {
    opacity: .62;
}

.topbar-crumb.current {
    opacity: 1;
    font-weight: 600;
    cursor: default;
}

/* 分段之间的“>”：用伪元素生成，避免模板里再套一层 index 判断 */
.topbar-crumb + .topbar-crumb::before {
    content: ">";
    margin-right: 5px;
    color: var(--nav-fg);
    opacity: .38;
}

.topbar-right {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 1 auto;
    min-width: 0;
}

.topbar-user {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--nav-fg);
    opacity: .84;
    padding: 6px 10px;
    border-radius: 20px;
    font-size: calc(12px * var(--jx-fs));
    font-weight: 400;
    cursor: pointer;
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: background .15s, border-color .15s;
}

.topbar-user-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.main {
    padding: 10px 10px calc(var(--tabbar-h) + 16px + env(safe-area-inset-bottom));
    max-width: 1280px;
    margin: 0 auto;
}

.tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--tabbar-h);
    display: flex;
    background: var(--glass-tab);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    border-top: 1px solid var(--line);
    z-index: 45;
    padding-bottom: env(safe-area-inset-bottom);
}

.tab-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    color: var(--text-muted);
    font-size: calc(11px * var(--jx-fs));
    position: relative;
    cursor: pointer;
}

.tab-item.active {
    color: var(--primary-text);
    font-weight: 600;
}

.tab-icon {
    font-size: calc(18px * var(--jx-fs));
    line-height: 1;
}

.tab-badge {
    position: absolute;
    top: 4px;
    right: 50%;
    margin-right: -22px;
    background: var(--danger);
    color: var(--on-accent);
    font-size: calc(10px * var(--jx-fs));
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    border-radius: 8px;
    text-align: center;
    padding: 0 4px;
}

.badge {
    background: var(--danger);
    color: var(--on-accent);
    font-size: calc(11px * var(--jx-fs));
    min-width: 18px;
    height: 18px;
    line-height: 18px;
    border-radius: 9px;
    text-align: center;
    padding: 0 5px;
}

/* 移动端抽屉菜单 */
.drawer {
    position: fixed;
    inset: 0;
    background: var(--overlay);
    z-index: 60;
    display: flex;
}

.drawer-panel {
    width: 84%;
    max-width: 320px;
    background: var(--bg-side);
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: calc(16px + env(safe-area-inset-bottom));
    scrollbar-width: thin;
    scrollbar-color: var(--line-2) transparent;
}

/* 抽屉里条目多、必然需要滚动：把滚动条做细做淡，避免它成为视觉噪声 */
.drawer-panel::-webkit-scrollbar {
    width: 4px;
}

.drawer-panel::-webkit-scrollbar-track {
    background: transparent;
}

.drawer-panel::-webkit-scrollbar-thumb {
    background: var(--line-2);
    border-radius: var(--radius-pill);
}

/* 抽屉：字号比桌面侧栏大一档，纵向间距收紧，保证「看得清」又不被撑长 */
.drawer-panel .nav {
    padding: 4px 0 8px;
}

/* 抽屉里的条目改成圆角胶囊选中块，去掉左侧竖条（竖条在窄栏里显得零碎）；
   固定 44px 高度：既是触控下限，也比默认内边距更短，减少滚动长度 */
.drawer-panel .nav-item {
    min-height: 44px;
    margin: 1px 8px;
    padding: 0 12px;
    font-size: calc(15px * var(--jx-fs));
    gap: 11px;
    border-left: 0;
    border-radius: var(--radius-pill);
}

.drawer-panel .nav-item.active {
    border-left-color: transparent;
}

.drawer-panel .nav-icon {
    width: 22px;
}

.drawer-panel .nav-group-title {
    padding: 9px 16px 2px;
    font-size: calc(11.5px * var(--jx-fs));
    letter-spacing: .5px;
}

.drawer-head {
    position: sticky;
    top: 0;
    z-index: 1;
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    padding: 0 16px;
    background: var(--bg-side);
    border-bottom: 1px solid var(--line);
    font-size: calc(14px * var(--jx-fs));
    font-weight: 700;
}

/* 手机侧边抽屉：占屏约 58%（原 84%），留出更多页面上下文；
   横向留白收紧，文字和图标略放大，确保窄栏仍便于扫读与点击。 */
@media (max-width: 767px) {
    .drawer-panel {
        width: 58%;
        min-width: 210px;
        max-width: 236px;
    }
    /* 手机抽屉：条目更矮、行与行相接，把纵向长度留给内容
       （40px 是本项目对触屏紧凑控件的下限，仍可稳定点中） */
    .drawer-panel .nav { padding: 2px 0 4px; }
    .drawer-panel .nav-item {
        min-height: 40px;
        margin: 0 6px;
        padding: 0 10px;
        gap: 10px;
        font-size: calc(15.5px * var(--jx-fs));
    }
    .drawer-panel .nav-icon { width: 21px; }
    /* 分组标题也压一档：6 个分组标题原本占掉约 170px */
    .drawer-panel .nav-group-title {
        padding: 7px 14px 1px;
        font-size: calc(11px * var(--jx-fs));
        line-height: 1.25;
        letter-spacing: .3px;
    }
    .drawer-head {
        padding: 0 12px;
        font-size: calc(15px * var(--jx-fs));
    }
}

.public-shell {
    min-height: 100vh;
}

/* --------------------------------------------------------------------------
   卡片 / 区块
   -------------------------------------------------------------------------- */
.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    /* 平面化：卡片不做投影，层次只靠 1px 描边 + 底色差。
       投影会让密集列表显得"浮起来"，在手机上尤其显脏。 */
    margin-bottom: 12px;
    overflow: hidden;
}

.card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--line);
}

.card-title {
    flex: 1;
    font-size: calc(14px * var(--jx-fs));
    font-weight: 600;
}

.card-body {
    padding: 14px;
}

.card-foot {
    padding: 11px 14px;
    border-top: 1px solid var(--line);
    background: var(--surface-2);
}

.card-plain {
    border: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   按钮
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    min-height: 36px;
    padding: 0 16px;
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    background: var(--info-light);
    color: var(--text);
    font-size: calc(13.5px * var(--jx-fs));
    cursor: pointer;
    transition: opacity .15s, background .15s;
    white-space: nowrap;
    user-select: none;
}

.btn:active {
    opacity: .82;
}

.btn[disabled] {
    opacity: .45;
    cursor: not-allowed;
}

.btn-primary {
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
}

.btn-ok {
    background: var(--ok);
    color: var(--on-accent);
}

.btn-danger {
    background: var(--danger);
    color: var(--on-accent);
}

.btn-warn {
    background: var(--warn);
    color: var(--on-accent);
}

/* 次要动作（取消 / 跟进 / 补收款等）：
   .btn-outline 在页面里已大量使用，但此前没有定义，落到 .btn 的 --info-light 上，
   在春意/经典主题里是一块发蓝的浅底，既不像取消也不像按钮；暗色主题又会变成
   另一块深紫。这里改为「跟随当前面底的中性浅底 + 描边 + 次要文字」，
   和 .btn-plain 同一套观感，任何主题下都不会和背景撞色或糊在一起。 */
.btn-outline {
    background: var(--surface);
    border-color: var(--line);
    color: var(--text-2);
}

.btn-plain {
    background: var(--surface);
    border-color: var(--line);
    color: var(--text-2);
}

.btn-ghost {
    background: transparent;
    color: var(--primary-text);
    border-color: var(--primary-text);
}

.btn-sm {
    min-height: 30px;
    padding: 0 13px;
    font-size: calc(12.5px * var(--jx-fs));
    border-radius: var(--radius-pill);
}

.btn-lg {
    min-height: 48px;
    padding: 0 22px;
    font-size: calc(16px * var(--jx-fs));
    border-radius: var(--radius-pill);
}

.btn-block {
    display: flex;
    width: 100%;
}

.btn-icon {
    min-width: 40px;
    padding: 0 12px;
}

.btn-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* 学员出勤批量操作：标签，不是按钮
   这五个动作是「一次把全班设成同一个状态」的快捷入口，
   重量不该和「提交核销」这类主操作一样，所以做成标签观感：
   无边框、浅底、字号小一号，靠文字本身表达；仍然保留够用的点击高度。 */
.attendance-quick-row {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.quick-row-label {
    flex: 0 0 auto;
    padding-right: 2px;
    color: var(--text-3);
    font-size: calc(12px * var(--jx-fs));
}

.qa-tag {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    padding: 0 11px;
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--info-light);
    color: var(--text-2);
    font-family: inherit;
    font-size: calc(12.5px * var(--jx-fs));
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s, color .15s;
}

.qa-tag:hover {
    background: var(--hover);
    color: var(--text);
}

.qa-tag:active {
    background: var(--selected);
}

.qa-tag[disabled] {
    opacity: .45;
    cursor: not-allowed;
}

/* 最窄屏（320）：让出「全选」标签并收一点内边距，保证 5 颗仍是一行 */
@media (max-width: 360px) {
    .quick-row-label {
        display: none;
    }

    .attendance-quick-row .qa-tag {
        padding: 0 9px;
    }
}

/* 触屏：标签高度提到 34px（与页内 30px 的状态分段同档，不喧宾夺主） */
@media (max-width: 767px) {
    .qa-tag {
        min-height: 34px;
    }
}

/* --------------------------------------------------------------------------
   表单
   -------------------------------------------------------------------------- */
.field {
    margin-bottom: 14px;
}

.field-label {
    display: block;
    margin-bottom: 7px;
    font-size: calc(12.5px * var(--jx-fs));
    color: var(--text-2);
}

.field-label .req {
    color: var(--danger-text);
    margin-left: 2px;
}

.input, .select, .textarea {
    width: 100%;
    min-height: 38px;
    padding: 8px 11px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-size: calc(13.5px * var(--jx-fs));
    outline: none;
    transition: border-color .15s, box-shadow .15s;
    appearance: none;
}

.select {
    background-image: var(--select-arrow);
    background-repeat: no-repeat;
    background-position: right 11px center;
    padding-right: 28px;
}

.textarea {
    min-height: 90px;
    resize: vertical;
    line-height: 1.6;
}

.input:focus, .select:focus, .textarea:focus {
    border-color: var(--primary-text);
    box-shadow: var(--ring);
}

.input::placeholder, .textarea::placeholder {
    color: var(--text-muted);
    opacity: 1;
}

.input[disabled], .select[disabled], .textarea[disabled] {
    background: var(--info-light);
    color: var(--text-muted);
}

.field-hint {
    margin-top: 4px;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 16px;
}

/* 表单里的「填写更多信息」折叠开关：整行可点，收起时一条细线提示还有内容 */
.more-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 4px 0 12px;
    padding: 10px 2px;
    border-top: 1px solid var(--line);
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    cursor: pointer;
    user-select: none;
}

.more-toggle:active {
    opacity: .7;
}

.more-toggle.on {
    color: var(--primary);
    font-weight: 600;
}

.more-toggle-hint {
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    font-weight: 400;
}

/* 「已填 N 项」计数：复用 .seg-count 的观感，但在折叠条里不能被压扁 */
.more-toggle .seg-count {
    margin-left: auto;
    flex: 0 0 auto;
}

.form-actions {
    display: flex;
    gap: 10px;
    margin-top: 6px;
}

.inline-form {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

/* 复选框行 */
.check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border: 1px solid var(--line);
    border-radius: 20px;
    font-size: calc(13px * var(--jx-fs));
    cursor: pointer;
    background: var(--surface);
    user-select: none;
}

.check input {
    margin: 0;
}

.check.on {
    border-color: var(--primary-text);
    background: var(--primary-light);
    color: var(--primary-text);
}

/* 传统复选框（方框 + 勾 + 文字）：明确是「勾选一项」的地方用它
   （登录页「记住登录状态」）——上面的 .check 是胶囊开关 / 多选胶囊，
   读起来像按钮，而且靠图标表示选中，不如方框一眼就懂。
   用法：<label class="check check-plain"><input type="checkbox" v-model="x"><span>文字</span></label>
   · 复用 .check 的行内排布与移动端 44px 触控下限，只把胶囊装饰去掉；
   · 勾选态交给原生控件自身（accent-color 上品牌色），不改 .check.on 的语义，
     所以设置页 / 多选胶囊那些地方完全不受影响。 */
.check-plain {
    gap: 8px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--text-2);
    font-size: calc(13.5px * var(--jx-fs));
}

.check-plain input[type="checkbox"] {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--primary-text);   /* 亮色=品牌绿，暗色=品牌紫粉 */
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   标签页（.subtabs 仅用于确实需要横向滚动的场景，见 §15；
   常规筛选/状态切换一律用 .seg-row，见 §21）
   -------------------------------------------------------------------------- */
.subtabs {
    display: flex;
    gap: 5px;
    overflow-x: auto;
    padding: 2px 0 8px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.subtabs::-webkit-scrollbar {
    display: none;
}

.subtab {
    padding: 5px 11px;
    border-radius: 18px;
    background: var(--surface);
    border: 1px solid var(--line);
    color: var(--text-2);
    font-size: calc(12.5px * var(--jx-fs));
    white-space: nowrap;
    cursor: pointer;
}

.subtab.active {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-accent);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   滑动式 tabs（两档；当前用于家长端「上课记录 / 课时变动」）
   并排两个胶囊按钮会被当成「操作按钮」；改成「一条轨道 + 一个滑到选中项的滑块」，
   一眼能看出是切换视图，而不是触发动作。观感沿用 .theme-seg 的选中语言：
   轨道 --surface-3 / 滑块 --surface / 选中文字 --primary-text + 加粗。
   · 滑块宽 =（轨道宽 − 左右内边距 − 档间距）/ 档数：这里按两档算
   · 位移交由 app.js 侧的 thumbStyle 计算（translateX(i * (100% + --st-gap))）
   · 要加第三档时，记得同时改下面两条 calc 与 thumbStyle
   -------------------------------------------------------------------------- */
.slide-tabs {
    --st-pad: 4px;
    --st-gap: 4px;
    position: relative;
    isolation: isolate;
    display: flex;
    gap: var(--st-gap);
    padding: var(--st-pad);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    overflow: hidden;
}

/* 放进 .card-head 当「卡片头」用时，滑轨占满整行（页签与列表之间由 card-head 的下发丝线 + 行内边距留出距离） */
.card-head > .slide-tabs {
    flex: 1;
}

.slide-tabs-thumb {
    position: absolute;
    z-index: 0;
    pointer-events: none;
    top: var(--st-pad);
    bottom: var(--st-pad);
    left: var(--st-pad);
    width: calc((100% - 2 * var(--st-pad) - var(--st-gap)) / 2);
    border-radius: var(--radius-pill);
    background: var(--surface);
    transition: transform .2s cubic-bezier(.22, .61, .36, 1);
}

.slide-tabs-item {
    position: relative;
    z-index: 1;
    flex: 1 1 0;
    min-width: 0;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-2);
    font-family: inherit;
    font-size: calc(14px * var(--jx-fs));
    line-height: 1.2;
    cursor: pointer;
    transition: color .2s;
}

.slide-tabs-item.on {
    color: var(--primary-text);
    font-weight: 700;
}

/* 星期分段：手机端显示单字简写（全 / 一 / 二 … / 日） */
.wk-s {
    display: none;
}

.subtab.week {
    padding: 5px 0;
    min-width: 44px;
    text-align: center;
    flex: 1 0 auto;
}

@media (max-width: 767px) {
    .wk-l {
        display: none;
    }

    .wk-s {
        display: inline;
    }

    /* 8 个星期选项（全+一~日）在一行内等分铺满，不再横向滚动 */
    .subtabs.week-row {
        overflow-x: visible;
        gap: 3px;
    }

    .subtabs.week-row .subtab.week {
        min-width: 0;
        padding: 0;
        flex: 1 1 0;
    }
}

/* --------------------------------------------------------------------------
   列表 / 表格
   -------------------------------------------------------------------------- */
.list {
    background: var(--surface);
}

.list-item {
    display: flex;
    gap: 8px;
    padding: 13px 14px;
    border-bottom: 1px solid var(--line);
    align-items: center;
}

.list-item:last-child {
    border-bottom: 0;
}

.list-item-main {
    flex: 1;
    min-width: 0;
}

.list-item-title {
    font-size: calc(15px * var(--jx-fs));
    font-weight: 600;
    margin-bottom: 3px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.list-item-sub {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.list-item-side {
    text-align: right;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    white-space: nowrap;
}

/* 手机端：条目里带「一排按钮」时改成上下两段
   --------------------------------------------------------------------------
   .list-item 默认是「左信息 + 右操作」的横排：宽屏没问题，但手机上一排按钮
   （编辑 / 重置密码 / 停用 这类）会把左侧文字挤成一条竖缝 —— 学校名、编码、
   额度全变成一个词一行。所以带 .btn-row 的条目在窄屏改成上下堆叠：信息占满
   整行，按钮排在下面、按剩余宽度等分。桌面与 iPad 保持原来的横排。 */
@media (max-width: 767px) {
    .list-item.stack {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }

    /* 标题里通常还挂着状态标签：横排靠省略号收尾，竖排就该让它换行，别把标签吃掉 */
    .list-item.stack .list-item-title {
        white-space: normal;
    }

    .list-item.stack .btn-row .btn {
        flex: 1 1 auto;
    }
}

.member-link-row {
    position: relative;
}

.member-link-row.pointer {
    cursor: pointer;
}

.member-mobile-balance,
.member-remove {
    display: none;
}

@media (hover: hover) {
    .member-link-row.pointer:hover {
        background: var(--surface-2);
    }
}

/* 手机端把低频移除操作收为右上角图标；本班课时并入副信息行。 */
@media (max-width: 767px) {
    .member-link-row {
        min-height: 74px;
        padding-right: 48px;
    }

    .member-link-row .member-side {
        display: none;
    }

    .member-mobile-balance {
        display: inline-flex;
        font-weight: 600;
    }

    .member-remove {
        position: absolute;
        top: 8px;
        right: 8px;
        display: inline-flex;
        width: 32px;
        height: 32px;
        color: var(--danger);
    }
}

/* --------------------------------------------------------------------------
   系统设置：窄屏说明与控件分两段，宽屏合并为一行
   -------------------------------------------------------------------------- */
.list-item.settings-row {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    align-items: start;
    gap: 6px 10px;
}

.settings-icon {
    grid-column: 1;
    grid-row: 1;
    padding-top: 1px;
}

.settings-copy {
    grid-column: 2;
    min-width: 0;
}

.settings-copy .field-label {
    margin-bottom: 2px;
}

.settings-desc {
    margin-top: 0;
}

.settings-control {
    grid-column: 2;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    margin-top: 5px;
}

.settings-field {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
}

.settings-field .check {
    flex: 0 0 auto;
    margin-top: 0;
}

.settings-field > .seg-row.seg-fit {
    flex: 1 1 auto;
    max-width: 180px;
    min-width: 0;
    margin-top: 0;
    padding: 0;
}

.settings-input {
    width: 100%;
    max-width: 180px;
    margin-top: 0;
}

.settings-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

.settings-actions .btn {
    flex: 0 0 auto;
}

/* 平板 / 桌面：说明在左，控件与「恢复默认」在同一行 */
@media (min-width: 768px) {
    .list-item.settings-row {
        grid-template-columns: 24px minmax(0, 1fr) minmax(290px, 330px);
        align-items: center;
        gap: 16px;
        padding: 12px 16px;
    }

    .settings-icon {
        grid-row: auto;
        padding-top: 0;
    }

    .settings-control {
        grid-column: 3;
        justify-content: flex-end;
        margin-top: 0;
    }
}

/* 大屏：说明通常也能完整放在一行；仍保留 title 供悬停查看 */
@media (min-width: 1280px) {
    .settings-desc {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .settings-copy .field-label {
        white-space: nowrap;
    }
}

/* 学员管理：紧凑小卡片清单，便于管理员在同一屏快速比较 */
.student-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    margin: 10px 0 12px;
}

.student-toolbar-label {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 3px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    white-space: nowrap;
}

.student-sort {
    display: flex;
    min-width: 0;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
}

.student-sort-btn {
    flex: 0 1 auto;
    min-width: 0;
    height: 30px;
    padding: 0 10px;
    border: 0;
    border-right: 1px solid var(--line);
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: calc(12px * var(--jx-fs));
    white-space: nowrap;
    cursor: pointer;
}

.student-sort-btn:last-child {
    border-right: 0;
}

.student-sort-btn:hover {
    background: var(--surface-2);
    color: var(--text);
}

.student-sort-btn.on {
    background: var(--primary-light);
    color: var(--primary-text);
    font-weight: 700;
}

.student-list-panel {
    min-width: 0;
}

.student-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 8px;
}

.student-card {
    position: relative;
    min-width: 0;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
    cursor: pointer;
    transition: background .12s, border-color .12s;
}

.student-card:hover {
    border-color: var(--primary);
    background: var(--surface-2);
}

.student-card-head,
.student-card-foot {
    display: flex;
    align-items: center;
    min-width: 0;
}

.student-card-head {
    gap: 10px;
}

.student-card-foot {
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px solid var(--line);
}

.student-card-date {
    display: inline-flex;
    align-items: center;
    min-width: 0;
    gap: 4px;
    overflow: hidden;
    color: var(--text-muted);
    font-size: calc(11px * var(--jx-fs));
    text-overflow: ellipsis;
    white-space: nowrap;
}

.student-card .student-balance {
    display: inline-flex;
    align-items: baseline;
    min-width: 0;
    gap: 4px;
    text-align: right;
    white-space: nowrap;
}

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

.student-card .student-balance > span {
    display: inline;
    margin-top: 0;
}

@media (max-width: 480px) {
    .student-toolbar {
        gap: 6px;
    }

    .student-toolbar-label {
        display: none;
    }

    .student-sort {
        width: 100%;
    }

    .student-sort-btn {
        flex: 1 1 0;
        padding: 0 6px;
    }

    /* 排序三分段是列表页的高频操作，30px 在手机上偏小，补到触控下限 */
    .student-sort {
        min-height: 44px;
    }

    .student-sort-btn {
        height: 44px;
        font-size: calc(13px * var(--jx-fs));
    }

    .student-card-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* 学员管理：通讯录式用户列表（保留给其它嵌入式学员清单使用）
   行内不再放操作按钮，所有写操作收进「学员档案」详情页 */
.student-row {
    position: relative;
    display: block;
    height: auto;
    padding: 12px;
    transition: background .12s;
}

.student-row::before {
    content: '';
    position: absolute;
    top: 12px;
    bottom: 12px;
    left: 0;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--text-3);
}

.student-row.is-active::before {
    background: var(--ok);
}

.student-row.is-inactive::before {
    background: var(--danger);
}

.student-row:hover {
    background: var(--surface-2);
}

.student-row-main {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.student-row-head {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.student-avatar {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--primary);
    border-radius: 50%;
    background: var(--primary-light);
    color: var(--primary-text);
    font-size: calc(16px * var(--jx-fs));
    font-weight: 700;
}

/* 两行身份信息：第一行姓名/性别，第二行状态/班级，避免单行挤在一起 */
.student-identity {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.student-name-line,
.student-meta-line {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.student-name {
    max-width: 150px;
    overflow: hidden;
    flex: 0 1 auto;
    color: var(--text);
    font-size: calc(15.5px * var(--jx-fs));
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.student-gender {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.student-class-summary {
    display: inline-flex;
    align-items: center;
    flex: 0 1 auto;
    gap: 3px;
    min-width: 0;
    max-width: 112px;
    overflow: hidden;
    padding: 2px 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: calc(11px * var(--jx-fs));
    text-overflow: ellipsis;
    white-space: nowrap;
}

.student-balance {
    flex: 0 0 auto;
    min-width: 62px;
    text-align: right;
    line-height: 1;
}

.student-balance strong {
    display: block;
    color: inherit;
    font-size: calc(17px * var(--jx-fs));
}

.student-balance > span {
    display: block;
    margin-top: 3px;
    color: var(--text-muted);
    font-size: calc(10.5px * var(--jx-fs));
    font-weight: 500;
}

.student-row-arrow {
    flex: 0 0 auto;
    color: var(--text-3);
    opacity: .7;
}

/* 课时数量步进器：输入框两侧提供 0.5 课时加减按钮 */
.hours-stepper {
    width: 100%;
    max-width: 320px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.hours-step {
    flex: 0 0 44px;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--line-2);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-2);
    cursor: pointer;
    transition: background .12s, border-color .12s, color .12s, transform .1s;
}

.hours-step:hover,
.hours-step:active {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--primary-text);
}

.hours-step:active {
    transform: scale(.96);
}

.hours-step:disabled {
    opacity: .4;
    cursor: not-allowed;
}

.hours-stepper .hours-input {
    flex: 1 1 auto;
    width: auto;
    min-width: 86px;
    height: 44px;
    min-height: 44px;
    padding: 0 8px;
    text-align: center;
    font-size: calc(16px * var(--jx-fs));
    font-weight: 700;
}

@media (max-width: 380px) {
    .student-row {
        padding-right: 9px;
        padding-left: 10px;
    }

    .student-avatar {
        flex-basis: 36px;
        width: 36px;
        height: 36px;
        font-size: calc(15px * var(--jx-fs));
    }

    .student-class-summary {
        max-width: 84px;
    }
}

/* --------------------------------------------------------------------------
   学员档案：身份卡 + 单行课时 + 滑动分段 tabs
   -------------------------------------------------------------------------- */

/* 身份卡：头像与姓名是第一眼信息，其余资料收进「更多资料」 */
.sd-profile {
    padding: 14px;
    background: var(--student-profile-bg);
}

.sd-hours,
.class-detail-teachers-card {
    background: var(--student-hours-bg);
}

.growth-profile-card {
    background: var(--student-profile-bg);
}

/* 班级详情：信息概览与管理操作统一收口，减少标题栏按钮堆叠。 */
.class-detail-hero {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 16px 12px;
}

.class-detail-hero-main {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
}

.class-detail-hero-icon {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--primary);
    border-radius: 8px;
    background: var(--primary-light);
    color: var(--primary-text);
}

.class-detail-hero-name {
    overflow: hidden;
    color: var(--text);
    font-size: calc(17px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.35;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.class-detail-hero-meta,
.class-detail-tools,
.class-join-qr-summary {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.class-detail-hero-meta {
    margin-top: 4px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.class-detail-hero-meta span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.class-detail-tools {
    padding: 0 16px 14px 67px;
    border-bottom: 1px solid var(--line);
}

.class-detail-tools .btn {
    min-height: 34px;
}

.class-join-qr-modal,
.student-bind-qr-modal {
    max-width: 440px;
}

.class-join-qr-summary,
.student-bind-qr-summary {
    justify-content: center;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 12px;
}

.class-join-qr-summary strong,
.student-bind-qr-summary strong {
    color: var(--text);
    font-size: calc(16px * var(--jx-fs));
}

.class-join-qr-summary span,
.student-bind-qr-summary span {
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.class-join-qr-modal .qr-canvas,
.student-bind-qr-modal .qr-canvas {
    display: block;
    margin: 0 auto;
}

@media (max-width: 640px) {
    .class-detail-hero {
        padding: 14px 14px 10px;
    }

    .class-detail-tools {
        padding: 0 14px 12px;
    }

    .class-detail-tools .btn {
        flex: 1 1 auto;
        justify-content: center;
    }
}

.sd-profile-main {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.sd-avatar {
    flex: 0 0 52px;
    width: 52px;
    height: 52px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--primary);
    border-radius: 50%;
    background: var(--primary-light);
    color: var(--primary-text);
    font-size: calc(21px * var(--jx-fs));
    font-weight: 700;
}

.sd-profile-info {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.sd-profile-name {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.sd-name {
    min-width: 0;
    overflow: hidden;
    color: var(--text);
    font-size: calc(19px * var(--jx-fs));
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sd-profile-meta {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
    color: var(--text-muted);
    font-size: calc(12.5px * var(--jx-fs));
}

.sd-profile-meta > span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 档案操作：手机端两列，桌面端一行铺开 */
.sd-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin-top: 14px;
}

.sd-profile .more-toggle {
    margin-top: 12px;
}

.sd-profile .kv {
    margin-top: 10px;
}

.sd-profile-edit {
    flex: 0 0 auto;
    align-self: flex-end;
    margin-bottom: 1px;
}

.sd-profile-edit .btn {
    min-height: 38px;
    padding: 0 11px;
    font-size: calc(13px * var(--jx-fs));
}

.sd-actions .btn {
    min-height: 34px;
    padding: 0 8px;
    font-size: calc(12px * var(--jx-fs));
}

.sd-actions:not(.is-manage) {
    grid-template-columns: minmax(0, 168px);
}

@media (min-width: 768px) {
    .sd-actions.is-manage {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        max-width: 640px;
    }
}

/* 课时信息：固定一行三等分，禁止换行（"累计分配/已用课时" 只是陪衬，字号压小） */
.sd-hours {
    display: flex;
    align-items: center;
    padding: 14px 8px;
}

.sd-hour {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    text-align: center;
}

.sd-hour strong {
    /* 用 inherit：剩余课时的高低颜色由 .text-ok / .text-danger 从容器传下来 */
    color: inherit;
    font-size: calc(16px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
    white-space: nowrap;
}

.sd-hour > span {
    color: var(--text-muted);
    font-size: calc(11px * var(--jx-fs));
    white-space: nowrap;
}

/* 主指标（剩余课时）放大并着色，形成主次 */
.sd-hour.is-main strong {
    font-size: calc(22px * var(--jx-fs));
    font-weight: 700;
}

.sd-hour-sep {
    flex: 0 0 1px;
    width: 1px;
    height: 26px;
    background: var(--line);
}

/* 滑动分段：等宽三格 + 会滑动的指示块 */
.sd-tabs {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
    margin: 10px 0;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
}

.sd-tabs-ind {
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 4px;
    width: calc((100% - 8px) / 3);
    border-radius: var(--radius-pill);
    background: var(--btn-primary-bg);
    transition: transform .24s cubic-bezier(.22, .61, .36, 1);
}

.sd-tab {
    position: relative;
    z-index: 1;
    min-height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 6px;
    border: 0;
    background: transparent;
    color: var(--text-2);
    font-family: inherit;
    font-size: calc(13.5px * var(--jx-fs));
    white-space: nowrap;
    cursor: pointer;
    transition: color .18s;
}

/* 选中项的文字必须用 --btn-primary-fg：它和上面 .sd-tabs-ind 的底色是一对，
   亮色下指示条是亮绿，白字只有 2.7:1，必须配深绿字 */
.sd-tab.on {
    color: var(--btn-primary-fg);
    font-weight: 600;
}

.sd-panels {
    /* 滑动切换的触感来源：内容区不参与横向滚动，仅由手势驱动 tab */
    touch-action: pan-y;
}

.sd-panels .card {
    margin-bottom: 0;
}

@media (min-width: 768px) {
    .sd-actions:not(.is-manage) {
        grid-template-columns: minmax(0, 168px);
        max-width: 168px;
    }
}

@media (max-width: 1023px) {
    /* 触控兜底：分段按钮在手机上保证 44px */
    .sd-tab {
        min-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   班级管理：常驻星期快捷条、状态 + 搜索单行、班级卡片网格
   -------------------------------------------------------------------------- */
.class-filter-panel {
    margin-bottom: 12px;
}

.seg-row.class-week-row {
    padding: 0 0 8px;
}

.class-filter-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.class-status-tabs {
    display: flex;
    gap: 4px;
    flex: 0 0 auto;
}

.class-status-tabs .seg-pill.sm {
    flex: 0 0 auto;
    padding: 0 9px;
}

.class-search-input {
    min-width: 0;
}

.class-search-btn {
    flex: 0 0 auto;
    min-height: 34px;
    padding: 0 10px;
}

.class-card-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 10px;
    margin-bottom: 10px;
}

.class-card {
    min-width: 0;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
    transition: border-color .15s, background .15s, transform .1s;
}

.class-card:active {
    transform: scale(.995);
}

@media (hover: hover) {
    .class-card:hover {
        border-color: var(--primary);
        background: var(--surface-2);
    }
}

.class-card-head {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}

.class-card-title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}

.class-card-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex: 0 0 auto;
    border-radius: 8px;
    background: var(--primary-light);
    color: var(--primary-text);
}

.class-card-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: calc(15px * var(--jx-fs));
    font-weight: 700;
}

.class-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

.class-meta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    padding: 4px 7px;
    border-radius: 6px;
    background: var(--surface-2);
    color: var(--text-2);
    font-size: calc(12px * var(--jx-fs));
    white-space: nowrap;
}

.class-meta .ico {
    flex: 0 0 auto;
    color: var(--text-3);
}

.class-card-foot {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 10px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
}

.class-card-teachers {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    min-width: 0;
}

.class-teacher {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 7px;
    border-radius: 999px;
    background: var(--primary-light);
    color: var(--primary-text);
    font-size: calc(12px * var(--jx-fs));
    white-space: nowrap;
}

@media (max-width: 767px) {
    .class-filter-row {
        gap: 6px;
        padding: 5px;
    }

    .class-status-tabs {
        gap: 3px;
    }

    .class-status-tabs .seg-pill.sm {
        padding: 0 7px;
    }

    .class-filter-row .class-search-input {
        min-height: 40px;
    }

    .class-card-list {
        grid-template-columns: 1fr;
        gap: 8px;
    }

    .class-card {
        padding: 13px;
    }
}

/* ---------------------------------------------------------------------------
   未核销提醒：「不用核销」动作（节假日 / 寒暑假停课等）
   复用 .btn.btn-plain.btn-sm 以获得统一的触控高度，这里只负责与上文留出间距。
   --------------------------------------------------------------------------- */
.pending-act {
    margin-top: 8px;
}

.table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

@media (min-width: 768px) {
    .report-mobile-list { display: none; }
}

@media (max-width: 767px) {
    /* 报表在手机端以纵向汇总行展示所有数据，桌面表格不再占用或横向滚动。 */
    .report-page .report-desktop-table { display: none; }
    .report-mobile-list { display: grid; gap: 8px; }
    .report-mobile-row { padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--surface); }
    .report-mobile-row > strong { display: block; margin-bottom: 7px; color: var(--text); font-size: calc(14px * var(--jx-fs)); }
    .report-mobile-row > div { display: flex; flex-wrap: wrap; gap: 5px 10px; color: var(--text-2); font-size: calc(12px * var(--jx-fs)); }
    .report-mobile-row span { white-space: nowrap; }
    .report-mobile-row b { margin-left: 2px; color: var(--text); font-variant-numeric: tabular-nums; }
    .report-mobile-total { border-color: var(--primary); background: var(--primary-light); }
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: calc(13px * var(--jx-fs));
    min-width: 560px;
}

.table th, .table td {
    padding: 8px 10px;
    text-align: left;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

.table th {
    background: var(--surface-2);
    color: var(--text-2);
    font-weight: 600;
}

.table tbody tr:active {
    background: var(--info-light);
}

.table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   标签 / 状态
   -------------------------------------------------------------------------- */
.tag {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 20px;
    font-size: calc(12px * var(--jx-fs));
    background: var(--info-light);
    color: var(--text-2);
    line-height: 1.7;
}

.tag-blue { background: var(--primary-light); color: var(--primary-text); }
.tag-ok { background: var(--ok-light); color: var(--ok-text); }
.tag-warn { background: var(--warn-light); color: var(--warn-text); }
.tag-danger { background: var(--danger-light); color: var(--danger-text); }
.tag-line { background: var(--surface); border: 1px solid var(--line); }
.status-manage-trigger {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border: 0;
    cursor: pointer;
    font-family: inherit;
}
.status-manage-trigger:hover { filter: brightness(.96); }
.full-btn { width: 100%; justify-content: center; }

.tag + .tag {
    margin-left: 4px;
}

.st-attend { background: var(--ok-light); color: var(--ok-text); }
.st-makeup { background: var(--primary-light); color: var(--primary-text); }
.st-absent { background: var(--danger-light); color: var(--danger-text); }
.st-leave { background: var(--warn-light); color: var(--warn-text); }
.st-blank { background: var(--info-light); color: var(--text-muted); }

.dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-right: 5px;
    vertical-align: middle;
}

.dot-ok { background: var(--ok); }
.dot-warn { background: var(--warn); }
.dot-danger { background: var(--danger); }
.dot-gray { background: var(--text-3); }

/* --------------------------------------------------------------------------
   核销页：简洁点名与高级出勤操作
   -------------------------------------------------------------------------- */
.attendance-head {
    align-items: center;
    gap: 10px;
}
.attendance-mode {
    flex: 0 0 auto;
}
.attendance-mode .seg-item {
    min-height: 30px;
    min-width: 48px;
    padding: 0 10px;
    flex: 0 0 auto;
}
.attendance-mode .seg-item.active {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-accent);
}
.attendance-simple-tools {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.attendance-tool-actions {
    display: inline-flex;
    flex: 0 0 auto;
    gap: 6px;
}
.stu-cards.stu-cards-simple {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}
.stu-simple-card {
    min-width: 0;
    min-height: 66px;
    padding: 8px 6px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-1);
    font-family: inherit;
    cursor: pointer;
}
.stu-simple-card.selected {
    border-color: var(--ok);
    background: var(--ok-light);
    color: var(--ok-text);
    box-shadow: inset 0 0 0 1px var(--ok);
}
.stu-simple-card:active { transform: scale(.98); }
.stu-simple-card:disabled { opacity: .6; cursor: not-allowed; }
.stu-simple-name {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: calc(15px * var(--jx-fs));
    font-weight: 600;
}
.stu-simple-hours {
    font-size: calc(11px * var(--jx-fs));
    color: var(--text-muted);
    white-space: nowrap;
}
.stu-simple-hours.low { color: var(--danger-text); font-weight: 600; }
.stu-cards.stu-cards-advanced { grid-template-columns: 1fr; }
.stu-card.stu-card-advanced {
    display: grid;
    grid-template-columns: minmax(100px, .7fr) minmax(0, 1.8fr);
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
}
.stu-identity { min-width: 0; }
.stu-card-advanced .stu-name { font-size: calc(15px * var(--jx-fs)); }
.stu-card-advanced .stu-hours { margin-top: 4px; }
.stu-actions { min-width: 0; }
.stu-status-row { gap: 4px; }
.stu-status-row .seg-item {
    min-height: 32px;
    font-size: calc(12px * var(--jx-fs));
}
.stu-extra.stu-extra-compact {
    min-height: 34px;
    margin-top: 5px;
    padding-top: 5px;
    gap: 6px;
}
.stu-extra-compact .hours-balls { flex-basis: 180px; gap: 4px; }
.stu-extra-compact .hour-ball { max-width: 28px; font-size: calc(11px * var(--jx-fs)); }
.deduct-note-field { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 8px; margin-top: 7px; }
.deduct-note-field label { color: var(--warn-text); font-size: calc(12px * var(--jx-fs)); font-weight: 600; white-space: nowrap; }
.deduct-note-field .input { min-width: 0; min-height: 32px; padding: 5px 8px; font-size: calc(12px * var(--jx-fs)); }

@media (max-width: 559px) {
    .attendance-head { align-items: flex-start; }
    .attendance-head .card-title { padding-top: 5px; }
    .attendance-simple-tools { align-items: stretch; flex-direction: column; }
    .attendance-tool-actions { width: 100%; justify-content: flex-end; }
    .stu-card.stu-card-advanced { grid-template-columns: 94px minmax(0, 1fr); gap: 8px; }
    .stu-status-row .seg-item { min-height: 30px; font-size: calc(11px * var(--jx-fs)); }
    .stu-extra-compact .hours-balls { flex-basis: 132px; gap: 3px; }
    .stu-extra-compact .hour-ball { max-width: 24px; font-size: calc(10px * var(--jx-fs)); }
    .stu-extra-compact .stu-extra-label, .stu-extra-compact .stu-extra-unit, .stu-extra-compact .stu-extra-note { font-size: calc(11px * var(--jx-fs)); }
    .deduct-note-field { grid-template-columns: 1fr; gap: 4px; }
}

.stu-cards {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    margin-bottom: 12px;
    align-items: stretch;
}

/* 手机 1 列；小 iPad 最多 3 列（768/810 宽只排 2 列，保证圆球不被压扁）；电脑 4 列 */
@media (min-width: 560px) {
    .stu-cards {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 900px) {
    .stu-cards {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .stu-cards {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

.stu-card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-radius: var(--radius);
    padding: 12px;
    border: 1px solid var(--ok);
}

.stu-card.has-status {
    border-color: var(--primary-text);
    background: var(--primary-light);
}

.stu-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    min-height: 22px;
}

.stu-name {
    font-size: calc(16px * var(--jx-fs));
    font-weight: 600;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stu-hours {
    flex: 0 0 auto;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    white-space: nowrap;
}

.stu-hours.low {
    color: var(--danger-text);
    font-weight: 600;
}

.seg {
    display: flex;
    gap: 4px;
}

.seg-item {
    flex: 1;
    min-width: 0;
    min-height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
    font-family: inherit;
    font-size: calc(13px * var(--jx-fs));
    color: var(--text-2);
    cursor: pointer;
    user-select: none;
    transition: all .12s;
}

.seg-item:active {
    transform: scale(.97);
}

.seg-item.active[data-st="attend"] { background: var(--ok); border-color: var(--ok); color: var(--on-accent); }
.seg-item.active[data-st="makeup"] { background: var(--primary); border-color: var(--primary); color: var(--on-accent); }
.seg-item.active[data-st="absent"] { background: var(--danger); border-color: var(--danger); color: var(--on-accent); }
.seg-item.active[data-st="leave"]  { background: var(--warn); border-color: var(--warn); color: var(--on-accent); }
.seg-item.active[data-st="blank"]  { background: var(--info-light); border-color: var(--text-3); color: var(--text-2); }

/* 卡片下沿的展开区：高度恒定，无论选中什么状态都不改变卡片高度，
   所以同一行/下一行的状态按钮永远不会位移，避免误点 */
.stu-extra {
    min-height: 52px;
    margin-top: 8px;
    padding-top: 8px;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    overflow: hidden;
    border-top: 1px dashed transparent;
}

.stu-extra.on {
    border-top-color: var(--line);
}

.stu-extra-label {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.stu-extra-unit {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.stu-extra-note {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--text-muted);
    font-size: calc(12.5px * var(--jx-fs));
    white-space: nowrap;
}

/* 非 1-5 整数的回填值（如 0.5 / 8 课时）没有对应圆球，用文字说明当前值 */
.stu-extra-custom {
    flex: 0 0 auto;
    color: var(--warn-text);
    font-size: calc(12px * var(--jx-fs));
    white-space: nowrap;
}

/* 1-5 数字圆球：等分排布，窄卡片时自动缩小而不是换行 */
.hours-balls {
    flex: 0 1 220px;
    min-width: 0;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
}

.hour-ball {
    width: 100%;
    max-width: 38px;
    margin: 0 auto;
    aspect-ratio: 1 / 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line-2);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-2);
    font-family: inherit;
    font-size: calc(13px * var(--jx-fs));
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background .12s, border-color .12s, color .12s, transform .1s;
}

.hour-ball:hover {
    border-color: var(--primary);
    color: var(--primary-text);
}

.hour-ball:active {
    transform: scale(.94);
}

/* 选中：实心主色 + 外圈，和未选中的描边空心球一眼可区分 */
.hour-ball.on {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
    outline: 2px solid var(--primary-light);
    outline-offset: 1px;
}

.hour-ball:disabled {
    opacity: .5;
    cursor: not-allowed;
}

/* 手机上核销状态按钮与数字圆球都保持在 44px 触控下限 */
@media (max-width: 767px) {
    .seg-item {
        min-height: 44px;
    }

    .hour-ball {
        max-width: 44px;
    }

    .hours-balls {
        flex-basis: 260px;
    }

    .stu-extra {
        min-height: 58px;
    }
}

.hours-input {
    width: 76px;
    min-height: 36px;
    text-align: center;
    padding: 4px 6px;
}

/* 底部悬浮提交条（移动端叠在 .tabbar 之上，桌面端（>=1024）见文件末尾对齐侧栏） */
.submit-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: 12px 14px 12px;
    display: flex;
    align-items: center;
    gap: 10px;
    z-index: 48;
}

.submit-bar-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: calc(13px * var(--jx-fs));
    color: var(--text-2);
    line-height: 1.4;
}

.submit-summary-row {
    display: block;
    white-space: nowrap;
}

.submit-summary-primary {
    color: var(--text);
    font-weight: 600;
}

.submit-summary-status {
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.submit-summary-row b {
    margin: 0 3px;
    color: var(--line-2);
    font-weight: 400;
}

.submit-summary-alert {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: calc(12px * var(--jx-fs));
}

/* 同时存在 tab 栏与提交条时，内容需让出两条固定栏的高度 */
.has-submit-bar {
    padding-bottom: calc(92px + var(--tabbar-h));
}

.locked-tip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    background: var(--tip-bg);
    color: var(--tip-text);
    border-radius: var(--radius);
    font-size: calc(13px * var(--jx-fs));
    margin-bottom: 12px;
}

.schedule {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-2);
}

.schedule span {
    background: var(--info-light);
    padding: 2px 8px;
    border-radius: 6px;
}

.proof-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
    gap: 8px;
}

.proof-item {
    position: relative;
    padding-top: 100%;
    border-radius: 10px;
    overflow: hidden;
    background: var(--info-light);
    border: 1px solid var(--line);
}

.proof-item img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 课堂记录图片删除键：叠在缩略图右上角；做得比常规按钮小，避免手机上误触 */
.proof-del {
    position: absolute;
    top: 3px;
    right: 3px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid color-mix(in srgb, var(--danger) 55%, var(--line));
    border-radius: 50%;
    background: var(--danger);
    color: var(--on-accent);
    box-shadow: none;
    cursor: pointer;
}

.proof-del:hover {
    background: color-mix(in srgb, var(--danger) 82%, var(--text));
}

.proof-del:focus-visible {
    outline: 2px solid var(--on-accent);
    outline-offset: 1px;
}

@media (max-width: 767px) {
    /* 手机缩略图更小，删除键再收一圈，误触概率更低；确认弹窗仍会二次确认 */
    .proof-del {
        top: 3px;
        right: 3px;
        width: 21px;
        height: 21px;
    }
}

.proof-add {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 4px;
    border: 1px dashed var(--text-3);
    border-radius: 10px;
    background: var(--surface);
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    min-height: 88px;
    cursor: pointer;
}

.proof-add input[type=file] {
    display: none;
}

/* 课堂记录 → 成长日志：提交前提示抄送对象，提交后展示名单 */
.proof-sync-tip {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-top: 10px;
    padding: 9px 10px;
    border: 1px solid color-mix(in srgb, var(--primary) 26%, var(--line));
    border-radius: 8px;
    background: var(--primary-light);
    color: var(--primary-text);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.55;
}

.proof-sync-tip .ico {
    flex: 0 0 auto;
    margin-top: 1px;
}

.growth-cc {
    display: grid;
    gap: 6px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
}

.growth-cc-title {
    display: flex;
    align-items: center;
    gap: 5px;
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    font-weight: 650;
}

.growth-cc-names {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.growth-cc-chip {
    min-height: 30px;
    padding: 3px 10px;
    border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--line));
    border-radius: 999px;
    background: var(--primary-light);
    color: var(--primary-text);
    font: inherit;
    font-size: calc(12px * var(--jx-fs));
    cursor: pointer;
}

.growth-cc-chip:disabled {
    cursor: default;
    opacity: 1;
}

.growth-cc-chip:not(:disabled):hover {
    border-color: var(--primary);
}

/* --------------------------------------------------------------------------
   统计
   -------------------------------------------------------------------------- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
}

.stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 13px;
}

.stat-num {
    font-size: calc(20px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
}

.stat-num.primary { color: var(--primary-text); }
.stat-num.ok { color: var(--ok-text); }
.stat-num.danger { color: var(--danger-text); }
.stat-num.warn { color: var(--warn-text); }

.stat-label {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    margin-top: 2px;
}

/* 重点信息只以明亮文字色和适度字重表达，不额外使用底色、边框或阴影。 */
.stat.is-focus .stat-num:not(.ok):not(.warn):not(.danger) {
    color: var(--highlight-blue);
}

.stat.is-focus .stat-num.danger {
    color: var(--highlight-red);
}

.key-value {
    color: var(--highlight-purple);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   首页：优先待核销提示 / Windows 式九宫格快捷入口
   待核销为独立卡片样式（不描红边）：标题行浅底、列表项主底色，只让数量与逾期文案用红色强调
   -------------------------------------------------------------------------- */
.pending-alert {
    margin-bottom: 12px;
    background: var(--surface);
    overflow: hidden;
}

/* 标题行用浅色头部底（与下方列表项区分），列表项保持卡片主底色 */
.pending-alert-head {
    width: 100%;
    border: 0;
    background: var(--surface-2);
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    text-align: left;
    cursor: pointer;
    transition: background .15s;
}

.pending-alert-head:hover,
.pending-alert-head:active {
    background: var(--primary-light);
}

.pending-alert-copy {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.pending-alert-copy strong {
    font-size: calc(14px * var(--jx-fs));
    font-weight: 600;
}

.pending-alert-copy small {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
}

.pending-count {
    color: var(--danger-text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.pending-alert-list {
    border-top: 1px solid var(--line);
    background: var(--surface);
}

.pending-alert-item {
    width: 100%;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    text-align: left;
    cursor: pointer;
}

.pending-alert-item:last-child {
    border-bottom: 0;
}

.pending-alert-item-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.pending-alert-item-main strong {
    font-size: calc(13px * var(--jx-fs));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pending-alert-item-main small {
    font-size: calc(12px * var(--jx-fs));
    color: var(--danger-text);
}

.quick-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
}

.quick-item {
    min-width: 0;
    min-height: 88px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-2);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 8px 4px;
    cursor: pointer;
    transition: background .12s, color .12s, transform .1s;
}

.quick-item:hover,
.quick-item:active {
    background: var(--surface-2);
    color: var(--primary-text);
}

.quick-item:active {
    transform: scale(.97);
}

.quick-icon {
    width: 46px;
    height: 46px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--surface-2);
    color: var(--primary-text);
    border: 1px solid var(--line);
}

.quick-label {
    max-width: 100%;
    font-size: calc(12.5px * var(--jx-fs));
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   课时核销：场次列表采用「时间主面板 + 班级信息 + 状态操作」卡片
   -------------------------------------------------------------------------- */
.lesson-stat-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.lesson-stat {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 32px;
    padding: 4px 10px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
    color: var(--text-2);
    font-size: calc(12.5px * var(--jx-fs));
    line-height: 1.3;
}

.lesson-stat .ico {
    flex: 0 0 auto;
}

.lesson-stat strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.lesson-stat-pending {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--primary-text);
}

.lesson-stat-pending strong {
    color: var(--primary-text);
}

.lesson-stat-done {
    border-color: var(--ok);
    background: var(--ok-light);
    color: var(--ok-text);
}

.lesson-stat-done strong {
    color: var(--ok-text);
}

.lesson-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
}

.lesson-grid .lesson-card {
    margin-bottom: 0;
}

.class-pick {
    cursor: pointer;
    transition: border-color .12s, transform .1s;
}

.class-pick:active {
    border-color: var(--primary-text);
    transform: scale(.995);
}

.lesson-card {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    min-width: 0;
    border-left: 3px solid var(--line-2);
    overflow: hidden;
    cursor: pointer;
    transition: border-color .12s, transform .1s;
}

.lesson-card:active {
    transform: scale(.995);
}

.lesson-card.lesson-overdue {
    border-left-color: var(--danger);
}

.lesson-card.lesson-pending {
    border-left-color: var(--primary);
}

.lesson-card.lesson-done {
    border-left-color: var(--ok);
}

.lesson-card.lesson-skipped {
    border-left-color: var(--warn);
}

.lesson-card.lesson-waiting {
    border-left-color: var(--line-2);
}

/* 当天没有场次的班级（只在「全」视图出现）：弱化整卡，和当天真要核销的班级区分开 */
.lesson-card.lesson-none {
    border-left-color: var(--line);
}

.lesson-card.lesson-none .lesson-time {
    background: var(--surface);
    color: var(--text-muted);
}

.lesson-card.lesson-none .lesson-title {
    color: var(--text-2);
    font-weight: 600;
}

.lesson-card.lesson-none .lesson-course {
    color: var(--text-muted);
}

/* 「全」视图的构成摘要：当天排课 / 其他班级 */
/* 构成摘要：纯说明文字。
   之前做成带边框的胶囊，看着像能点的筛选器，实际只是只读统计 —— 与「日期/星期」
   这些真控制混在一起，正是这一页「没有主次」的原因之一。 */
.lesson-split {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 10px;
    margin-bottom: 10px;
    padding-left: 2px;
}

.lesson-split-item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.4;
}

.lesson-split-item.on {
    color: var(--primary-text);
    font-weight: 600;
}

.lesson-split-item .ico {
    flex: 0 0 auto;
    opacity: .85;
}

.lesson-split-tip {
    flex: 1 1 100%;
    min-width: 0;
    color: var(--text-3);
    font-size: calc(11.5px * var(--jx-fs));
    line-height: 1.45;
}

.lesson-time {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    padding: 14px 8px;
    border-right: 1px solid var(--line);
    background: var(--surface-2);
    color: var(--text-2);
    text-align: center;
}

.lesson-overdue .lesson-time {
    background: var(--danger-light);
    color: var(--danger-text);
}

.lesson-pending .lesson-time {
    background: var(--primary-light);
    color: var(--primary-text);
}

.lesson-done .lesson-time {
    background: var(--ok-light);
    color: var(--ok-text);
}

.lesson-skipped .lesson-time {
    background: var(--warn-light);
    color: var(--warn-text);
}

.lesson-start {
    font-size: calc(21px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.lesson-end,
.lesson-weekday {
    font-size: calc(11.5px * var(--jx-fs));
    line-height: 1.35;
    white-space: nowrap;
}

.lesson-weekday {
    margin-top: 5px;
    padding-top: 5px;
    border-top: 1px solid currentColor;
    opacity: .85;
}

.lesson-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    padding: 13px 14px 12px;
}

.lesson-head {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    min-width: 0;
}

.lesson-title-block {
    flex: 1;
    min-width: 0;
}

.lesson-course {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 2px;
    color: var(--primary-text);
    font-size: calc(12px * var(--jx-fs));
    font-weight: 600;
    line-height: 1.35;
}

.lesson-course .ico {
    flex: 0 0 auto;
}

.lesson-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
    font-size: calc(16px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.4;
}

.lesson-head > .tag {
    flex: 0 0 auto;
    margin-top: 1px;
}

.lesson-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin-top: 9px;
    color: var(--text-2);
    font-size: calc(12.5px * var(--jx-fs));
}

.lesson-meta-item {
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lesson-meta-item .ico {
    flex: 0 0 auto;
    color: var(--text-muted);
}

.lesson-result {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin-top: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-2);
    font-size: calc(12px * var(--jx-fs));
}

.lesson-result span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.lesson-result .ico {
    color: var(--text-muted);
}

.lesson-result strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.lesson-action {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: auto;
    padding-top: 12px;
}

/* 同一周内已经在别的日期核销过的场次被「带」到这个星期标签下展示，
   明确写出核销日期，避免用户以为是另一笔待核销的课而重复核销 */
.lesson-carry {
    display: flex;
    align-items: flex-start;
    gap: 5px;
    margin-top: 8px;
    color: var(--primary-text);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.45;
}

.lesson-carry .ico {
    flex: 0 0 auto;
    margin-top: 2px;
}

.lesson-action-tip {
    flex: 1 1 160px;
    min-width: 0;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.4;
}

.lesson-action .btn {
    min-width: 150px;
}

@media (min-width: 1024px) {
    .lesson-grid {
        grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
    }
}

@media (max-width: 767px) {
    .lesson-card {
        grid-template-columns: 82px minmax(0, 1fr);
    }

    .lesson-time {
        padding: 12px 6px;
    }

    .lesson-start {
        font-size: calc(19px * var(--jx-fs));
    }

    .lesson-main {
        padding: 12px;
    }

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

    .lesson-action .btn {
        width: 100%;
        min-width: 0;
    }

    /* 手机端先说明再放按钮，避免小字和按钮挤在一行 */
    .lesson-action-tip {
        flex-basis: 100%;
    }

    .lesson-split-tip {
        flex-basis: 100%;
    }
}

.bar {
    height: 8px;
    border-radius: 4px;
    background: var(--info-light);
    overflow: hidden;
}

.bar-in {
    height: 100%;
    background: var(--primary);
    border-radius: 4px;
}

/* --------------------------------------------------------------------------
   空态 / 加载 / 分页
   -------------------------------------------------------------------------- */
.empty {
    padding: 36px 18px;
    text-align: center;
    color: var(--text-muted);
}

.empty-icon {
    font-size: calc(40px * var(--jx-fs));
    opacity: .5;
    margin-bottom: 8px;
}

.empty-text {
    font-size: calc(13px * var(--jx-fs));
}

.loading-inline {
    padding: 22px;
    text-align: center;
    color: var(--text-muted);
    font-size: calc(13px * var(--jx-fs));
}

.pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 0;
}

.pager-info {
    font-size: calc(13px * var(--jx-fs));
    color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   弹窗（页面内表单弹窗）
   -------------------------------------------------------------------------- */
.modal-mask {
    position: fixed;
    inset: 0;
    background: var(--overlay);
    z-index: 70;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.modal {
    background: var(--glass-panel);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    width: 100%;
    max-width: 560px;
    max-height: 92vh;
    border-radius: 16px 16px 0 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.modal-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--line);
    font-size: calc(15px * var(--jx-fs));
    font-weight: 600;
    /* 标题行 = 主色实底（亮色深林绿），与左侧栏同一块色；
       面板主体仍是 --glass-panel 的浅色玻璃，层次靠这一条深色标题带拉出来。
       前景走 --side-* 令牌，暗色主题下仍是原来的紫黑玻璃 + 浅色字。 */
    background: var(--primary);
    color: var(--on-accent);
    border-bottom-color: var(--side-line);
}

/* 标题行上的图标沿用文字色；关闭按钮给它一层半透明白的悬停底，
   否则会落到 .icon-btn:hover 的浅色 --hover 底上，在深色标题里很突兀 */
.modal-head .ico {
    color: currentColor;
}

.modal-head .icon-btn {
    color: var(--side-fg-2);
}

.modal-head .close:hover,
.modal-head .icon-btn:hover,
.modal-head .close:active,
.modal-head .icon-btn:active {
    background: var(--side-hover);
    color: var(--side-fg);
    border-color: transparent;
}

/* 标题行是品牌色实底，主按钮若继续用主色实底就会「绿底绿按钮」，
   只靠一点明度差很难看出边界。这里改成白底 + 品牌深色字：
   按钮始终从标题行里浮出来，切到经典蓝 / 春意绿 / 古朴棕 / 暗色紫也都成立。 */
.modal-head .btn-primary {
    background: var(--on-accent);
    border-color: transparent;
    color: var(--primary-dark);
    box-shadow: none;
}

/* 活动搭建器的标题行是白底（.activity-page-editor 单独改过），
   白底上的按钮要回到常规主按钮，否则会和标题行融为一体。 */
.activity-page-editor .modal-head .btn-primary {
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
}

/* 标题占满剩余宽度，右侧图标按钮自动靠右 */
.modal-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.modal-head .close {
    margin-left: auto;
    border: 0;
    background: transparent;
    font-size: calc(20px * var(--jx-fs));
    /* 标题行是主色深底，关闭按钮不能用浅底上的 --text-muted，改走深底前景令牌 */
    color: var(--side-fg-2);
    cursor: pointer;
    line-height: 1;
}

.modal-body {
    padding: 16px;
    overflow-y: auto;
    flex: 1;
    -webkit-overflow-scrolling: touch;
}

/* 弹窗表单里选择器和输入框同高（.input 38px / .select-field 34px）：
   两列表单的行距才会均匀，不会一行 74px、一行 79px 地跳 */
.modal-body .select-field {
    min-height: 38px;
}

.modal-foot {
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--line);
    display: flex;
    gap: 8px;
    background: var(--surface-2);
}

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

/* --------------------------------------------------------------------------
   操作日志列表（手机优先的紧凑卡片）
   -------------------------------------------------------------------------- */
.log-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.log-card {
    display: block;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    margin-bottom: 8px;
    cursor: pointer;
    transition: background .12s, border-color .12s;
}

.log-card:hover {
    border-color: var(--primary);
    background: var(--surface-2);
}

.log-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.log-card-time {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    flex: 0 0 auto;
}

.log-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    flex: 1 1 auto;
    justify-content: flex-end;
    min-width: 0;
}

.log-card-tag {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-2);
    font-size: calc(11px * var(--jx-fs));
    line-height: 1.4;
    white-space: nowrap;
}

.log-card-tag-module {
    background: var(--primary-light);
    color: var(--primary-text);
}

.log-card-tag-action {
    background: var(--info-light, var(--surface-2));
    color: var(--text-2);
}

.log-card-detail {
    font-size: calc(13.5px * var(--jx-fs));
    line-height: 1.5;
    color: var(--text);
    word-break: break-word;
    white-space: pre-wrap;
}

.log-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 8px;
    margin-top: 6px;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
}

.log-card-meta .ico {
    flex: 0 0 auto;
    color: var(--text-3);
}

.log-card-user {
    color: var(--text-2);
    font-weight: 600;
}

.log-card-role {
    color: var(--text-muted);
    font-weight: 400;
}

.log-card-ip {
    color: var(--text-muted);
}

.log-card-branch {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    color: var(--text-muted);
}

@media (max-width: 767px) {
    .log-card {
        padding: 10px 11px;
        margin-bottom: 6px;
        border-radius: 8px;
    }

    .log-card-detail {
        font-size: calc(13px * var(--jx-fs));
        line-height: 1.45;
    }

    .log-card-time {
        font-size: calc(11.5px * var(--jx-fs));
    }

    .log-card-meta {
        font-size: calc(11.5px * var(--jx-fs));
        gap: 4px 6px;
    }
}

/* --------------------------------------------------------------------------
   登录 / 公开首页
   -------------------------------------------------------------------------- */
.login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: var(--grad-login);
}

.login-card {
    width: 100%;
    max-width: 400px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 28px 24px;
}

.bind-selected-card {
    margin-top: 12px;
}

.bind-selected-card .card-body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.bind-selected-card .list-item-main {
    min-width: 0;
}

.bind-form-card {
    margin-top: 10px;
}

.login-logo {
    text-align: center;
    margin-bottom: 20px;
}

.login-logo-icon {
    width: 56px;
    height: 56px;
    border-radius: 16px;
    background: var(--primary);
    color: var(--on-accent);
    font-size: calc(26px * var(--jx-fs));
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 10px;
}

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

.login-sub {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    margin-top: 2px;
}

/* 校长切换分校：5 个及以下纵向排列，超过 5 个时改为两列以控制列表高度。 */
.branch-select-card {
    max-width: 660px;
}

/* 分校进入是主操作；离开当前流程的入口收为次要文字操作。 */
.branch-exit-actions {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin-top: 12px;
}

.branch-exit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 30px;
    padding: 4px 6px;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.4;
    cursor: pointer;
}

.branch-exit-btn:hover,
.branch-exit-btn:focus-visible {
    color: var(--primary-text);
    text-decoration: underline;
}

.branch-exit-btn:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 4px;
}

.branch-pick-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
}

.branch-pick-list:has(.branch-pick-card:nth-child(6)) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.branch-pick-card {
    position: relative;
    min-width: 0;
    min-height: 78px;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.branch-pick-card:hover,
.branch-pick-card:active {
    border-color: var(--primary);
    background: var(--surface-2);
}

.branch-pick-card.on {
    border-color: var(--primary);
    background: var(--primary-light);
    box-shadow: inset 0 0 0 1px var(--primary);
}

.branch-pick-card:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.branch-pick-card:disabled {
    cursor: default;
    opacity: .75;
}

.branch-pick-icon {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    background: var(--surface-2);
    color: var(--text-2);
    border: 1px solid var(--line);
}

.branch-pick-card.on .branch-pick-icon {
    background: var(--surface);
    border-color: var(--primary);
    color: var(--primary-text);
}

.branch-pick-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.branch-pick-name {
    display: block;
    overflow: hidden;
    font-size: calc(14.5px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.branch-pick-code {
    display: block;
    overflow: hidden;
    color: var(--text-muted);
    font-size: calc(11.5px * var(--jx-fs));
    line-height: 1.4;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.branch-pick-card.on .branch-pick-code {
    color: var(--primary-text);
}

.branch-pick-check {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line-2);
    border-radius: 50%;
    background: var(--surface);
    color: transparent;
}

.branch-pick-card.on .branch-pick-check {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
}

@media (max-width: 560px) {
    .branch-pick-list {
        grid-template-columns: minmax(0, 1fr);
    }

    /* 手机端保持更舒适的触控高度。 */
    .branch-pick-card {
        min-height: 74px;
    }
}

.hero {
    position: relative;
    isolation: isolate;
    background: var(--grad-hero);
    color: var(--on-accent);
    padding: 20px 16px 18px;
    border-radius: var(--radius);
    margin-bottom: 8px;
    overflow: hidden;
}

.hero > :not(.hero-tile) {
    position: relative;
    z-index: 1;
}

.hero-tile {
    position: absolute;
    z-index: 0;
    width: 10px;
    height: 10px;
    border: 1px solid var(--hero-tile-line);
    background: var(--hero-tile-bg);
    opacity: 0;
    pointer-events: none;
}

.hero-tile.t1 { left: -12px; top: 25%; animation: hero-tile-east 7s linear infinite; }
.hero-tile.t2 { left: 8%; bottom: -12px; width: 7px; height: 7px; animation: hero-tile-north 8.4s linear 1.5s infinite; }
.hero-tile.t3 { right: 18%; top: -14px; width: 14px; height: 14px; animation: hero-tile-south 9.2s linear 3.2s infinite; }
.hero-tile.t4 { right: -12px; bottom: 28%; width: 8px; height: 8px; animation: hero-tile-west 6.5s linear .8s infinite; }
.hero-tile.t5 { left: 32%; top: 18%; width: 6px; height: 6px; animation: hero-tile-pulse 5.2s ease-in-out 2s infinite; }
.hero-tile.t6 { left: 61%; bottom: 17%; width: 12px; height: 12px; animation: hero-tile-pulse 6.6s ease-in-out 4s infinite; }
.hero-tile.t7 { left: 77%; top: 45%; width: 5px; height: 5px; animation: hero-tile-west 8s linear 2.7s infinite; }
.hero-tile.t8 { left: 22%; top: 62%; width: 9px; height: 9px; animation: hero-tile-pulse 7.4s ease-in-out 1s infinite; }

@keyframes hero-tile-east {
    0%, 100% { transform: translateX(0); opacity: 0; }
    15% { opacity: .22; }
    65% { opacity: .36; }
    88% { transform: translateX(360px); opacity: 0; }
}

@keyframes hero-tile-west {
    0%, 100% { transform: translateX(0); opacity: 0; }
    18% { opacity: .20; }
    67% { opacity: .34; }
    88% { transform: translateX(-330px); opacity: 0; }
}

@keyframes hero-tile-north {
    0%, 100% { transform: translateY(0); opacity: 0; }
    18% { opacity: .18; }
    66% { opacity: .34; }
    88% { transform: translateY(-160px); opacity: 0; }
}

@keyframes hero-tile-south {
    0%, 100% { transform: translateY(0); opacity: 0; }
    18% { opacity: .20; }
    66% { opacity: .36; }
    88% { transform: translateY(160px); opacity: 0; }
}

@keyframes hero-tile-pulse {
    0%, 100% { transform: scale(.7); opacity: 0; }
    30% { opacity: .26; }
    55% { transform: scale(1); opacity: .38; }
    78% { transform: scale(1.1); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .hero-tile { animation: none; opacity: .17; }
}

/* 访客页横向兜底：公开首页不经过 .main，但同样不允许出现横向滚动条 */
.public-shell.no-scroll-x {
    overflow-x: hidden;
}

/* 公开页面内容层：移动端贴边留白与后台页保持一致，宽屏收敛到可读宽度
   注意：离线 Vue 运行时会为带 v-if 的组件根节点套一层容器 div，
   因此这里按「public-shell 下的包装层」控制内边距，按 .public-home 控制内容宽度。 */
.public-shell > div {
    padding: 8px 10px 24px;
}

.public-home .public-bar,
.public-home .hero,
.public-home .home-flow,
.public-home .loading-inline,
.public-home .empty {
    width: auto;
    max-width: 1080px;
    margin-left: auto;
    margin-right: auto;
}

@media (min-width: 768px) {
    .public-shell > div {
        padding: 0 20px 28px;
    }

    /* 宽屏放宽内容宽度，但保留可读上限，避免首页卡片被拉得过长 */
    .public-home .public-bar,
    .public-home .hero,
    .public-home .home-flow,
    .public-home .loading-inline,
    .public-home .empty {
        max-width: 1240px;
    }
}

@media (min-width: 1024px) {
    .public-shell > div {
        padding: 0 24px 32px;
    }
}

/* 首页版式：访客官网与登录后工作台共用同一套间距与分区节奏 */
.public-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 8px;
    padding: 6px 8px 6px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

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

.public-brand-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 7px;
    background: var(--primary-light);
    color: var(--primary-text);
}

.public-brand-name {
    font-size: calc(14.5px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.home-flow {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
}

.home-flow > .card,
.home-flow > .pending-alert {
    margin-bottom: 0;
}

.home-flow > .page-head {
    margin-bottom: 0;
}

/* 已登录首页桌面工作台：概览统计 + 主次分栏 */
.home-stat-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 12px;
}

.home-stat {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.home-stat-icon {
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: var(--info-light);
    color: var(--text-2);
}

.home-stat-icon.primary {
    background: var(--primary-light);
    color: var(--primary-text);
}

.home-stat-icon.ok {
    background: var(--ok-light);
    color: var(--ok-text);
}

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

.home-stat-copy {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.home-stat-copy strong {
    font-size: calc(22px * var(--jx-fs));
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.home-stat-copy small {
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

/* ==========================================================================
   核心三件事入口卡（已登录工作台）
   · 桌面：横向三列，与 home-stat-grid 等宽（minmax(0,1fr) 三等分）
   · 手机：纵向三张卡，56-60px 高，与 native App "入口行" 一致
   · 默认 v-if 隐藏，靠模板里的 canClasses / canStudent / canSignin 决定
   ========================================================================== */

/* 首页四个主入口以 2×2 网格呈现，便于快速识别和单手触达。 */
.home-core-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 12px;
}

.core-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 14px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease, transform .1s ease;
}

.core-card:hover,
.core-card:active {
    background: var(--primary-light);
    border-color: var(--primary);
    color: var(--primary-text);
}

.core-card:active {
    transform: scale(.98);
}

.core-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: var(--info-light);
    color: var(--text-2);
}

.core-card:hover .core-icon,
.core-card:active .core-icon {
    background: var(--surface);
    color: var(--primary-text);
}

.core-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.core-main strong {
    font-size: calc(14.5px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
}

.core-main small {
    display: block;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

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

.core-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    min-width: 18px;
    height: 18px;
    padding: 0 3px;
    border-radius: 50%;
    background: var(--danger);
    color: var(--on-accent);
    font-size: calc(10px * var(--jx-fs));
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* 手机端：主入口保持两列，避免四张卡纵向占满首屏。 */
@media (max-width: 767px) {
    .home-core-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    .core-card {
        padding: 12px 14px;
        min-height: 56px;
    }

    .core-icon {
        width: 36px;
        height: 36px;
    }

    .core-badge {
        top: 7px;
        right: 7px;
        transform: none;
    }

    .core-card:active {
        transform: none;
    }
}

.member-dashboard {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    align-items: start;
}

.member-dashboard.no-main {
    grid-template-columns: minmax(0, 1fr);
}

.member-dashboard.no-main .member-main {
    display: none;
}

.member-main,
.member-side {
    min-width: 0;
    display: grid;
    gap: 12px;
}

.member-main > .card,
.member-side > .card {
    margin-bottom: 0;
}

.today-class-list {
    background: var(--surface);
}

.today-class-item {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    text-align: left;
    cursor: pointer;
    transition: background .12s;
}

.today-class-item:last-child {
    border-bottom: 0;
}

.today-class-item:hover,
.today-class-item:active {
    background: var(--info-light);
}

.today-class-time {
    flex: 0 0 48px;
    color: var(--primary-text);
    font-size: calc(13px * var(--jx-fs));
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.today-class-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.today-class-main strong,
.today-class-main small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.today-class-main strong {
    font-size: calc(13.5px * var(--jx-fs));
}

.today-class-main small {
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.today-class-count {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    white-space: nowrap;
}

@media (max-width: 767px) {
    .home-stat-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    .home-stat {
        gap: 9px;
        padding: 11px;
    }

    .home-stat-icon {
        width: 36px;
        height: 36px;
    }

    .home-stat-copy strong {
        font-size: calc(19px * var(--jx-fs));
    }
}

.fact-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    border-top: 1px solid var(--line);
    background: var(--surface-2);
}

.fact {
    padding: 12px 14px;
    text-align: center;
}

.fact + .fact {
    border-left: 1px solid var(--line);
}

.fact-num {
    font-size: calc(20px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.2;
    color: var(--primary-text);
}

.fact-label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    margin-top: 3px;
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
}

.quick-card .quick-item {
    background: var(--surface-2);
    border: 1px solid var(--line);
}

.quick-card .quick-item:hover,
.quick-card .quick-item:active {
    background: var(--primary-light);
    border-color: var(--primary-text);
}

.quick-card .quick-icon {
    background: var(--surface);
    border-color: transparent;
}

/* 覆盖统计、核心入口和快捷入口的默认与交互状态，仅保留 SVG 图标。 */
.home-stat-icon,
.home-stat-icon.primary,
.home-stat-icon.ok,
.home-stat-icon.danger,
.core-icon,
.core-card-primary .core-icon,
.core-card:hover .core-icon,
.core-card:active .core-icon,
.quick-card .quick-icon {
    background: transparent;
    border-color: transparent;
}

@media (min-width: 1024px) {
    .home-flow {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
    }

    .member-dashboard {
        grid-template-columns: minmax(0, 1.65fr) minmax(300px, 1fr);
    }

    .member-side .quick-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .member-dashboard.no-main .member-side .quick-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.hero-title {
    font-size: calc(19px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.35;
}

.hero-sub {
    font-size: calc(12.5px * var(--jx-fs));
    opacity: .9;
    margin-top: 5px;
}

.hero-meta {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 11px;
    font-size: calc(11.5px * var(--jx-fs));
}

.hero-meta span {
    background: var(--hero-chip);
    padding: 3px 9px;
    border-radius: 14px;
}

.btn-login-top {
    padding: 0 14px;
    height: 36px;
    font-weight: 600;
}

.hero.hero-marketing {
    text-align: left;
    padding: 22px 16px 20px;
    background: var(--grad-hero);
}

.hero-marketing .hero-title {
    font-size: calc(19px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.35;
    color: var(--on-accent);
}

.hero-marketing .hero-sub {
    font-size: calc(12.5px * var(--jx-fs));
    opacity: .92;
    margin-top: 8px;
    color: var(--on-accent);
}

.hero-marketing .hero-cta {
    margin-top: 14px;
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.hero-marketing .hero-cta .btn {
    background: var(--on-accent);
    color: var(--primary-dark);
    border: 1px solid var(--on-accent);
}

.hero-marketing .hero-cta .btn:active {
    opacity: .88;
}

@media (max-width: 767px) {
    .hero.hero-marketing {
        padding: 18px 14px 16px;
    }

    .hero-marketing .hero-title {
        font-size: calc(18px * var(--jx-fs));
    }
}

@media (min-width: 768px) {
    .hero.hero-marketing {
        padding: 40px 32px 36px;
    }

    .hero-marketing .hero-title {
        font-size: calc(30px * var(--jx-fs));
        line-height: 1.28;
    }

    .hero-marketing .hero-sub {
        font-size: calc(14px * var(--jx-fs));
        margin-top: 10px;
    }

    .hero-marketing .hero-cta {
        margin-top: 20px;
    }

    .hero-marketing .hero-cta .btn {
        height: 44px;
        padding: 0 22px;
    }

    .scene-card {
        padding: 18px 16px;
    }

    .public-bar {
        padding: 8px 10px 8px 14px;
    }
}

.scene-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 12px;
}

.scene-card {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 14px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    text-decoration: none;
    transition: background .15s, border-color .15s, transform .1s;
}

.scene-card:hover,
.scene-card:active {
    background: var(--primary-light);
    border-color: var(--primary);
    color: var(--primary-text);
}

.scene-card:active {
    transform: scale(.99);
}

.scene-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 9px;
    background: var(--info-light);
    color: var(--primary-text);
}

.scene-card:hover .scene-icon,
.scene-card:active .scene-icon {
    background: var(--surface);
    color: var(--primary-text);
}

.scene-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.scene-main strong {
    font-size: calc(14px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
}

.scene-main small {
    display: -webkit-box;
    font-size: calc(11.5px * var(--jx-fs));
    line-height: 1.4;
    color: var(--text-muted);
    overflow: hidden;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    word-break: break-word;
}

.workflow-card .workflow-steps {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
}

.workflow-step {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.workflow-num {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--primary-light);
    color: var(--primary-text);
    font-size: calc(14px * var(--jx-fs));
    font-weight: 700;
}

.workflow-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.workflow-main strong {
    font-size: calc(14.5px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
}

.workflow-main small {
    display: block;
    font-size: calc(12.5px * var(--jx-fs));
    color: var(--text-muted);
}

@media (min-width: 768px) {
    .scene-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .workflow-card .workflow-steps {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .workflow-step {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
    }
}

.public-foot {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 18px 14px;
    margin-top: 4px;
    border-top: 1px solid var(--line);
    background: var(--surface-2);
    border-radius: var(--radius);
    text-align: left;
}

.public-foot-text strong {
    display: block;
    font-size: calc(15px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
}

.public-foot-text small {
    display: block;
    font-size: calc(12.5px * var(--jx-fs));
    color: var(--text-muted);
    margin-top: 4px;
}

.public-foot-cta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.public-foot-cta .btn {
    flex: 1 1 auto;
    min-width: 0;
}

@media (min-width: 768px) {
    .public-foot {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .public-foot-text {
        flex: 1 1 auto;
    }

    .public-foot-cta {
        flex: 0 0 auto;
    }

    .public-foot-cta .btn {
        flex: 0 0 auto;
    }
}

.section-title {
    font-size: calc(16px * var(--jx-fs));
    font-weight: 700;
    margin: 18px 0 10px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.section-title:before {
    content: '';
    width: 4px;
    height: 16px;
    border-radius: 2px;
    background: var(--primary);
}

.intro-text {
    font-size: calc(14px * var(--jx-fs));
    color: var(--text-2);
    line-height: 1.85;
    white-space: pre-wrap;
    word-break: break-word;
}

.announce-item {
    padding: 12px 14px;
    border-bottom: 1px solid var(--line);
    cursor: pointer;
}

.announce-item:last-child {
    border-bottom: 0;
}

.announce-title {
    font-size: calc(15px * var(--jx-fs));
    font-weight: 600;
    margin-bottom: 3px;
}

.announce-sum {
    font-size: calc(13px * var(--jx-fs));
    color: var(--text-muted);
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.content-html {
    font-size: calc(15px * var(--jx-fs));
    line-height: 1.85;
    color: var(--text-2);
    word-break: break-word;
}

.content-html img {
    border-radius: 10px;
    margin: 8px 0;
}

/* --------------------------------------------------------------------------
   全局反馈层（api.js 使用）
   -------------------------------------------------------------------------- */
#jx-layer {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 999;
}

/* 提示条放在下方（距底部约四分之一屏高）：
   顶部是 App 标题栏和搜索/筛选区，提示压在那里最挡视线，也最容易和顶栏叠在一起。 */
.jx-toast {
    position: fixed;
    left: 50%;
    bottom: 25%;
    transform: translateX(-50%);
    max-width: 86vw;
    padding: 10px 16px;
    border-radius: 10px;
    font-size: calc(14px * var(--jx-fs));
    color: var(--on-accent);
    background: var(--toast-bg);
    box-shadow: var(--shadow-lg);
    z-index: 1002;
    animation: jxRise .18s ease-out;
    word-break: break-word;
}

.jx-toast-ok { background: var(--toast-ok-bg); }
.jx-toast-err { background: var(--toast-err-bg); }
.jx-toast-info { background: var(--toast-bg); }

@keyframes jxRise {
    from { opacity: 0; transform: translateX(-50%) translateY(10px); }
    to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

.jx-mask {
    position: fixed;
    inset: 0;
    background: var(--overlay);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    pointer-events: auto;
    padding: 24px;
}

.jx-confirm {
    width: 100%;
    max-width: 320px;
    background: var(--surface);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: var(--shadow-lg);
}

.jx-confirm-title {
    padding: 16px 18px 4px;
    font-size: calc(16px * var(--jx-fs));
    font-weight: 600;
}

.jx-confirm-body {
    padding: 6px 18px 18px;
    font-size: calc(14px * var(--jx-fs));
    color: var(--text-2);
    line-height: 1.7;
    word-break: break-word;
}

.jx-confirm-foot {
    display: flex;
    border-top: 1px solid var(--line);
}

.jx-confirm-foot .btn {
    flex: 1;
    border-radius: 0;
    min-height: 46px;
    background: var(--surface);
    color: var(--text-2);
}

.jx-confirm-foot .btn-primary {
    background: var(--surface);
    color: var(--primary-text);
    font-weight: 600;
}

.jx-loading {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 1001;
    background: var(--loading-mask);
    pointer-events: auto;
}

.jx-spinner {
    width: 34px;
    height: 34px;
    border: 3px solid var(--spinner-track);
    border-top-color: var(--primary-text);
    border-radius: 50%;
    animation: jxSpin .8s linear infinite;
}

@keyframes jxSpin {
    to { transform: rotate(360deg); }
}

/* --------------------------------------------------------------------------
   工具类
   -------------------------------------------------------------------------- */
.flex { display: flex; }
.between { display: flex; align-items: center; justify-content: space-between; }
.center { display: flex; align-items: center; justify-content: center; }
.wrap { flex-wrap: wrap; }
.col { flex-direction: column; }
.gap4 { gap: 4px; }
.gap8 { gap: 8px; }
.gap12 { gap: 12px; }
.f1 { flex: 1; }
.mt4 { margin-top: 4px; }
.mt8 { margin-top: 8px; }
.mt12 { margin-top: 12px; }
.mt16 { margin-top: 16px; }
.mb4 { margin-bottom: 4px; }
.mb8 { margin-bottom: 8px; }
.mb12 { margin-bottom: 12px; }
.ml8 { margin-left: 8px; }
.text-muted { color: var(--text-muted); }
.text-2 { color: var(--text-2); }
.text-primary { color: var(--primary-text); }
.text-ok { color: var(--ok-text); }
.text-danger { color: var(--danger-text); }
.text-warn { color: var(--warn-text); }
.text-right { text-align: right; }
.text-center { text-align: center; }
.fs12 { font-size: calc(12px * var(--jx-fs)); }
.fs13 { font-size: calc(13px * var(--jx-fs)); }
.fs15 { font-size: calc(15px * var(--jx-fs)); }
.fs18 { font-size: calc(18px * var(--jx-fs)); }
.fw6 { font-weight: 600; }
.fw7 { font-weight: 700; }
.nowrap { white-space: nowrap; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.w-full { width: 100%; }
.hidden { display: none !important; }
.pointer { cursor: pointer; }
.pre { white-space: pre-wrap; word-break: break-word; }
.divider { height: 1px; background: var(--line); margin: 12px 0; }

/* --------------------------------------------------------------------------
   响应式
   -------------------------------------------------------------------------- */
@media (min-width: 560px) {
    .form-grid {
        grid-template-columns: 1fr 1fr;
    }
    .form-grid .span2 {
        grid-column: span 2;
    }
    .stat-grid {
        grid-template-columns: repeat(4, 1fr);
    }
    .modal-mask {
        align-items: center;
    }
    .modal {
        border-radius: 16px;
        max-height: 86vh;
    }
}

@media (min-width: 768px) {
    .main {
        padding: 16px 20px 28px;
    }
    .quick-grid {
        grid-template-columns: repeat(9, minmax(0, 1fr));
    }
    .quick-item {
        min-height: 80px;
    }
}

@media (orientation: landscape) {
    .quick-grid {
        grid-template-columns: repeat(9, minmax(0, 1fr));
    }
    .quick-item {
        min-height: 80px;
    }
}

@media (orientation: landscape) and (max-width: 767px) {
    .quick-grid {
        gap: 2px;
    }
    .quick-item {
        gap: 5px;
        padding: 5px 2px;
    }
    .quick-icon {
        width: 38px;
        height: 38px;
    }
    .quick-label {
        font-size: calc(10.5px * var(--jx-fs));
    }
}

@media (min-width: 1024px) {
    .sidebar {
        display: block;
    }
    .body {
        margin-left: var(--sidebar-w);
        width: calc(100% - var(--sidebar-w));
        min-width: 0;
    }
    .topbar-menu {
        display: none;
    }
    .tabbar {
        display: none;
    }
    .drawer {
        display: none !important;
    }
    .main {
        padding: 18px 24px 32px;
    }
    .stat-grid {
        grid-template-columns: repeat(6, 1fr);
    }
}

/* 大屏时提交条与侧栏对齐 */
@media (min-width: 1024px) {
    .submit-bar {
        left: var(--sidebar-w);
        bottom: 0;
        z-index: 48;
    }
}

/* --------------------------------------------------------------------------
   触控优化（手机/平板：<1024px，即底部 Tab 存在的宽度）
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
    .topbar-menu,
    .topbar-theme {
        min-height: 44px;
    }
    .btn-sm {
        min-height: 44px;
    }
    .check {
        min-height: 44px;
    }
    /* 核销状态按钮的触控下限只在手机生效；iPad/桌面按新的紧凑高度 38px */
    .subtab {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    .hours-input {
        min-height: 44px;
    }
    .stu-extra,
    .btn-row {
        gap: 10px;
    }
    .has-submit-bar {
        padding-bottom: calc(92px + var(--tabbar-h) + env(safe-area-inset-bottom));
    }
}

/* ==========================================================================
   UI 增强层（主题化 + 线性图标 + 专业化细节）
   颜色一律引用 theme.css 的语义 token，因此亮/暗主题自动适配。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 已有容器内的图标适配（原来放 emoji 的位置，现在放 <ui-icon>）
   -------------------------------------------------------------------------- */
.nav-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    color: inherit;
    opacity: .9;
}

.nav-item.active .nav-icon {
    opacity: 1;
}

.empty-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin: 0 auto 12px;
    border-radius: 50%;
    background: var(--surface-3);
    color: var(--text-3);
    font-size: 0;          /* 兼容残留的 emoji 文本：不再显示 */
}

.empty-icon > svg {
    /* 空态大图标同样跟随字号设置（--ico-size 在 .ico 上，这里只补 28px 这一档的缩放） */
    width: calc(28px * var(--jx-fs));
    height: calc(28px * var(--jx-fs));
}

.login-logo-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--on-accent);
}

.topbar-menu:hover {
    background: var(--nav-fg-soft);
    color: var(--nav-fg);
    opacity: 1;
}

.topbar-theme:hover,
.topbar-theme:focus-visible {
    background: transparent;
    opacity: 1;
}

.topbar-theme:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.tab-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 20px;
}

.brand-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--grad-brand);
    color: var(--on-accent);
}

/* 图标与文字并排时的通用间距 */
.ico + .nav-text,
.ico + span:not(.ico) {
    margin-left: 0;
}

/* --------------------------------------------------------------------------
   2. 页面头部（标题 + 操作区），替代各页面手写的标题行
   -------------------------------------------------------------------------- */
.page-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.page-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: calc(17px * var(--jx-fs));
    font-weight: 700;
    color: var(--text);
    line-height: 1.4;
}

.page-title .ico {
    color: var(--primary-text);
}

.page-sub {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
}

.page-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* 课时核销：周次导航与日期跳转整合为一条紧凑工具栏。 */
.week-toolbar-wrap {
    flex: 1 1 290px;
    min-width: 0;
    margin-left: 0;
}

.week-toolbar-nav {
    display: flex;
    align-items: center;
    min-width: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    overflow: hidden;
}

.week-toolbar-nav .icon-btn {
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: 0;
}

.week-toolbar-nav .btn {
    min-height: 36px;
    padding: 0 12px;
    border-top: 0;
    border-bottom: 0;
    border-radius: 0;
    border-left-color: var(--line);
    border-right-color: var(--line);
    font-weight: 600;
}

.week-toolbar-date {
    flex: 0 1 146px;
    min-width: 126px;
}

.week-toolbar-date .date-field {
    min-height: 36px;
    background: var(--surface);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 767px) {
    .week-toolbar-wrap {
        width: 100%;
        justify-content: space-between;
        gap: 8px;
        padding: 5px;
        border: 1px solid var(--line);
        border-radius: var(--radius-sm);
        background: var(--surface-2);
    }

    .week-toolbar-nav {
        flex: 0 0 auto;
    }

    .week-toolbar-date {
        flex: 1 1 126px;
        min-width: 0;
    }

    .week-toolbar-date .date-field {
        padding: 0 8px;
    }
}

/* --------------------------------------------------------------------------
   3. 方形图标按钮（顶栏 / 卡片头 / 行内操作）
   -------------------------------------------------------------------------- */
.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-2);
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s, transform .1s;
}

@media (hover: hover) {
    .icon-btn:hover {
        background: var(--hover);
        color: var(--text);
        border-color: var(--line);
    }
}

.icon-btn:active {
    transform: scale(.96);
}

.icon-btn.on {
    background: var(--primary-light);
    color: var(--primary-text);
    border-color: var(--primary);
}

.icon-btn[disabled] {
    opacity: .45;
    cursor: not-allowed;
}

.icon-btn.sm {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-pill);
}

/* 带文字的图标按钮间距 */
.btn > .ico:first-child {
    margin-right: 2px;
}

/* --------------------------------------------------------------------------
   4. 主题切换分段控件（顶栏用紧凑版，我的页面用完整版）
   -------------------------------------------------------------------------- */
.theme-seg {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    background: var(--surface-3);
    border: 1px solid var(--line);
    border-radius: 10px;
}

.theme-seg-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    min-width: 34px;
    height: 30px;
    padding: 0 9px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--text-3);
    font-size: calc(13px * var(--jx-fs));
    cursor: pointer;
    transition: background .15s, color .15s;
}

.theme-seg-item.on {
    background: var(--surface);
    color: var(--primary-text);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   5. 键值信息行（详情页 / 溯源弹窗）
   -------------------------------------------------------------------------- */
.kv {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
}

.kv-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 9px 0;
    border-bottom: 1px dashed var(--line);
    font-size: calc(13px * var(--jx-fs));
}

.kv-row:last-child {
    border-bottom: 0;
}

.kv-k {
    flex: 0 0 40%;
    max-width: 40%;
    color: var(--text-muted);
}

.kv-v {
    flex: 1;
    color: var(--text);
    word-break: break-word;
    text-align: right;
}

@media (min-width: 560px) {
    .kv {
        grid-template-columns: 1fr 1fr;
        column-gap: 24px;
    }
}

/* --------------------------------------------------------------------------
   “我的”页安全入口：整行按钮点击后打开底部密码面板
   -------------------------------------------------------------------------- */
.mine-action {
    width: 100%;
    min-height: 58px;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, background .15s, transform .1s;
}

.mine-action:active {
    transform: scale(.995);
}

@media (hover: hover) {
    .mine-action:hover {
        border-color: var(--primary);
        background: var(--surface-2);
    }
}

.mine-action-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: var(--primary-light);
    color: var(--primary-text);
}

.mine-action-copy {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.mine-action-title {
    font-size: calc(14px * var(--jx-fs));
    font-weight: 600;
}

.mine-action-desc {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
}

.mine-action-arrow {
    flex: 0 0 auto;
    color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   6. 骨架屏 / 加载态
   -------------------------------------------------------------------------- */
.skeleton {
    border-radius: 6px;
    background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%);
    background-size: 400% 100%;
    animation: jxShimmer 1.4s ease-in-out infinite;
    min-height: 14px;
}

@keyframes jxShimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.loading-inline {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.loading-inline .ico {
    animation: jxSpin 1s linear infinite;
}

/* --------------------------------------------------------------------------
   7. 表格与列表的专业化细节
   -------------------------------------------------------------------------- */
.table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    border-bottom: 1px solid var(--line-2);
}

.table.striped tbody tr:nth-child(even) {
    background: var(--surface-2);
}

@media (hover: hover) {
    .table tbody tr:hover {
        background: var(--hover);
    }

    .list-item:hover {
        background: var(--hover);
    }
}

.table-wrap {
    border-radius: var(--radius);
}

.tnum {
    font-variant-numeric: tabular-nums;
}

/* 数字/统计卡上方的图标徽标 */
.stat-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-bottom: 6px;
    border-radius: 9px;
    background: var(--primary-light);
    color: var(--primary-text);
}

.stat-icon.ok { background: var(--ok-light); color: var(--ok-text); }
.stat-icon.warn { background: var(--warn-light); color: var(--warn-text); }
.stat-icon.danger { background: var(--danger-light); color: var(--danger-text); }

/* --------------------------------------------------------------------------
   8. 其它细节增强
   -------------------------------------------------------------------------- */
.card-head {
    background: var(--surface);
}

.card-head .card-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.soft-card {
    background: var(--surface-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
}

.hairline {
    height: 1px;
    background: var(--line);
    margin: 10px 0;
}

.badge-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--primary);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 20px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--text-2);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.6;
}

.chip .ico {
    color: var(--text-3);
}

/* 常用原因胶囊：点一下把整句填进输入框，比每次手打快 */
.reason-pick {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.reason-chip {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    line-height: 1.3;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s, transform .1s;
}

.reason-chip:active {
    transform: scale(.98);
}

.reason-chip.on {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--primary-text);
    font-weight: 600;
}

@media (max-width: 767px) {
    .reason-chip {
        min-height: 44px;
        padding: 0 16px;
    }
}

.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    color: var(--primary-text);
    font-size: calc(13px * var(--jx-fs));
}

button.link-arrow {
    border: 0;
    background: transparent;
    padding: 0;
    font-family: inherit;
    cursor: pointer;
}

.locked-tip {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

/* 提示文案占满剩余宽度，右侧动作按钮（重新核销 / 强制核销）自动靠右。
   窄屏换行后按钮单独一行，不会被长文案挤变形。 */
.locked-tip > span {
    flex: 1;
    min-width: 0;
}

.locked-tip > .btn {
    margin-left: auto;
    flex: 0 0 auto;
}

.locked-tip.edit-tip {
    border-color: var(--warn);
}

.locked-tip .ico {
    flex: 0 0 auto;
}

/* 顶栏在移动端更紧凑 */
@media (max-width: 767px) {
    .page-title {
        font-size: calc(16px * var(--jx-fs));
    }

    .icon-btn {
        width: 38px;
        height: 38px;
    }
}

/* 触摸设备不显示 hover 残留 */
@media (hover: none) {
    .icon-btn:hover,
    .list-item:hover,
    .table tbody tr:hover {
        background: inherit;
    }
}

/* --------------------------------------------------------------------------
   9. 应用外壳内的图标按钮 / 徽标（配合 app.js 顶栏与抽屉）
   -------------------------------------------------------------------------- */
.brand-name {
    font-size: calc(16px * var(--jx-fs));
    font-weight: 700;
    letter-spacing: .3px;
}

@media (hover: hover) {
    .topbar-user:hover {
        background: var(--nav-fg-soft);
        border-color: transparent;
        opacity: 1;
    }

    .topbar-crumb:hover {
        color: var(--nav-fg);
        opacity: 1;
    }

    .topbar-crumb.current:hover {
        opacity: 1;
    }
}

.topbar-user .ico {
    opacity: .85;
}

.drawer-head {
    gap: 0;
}

/* 窄屏：路径条保持单行可横向滑动，用户入口收成图标，避免挤压路径 */
@media (max-width: 480px) {
    .topbar {
        gap: 4px;
        padding-left: 6px;
        padding-right: 8px;
    }

    /* 窄屏：顶栏按钮收窄内边距而不是砍掉文字，文字标签必须保留 */
    .topbar-menu {
        padding: 0 9px;
        gap: 4px;
        font-size: calc(12.5px * var(--jx-fs));
    }

    .topbar-theme {
        padding: 0;
    }

    .topbar-crumb {
        min-height: 40px;
        align-items: center;
    }

    .topbar-user {
        /* 窄屏姓名隐藏，只留「图标 + 下拉箭头」，所以宽度按这两者给足；
           乘 --jx-fs 是为了字号调大（图标跟着放大）时不会被挤掉箭头 */
        max-width: calc(54px * var(--jx-fs));
        padding: 6px 8px;
    }

    .topbar-user-name {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   10. 图标与文字的间距（避免图标贴着文字）
   说明：已经用 display:flex + gap 的容器（.card-title/.page-title/.chip/.btn/
        .nav-item/.locked-tip/.loading-inline/.theme-seg-item/.topbar-* 等）无需处理；
        这里是「块级 + 文本截断」类容器，改用 margin 保证 ellipsis 不被破坏。
   -------------------------------------------------------------------------- */
.field-label > .ico:first-child,
.field-hint > .ico:first-child,
.hero-title > .ico:first-child,
.login-title > .ico:first-child,
.list-item-title > .ico:first-child,
.announce-title > .ico:first-child,
.announce-sum > .ico:first-child,
.stat-label > .ico:first-child,
.page-sub > .ico:first-child,
.stu-name > .ico:first-child,
.kv-k > .ico:first-child,
.kv-v > .ico:first-child,
.tag > .ico:first-child,
.subtab > .ico:first-child,
.empty-text > .ico:first-child,
.ml8 > .ico:first-child {
    margin-right: 6px;
}

/* 家长端「学员姓名」行（学员中心卡片 / 孩子课时明细）：图标与姓名之间留 5px，不要贴在一起。
   这两处是块级容器里的 inline 文本，没有 flex gap 可用
   （改成 flex 会让「姓名 + 性别标签 + 关系标签」不再自动换行，窄屏反而会溢出）。 */
.stu-name-line > .ico:first-child {
    margin-right: 5px;
}

/* 行尾图标（如「查看详情 ›」）左侧留白 */
.list-item-side > .ico:last-child,
.list-item-title > .ico:last-child,
.card-title > .ico:last-child,
.page-title > .ico:last-child {
    margin-left: 4px;
}

/* 小胶囊内的图标 + 文字（日程、联系方式） */
.schedule span,
.hero-meta span,
.list-item-sub > span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* 只有一个统计卡时通栏显示，避免只占左半列 */
.stat-grid > .stat:only-child {
    grid-column: 1 / -1;
}

/* 整行作为可选项（如选择分校）时，去掉胶囊圆角，改用行选中态观感 */
.list-item.check {
    border-radius: 10px;
}

/* 主题分段控件在极窄屏允许换行，避免溢出 */
@media (max-width: 359px) {
    .theme-seg {
        flex-wrap: wrap;
    }

    .theme-seg-item {
        padding: 0 7px;
        font-size: calc(12px * var(--jx-fs));
    }
}

/* 结论性提示条与说明块内的图标垂直居中 */
.page-head .ico,
.kv-row .ico {
    flex: 0 0 auto;
}

/* ==========================================================================
   11. 日期底部滑出选择器（ui-date 组件）与通用底部面板 .sheet
   ========================================================================== */

/* ---- 日期字段（ui-date 的触发按钮） ---- */
.date-wrap {
    display: block;
}

.date-field {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-height: 34px;
    padding: 0 9px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-size: calc(13px * var(--jx-fs));
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.date-field > .ico {
    flex: 0 0 auto;
    color: var(--text-3);
}

.date-field .df-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.date-field .df-text.is-empty {
    color: var(--text-muted);
}

.date-field:active {
    background: var(--hover);
}

/* ---- 时间字段与小时分组选择器（ui-time） ---- */
.time-wrap {
    display: block;
}

.time-field {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-height: 40px;
    padding: 0 9px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-size: max(16px, calc(13px * var(--jx-fs)));
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.time-field > .ico {
    flex: 0 0 auto;
    color: var(--text-3);
}

.time-field .tf-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.time-field .tf-text.is-empty {
    color: var(--text-muted);
}

.time-field:active {
    background: var(--hover);
}

.sheet-time {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr);
    max-width: 520px;
}

.sheet-time > .sheet-head,
.sheet-time > .sheet-foot {
    grid-column: 1 / -1;
}

.time-hour-list {
    max-height: 262px;
    overflow-y: auto;
    padding: 8px;
    border-right: 1px solid var(--line);
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.time-hour-list-item {
    display: block;
    width: 100%;
    min-height: 36px;
    margin: 0 0 5px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-2);
    font: inherit;
    font-size: calc(13px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.time-hour-list-item:last-child {
    margin-bottom: 0;
}

.time-hour-list-item:active {
    background: var(--hover);
}

.time-hour-list-item.on {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
    font-weight: 700;
}

.time-picker-main {
    min-width: 0;
    padding: 10px;
}

.time-current-hour {
    display: flex;
    align-items: baseline;
    justify-content: center;
    min-height: 38px;
    margin-bottom: 8px;
    border: 1px solid var(--primary);
    border-radius: var(--radius-sm);
    background: var(--primary-light);
    color: var(--primary-text);
    font-variant-numeric: tabular-nums;
}

.time-current-hour strong {
    font-size: calc(27px * var(--jx-fs));
    line-height: 1;
}

.time-current-hour span {
    margin-left: 4px;
    font-size: calc(12px * var(--jx-fs));
    font-weight: 600;
}

.time-minute-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 6px;
}

.time-minute-card {
    min-height: 47px;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: calc(14px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.time-minute-card:active {
    background: var(--hover);
}

.time-minute-card.on {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
    font-weight: 700;
}

@media (max-width: 390px) {
    .sheet-time {
        grid-template-columns: 72px minmax(0, 1fr);
    }

    .time-hour-list {
        max-height: 252px;
        padding: 6px;
    }

    .time-picker-main {
        padding: 8px;
    }

    .time-current-hour strong {
        font-size: calc(24px * var(--jx-fs));
    }

    .time-minute-grid {
        gap: 4px;
    }

    .time-minute-card {
        min-height: 43px;
        font-size: calc(13px * var(--jx-fs));
    }
}

/* 每小时是一组：左侧小时标题，右侧 00-55 分钟卡片，整组纵向滚动选择。 */
.sheet-time {
    display: block;
    max-width: 520px;
}

.time-group-list {
    max-height: min(66vh, 560px);
    overflow-y: auto;
    padding: 8px 12px 10px;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.time-hour-group {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr);
    gap: 10px;
    align-items: stretch;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
}

.time-hour-group:first-child {
    padding-top: 0;
}

.time-hour-group:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.time-hour-group .time-current-hour {
    min-height: 100px;
    margin: 0;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.time-hour-group .time-current-hour strong {
    font-size: calc(34px * var(--jx-fs));
}

.time-hour-group .time-current-hour span {
    margin: 5px 0 0;
}

@media (max-width: 390px) {
    .time-group-list {
        padding: 6px 10px 8px;
    }

    .time-hour-group {
        grid-template-columns: 70px minmax(0, 1fr);
        gap: 7px;
        padding: 7px 0;
    }

    .time-hour-group .time-current-hour {
        min-height: 92px;
    }

    .time-hour-group .time-current-hour strong {
        font-size: calc(28px * var(--jx-fs));
    }
}

/* ---- 底部滑出面板（手机）/ 居中弹层（桌面） ---- */
.sheet-mask {
    position: fixed;
    inset: 0;
    background: var(--overlay);
    z-index: 90;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    animation: jxFade .16s ease-out;
}

.sheet {
    width: 100%;
    max-width: 420px;
    background: var(--glass-panel);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    border: 1px solid var(--line);
    border-bottom: 0;
    border-radius: 16px 16px 0 0;
    box-shadow: var(--shadow-lg);
    max-height: 88vh;
    overflow: hidden;
    padding-bottom: calc(10px + env(safe-area-inset-bottom));
    animation: jxSlideUp .22s cubic-bezier(.22, .61, .36, 1);
}

@media (min-width: 768px) {
    .sheet-mask {
        align-items: center;
    }

    .sheet {
        margin: 0 16px;
        border: 1px solid var(--line);
        border-radius: 14px;
        padding-bottom: 10px;
        animation: jxPop .16s ease-out;
    }
}

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

@keyframes jxPop {
    from { transform: scale(.97); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

@keyframes jxFade {
    from { opacity: 0; }
    to { opacity: 1; }
}

.sheet-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 13px 14px 11px;
    border-bottom: 1px solid var(--line);
}

.sheet-title {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: calc(14px * var(--jx-fs));
    font-weight: 600;
}

.sheet-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 10px;
}

.sheet-month {
    font-size: calc(14px * var(--jx-fs));
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* 日期快速跳转：年与月分开选择，避免逐月翻到出生年月 */
.sheet-jump {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: 0;
}

.sheet-jump-btn,
.sheet-quick-item {
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text);
    font: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.sheet-jump-btn {
    padding: 6px 8px;
    font-size: calc(14px * var(--jx-fs));
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.sheet-jump-btn:active,
.sheet-quick-item:active {
    background: var(--hover);
}

.sheet-quick-pick {
    padding: 4px 12px 10px;
}

.sheet-quick-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 40px;
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.sheet-quick-spacer {
    width: 32px;
    height: 32px;
}

.sheet-quick-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
}

.sheet-quick-item {
    min-height: 40px;
    padding: 6px;
    border-color: var(--line);
    background: var(--surface);
    font-size: calc(13px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
}

.sheet-quick-item.on {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
    font-weight: 600;
}

.sheet-week,
.sheet-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    padding: 0 10px;
}

.sheet-week {
    padding-bottom: 4px;
}

.sheet-week span {
    text-align: center;
    font-size: calc(11.5px * var(--jx-fs));
    color: var(--text-muted);
    padding: 2px 0;
}

.sheet-grid {
    padding-bottom: 6px;
}

.sheet-day {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 38px;
    border: 1px solid transparent;
    border-radius: 8px;
    font-size: calc(13.5px * var(--jx-fs));
    color: var(--text);
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    user-select: none;
}

.sheet-day.pad {
    color: var(--text-3);
    opacity: .4;
    cursor: default;
}

.sheet-day.today {
    border-color: var(--line-2);
    color: var(--primary-text);
    font-weight: 600;
}

.sheet-day.on {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-accent);
    font-weight: 600;
}

.sheet-foot {
    display: flex;
    gap: 8px;
    padding: 8px 12px 2px;
    border-top: 1px solid var(--line);
}

.sheet-foot .btn {
    flex: 1;
    min-height: 38px;
}

/* ==========================================================================
   12. 移动端 App 化（原生 App 的观感与手感）
   ========================================================================== */

/* 去掉网页感：消除点击高亮延迟、禁止整页橡皮筋回弹 */
button,
.btn,
.subtab,
.seg-item,
.tab-item,
.nav-item,
.list-item,
.check,
.icon-btn,
.sheet-day,
.date-field {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

html,
body {
    overscroll-behavior-y: none;
}

@media (max-width: 767px) {
    /* 手机端卡片圆角略大，更接近原生卡片观感（投影已全局去掉，这里不再需要覆盖）
       只改这一个令牌：全站卡片族一起变，不会再出现「学员卡 6px、别的卡 12px」 */
    :root {
        --radius-card: 12px;
    }

    /* 顶栏已显示页面标题，页内不再重复大标题（省空间、更像 App） */
    .page-head {
        margin-bottom: 8px;
    }

    .page-head .page-title {
        display: none;
    }

    /* 列表行 / 底部 Tab 的按压反馈（原生 App 手感） */
    .list-item:active {
        background: var(--hover);
    }

    .tab-item:active {
        background: var(--hover);
    }

    .tab-item {
        font-size: calc(10.5px * var(--jx-fs));
    }

    /* 弹窗贴底后，标题行更紧凑 */
    .modal-head {
        padding: 12px 14px 10px;
    }
}

/* ==========================================================================
   13. ui-select 选择面板（替代原生 <select>，与 ui-date 共用 .sheet-mask/.sheet）
   顶部搜索框 + 选项列表 + 选中态 + 底部清除
   ========================================================================== */

.select-wrap {
    display: inline-block;
    width: 100%;
}

.select-field {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    width: 100%;
    min-height: 34px;
    padding: 0 9px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-size: calc(13px * var(--jx-fs));
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.select-field:hover:not([disabled]) {
    border-color: var(--line-2);
}

.select-field:active:not([disabled]) {
    background: var(--hover);
}

.select-field:focus-visible {
    border-color: var(--primary-text);
    outline: none;
    box-shadow: var(--ring);
}

.select-field[disabled] {
    background: var(--info-light);
    color: var(--text-muted);
    cursor: not-allowed;
}

.sf-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sf-text.is-empty {
    color: var(--text-muted);
}

/* .sheet-select 改造：标题 + (搜索框) + 选项列表 + (底部按钮) */
.sheet-select {
    display: flex;
    flex-direction: column;
    max-height: 86vh;
}

.sheet-search {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
}

.sheet-search > .ico {
    color: var(--text-3);
    flex: 0 0 auto;
}

.sheet-search > .input {
    flex: 1;
    min-width: 0;
    min-height: 34px;
    border: 0;
    padding: 0;
    background: transparent;
    box-shadow: none;
    font-size: calc(14px * var(--jx-fs));        /* iOS Safari 必须 >=16 才不缩放；这里只在面板内使用，可保持 14 */
    -webkit-appearance: none;
    appearance: none;
}

.sheet-search > .input:focus {
    box-shadow: none;
    border-color: transparent;
}

.sheet-search > .icon-btn {
    flex: 0 0 auto;
}

.sheet-list {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

.sheet-opt {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--line);
    cursor: pointer;
    user-select: none;
    transition: background .12s;
}

.sheet-opt:last-child {
    border-bottom: 0;
}

.sheet-opt:active {
    background: var(--hover);
}

.sheet-opt-main {
    flex: 1;
    min-width: 0;
}

.sheet-opt-label {
    font-size: calc(14.5px * var(--jx-fs));
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sheet-opt-hint {
    font-size: calc(12px * var(--jx-fs));
    color: var(--text-muted);
    margin-top: 2px;
}

.sheet-opt.on .sheet-opt-label {
    color: var(--primary-text);
    font-weight: 600;
}

.sheet-opt.on {
    background: var(--primary-light);
}

.sheet-opt.disabled {
    opacity: .45;
    cursor: not-allowed;
}

.sheet-opt > .ico {
    color: var(--primary-text);
    flex: 0 0 auto;
}

/* ==========================================================================
   14. 紧凑搜索栏 .searchbar（节省屏比空间的关键）
   单行：搜索图标 + 输入 + 清除 + 右侧筛选按钮
   点击筛选按钮 → 触发自定义事件 @open-filter，由父组件弹出筛选 sheet
   ========================================================================== */

.searchbar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px;
    margin-bottom: 10px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    position: sticky;
    top: calc(var(--topbar-h) + 6px);
    z-index: 30;
}

.searchbar-input {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 7px;
    min-height: 34px;
    padding: 0 10px;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
    transition: background .15s;
}

.searchbar-input:focus-within {
    background: var(--surface);
    box-shadow: var(--ring);
}

.searchbar-input > .ico {
    color: var(--text-3);
    flex: 0 0 auto;
}

.searchbar-input > .input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    padding: 0;
    min-height: 30px;
    box-shadow: none;
}

.searchbar-input > .input:focus {
    box-shadow: none;
    border-color: transparent;
}

.searchbar-input > .icon-btn {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
}

.searchbar-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
}

.searchbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 34px;
    padding: 0 12px;
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--info-light);
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    cursor: pointer;
    transition: background .15s;
}

.searchbar-btn:hover {
    background: var(--hover);
}

.searchbar-btn:active {
    background: var(--selected);
}

.searchbar-btn.on {
    background: var(--primary-light);
    color: var(--primary-text);
    font-weight: 600;
}

.searchbar-btn .ico {
    flex: 0 0 auto;
}

.searchbar-btn .badge-dot {
    flex: 0 0 auto;
}

/* 移动端：搜索栏 + 筛选按钮全部贴底一行，按钮紧凑 */
@media (max-width: 767px) {
    .searchbar {
        padding: 5px;
        gap: 4px;
        top: calc(var(--topbar-h) + 4px);
    }

    .searchbar-input {
        min-height: 32px;
        padding: 0 8px;
    }

    .searchbar-btn {
        min-height: 32px;
        padding: 0 10px;
        font-size: calc(12.5px * var(--jx-fs));
    }
}

/* ==========================================================================
   15. 标签页 .subtabs 横向滚动渐隐（"两端渐隐"提示有更多内容）
   ========================================================================== */

.scroll-x {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    position: relative;
}

.scroll-x::-webkit-scrollbar {
    display: none;
}

/* 用 mask-image 实现两端渐隐（移动端原生支持；旧 Android 仅靠 padding 兜底）
   说明：mask 里的 black / transparent 是遮罩通道值，不参与主题配色，故不使用颜色令牌。 */
@supports (mask-image: linear-gradient(black, black)) or (-webkit-mask-image: linear-gradient(black, black)) {
    .scroll-x.fade-edge {
        -webkit-mask-image: linear-gradient(90deg, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(90deg, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }
}

/* ==========================================================================
   16. .subtabs 在移动端的小尺寸补丁：
   之前靠 padding/gap 与 min-width 造成 7 个星期 tab 在窄屏被挤压。
   现在改成"等分铺满"——与 native App 一样，单行均分。
   ========================================================================== */

@media (max-width: 767px) {
    .subtab.week {
        min-width: 0;
        padding: 0;
        flex: 1 1 0;
        font-size: calc(12.5px * var(--jx-fs));
    }

    .subtabs.week-row {
        gap: 3px;
    }
}

/* ==========================================================================
   17. iPad / 中间断点（768-1023）：
   · 表格自动转为卡片列表（class="list"）—— 比强行横向滚动更接近原生 App
   · 表单栅格 2 列
   · 顶栏标题字号略增
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {
    .form-grid {
        grid-template-columns: 1fr 1fr;
    }

    .form-grid .span2 {
        grid-column: span 2;
    }

    .stat-grid {
        grid-template-columns: repeat(4, 1fr);
    }

    /* 桌面表格在 iPad 上以列表形式呈现（覆盖式 class） */
    .table-wrap.table-wrap-list table.table {
        min-width: 0;
    }

    .table-wrap.table-wrap-list .table thead {
        display: none;
    }

    .table-wrap.table-wrap-list .table,
    .table-wrap.table-wrap-list .table tbody,
    .table-wrap.table-wrap-list .table tr,
    .table-wrap.table-wrap-list .table td {
        display: block;
        width: 100%;
    }

    .table-wrap.table-wrap-list .table tr {
        background: var(--surface);
        border: 1px solid var(--line);
        border-radius: var(--radius);
        padding: 13px 14px;
        margin-bottom: 10px;
    }

    .table-wrap.table-wrap-list .table td {
        border: 0;
        padding: 4px 0;
        white-space: normal;
        display: flex;
        justify-content: space-between;
        gap: 10px;
        font-size: calc(13.5px * var(--jx-fs));
    }

    .table-wrap.table-wrap-list .table td::before {
        content: attr(data-label);
        color: var(--text-muted);
        font-size: calc(12.5px * var(--jx-fs));
        flex: 0 0 auto;
    }
}

/* ==========================================================================
   18. 触摸体验增强（原生 App 手感）
   ========================================================================== */

/* iOS Safari 输入框 < 16px 会触发整页缩放：所有 .input 提到 16px */
.input,
.select,
.textarea {
    font-size: calc(14px * var(--jx-fs));
}

@media (max-width: 1023px) {
    .input,
    .select,
    .textarea,
    .searchbar-input > .input,
    .sheet-search > .input {
        font-size: calc(16px * var(--jx-fs));   /* 防止 iOS 自动缩放导致布局抖动 */
    }
}

/* 用 100dvh 替代 100vh 解决 iOS Safari 顶部/底部地址栏抖动 */
.shell,
.public-shell,
.splash {
    min-height: 100vh;
    min-height: 100dvh;
}

.modal,
.sheet {
    max-height: 92vh;
    max-height: 92dvh;
}

/* 路由切换的 fade 过渡（轻量、不影响性能） */
.route-fade-enter-active,
.route-fade-leave-active {
    transition: opacity .18s ease;
}

/* 平面化：页面切换只做淡入淡出，不做上下位移（位移会产生"层次起伏"的伪 3D 感） */
.route-fade-enter-from {
    opacity: 0;
}

.route-fade-leave-to {
    opacity: 0;
}

/* 用户偏好「减少动效」时关闭过渡 */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0s !important;
        animation-duration: 0s !important;
    }
}

/* ==========================================================================
   19. 暗色模式细节（输入框 / 滚动条 / 提示）
   ========================================================================== */

html[data-theme="romance"] .searchbar-input {
    background: var(--surface-3);
}

html[data-theme="romance"] .sheet-opt:active {
    background: var(--hover);
}

html[data-theme="romance"] .table-wrap.table-wrap-list .table tr {
    background: var(--surface);
}

/* ==========================================================================
   20. 工具类补充
   ========================================================================== */

.hairline-r {
    border-right: 1px solid var(--line);
}

.no-scroll-x {
    overflow-x: hidden;
}

.bottom-safe {
    padding-bottom: env(safe-area-inset-bottom);
}

.top-safe {
    padding-top: env(safe-area-inset-top);
}

/* ==========================================================================
   21. seg-pill / seg-row：紧凑三态分段（节省高度）
   · 高度比 .subtabs 更小，适合贴在搜索栏下方作为状态计数
   · 桌面端显示文字，移动端仅显示文字+数字
   ========================================================================== */

.seg-row {
    display: flex;
    gap: 6px;
    padding: 6px 0 12px;
}

.seg-pill {
    flex: 1;
    min-width: 0;              /* 允许窄屏收缩：避免分段把父级撑出横向滚动条 */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 36px;
    padding: 0 12px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: background .15s, color .15s, border-color .15s, transform .1s;
}

.seg-pill:active {
    transform: scale(.98);
}

.seg-pill.on {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-accent);
    font-weight: 600;
}

.seg-pill .seg-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 1 auto;
    min-width: 22px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--surface-3);
    color: var(--text-2);
    font-size: calc(11.5px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin-left: 2px;
}

.seg-pill.on .seg-count {
    background: var(--on-accent-soft);
    color: var(--on-accent);
}

.seg-pill.sm {
    min-height: 32px;
    padding: 0 8px;
    font-size: calc(12.5px * var(--jx-fs));
}

/* 表单/设置项里的枚举分段：不铺满整行，按内容宽度居中即可（桌面端否则会拉得很长） */
.seg-row.seg-fit {
    max-width: 240px;
    padding-bottom: 0;
}

/* 只读枚举：置灰并屏蔽点击（与 disabled 输入框的观感一致） */
.seg-row.seg-readonly {
    opacity: .55;
    pointer-events: none;
}

/* 星期筛选：在高级筛选 sheet 内显示，等分铺满 */
.week-row-weekday {
    display: flex;
    gap: 4px;
    flex-wrap: nowrap;
}

.week-row-weekday .seg-pill {
    flex: 1;
    padding: 0 4px;
}

/* 手机端：8 个星期按钮做成正圆
   --------------------------------------------------------------------------
   .seg-pill 的基础样式是 flex: 1（按可用宽度等分）+ border-radius: 18px，
   宽度一富余就变成「圆角长条」—— 同一个页面在 360 的小屏上看着是圆的，
   到 390 / 430 这类宽一点的手机上就明显变成圆角矩形，所以不能靠等分。
   这里把直径钉成固定长度（宽 = 高，才可能是正圆），多出来的宽度交给间隙：
     · justify-content: space-between → 富余宽度均分到 8 个圆之间，
       首尾仍然贴住两端，读起来还是一整条「等分」的筛选条；
     · gap 收到 2px，保证 360px 宽的手机上 8×40 + 7×2 = 334px 放得下
       （.main 左右各 10px，360 的可用宽度是 340px），正好是 40px 正圆，
       同时满足项目「移动端可点区域 ≥ 40px」的触控下限；
     · flex-shrink 保留 1 + min-width: 0 → 更窄的屏幕（≤359px）允许压窄，
       绝不撑出横向滚动条；那一档另有更小的直径，见下面的 359 断点。
   桌面（>=768px）不动：宽屏上「圆角长条」本来就是这个分段控件该有的样子。 */
@media (max-width: 767px) {
    .week-row-weekday {
        gap: 2px;
        justify-content: space-between;
    }

    .week-row-weekday .seg-pill,
    .week-row-weekday .seg-pill.sm {
        flex: 0 1 40px;
        width: 40px;
        height: 40px;
        min-width: 0;
        min-height: 40px;
        padding: 0;
        border-radius: 50%;
    }
}

/* 超窄屏（iPhone SE 一代 / 320px 级）：8 个 40px 圆放不下（需要 334px，只有 300px），
   再压窄就成了竖椭圆，所以直径整体降到 34px —— 8×34 + 7×2 = 286px 依然放得下。 */
@media (max-width: 359px) {
    .week-row-weekday .seg-pill,
    .week-row-weekday .seg-pill.sm {
        flex-basis: 34px;
        width: 34px;
        height: 34px;
        min-height: 34px;
    }
}

/* ==========================================================================
   22. sheet-body（与 sheet-foot 配套）—— 让 sheet 内部可滚动区域有明确分界
   ========================================================================== */

.sheet-body {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding: 14px 16px;
}

.sheet-body .field:last-child {
    margin-bottom: 0;
}

/* ==========================================================================
   23. 触控目标兜底（放在文件最后：组件样式都在上面，这里必须能覆盖它们）
   · 手机 / iPad（<1024px，底部 Tab 存在的宽度）上，可点区域不小于舒适阈值
   · 桌面端保持原来的紧凑尺寸，不牺牲信息密度
   阈值取法：
      正文动作按钮 44px —— 与 iOS / Android 原生最小触控高度一致
      分段控件与图标按钮 40px —— 贴近原生分段控件（iOS 约 32pt）但更宽容误触
   ========================================================================== */

@media (max-width: 1023px) {
    .btn,
    .btn-sm {
        min-height: 44px;
    }

    .seg-pill,
    .seg-pill.sm {
        min-height: 40px;
    }

    .icon-btn.sm {
        width: 40px;
        height: 40px;
    }

    .theme-seg-item {
        height: 40px;
        min-width: 40px;
    }

    /* 搜索栏上的筛选按钮：跟随搜索栏自身高度，避免"小按钮挂在大框里" */
    .searchbar-btn {
        min-width: 44px;
        min-height: 44px;
    }

    /* 正文内联链接（如公告附件）在触屏上也要有足够点击高度 */
    .link-arrow {
        display: inline-flex;
        align-items: center;
        min-height: 40px;
    }

    /* 底部面板里的选项行：一行一个，天然够高，但保证最小高度 */
    .sheet-opt {
        min-height: 48px;
    }
}

/* ==========================================================================
   24. 手机 App 顶栏与入口集中（2026 全站 UI）
   --------------------------------------------------------------------------
   修正一个前后端不一致：第 12 节按「顶栏已显示页面标题」在手机端隐藏了页内标题，
   但顶栏此前渲染的是面包屑，导致手机上既看不到页面标题、又挤了 4-5 段面包屑。
   这里把手机顶栏收敛为「返回/菜单 + 页面标题 + 主题 + 我的」的原生结构，
   面包屑只在有横向空间的平板/桌面出现。
   ========================================================================== */

/* 页面标题：桌面隐藏（桌面用面包屑表达位置） */
.topbar-title {
    display: none;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--nav-fg);
    font-size: calc(16px * var(--jx-fs));
    font-weight: 600;
    line-height: 1.2;
}

/* 返回键与菜单键同尺寸：顶栏左侧永远只有一个入口，位置固定不跳动 */
.topbar-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    min-height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--nav-fg);
    opacity: .86;
    cursor: pointer;
    transition: background .15s, opacity .15s;
}

.topbar-back:active {
    background: var(--hover);
}

.topbar-back:focus-visible {
    outline: none;
    box-shadow: var(--ring);
}

/* 桌面/平板：返回键不出现（侧栏常驻，走面包屑） */
@media (min-width: 768px) {
    .topbar-back {
        display: none;
    }
}

@media (max-width: 767px) {
    /* 手机：标题取代面包屑；面包屑在 390px 下会横向滚动且与底部 Tab 表达重复 */
    .topbar-breadcrumb {
        display: none;
    }

    .topbar-title {
        display: block;
        font-size: calc(16.5px * var(--jx-fs));
    }

    .topbar {
        gap: 6px;
        padding-left: 6px;
        padding-right: 8px;
    }

    .topbar-actions {
        gap: 0;
    }

    /* 顶栏所有入口统一 44px 触控下限 */
    .topbar-menu,
    .topbar-theme,
    .topbar-back,
    .topbar-user {
        min-height: 44px;
    }

    /* 手机顶栏只留图标，把宽度让给页面标题 */
    .topbar-menu {
        width: 44px;
        min-width: 44px;
        padding: 0;
        gap: 0;
    }

    .topbar-menu > span {
        display: none;
    }

    /* 顶栏已提供统一位置的返回键，页内不再重复一个（否则详情页会出现两个返回） */
    .page-head .icon-btn[title="返回"] {
        display: none;
    }
}

/* 主题按钮：图标本身已区分「亮 / 暗 / 跟随系统」，
   原先按模式给绿/紫/蓝三种颜色，绿色与全站状态色（绿=正常）语义冲突，
   这里统一为顶栏前景色，模式只由图标表达。 */
.topbar-theme.theme-mode-classic,
.topbar-theme.theme-mode-fresh,
.topbar-theme.theme-mode-romance,
.topbar-theme.theme-mode-auto {
    color: var(--nav-fg);
}

/* 抽屉顶部：身份卡（谁、什么角色、哪个分校），让 17 项菜单有明确归属 */
.drawer-id {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-width: 0;
    margin-left: 8px;
}

.drawer-id strong {
    font-size: calc(14.5px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.drawer-id small {
    color: var(--text-muted);
    font-size: calc(11.5px * var(--jx-fs));
    font-weight: 400;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ==========================================================================
   25. 入口集中：功能入口用「两级层次」而不是彩虹色
   --------------------------------------------------------------------------
   · tone-accent —— 核销/数据这类天天要用的实操入口，品牌浅底 + 品牌色图标
   · tone-plain  —— 教务/系统这类配置类入口，中性浅底，安静不抢注意力
   刻意不用多色：琥珀/玫红在本系统里是「提醒/异常」状态色，
   拿来做分类色会让用户误读状态（状态色语义必须保持 绿=正常 / 琥珀=提醒 / 玫红=异常）。
   ========================================================================== */

.quick-item .quick-icon.tone-accent,
.core-card .core-icon.tone-accent {
    background: var(--primary-light);
    color: var(--primary-text);
    border-color: transparent;
}

.quick-item .quick-icon.tone-plain,
.core-card .core-icon.tone-plain {
    background: var(--surface-2);
    color: var(--text-2);
    border-color: transparent;
}

/* 手机端入口方块放大：拇指更容易命中，也恢复「一眼可辨」的 App 感 */
@media (max-width: 767px) {
    .quick-card .quick-grid {
        gap: 8px;
    }

    .quick-card .quick-item {
        min-height: 96px;
    }

    .quick-item .quick-icon {
        width: 50px;
        height: 50px;
        border-radius: 14px;
    }

    .quick-label {
        font-size: calc(13px * var(--jx-fs));
    }

    /* 首页 KPI 压成一行四连数字条（与原生 App 的概览条一致）：
       2×2 卡片要占约 160px，竖排数字条约 100px，首屏能多露出一块内容。
       图标保留 —— 待核销那格靠图标底色继续承担「有事情要处理」的提醒作用。 */
    .home-stat-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 6px;
    }

    .home-stat {
        flex-direction: column;
        align-items: center;
        gap: 4px;
        padding: 10px 4px;
        text-align: center;
    }

    .home-stat-icon {
        width: 28px;
        height: 28px;
        border-radius: 8px;
    }

    .home-stat-copy {
        align-items: center;
        gap: 1px;
    }

    .home-stat-copy strong {
        font-size: calc(19px * var(--jx-fs));
    }

    .home-stat-copy small {
        font-size: calc(10.5px * var(--jx-fs));
        white-space: nowrap;
    }
}

/* ==========================================================================
   26. 卡片圆角统一（全站唯一入口）
   --------------------------------------------------------------------------
   问题：卡片族里有人自己写了圆角 —— 学员卡 6px、快捷入口块 8px、日志卡手机端 8px、
        结果条与「我的」动作行用 7px（那是输入框的 --radius-sm），
        其余卡片是 10px（手机 12px）。同一屏里并排放着 6 / 7 / 8 / 10 / 12 五种圆角，
        看起来就像没做完。
   做法：卡片族一次性全部指向 --radius-card（桌面 = --radius 10px，手机 = 12px），
        以后新增卡片只认这一个令牌，不要再单独写死像素值。
   不在此列的：按钮（--radius-pill 胶囊）、输入框（--radius-sm）、
             弹窗与底部面板（--radius-lg）、纯圆形图标（--radius-pill）。
   ========================================================================== */

.card,
.stat,
.hero,
.public-bar,
.student-card,
.class-card,
.class-filter-row,
.log-card,
.locked-tip,
.searchbar,
.home-stat,
.core-card,
.quick-item,
.lesson-result,
.mine-action {
    border-radius: var(--radius-card);
}

/* ==========================================================================
   27. 列表页筛选：一个搜索框 + 一个胶囊「高级」按钮
   --------------------------------------------------------------------------
   上一版把状态胶囊摊在搜索框旁边，既挤又碎：搜索提示被截断、按钮大小不一。
   现在按系统级 App 的常规做法收敛成两件东西：
     · 搜索框：填充胶囊、无边框（输入区自己就是一颗胶囊）
     · 「高级」胶囊按钮：点开弹出筛选面板
   状态、排序以及各页自己的高级条件全部搬进面板里，
   列表页顶部因此只剩一行，且搜索框能用满整行宽度。
   ========================================================================== */

.filter-bar {
    position: sticky;
    top: calc(var(--topbar-h) + 6px);
    z-index: 30;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    padding: 6px 0;
    background: var(--bg);
}

/* 搜索栏退掉原来的容器边框与内边距：外框不再需要，输入区自己就是胶囊 */
.filter-bar > .searchbar {
    position: static;
    flex: 1 1 auto;
    min-width: 0;
    margin-bottom: 0;
    padding: 0;
    border: 0;
    background: transparent;
    z-index: auto;
}

/* 搜索框：填充色原先用 --surface-3，但它与页面底色 --bg-app 在亮色主题下几乎同色，
   外层容器去边框后就"看不见"这个输入框了。
   改为标准输入框的 --surface + 1px 描边：亮色是白底细边，暗色也依然分得开。 */
.filter-bar .searchbar-input {
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
}

.filter-bar .searchbar-input:focus-within {
    border-color: var(--primary);
    background: var(--surface);
    box-shadow: var(--ring);
}

/* 暗色主题沿用「越靠前越亮」的层次：搜索框用 --surface-3，比页面底色亮一档。
   显式写下来，避免依赖上面那条历史规则导致将来被误改。 */
html[data-theme="romance"] .filter-bar .searchbar-input {
    background: var(--surface-3);
}

html[data-theme="romance"] .filter-bar .searchbar-input:focus-within {
    background: var(--surface-2);
}

/* 输入区里的清除按钮：小圆形，不抢搜索框本身的视觉 */
.filter-bar .searchbar-input > .icon-btn {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--text-3);
    color: var(--surface);
}

.filter-bar .searchbar-input > .icon-btn > .ico {
    width: 12px;
    height: 12px;
}

/* 高级筛选入口：胶囊按钮，筛选生效时整颗点亮 */
.filter-adv-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    min-height: 40px;
    padding: 0 15px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--text-2);
    font-family: inherit;
    font-size: calc(13.5px * var(--jx-fs));
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s, transform .1s;
}

.filter-adv-btn:active {
    transform: scale(.97);
}

.filter-adv-btn.on {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
}

.filter-adv-btn .ico {
    flex: 0 0 auto;
}

/* 面板里的状态/排序分段：按内容宽度居中排布，不铺满整行 */
.sheet-body .seg-row {
    padding: 0;
    gap: 8px;
}

.sheet-body .seg-row .seg-pill {
    flex: 0 0 auto;
    min-width: 72px;
    padding: 0 14px;
}

@media (max-width: 767px) {
    .filter-bar {
        top: calc(var(--topbar-h) + 4px);
        gap: 8px;
        padding: 5px 0;
    }

    /* 触屏上搜索框与按钮都到 44px，拇指更容易命中 */
    .filter-bar .searchbar-input,
    .filter-adv-btn {
        min-height: 44px;
    }

    .filter-adv-btn {
        padding: 0 16px;
    }
}

/* 未核销提醒：将范围筛选和批量操作前置到列表上方。 */
.pending-tools {
    margin: 0 0 10px;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
}

.pending-tools-head,
.pending-batch-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.pending-tools-head {
    min-height: 20px;
    color: var(--text-2);
    font-size: calc(12.5px * var(--jx-fs));
    font-weight: 600;
}

.pending-tools-head > span:first-child,
.pending-batch-row > span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.pending-tools-note {
    min-width: 0;
    overflow: hidden;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    font-weight: 400;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pending-range-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 7px;
    margin-top: 10px;
}

.pending-range-tab {
    min-width: 0;
    min-height: 36px;
    padding: 0 8px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--text-2);
    font: inherit;
    font-size: calc(12.5px * var(--jx-fs));
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s, transform .1s;
}

.pending-range-tab:active { transform: scale(.97); }

.pending-range-tab.on {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-accent);
}

.pending-custom-range {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin-top: 10px;
}

.pending-date-field {
    display: flex;
    align-items: center;
    min-width: 0;
    min-height: 40px;
    padding: 0 9px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.pending-date-field > span {
    flex: 0 0 auto;
    margin-right: 6px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.pending-date-field > ui-date {
    min-width: 0;
    flex: 1 1 auto;
}

.pending-date-field .date-field {
    min-height: 38px;
    padding: 0;
    border: 0;
    background: transparent;
}

.pending-batch-row {
    justify-content: space-between;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
    color: var(--text-2);
    font-size: calc(12px * var(--jx-fs));
}

.pending-batch-row > span { min-width: 0; }
.pending-batch-row .btn { flex: 0 0 auto; }

@media (max-width: 767px) {
    .pending-tools { padding: 11px; }

    .pending-range-tabs {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 7px;
    }

    .pending-range-tab {
        min-height: 40px;
        padding: 0 6px;
    }

    .pending-custom-range { gap: 6px; }

    .pending-date-field {
        min-height: 42px;
        padding: 0 8px;
    }

    .pending-batch-row {
        align-items: flex-start;
        gap: 10px;
        font-size: calc(11.5px * var(--jx-fs));
    }

    .pending-batch-row .btn {
        min-height: 40px;
        padding: 0 10px;
    }
}

/* ==========================================================================
   26.1 平台端（机构管理 / 续期密钥）筛选条
   --------------------------------------------------------------------------
   卡片里的筛选条不用吸顶（卡片自己有标题栏，吸顶会在卡片中切出一条底色带），
   并且允许换行：大屏把「搜索 + 省 + 市 + 状态」内联，一行放得下就一行，
   放不下自动换第二行；条件多的页面在手机上收进「筛选」面板，筛选条只留一行。
   ========================================================================== */
.card-body > .filter-bar {
    position: static;
    z-index: auto;
    flex-wrap: wrap;
    row-gap: 8px;
    margin-bottom: 12px;
    padding: 0;
    background: transparent;
}

.card-body > .filter-bar > .searchbar {
    flex: 1 1 240px;
}

/* 内联条件组：省 / 市选择器 + 状态胶囊。
   不收缩（flex: 0 0 auto），否则会被搜索框挤到内部换行 —— 明明放得下却变两行。 */
.filter-inline {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

/* 选择器沿用固定宽度（min-width 决定内联组的内在宽度）。
   只写 flex-basis 不行：内在宽度会按「内容 + min-width」算，整组被压窄后
   状态胶囊就会被挤到第二行，明明一行放得下。 */
.filter-inline .select-wrap {
    flex: 0 0 148px;
    min-width: 148px;
}

/* 选择器与搜索框、状态胶囊同高，一行里顶端齐平 */
.filter-inline .select-field {
    min-height: 40px;
}

.filter-inline .seg-row {
    flex: 0 0 auto;
    padding: 0;
}

/* 状态胶囊按内容宽度排（.seg-pill 默认 flex:1 会被拉成等分整行的大按钮） */
.filter-inline .seg-pill {
    flex: 0 0 auto;
    min-height: 40px;
    padding: 0 14px;
}

/* 可收起：大屏不用面板，条件都内联 */
.filter-bar.is-collapsible > .filter-adv-btn {
    display: none;
}

@media (max-width: 767px) {
    /* 手机上搜索框先让位（基准给窄一点），保证「搜索 + 筛选」始终在同一行 */
    .card-body > .filter-bar > .searchbar {
        flex: 1 1 150px;
        min-width: 0;
    }

    .filter-inline .select-wrap {
        flex: 1 1 120px;
        min-width: 112px;
    }

    .filter-inline .select-field {
        min-height: 44px;
    }

    /* 手机端：条件收进面板，筛选条只有「搜索 + 筛选」一行 */
    .filter-bar.is-collapsible > .filter-inline {
        display: none;
    }

    .filter-bar.is-collapsible > .filter-adv-btn {
        display: inline-flex;
    }
}

/* ==========================================================================
   27.1 课时核销页：只用星期条切换
   --------------------------------------------------------------------------
   这一页原来对「日期」有三套入口（日期输入框、「高级」按钮、星期胶囊），
   点开的是同一个日期选择器；后面还跟一排看着能点、实际只读的统计胶囊。
   按用户要求整体去掉日期相关控件（日期条 + 日期选择弹层），
   本页只用星期条切换：点某天 = 跳到本周那天，点「全」回到今天。
   统计数字并入页头副标题，不再单独占一行。
   ========================================================================== */

/* 宽屏下星期条不再被拉成 7 个巨型胶囊，保持在「分段控件」的合理比例 */
@media (min-width: 1024px) {
    .week-row-weekday {
        max-width: 640px;
    }
}

/* ==========================================================================
   27.2 工具条：搜索框所在的横条，连同条内控件统一用胶囊
   --------------------------------------------------------------------------
   班级管理的「状态 + 搜索 + 搜索按钮」是一条工具条，
   原来一条里混了三种圆角：外框 10px、分段 18px、输入框 7px。
   这里把外框、分段、输入框、按钮全部收敛到 --radius-pill，
   让工具条整体读作「一条胶囊」，里面的控件是一颗颗小胶囊。
   （列表页顶部的 .filter-bar 搜索框在 27 节已经是胶囊，此处补齐同类工具条）
   ========================================================================== */

.class-filter-row {
    border-radius: var(--radius-pill);
    padding: 5px 10px;
    gap: 6px;
}

.class-status-tabs .seg-pill.sm {
    border-radius: var(--radius-pill);
    min-height: 34px;
}

.class-search-input {
    border-radius: var(--radius-pill);
    min-height: 34px;
    padding: 0 12px;
}

.class-search-btn {
    border-radius: var(--radius-pill);
    min-height: 34px;
}

/* 公告页的搜索条：同一套工具条语言 */
.searchbar {
    border-radius: var(--radius-pill);
    padding: 5px 6px;
}

.searchbar .searchbar-input {
    border-radius: var(--radius-pill);
}

.searchbar-actions {
    padding-right: 4px;
}

@media (max-width: 767px) {
    .class-filter-row {
        padding: 5px 10px;
    }

    .class-filter-row .class-search-input {
        min-height: 40px;
    }

    .class-filter-row .class-search-btn {
        min-height: 40px;
    }
}

/* 学员管理：状态常驻，排序与班级筛选收为一个小图标入口。 */
.student-filter-row {
    position: sticky;
    top: calc(var(--topbar-h) + 6px);
    z-index: 30;
    margin-bottom: 10px;
}

.student-filter-row .class-search-input {
    flex: 1 1 120px;
}

.student-filter-sort-btn {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-color: var(--line);
    background: var(--surface-2);
}

/* 学员页：查找与新增一行，状态、排序与班级筛选独立成行。 */
.student-control-bar {
    position: sticky;
    top: calc(var(--topbar-h) + 6px);
    z-index: 30;
    display: grid;
    gap: 6px;
    margin-bottom: 10px;
    padding: 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.student-search-row {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.student-search-row .student-search-input {
    flex: 1 1 160px;
    min-width: 0;
    min-height: 40px;
    padding: 0 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.student-search-submit {
    flex: 0 0 auto;
    min-height: 40px;
    padding: 0 11px;
}

.student-create-btn {
    flex: 0 0 auto;
    min-height: 40px;
    padding: 0 12px;
    white-space: nowrap;
}

.student-control-bar .student-filter-row {
    position: static;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.student-filter-select {
    min-width: 0;
}

.student-filter-select .select-field {
    min-height: 34px;
    padding: 0 8px;
    font-size: calc(12px * var(--jx-fs));
}

/* 学员状态与排序/班级选择同属一行筛选，统一为 34px 标准圆角控件。 */
.student-filter-row .class-status-tabs .seg-pill.sm {
    box-sizing: border-box;
    min-height: 34px;
    height: 34px;
    border-radius: var(--radius-sm);
}

@media (max-width: 767px) {
    .student-filter-row {
        top: calc(var(--topbar-h) + 4px);
        gap: 5px;
        padding: 5px;
    }

    .student-filter-row .class-status-tabs {
        gap: 2px;
    }

    .student-filter-row .class-status-tabs .seg-pill.sm {
        padding: 0 7px;
    }

    .student-filter-row .class-search-input {
        flex-basis: 86px;
        padding: 0 8px;
    }

    .student-filter-row .class-search-btn {
        padding: 0 8px;
    }

    .student-filter-sort-btn {
        width: 40px;
        height: 40px;
    }
}

@media (max-width: 767px) {
    /* 报表页四项是固定集合：等宽收紧并省略重复图标，保证一屏完整显示。 */
    .report-tabs {
        display: flex;
        gap: 4px;
        overflow-x: hidden;
        padding: 4px 0;
    }

    .report-tabs .subtab {
        flex: 1 1 0;
        min-width: 0;
        min-height: 36px;
        padding: 0 5px;
        font-size: calc(12px * var(--jx-fs));
        white-space: nowrap;
    }

    .report-tabs .subtab > .ico {
        display: none;
    }
}

.load-more {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    padding: 14px 0 4px;
}

/* 数据报表：一级为四项滑式页签，二级筛选保留普通按钮式分段。 */
.report-workspace { padding: 0; overflow: hidden; }
.report-workspace > .card-head { padding: 10px; }
.report-workspace-body { padding: 12px; }
/* 工作区自身是唯一的卡片容器，内部统计区统一降级为无框分区。 */
.report-workspace-body .card {
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    overflow: visible;
}
.report-workspace-body .card + .card { margin-top: 20px; }
/* 所有内层标题、数据列表与汇总脚注沿同一条内容基线排布。 */
.report-workspace-body .card-head {
    padding: 0 0 10px;
    border-bottom: 1px solid var(--line);
}
.report-workspace-body .card-foot {
    padding: 10px 0 0;
    border-top: 0;
    background: transparent;
}
.report-workspace-body .card-head + .list,
.report-workspace-body .card-head + .report-mobile-list,
.report-workspace-body .card-head + .table-wrap { margin-top: 0; }
.report-slide-tabs .slide-tabs-thumb { width: calc((100% - 2 * var(--st-pad) - 3 * var(--st-gap)) / 4); }
.report-group-buttons { padding-top: 0; }

@media (max-width: 767px) {
    .report-workspace > .card-head { padding: 8px; }
    .report-workspace-body { padding: 16px 14px; }
    .report-workspace-body .card + .card { margin-top: 18px; }
    .report-slide-tabs .slide-tabs-item { min-height: 36px; font-size: calc(12px * var(--jx-fs)); }
    /* 手机汇总行用分隔线组织信息，不再做一行一张小卡。 */
    .report-workspace .report-mobile-list { gap: 0; }
    .report-workspace .report-mobile-row {
        padding: 11px 0;
        border: 0;
        border-bottom: 1px solid var(--line);
        border-radius: 0;
        background: transparent;
    }
    .report-workspace .report-mobile-row:last-child { border-bottom: 0; }
    .report-workspace .report-mobile-total { border-color: var(--primary); background: transparent; }
}

/* ==========================================================================\n   营销活动与公开报名\n   ========================================================================== */
.marketing-switch {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    padding: 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    box-shadow: var(--shadow);
}
.marketing-switch .btn { margin-left: auto; }
.marketing-tabs-wrap {
    --st-pad: 3px;
    --st-gap: 3px;
    position: relative;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--st-gap);
    flex: 1 1 auto;
    max-width: none;
    padding: var(--st-pad);
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface-3);
}
.marketing-tabs-wrap::before {
    position: absolute;
    top: var(--st-pad);
    bottom: var(--st-pad);
    left: var(--st-pad);
    width: calc((100% - 2 * var(--st-pad) - var(--st-gap)) / 2);
    border-radius: 6px;
    background: var(--primary);
    content: "";
    transition: transform .2s cubic-bezier(.22, .61, .36, 1);
}
.marketing-tabs-wrap.forms::before { transform: translateX(calc(100% + var(--st-gap))); }
.marketing-tabs-wrap .seg-pill {
    position: relative;
    z-index: 1;
    min-height: 34px;
    padding: 0 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--text-2);
}
.marketing-tabs-wrap .seg-pill.on { background: transparent; color: var(--on-accent); }
.marketing-create {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 9px;
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
}
.marketing-create:hover { background: var(--btn-primary-bg); color: var(--btn-primary-fg); border-color: transparent; }
.marketing-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 16px;
    margin: 0 0 14px;
    padding: 2px 0;
}
.marketing-toolbar-copy { display: grid; min-width: 0; gap: 3px; }
.marketing-toolbar-copy strong { color: var(--text); font-size: calc(15px * var(--jx-fs)); }
.marketing-toolbar-copy span { overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.marketing-toolbar-actions { display: inline-flex; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; }
.marketing-primary-actions { display: inline-flex; flex: 0 0 auto; gap: 8px; }
.marketing-primary-actions .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 38px;
    padding: 0 15px;
    border-radius: 999px;
    white-space: nowrap;
}
.marketing-search {
    display: flex;
    align-items: center;
    min-width: min(280px, 42vw);
    height: 38px;
    gap: 6px;
    padding: 0 4px 0 12px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text-muted);
}
.marketing-search:focus-within { border-color: var(--primary); box-shadow: var(--ring); }
.marketing-search .input { flex: 1 1 0; min-width: 0; height: 34px; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.marketing-search .input:focus { box-shadow: none; }
.marketing-search .icon-btn { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 50%; background: var(--primary-light); color: var(--primary-text); }
.marketing-search .icon-btn:hover { border-color: var(--primary); background: var(--primary); color: var(--on-accent); }
.marketing-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.marketing-card {
    position: relative;
    min-width: 0;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    box-shadow: var(--shadow);
}
.marketing-card > img { display: block; width: 100%; height: 128px; object-fit: cover; background: var(--surface-2); }
.marketing-card-body { padding: 14px; }
.marketing-card-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: calc(16px * var(--jx-fs)); font-weight: 700; color: var(--text); }
.marketing-card-body > .text-muted { display: -webkit-box; min-height: 18px; margin-top: 4px; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-height: 1.45; }
.marketing-meta { display: flex; flex-wrap: wrap; gap: 6px 10px; margin-top: 10px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.activity-status { display: inline-flex; align-items: center; gap: 3px; border: 0; cursor: pointer; font-family: inherit; transition: filter .15s, opacity .15s; }
.activity-status-menu { position: relative; display: inline-flex; z-index: 3; }
.activity-status .ico { flex: 0 0 auto; }
.activity-status-popover { position: absolute; top: calc(100% + 6px); left: 0; display: grid; min-width: 88px; gap: 3px; padding: 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); box-shadow: var(--shadow-lg); }
.activity-status-popover button { min-height: 30px; padding: 0 9px; border: 0; border-radius: 5px; background: transparent; color: var(--text-2); font: inherit; font-size: calc(12px * var(--jx-fs)); text-align: left; cursor: pointer; }
.activity-status-popover button:hover { background: var(--hover); color: var(--text); }
.activity-status-popover button.on { background: var(--primary-light); color: var(--primary-text); font-weight: 700; }
.marketing-card:has(.activity-status-popover) { z-index: 5; overflow: visible; }
.activity-status.tag-line { border: 1px solid var(--line); }
.activity-status:hover:not([disabled]) { filter: brightness(.96); }
.activity-status[disabled] { opacity: .55; cursor: wait; }
.marketing-actions .icon-btn.danger,
.form-library-list .icon-btn.danger { color: var(--danger-text); }
.marketing-actions .icon-btn.danger:hover,
.form-library-list .icon-btn.danger:hover { border-color: var(--danger-text); background: var(--danger-light); }
.marketing-actions { display: flex; gap: 6px; margin-top: 12px; padding-top: 9px; border-top: 1px solid var(--line); }
.marketing-card.no-cover .marketing-card-body { padding: 15px; }
.form-library-workspace { min-width: 0; }
.form-library-tabs { width: min(100%, 360px); margin: 0 0 12px; }
.form-library-tabs .slide-tabs-item { min-height: 34px; font-size: calc(13px * var(--jx-fs)); }
@media (max-width: 767px) { .form-library-tabs { width: 100%; max-width: none; } }
.form-library-list { display: grid; gap: 10px; }
.form-library-card {
    display: grid;
    grid-template-columns: 42px minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    min-width: 0;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    box-shadow: var(--shadow);
    transition: border-color .15s, box-shadow .15s, transform .15s;
}
.form-library-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.form-library-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 8px;
    background: var(--primary-light);
    color: var(--primary-text);
}
.form-library-card-main { min-width: 0; }
.form-library-card-head { display: flex; align-items: center; gap: 7px; min-width: 0; }
.form-library-card-title { overflow: hidden; color: var(--text); font-size: calc(15px * var(--jx-fs)); font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.form-library-card-head .tag { flex: 0 0 auto; }
.form-library-card-description { margin: 3px 0 0; overflow: hidden; color: var(--text-2); font-size: calc(12.5px * var(--jx-fs)); line-height: 1.45; text-overflow: ellipsis; white-space: nowrap; }
.form-library-card-meta { display: flex; flex-wrap: wrap; gap: 5px 12px; margin-top: 8px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.form-library-card-meta span { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.form-library-card-actions { display: flex; align-items: center; gap: 6px; }
.form-library-card-actions .icon-btn.danger { color: var(--danger-text); }
.form-library-card-actions .icon-btn.danger:hover { border-color: var(--danger-text); background: var(--danger-light); }
.marketing-editor { width: min(760px, calc(100vw - 24px)); }
/* 新建入口先明确内容类型，再进入以预览为主的编辑器。 */
.marketing-create-menu { width: min(420px, calc(100vw - 32px)); }
.marketing-create-menu .modal-body { display: grid; gap: 10px; }
.marketing-create-option {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) 22px;
    width: 100%;
    align-items: center;
    gap: 10px;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    color: var(--primary-text);
    text-align: left;
    cursor: pointer;
}
.marketing-create-option:hover { border-color: var(--primary); background: var(--primary-light); }
.marketing-create-option > span { display: grid; gap: 3px; }
.marketing-create-option b { color: var(--text); font-size: calc(14px * var(--jx-fs)); }
.marketing-create-option small { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
/* 活动搭建器：每一个内容块都是可直接识别、可排序的页面单元。 */
.marketing-editor .modal-head { position: sticky; top: 0; z-index: 4; }
.marketing-editor .modal-body { background: var(--surface); }
.editor-section { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.editor-section-head > strong { color: var(--text); font-size: calc(14px * var(--jx-fs)); }
.block-editor { position: relative; padding: 14px; margin-top: 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); box-shadow: var(--shadow-lg); }
.marketing-editor .editor-section:has(.block-editor) { padding: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); }
.marketing-editor .editor-section:has(.block-editor) .editor-section-head { padding: 0 2px 10px; margin-bottom: 0; border-bottom: 1px solid var(--line); }
.marketing-editor .editor-section:has(.block-editor) .block-editor { margin: 0; padding: 14px 2px; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.marketing-editor .editor-section:has(.block-editor) .block-editor + .block-editor { border-top: 1px solid var(--line); }
.block-editor:hover { border-color: var(--line-strong); }
.block-tools { min-height: 30px; margin: 0 0 10px; padding-bottom: 9px; border-bottom: 1px solid var(--line); }
.block-tools b { font-size: calc(12px * var(--jx-fs)); font-weight: 700; letter-spacing: 0; text-transform: none; }
.form-field-row {
    grid-template-columns: 88px minmax(0, 1fr) minmax(136px, .8fr) auto auto 28px;
    align-items: center;
    gap: 7px;
    min-height: 48px;
    margin-top: 6px;
    padding: 8px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface-2);
}
.field-type-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    min-height: 28px;
    padding: 0 6px;
    border-radius: 7px;
    background: var(--surface);
    color: var(--primary-text);
    font-size: calc(12px * var(--jx-fs));
    font-weight: 700;
    white-space: nowrap;
}
.field-type-badge .ico { flex: 0 0 auto; }
.form-field-row > label {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 30px;
    padding: 0 9px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text-2);
    font-size: calc(13px * var(--jx-fs));
    white-space: nowrap;
}
.form-field-row > label input { width: 15px; height: 15px; margin: 0; accent-color: var(--primary); }
.field-row-actions { display: inline-flex; gap: 4px; justify-self: end; }
.field-row-actions .icon-btn.sm { width: 28px; height: 28px; border-radius: 7px; }
.form-field-row .textarea { grid-column: 2 / 4; }
.form-field-row .textarea ~ .field-row-actions { grid-column: auto; }
.marketing-editor .modal-foot { position: sticky; bottom: 0; z-index: 3; margin: 0 -18px -18px; padding: 12px 18px calc(12px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); background: var(--surface); }
.editor-section-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.btn-row.marketing-tool-row { flex-wrap: nowrap; overflow-x: auto; max-width: 100%; padding: 1px; scrollbar-width: none; }
.btn-row.marketing-tool-row::-webkit-scrollbar { display: none; }
.marketing-tool-btn {
    flex: 0 0 54px;
    width: 54px;
    height: 54px;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text-2);
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s, transform .1s;
}
.marketing-tool-btn::after { content: attr(title); font-size: 10px; line-height: 1; white-space: nowrap; }
.marketing-tool-btn:hover { border-color: var(--primary); background: var(--primary-light); color: var(--primary-text); }
.marketing-tool-btn:active { transform: scale(.96); }
.btn-row { display: flex; flex-wrap: wrap; gap: 5px; }
.block-editor { padding: 10px; margin-top: 8px; border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--surface-2); }
.block-tools { display: flex; align-items: center; gap: 4px; margin-bottom: 8px; }
.block-tools b { flex: 1; font-size: calc(12px * var(--jx-fs)); color: var(--text-2); text-transform: uppercase; }
.block-image-tools { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 0 0 10px; }
.block-image-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.block-image-pair .file-pick { justify-content: center; }
.block-image-preview { display: block; width: 72px; height: 56px; border: 1px solid var(--line); border-radius: 6px; object-fit: cover; background: var(--surface); }
/* 单图已上传时，文件选择标签覆盖预览图，直接点图片即可更换。 */
.block-image-tools .file-pick:has(+ .block-image-preview) {
    position: relative;
    z-index: 1;
    width: 72px;
    min-width: 72px;
    height: 56px;
    min-height: 56px;
    margin-right: -80px;
    padding: 0;
    border: 0;
    opacity: 0;
}
.block-image-tools .file-pick:has(+ .block-image-preview) + .block-image-preview {
    cursor: pointer;
}
.block-banner-list { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
.block-banner-list > span { position: relative; display: block; }
.block-banner-list .block-image-preview { width: 96px; height: 64px; }
.block-banner-list .icon-btn { position: absolute; top: -6px; right: -6px; width: 24px; height: 24px; border-radius: 7px; background: var(--surface); border-color: var(--line); }
.file-pick { display: inline-flex; align-items: center; min-height: 36px; padding: 0 10px; border: 1px dashed var(--line-strong); border-radius: var(--radius-card); color: var(--primary-text); cursor: pointer; }
.file-pick input { display: none; }
.field-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .9fr) auto 32px; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.field-row:last-child { border-bottom: 0; }
.field-row-textarea { min-height: 78px; resize: vertical; }
.public-choice { display: flex; flex-wrap: wrap; gap: 8px 14px; padding: 8px 0; }
.public-choice label { display: inline-flex; align-items: center; gap: 5px; min-height: 28px; color: var(--text-2); }
.public-choice input { width: 16px; height: 16px; accent-color: var(--primary); }
.public-upload { display: inline-flex; align-items: center; min-height: 38px; padding: 0 12px; border: 1px dashed var(--primary); border-radius: var(--radius-card); color: var(--primary-text); cursor: pointer; }
.public-upload input { display: none; }
/* 独立公开活动页：不继承后台卡片风格，采用轻量活动落地页的内容流。 */
html:has(.activity-page),
body:has(.activity-page),
.public-shell:has(.activity-page) { background: var(--bg-app); color-scheme: inherit; }
.public-shell:has(.activity-page) > div { padding: 0; }
.public-activity { width: 100%; max-width: none; margin: 0; padding: 0 0 64px; color: var(--text); font-family: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; }
.activity-page { width: min(100%, 920px); margin: 0 auto; padding: 20px 20px 72px; }
.activity-sitebar { display: flex; align-items: center; justify-content: space-between; min-height: 52px; margin: 0 auto 14px; color: var(--primary-text); }
.activity-sitebar > span { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 800; }
.activity-sitebar > span .ico { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border-radius: 9px; background: var(--surface-2); }
.activity-share { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--primary-text); box-shadow: var(--shadow); cursor: pointer; }
.activity-share:hover { background: var(--hover); }
.public-hero { position: relative; display: flex; align-items: end; min-height: 368px; padding: 28px; border: 0; border-radius: 18px; color: var(--on-accent); background: var(--grad-brand); background-size: cover; background-position: center; overflow: hidden; box-shadow: var(--shadow-lg); }
.public-hero::before { position: absolute; inset: 0; background: var(--hero-overlay); content: ""; }
.public-hero::after { position: absolute; top: -92px; right: -52px; width: 240px; height: 240px; border: 1px solid var(--hero-tile-line); border-radius: 50%; box-shadow: 0 0 0 34px var(--hero-tile-bg), 0 0 0 68px var(--hero-tile-bg); content: ""; }
.activity-hero-copy { position: relative; z-index: 1; width: min(100%, 640px); padding: 0; border: 0; border-radius: 0; background: transparent; }
.activity-eyebrow { display: inline-flex; align-items: center; min-height: 26px; padding: 0 10px; border: 1px solid var(--hero-tile-line); border-radius: 999px; background: var(--hero-tile-bg); color: var(--on-accent); font-size: 12px; font-weight: 700; }
.public-hero h1 { margin: 12px 0 0; font-size: clamp(28px, 4vw, 44px); font-weight: 800; line-height: 1.18; letter-spacing: 0; }
.public-hero p { max-width: 540px; margin: 12px 0 0; color: var(--hero-fg-muted); font-size: 15px; line-height: 1.7; }
.public-block { margin-top: 20px; padding: 28px; border: 0; border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); }
.activity-section-text { border-left: 4px solid var(--primary); }
.public-block h2 { margin: 0 0 12px; color: var(--primary-text); font-size: 21px; font-weight: 800; line-height: 1.35; }
.public-copy { margin: 0; color: var(--text-2); font-size: 15px; line-height: 1.9; white-space: pre-wrap; }
.activity-section-image, .activity-section-two_image { padding: 8px; overflow: hidden; }
.public-block > img { display: block; width: 100%; max-height: 680px; border-radius: 10px; object-fit: cover; }
.public-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.public-two img { width: 100%; aspect-ratio: 1 / .8; object-fit: cover; border-radius: 10px; }
.activity-section-banner { position: relative; padding: 0; overflow: hidden; }
.public-banner { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface-2); }
.public-banner img { display: none; width: 100%; height: 100%; object-fit: cover; }
.public-banner img.active { display: block; }
.public-banner-dots { position: absolute; right: 0; bottom: 10px; left: 0; z-index: 1; display: flex; justify-content: center; gap: 6px; }
.public-banner-dot { width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%; background: var(--activity-control-dot); cursor: pointer; }
.public-banner-dot.active { width: 18px; border-radius: 4px; background: var(--activity-control-active); }
.activity-section-form { padding: 30px; border: 1px solid var(--line); background: var(--surface-2); scroll-margin-top: 18px; }
.public-form > p { margin: -4px 0 20px; color: var(--text-muted); font-size: 14px; line-height: 1.65; }
.public-form .field { margin-top: 14px; }
.public-form .field-label { color: var(--text); font-weight: 700; }
.public-form .input, .public-form .textarea, .public-form .ui-select-trigger { border-color: var(--line); background: var(--surface); }
.public-choice { gap: 9px 16px; padding: 6px 0; }
.public-choice label { min-height: 36px; color: var(--text-2); }
.public-upload { min-height: 42px; border-color: var(--primary); border-radius: 8px; background: var(--surface); color: var(--primary-text); }
.public-success { min-height: 200px; justify-content: center; color: var(--primary-text); }
.public-success span { color: var(--text-muted); }
.activity-signup-float { position: fixed; right: max(22px, env(safe-area-inset-right)); bottom: max(22px, env(safe-area-inset-bottom)); z-index: 60; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 0 20px; border: 0; border-radius: 999px; background: var(--primary); color: var(--on-accent); box-shadow: var(--shadow-lg); font-family: inherit; font-size: 14px; font-weight: 800; cursor: pointer; }
.activity-signup-float:hover { background: var(--primary-dark); transform: translateY(-1px); }
.activity-signup-float:active { transform: translateY(0); }
.activity-signup-mask { position: fixed; inset: 0; z-index: 70; display: flex; align-items: flex-end; justify-content: center; background: var(--overlay); }
.activity-signup-dialog { display: flex; flex-direction: column; width: 100%; max-width: 560px; max-height: 92vh; overflow: hidden; border-radius: 16px 16px 0 0; background: var(--glass-panel); -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%); backdrop-filter: blur(var(--glass-blur)) saturate(150%); }
.activity-signup-head { position: relative; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--side-line); background: var(--primary); color: var(--on-accent); }
.activity-signup-head span { display: block; color: var(--side-fg-2); font-size: calc(12px * var(--jx-fs)); font-weight: 600; }
.activity-signup-head h2 { margin: 2px 0 0; color: currentColor; font-size: calc(15px * var(--jx-fs)); line-height: 1.35; }
.activity-signup-head .icon-btn { color: var(--side-fg-2); }
.activity-signup-head .icon-btn:hover, .activity-signup-head .icon-btn:active { border-color: transparent; background: var(--side-hover); color: var(--side-fg); }
.activity-signup-body { flex: 1; padding: 16px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.activity-signup-body .field { margin-top: 16px; }
.activity-signup-body .field-label { color: var(--text); font-weight: 700; }
.activity-signup-body .input, .activity-signup-body .textarea, .activity-signup-body .ui-select-trigger { border-color: var(--line); background: var(--surface); }
.activity-signup-submit { width: 100%; min-height: 44px; margin-top: 22px; border-radius: var(--radius); }
@media (min-width: 560px) { .activity-signup-mask { align-items: center; } .activity-signup-dialog { max-height: 86vh; border-radius: 16px; } }
@media (max-width: 559px) { .activity-signup-body { padding: 16px 16px calc(16px + env(safe-area-inset-bottom)); } }
@media (max-width: 767px) {
    .public-activity { padding-bottom: 76px; }
    .activity-page { padding: 12px 12px 84px; }
    .activity-sitebar { min-height: 46px; margin-bottom: 8px; }
    .public-hero { min-height: min(62vh, 430px); padding: 20px; border-radius: 14px; }
    .public-hero h1 { font-size: 30px; }
    .public-hero p { font-size: 14px; }
    .public-block { margin-top: 14px; padding: 22px 18px; border-radius: 12px; }
    .activity-section-image, .activity-section-two_image { padding: 6px; }
    .public-two { gap: 6px; }
    .public-two img { border-radius: 8px; }
    .activity-section-form { padding: 24px 18px; }
    .activity-signup-float { right: 16px; bottom: max(16px, env(safe-area-inset-bottom)); min-height: 46px; padding: 0 18px; }
}
/* 新建与编辑活动是独立工作区，不使用对话框遮罩；组件属性仍使用标准弹窗。 */
.modal-mask:has(.activity-page-editor) { align-items: stretch; background: var(--bg); }
.activity-page-editor { width: 100%; height: 100dvh; max-width: none; max-height: none; border-radius: 0; }
.activity-page-editor .modal-head { flex: 0 0 auto; }
.activity-page-editor .modal-body { min-height: 0; }
@media (max-width: 767px) {
    .modal-mask:has(.activity-page-editor) { padding-bottom: env(safe-area-inset-bottom); }
    .activity-page-editor { width: 100%; height: 100dvh; max-width: none; max-height: none; border-radius: 0; }
}
@media (max-width: 767px) {
    .marketing-editor.activity-page-editor .modal-foot {
        position: static;
        flex: 0 0 auto;
        margin: 0;
        padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
        gap: 8px;
    }
    .marketing-grid { grid-template-columns: 1fr; }
    .marketing-card { display: grid; grid-template-columns: 96px minmax(0, 1fr); }
    .marketing-card.no-cover { display: block; }
    .marketing-card > img { height: 100%; min-height: 120px; }
    .form-library-card { grid-template-columns: 38px minmax(0, 1fr); gap: 10px; padding: 12px; }
    .form-library-card-icon { width: 38px; height: 38px; }
    .form-library-card-actions { grid-column: 2; justify-content: flex-end; margin-top: -2px; }
    .form-library-card-description { white-space: normal; }
    .form-library-card-meta { gap: 4px 10px; margin-top: 7px; }
    .form-library-card:hover { transform: none; }
    .marketing-editor .modal-body { padding: 14px; }
    .editor-section-head { align-items: flex-start; flex-direction: column; }
    .field-row { grid-template-columns: minmax(0, 1fr) auto 32px; }
    .field-row .input:nth-child(2) { grid-column: 1 / -1; }
    .form-field-row {
        grid-template-columns: 28px minmax(60px, 1fr) auto repeat(3, 26px);
        align-items: center;
        gap: 5px;
        min-height: 42px;
        margin-top: 5px;
        padding: 6px;
        border-radius: 9px;
    }
    .form-field-row > .field-type-badge {
        grid-column: 1;
        grid-row: 1;
        width: 28px;
        min-height: 28px;
        justify-content: center;
        padding: 0;
        font-size: 0;
    }
    .form-field-row > .field-type-badge .ico { width: 15px; height: 15px; }
    .form-field-row > .input { grid-column: 2; grid-row: 1; min-width: 0; }
    .form-field-row > .input + .input { grid-column: 2 / -1; grid-row: 2; }
    .form-field-row > .textarea { grid-column: 2 / -1; grid-row: 2; }
    .form-field-row > label { grid-column: 3; grid-row: 1; min-height: 28px; padding: 0 7px; font-size: 12px; }
    .form-field-row > .field-row-actions { grid-column: 4 / -1; grid-row: 1; gap: 2px; }
    .form-field-row > .icon-btn { grid-row: 1; width: 26px; height: 26px; padding: 0; border-radius: 7px; }
    .form-field-row > .icon-btn:nth-last-child(3) { grid-column: 4; }
    .form-field-row > .icon-btn:nth-last-child(2) { grid-column: 5; }
    .form-field-row > .icon-btn:last-child { grid-column: 6; }
    .field-row-actions .icon-btn.sm { width: 26px; height: 26px; border-radius: 7px; }
    .marketing-tool-btn { flex-basis: 52px; width: 52px; height: 52px; }
}

/* 管理端头像：统一预览尺寸，图片不撑高卡片。 */
.student-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.avatar-upload { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 4px 10px 4px 4px; border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--surface); color: var(--text-2); cursor: pointer; }
.avatar-upload img, .avatar-upload > span { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; object-fit: cover; background: var(--surface-2); }
.avatar-upload b { font-size: calc(13px * var(--jx-fs)); font-weight: 600; }
.avatar-upload input { display: none; }

/* ==========================================================================
   28. 左侧菜单间距 + 三类卡片四列（电脑 / iPad）
   ========================================================================== */

/* ---- 左侧菜单（电脑与 iPad）：条目 padding 7px 12px，条目之间 1px ----
   用 .nav-group 的 gap 控制间距，而不是给 .nav-item 加 margin：
   margin 会在相邻条目之间发生折叠，写 4px 实际只有 4px 而不是 8px。
   竖向 padding 从 3px 提到 7px 后条目更高，点击/悬停区域更好按；
   条目之间只留 1px，整列读起来是一条连续的列表，而不是一张张飘着的小卡片。 */
@media (min-width: 768px) {
    .nav-group {
        display: flex;
        flex-direction: column;
        gap: 1px;
    }

    .nav-item {
        padding: 7px 12px;
    }
}

@media (max-width: 767px) {
    /* 手机抽屉：行与行直接相接（不额外加缝），整块更紧凑 */
    .nav-group {
        display: flex;
        flex-direction: column;
        gap: 0;
    }

    /* 竖向间距统一交给 gap，条目自身只保留左右内缩，避免两种间距叠加 */
    .drawer-panel .nav-item {
        margin: 0 6px;
    }
}

/* ---- 班级 / 学员 / 老师卡：电脑与 iPad 四列，手机单列 ---- */
@media (min-width: 768px) {
    .student-card-grid,
    .class-card-list,
    .teacher-card-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    .student-card-grid,
    .class-card-list,
    .teacher-card-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---- 老师卡：与学员卡同一套观感（头像 + 姓名 + 状态 + 底部通栏动作） ---- */
.teacher-card-grid {
    display: grid;
    gap: 8px;
}

.teacher-card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    transition: background .12s, border-color .12s;
}

.teacher-card:hover {
    border-color: var(--primary);
    background: var(--surface-2);
}

.teacher-card-tools {
    position: absolute;
    top: 7px;
    right: 7px;
    z-index: 1;
    display: flex;
    gap: 2px;
}

.teacher-card-tools .icon-btn.sm {
    width: 28px;
    height: 28px;
}

.teacher-card > .student-card-head {
    padding-right: 60px;
}

.teacher-card.is-inactive {
    opacity: .7;
}

.teacher-card-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-top: 7px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.teacher-card-body > span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.teacher-card-classes {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 8px;
}

.teacher-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px solid var(--line);
}

/* ==========================================================================
   29. 卡片在窄列下的自适应（四列布局的配套修复）
   --------------------------------------------------------------------------
   四列后每张卡只有 180~290px，之前按宽卡写的内部排版会出问题：
   · 状态标签「在读」被折成上下两行  → .tag 补 white-space: nowrap
   · 班级名被挤成「钢琴…」            → 班级名放不下时，让状态标签换到第二行
   · 学员卡的「1 个班」「剩余课时」被切 → 允许身份行与页脚换行
   ========================================================================== */

/* 标签是整体语义，任何宽度下都不该断成两行 */
.tag {
    white-space: nowrap;
}

/* 班级卡：宽度够时保持一行；不够时状态标签整块换到第二行，班级名用满整行 */
.class-card-title {
    flex-wrap: wrap;
}

.class-card-name {
    flex: 1 1 auto;
}

/* 学员卡：窄列下把信息换行显示，而不是压缩后截断 */
.student-name-line,
.student-meta-line,
.student-card-foot,
.teacher-card-foot {
    flex-wrap: wrap;
    row-gap: 4px;
}

.student-card-date {
    flex: 1 1 auto;
}

.student-class-summary {
    flex: 0 1 auto;
    max-width: 100%;
}

/* --------------------------------------------------------------------------
   触控下限补漏（iPad / 平板宽度）
   · 排序三分段的高度规则原先只写在 max-width:480px 里，
     导致 481-1023px（含 iPad）一直是 30px，低于本项目 40px 的分段控件下限。
   · 顶栏面包屑在 >480px 时只有 16px 高，平板上点不准。
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
    .student-sort {
        min-height: 40px;
    }

    .student-sort-btn {
        height: 40px;
    }

    .topbar-crumb {
        display: inline-flex;
        align-items: center;
        min-height: 40px;
    }

    .topbar-user {
        min-height: 44px;
    }
}

/* ==========================================================================
   31. 学员入口：绑定码卡片（二维码 + 多列 + 停用/删除）
   --------------------------------------------------------------------------
   这张卡片的三个诉求都来自实际使用：
     · 二维码：原来只在「生成」弹窗里画过一次，关掉就没了；家长再要一张只能重新生成，
       所以列表里必须每张码都自带二维码，随时可以截图发出去。
     · 停用 / 删除：写错备注或发错班级时要能收拾掉。
       已被家长用过的码只允许停用（历史绑定要能追溯来源），从未用过的才允许删除。
     · 多列：电脑与 iPad 一行放多张，手机单列。
   ========================================================================== */

.code-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 10px;
}

.code-card {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 12px;
    min-width: 0;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
}

/* 已停用的码整张弱化，一眼能和生效中的区分开 */
.code-card.is-off {
    opacity: .62;
}

/* 二维码必须白底：暗色主题下也要保持可扫（令牌在两套主题下同值） */
.code-card-qr {
    flex: 0 0 auto;
    padding: 6px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--qr-bg);
    line-height: 0;
}

.code-card-qr canvas {
    display: block;
}

.code-card-main {
    flex: 1 1 140px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.code-card-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
}

.code-card-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: calc(14.5px * var(--jx-fs));
    font-weight: 700;
}

.code-card-tags {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}

.code-card-meta {
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.4;
}

.code-card-actions {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
}

.code-card-actions .btn {
    flex: 0 0 auto;
}

/* 删除：低强调但语义明确；被用过时禁用并提示改用「停用」 */
.code-del {
    background: transparent;
    border-color: var(--line);
    color: var(--danger-text);
}

.code-del:hover:not([disabled]) {
    background: var(--danger-light);
}

@media (max-width: 767px) {
    .code-card-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* 手机：二维码与信息并排，动作按钮铺满一行更好点 */
    .code-card-actions .btn {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* ===========================================================================
   30. 教务对象卡片：课时 / 班级 / 学员 / 老师
   ---------------------------------------------------------------------------
   以微信与小程序的列表单元为参照：先识别对象，再扫读关键信息，最后进入操作。
   所有业务状态仍用原有语义色；这里仅统一表面、留白、分隔与触控反馈。
   =========================================================================== */

/* 所有可进入详情的对象卡片，统一使用平面反馈，不做上浮或缩放。 */
.student-card,
.class-card,
.teacher-card,
.lesson-card {
    box-shadow: none;
}

.student-card:active,
.class-card:active,
.teacher-card:active,
.lesson-card:active {
    transform: none;
    background: var(--hover);
}

@media (hover: hover) {
    .student-card:hover,
    .class-card:hover,
    .teacher-card:hover,
    .lesson-card:hover {
        border-color: var(--line-2);
        background: var(--surface-2);
    }
}

/* 班级：上方身份、中央两列信息、底部教师归属，避免信息都变成胶囊。 */
.class-card-list {
    gap: 12px;
}

.class-card {
    padding: 0;
    overflow: hidden;
    border-radius: var(--radius-card);
}

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

.class-card-title {
    gap: 10px;
}

.class-card-mark {
    width: 36px;
    height: 36px;
    border: 1px solid var(--line);
    border-radius: 10px;
}

.class-card-name {
    font-size: calc(16px * var(--jx-fs));
    line-height: 1.35;
}

.class-card-meta {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px 10px;
    margin-top: 0;
    padding: 0 14px 13px;
}

.class-meta {
    min-width: 0;
    padding: 0;
    border-radius: 0;
    background: transparent;
    color: var(--text-2);
    font-size: calc(12px * var(--jx-fs));
    overflow: hidden;
    text-overflow: ellipsis;
}

.class-meta.is-key {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 100%;
    color: var(--highlight-blue);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.class-meta.is-key .ico {
    flex: 0 0 auto;
}

.class-card-foot {
    align-items: center;
    min-height: 46px;
    margin-top: 0;
    padding: 9px 14px;
    background: var(--surface-2);
}

.class-card-teachers {
    align-items: center;
}

.class-teacher {
    padding: 3px 7px;
    border: 1px solid var(--line);
    background: var(--surface);
}

/* 学员：以头像 + 姓名 + 课时余额作为一眼可读的主次关系。 */
.student-card-grid {
    grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
    gap: 12px;
}

.student-card {
    padding: 0;
    overflow: hidden;
    border-radius: var(--radius-card);
}

.student-card-head {
    min-height: 72px;
    padding: 14px;
    gap: 11px;
}

.student-avatar {
    flex-basis: 42px;
    width: 42px;
    height: 42px;
    border-color: var(--line-2);
    font-size: calc(17px * var(--jx-fs));
}

.student-identity {
    gap: 5px;
}

.student-name {
    font-size: calc(16px * var(--jx-fs));
    line-height: 1.3;
}

.student-class-summary {
    max-width: 132px;
    padding: 2px 6px;
    background: var(--surface-2);
}

.student-card-foot {
    min-height: 48px;
    margin-top: 0;
    padding: 8px 14px;
    background: var(--surface-2);
}

.student-card .student-balance {
    color: var(--highlight-green);
}

.student-card .student-balance.text-ok {
    color: var(--highlight-green);
}

.student-card .student-balance.text-danger {
    color: var(--highlight-red);
}

.student-card .student-balance strong {
    font-size: calc(19px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
}

.student-card-date {
    font-size: calc(11.5px * var(--jx-fs));
}

/* 老师：沿用相同身份头部；低频账号信息缩为清晰的两行，操作固定在底栏。 */
.teacher-card-grid {
    gap: 12px;
}

.teacher-card {
    padding: 0;
    overflow: hidden;
    border-radius: var(--radius-card);
}

.teacher-card > .student-card-head {
    min-height: 72px;
    padding: 14px 14px 10px;
}

.teacher-card-body {
    gap: 5px;
    margin-top: 0;
    padding: 0 14px 10px;
    font-size: calc(12px * var(--jx-fs));
}

.teacher-card-classes {
    min-height: 34px;
    margin-top: 0;
    padding: 8px 14px 10px;
    border-top: 1px solid var(--line);
}

.teacher-card > .text-muted.fs12.mt8 {
    min-height: 34px;
    margin: 0;
    padding: 8px 14px 10px;
    border-top: 1px solid var(--line);
}

.teacher-card-foot {
    min-height: 50px;
    margin-top: auto;
    padding: 8px 10px 8px 14px;
    background: var(--surface-2);
}

.teacher-card.is-inactive {
    opacity: 1;
}

.teacher-card.is-inactive .student-avatar {
    border-color: var(--danger);
    color: var(--danger-text);
    background: var(--danger-light);
}

/* 核销：竖排信息卡 —— 状态与时间是第一眼信息，班级名是标题。 */
.lesson-grid {
    align-items: start;
    gap: 12px;
}

.lesson-card {
    display: block;
    min-width: 0;
    padding: 0;
    overflow: hidden;
    border-left-width: 5px;
    border-radius: var(--radius-card);
}

.lesson-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 13px 14px 12px;
}

.lesson-card-head {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
}

.lesson-title {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    font-size: calc(16.5px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 类别标签紧跟在班级名后面，括号形式，弱化处理 */
.lesson-course {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    margin: 0;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lesson-state-badge {
    flex: 0 0 auto;
    margin-left: auto;
    min-height: 26px;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    font-size: calc(12.5px * var(--jx-fs));
    font-weight: 700;
    line-height: 18px;
    letter-spacing: .3px;
}

.lesson-card.lesson-pending .lesson-state-badge {
    border: 1px solid var(--primary);
    background: var(--primary);
    color: var(--on-accent);
}

.lesson-card.lesson-overdue .lesson-state-badge {
    border: 1px solid var(--danger);
    background: var(--danger);
    color: var(--on-accent);
}

.lesson-card.lesson-done .lesson-state-badge {
    border: 1px solid var(--ok);
}

.lesson-card.lesson-skipped .lesson-state-badge {
    border: 1px solid var(--warn);
}

/* 时间只留图标，不再有「时间」二字。
   时间是这类卡片的第一眼信息，用主色高亮（亮色 = 品牌绿，暗色 = 品牌紫粉），
   图标与文字同色 —— 这是主题规范里「文字/图标用 --primary-text」那一档，
   两套主题各自的对比度都 > 5:1，不需要为暗色单独覆盖。 */
.lesson-time-row {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    color: var(--primary-text);
    font-size: calc(15px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.35;
    font-variant-numeric: tabular-nums;
}

/* 原来把图标单独压成弱化灰，会把高亮从图标处切断；现在跟随时间文字同色 */
.lesson-time-row .ico {
    flex: 0 0 auto;
    color: inherit;
}

.lesson-time-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 老师 / 学员 / 教室：带标签，两端分散 */
.lesson-meta-row {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    color: var(--text);
    font-size: calc(12.5px * var(--jx-fs));
    font-weight: 500;
    line-height: 1.4;
}

.lesson-meta-item {
    display: inline-flex;
    align-items: center;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lesson-meta-item:first-child {
    flex: 0 1 auto;
}

.lesson-meta-count {
    flex: 0 0 auto;
}

.lesson-meta-room {
    flex: 0 1 auto;
    margin-left: auto;
}

.lesson-meta-label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-weight: 400;
}

.lesson-meta {
    gap: 7px 12px;
    margin-top: 10px;
}

.lesson-result {
    margin-top: 11px;
    padding: 8px 10px;
}

.lesson-action {
    min-height: 45px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
}

.lesson-action .btn {
    min-height: 38px;
}

@media (max-width: 767px) {
    .class-card-meta {
        gap: 8px;
    }

    .class-card-head {
        padding: 13px 13px 10px;
    }

    .class-card-meta {
        padding: 0 13px 12px;
    }

    .class-card-foot {
        padding-right: 13px;
        padding-left: 13px;
    }

    .student-card-head {
        min-height: 74px;
        padding: 13px;
    }

    .student-card-foot {
        padding-right: 13px;
        padding-left: 13px;
    }

    .teacher-card > .student-card-head,
    .teacher-card-body {
        padding-right: 13px;
        padding-left: 13px;
    }

    .teacher-card-classes,
    .teacher-card > .text-muted.fs12.mt8 {
        padding-right: 13px;
        padding-left: 13px;
    }

    .lesson-body {
        gap: 7px;
        padding: 12px 13px 11px;
    }

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

    .lesson-state-badge {
        min-height: 24px;
        padding: 2px 9px;
        font-size: calc(12px * var(--jx-fs));
        line-height: 18px;
    }

    .lesson-time-row {
        font-size: calc(14.5px * var(--jx-fs));
    }

    .lesson-meta-row {
        gap: 8px;
        font-size: calc(12px * var(--jx-fs));
    }

    .class-status-tabs .seg-pill.sm {
        min-height: 40px;
    }
}

/* ==========================================================================
   28. 手机端字号（小 / 中 / 大）—— 只缩放文字，不缩放页面
   --------------------------------------------------------------------------
   顶栏主题按钮左侧的小 / 中 / 大三个按钮改的是 <html data-font>；
   本文件里所有 font-size 都写成 calc(<原值>px * var(--jx-fs))，
   于是 --jx-fs 一改，全站文字一起变，而盒模型尺寸、图标、间距、
   固定定位（底栏 / 抽屉 / 弹层）与滚动逻辑完全不动。
   为什么不用整页 zoom：zoom 会重新定义视口宽度（相当于把 360px 手机压成
   310px 的布局），还会影响固定定位与滚动计算，风险远大于收益。
   档位：sm = 1（原有字号）/ md = 1.08 / lg = 1.16；只在 <=1023px 生效，
   桌面保持原字号（也不显示入口）。详见 docs/界面与主题规范.md §2.2。
   ========================================================================== */

@media (max-width: 1023px) {
    html[data-font="md"] {
        --jx-fs: 1.08;
        --jx-fs-sub: 1.08;
    }

    html[data-font="lg"] {
        --jx-fs: 1.16;
        /* 搜索框 / 菜单只升到「中」档：它们的基准字号已经偏大，再乘 1.16 会失真 */
        --jx-fs-sub: 1.08;
    }
}

/* 宽度已经顶到边的行不参与放大：星期筛选在手机上一行 8 项等分，
   再放大会把「周一」挤出胶囊。自定义属性会被后代继承，所以在这里把
   --jx-fs 固定回 1 即可，不需要重写任何一条字号。 */
@media (max-width: 767px) {
    .week-row-weekday {
        --jx-fs: 1;
    }
}

/* --------------------------------------------------------------------------
   28.1 顶栏字号入口（一个图标按钮 + 点开的字号面板）
   · 只在手机 / 平板显示（<=1023px）：桌面没有这个需求，也不去动桌面字号
   · 顶栏只占一个图标位（与主题按钮同宽 36px）：三个档位收进底部面板，
     点选或左右拖动切换；当前档位在面板里高亮，按钮 title 也写明
   -------------------------------------------------------------------------- */
.topbar-font {
    display: none;
    align-items: center;
    justify-content: center;
    width: 36px;
    min-width: 36px;
    min-height: 36px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--nav-fg);
    line-height: 1;
    opacity: .86;
    cursor: pointer;
    transition: background .15s, opacity .15s;
}

/* 与主题按钮同一套悬停 / 聚焦反馈：只提亮，不加底块 */
.topbar-font:hover,
.topbar-font:focus-visible {
    background: transparent;
    opacity: 1;
}

.topbar-font:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

@media (max-width: 1023px) {
    .topbar-font {
        display: inline-flex;
        min-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   28.2 字号面板里的三档滑轨（等分三段，当前档位实底高亮）
   · 三档标签自带字号差，一眼看出「小 / 中 / 大」的区别
   · 横向滑动由 app.js 的 pointerdown / pointerup 处理，纵向仍可拖动面板
   -------------------------------------------------------------------------- */
.font-scale {
    display: flex;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    touch-action: pan-y;
    user-select: none;
}

.font-scale-item {
    flex: 1 1 0;
    min-width: 0;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-2);
    font-family: inherit;
    cursor: pointer;
    transition: background .15s, color .15s;
}

.font-scale-item.lv-sm {
    font-size: calc(13px * var(--jx-fs));
}

.font-scale-item.lv-md {
    font-size: calc(15px * var(--jx-fs));
}

.font-scale-item.lv-lg {
    font-size: calc(17px * var(--jx-fs));
}

.font-scale-item.on {
    background: var(--primary);
    color: var(--on-accent);
    font-weight: 700;
}

.font-scale-hint {
    margin-top: 10px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    text-align: center;
}

/* --------------------------------------------------------------------------
   28.3 家长端「学员中心」标题栏
   · 家长端走 public-shell，本来没有顶栏 —— 家长就没有字号 / 主题入口，这里补一条
   · 左：图标 + 学员中心；右：字号入口 + 主题入口（复用教务端同一套按钮）
   · public-shell 带 overflow-x: hidden（会成为滚动容器），sticky 在里面不生效，
     所以标题栏用 fixed，并给 .parent-shell 留出等高的 padding-top
   -------------------------------------------------------------------------- */
.parent-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: calc(48px + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) 8px 0 14px;
    background: var(--glass-nav);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    backdrop-filter: blur(var(--glass-blur)) saturate(150%);
    border-bottom: 1px solid var(--line);
    color: var(--nav-fg);
}

.parent-bar-title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: calc(16px * var(--jx-fs));
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}

.parent-bar-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 2px;
}

/* 家长端外壳为固定标题栏让位（高度 = 48px 内容 + 1px 分隔线 + 状态栏安全区） */
.public-shell.parent-shell {
    padding-top: calc(49px + env(safe-area-inset-top));
}

/* --------------------------------------------------------------------------
   28.4 表单与搜索框在最大字号下回落两档
   --------------------------------------------------------------------------
   「大」档（--jx-fs: 1.16）对正文刚好，但下面两类元素本身基准字号就偏大，
   再乘 1.16 会明显失真，所以它们改乘 --jx-fs-sub（大档时 = 中档的 1.08）：
     · 页面搜索框 .searchbar-input（手机 / 平板下为防 iOS 缩放已是 16px，
       乘 1.16 = 18.56px 太满，占位文字容易被挤断）与面板内搜索框 .sheet-search
     · 左侧栏 / 抽屉菜单 .nav（手机抽屉条目 15.5px，乘 1.16 = 17.98px，
       「未核销提醒」这类 5 字条目一行挤不下，且分组标题也跟着虚大）
   做法是在这两个容器上就地改写 --jx-fs：容器内的文字与 <ui-icon> 图标会一起
   跟着走（theme.css 的 .ico 同样读 --jx-fs），不需要逐条改字号。
   三点约束：
     1. 只在「大」档降一档，「中」档与原来一致；
     2. 最低就是「小」档的 1 —— 菜单在最小档已经很小，不再继续下调；
     3. 桌面（>=1024px）--jx-fs-sub 恒为 1，菜单与搜索框保持原尺寸，
        所以这条规则在桌面等于空操作。
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
    /* 最大字号下，表单标签、输入内容与搜索文本固定回小档，留出编辑空间。 */
    html[data-font="lg"] .field,
    html[data-font="lg"] .searchbar-input,
    html[data-font="lg"] .sheet-search {
        --jx-fs: 1;
    }
}

.searchbar-input,
.sheet-search,
.nav {
    --jx-fs: var(--jx-fs-sub);
}

/* --------------------------------------------------------------------------
   32. 运营端（超级管理员）：系统设置 + 运营首页报表
   · 颜色全部引用 theme.css 语义令牌，暗色主题自动生效
   · 自定义 SVG 图标：替换侧栏 / 登录页的内置图标（未配置时保持原样）
   · .trend-* 是运营首页的无依赖条形图（宽度由 :style 动态给出）
   -------------------------------------------------------------------------- */

/* 32.1 自定义系统图标（SVG）
   配置了自定义图标时，容器只当「画框」用：背景透明、去掉描边，只显示图标本身。
   内置图标那种渐变底 / 描边是给默认图标做的，套在自有品牌图标上会多出一个方框。 */
.brand-logo.has-img,
.login-logo-icon.has-img {
    background: transparent;
    border: 0;
}

.brand-logo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    border-radius: 6px;
}

.login-logo-icon img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    border-radius: 14px;
}

/* 32.2 运营首页条形图（新增机构趋势 / 地区分布） */
.trend-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 0;
}

.trend-label {
    flex: 0 0 74px;
    min-width: 0;
    color: var(--text-2);
    font-size: calc(12.5px * var(--jx-fs));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.trend-track {
    flex: 1;
    min-width: 0;
    height: 10px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    overflow: hidden;
}

.trend-fill {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: var(--primary);
    transition: width .25s ease;
}

.trend-num {
    flex: 0 0 58px;
    text-align: right;
    color: var(--text-3);
    font-size: calc(12.5px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
}

/* 32.3 客服二维码预览：二维码必须有浅底静默区才扫得开，因此固定用 --qr-bg */
.qr-preview {
    display: block;
    width: 148px;
    height: 148px;
    object-fit: contain;
    background: var(--qr-bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 8px;
}

/* 主题选择面板：与字号面板共用弹出容器，四种风格以可扫描的列表呈现。 */
.sheet-theme .sheet-body {
    padding: 10px 14px 14px;
}

.theme-choice-list {
    display: grid;
    gap: 8px;
}

.theme-choice {
    width: 100%;
    min-height: 62px;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.theme-choice.on {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--primary-text);
}

.theme-choice-icon {
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--surface-2);
}

.theme-choice-auto .theme-choice-icon { color: var(--theme-preview-auto-fg); }
.theme-choice-classic .theme-choice-icon { color: var(--theme-preview-classic-fg); background: var(--theme-preview-classic-bg); }
.theme-choice-spring .theme-choice-icon { color: var(--theme-preview-spring-fg); background: var(--theme-preview-spring-bg); }
.theme-choice-fresh .theme-choice-icon { color: var(--theme-preview-fresh-fg); background: var(--theme-preview-fresh-bg); }
.theme-choice-rustic .theme-choice-icon { color: var(--theme-preview-rustic-fg); background: var(--theme-preview-rustic-bg); }
.theme-choice-romance .theme-choice-icon { color: var(--theme-preview-romance-fg); background: var(--theme-preview-romance-bg); }

.theme-choice-copy {
    display: flex;
    min-width: 0;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 3px;
}

.theme-choice-copy strong { font-size: calc(14px * var(--jx-fs)); }
.theme-choice-copy small { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }

/* 公开活动：内容区使用单一卡片，所有组件按统一5px网格排列。 */
.public-hero { border: 0; border-radius: 14px; box-shadow: none; }
.activity-content {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin: 5px 0 0;
    padding: 0;
    border: 0;
    border-radius: 14px;
    background: var(--on-accent);
    box-shadow: none;
}
.activity-content .public-block {
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}
.activity-content .activity-section-text,
.activity-content .activity-section-form {
    padding: 14px 0;
    border: 0;
    background: transparent;
}
.activity-content .public-block h2 { margin-bottom: 8px; }
/* 文字组件独立成卡片，避免标题和正文漂浮在图片区之间。 */
.activity-content .activity-section-text {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 22px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
}
.activity-content .activity-section-text h2 {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0;
    color: var(--primary-text);
    font-size: 21px;
    line-height: 1.35;
}
.activity-content .activity-section-text h2::before {
    width: 4px;
    height: 22px;
    border-radius: 999px;
    background: var(--primary);
    content: "";
}
.activity-content .activity-section-text .public-copy {
    margin: 0;
    color: var(--text-2);
    font-size: 15px;
    line-height: 1.9;
}
.activity-content .activity-section-image,
.activity-content .activity-section-two_image,
.activity-content .activity-section-banner { overflow: visible; }
.activity-content .public-block > img {
    width: 100%;
    border-radius: 5px;
}
.activity-content .public-two {
    width: 100%;
    gap: 5px;
}
.activity-content .public-two img { border-radius: 5px; }
.activity-content .public-banner { gap: 5px; padding: 0; }
.activity-content .public-banner img { border-radius: 14px; }
@media (max-width: 767px) {
    .activity-content { gap: 10px; margin: 12px 0 0; padding: 0; }
    .activity-content .public-block { margin: 0; padding: 0; border-radius: 0; }
    .activity-content .activity-section-form { padding: 14px 0; }
    .activity-content .activity-section-text { padding: 18px; border-radius: 14px; }
    .activity-content .public-two { gap: 5px; }
    .activity-content .public-two img { border-radius: 14px; }
}

/* 活动编辑器：上传素材始终归属到各自的组件卡片，不再散落在同一大面板内。 */
.marketing-editor .editor-section:has(.block-editor) {
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}
.marketing-editor .editor-section:has(.block-editor) .editor-section-head {
    margin: 0 0 12px;
    padding: 0 2px;
    border: 0;
}
/* 页面组件工具栏：五个按钮等宽，宽屏也保持紧凑，不拉成整行。 */
.marketing-editor .editor-section:has(.block-editor) .editor-section-head > .btn-row {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    width: min(100%, 420px);
    max-width: 420px;
    gap: 6px;
}
.marketing-editor .editor-section:has(.block-editor) .editor-section-head > .btn-row > button {
    width: 100%;
    min-width: 0;
    min-height: 54px;
    padding: 6px 4px;
    border-radius: 9px;
}
.marketing-editor .editor-section:has(.block-editor) .block-editor {
    margin: 12px 0 0;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: none;
}
.marketing-editor .editor-section:has(.block-editor) .block-editor:first-of-type { margin-top: 0; }
.marketing-editor .editor-section:has(.block-editor) .block-editor + .block-editor { border-top: 1px solid var(--line); }
.marketing-editor .block-tools {
    min-height: 34px;
    margin: 0 0 12px;
    padding: 0 0 10px;
    border-bottom: 1px solid var(--line);
}
.marketing-editor .block-tools b { color: var(--text); font-size: calc(13px * var(--jx-fs)); }
.marketing-editor .block-editor { position: relative; }
.marketing-editor .block-tools > .btn-row {
    display: inline-flex;
    flex: 0 0 auto;
    margin-left: auto;
}
.marketing-editor .block-editor > .btn-row {
    position: absolute;
    top: 14px;
    right: 14px;
    display: inline-flex;
    flex-wrap: nowrap;
}
.marketing-editor .block-tools .icon-btn {
    position: absolute;
    top: 14px;
    width: 30px;
    height: 30px;
}
.marketing-editor .block-tools .icon-btn:nth-last-child(1) { right: 14px; }
.marketing-editor .block-tools .icon-btn:nth-last-child(2) { right: 48px; }
.marketing-editor .block-tools .icon-btn:nth-last-child(3) { right: 82px; }
.marketing-editor .block-image-tools {
    align-items: stretch;
    gap: 10px;
    padding: 0;
}
.marketing-editor .block-banner-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
    gap: 10px;
}
.marketing-editor .block-banner-list > span {
    min-width: 0;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface-2);
}
.marketing-editor .block-banner-list .block-image-preview {
    width: 100%;
    height: 76px;
    border: 0;
    border-radius: 5px;
}
.marketing-editor .block-banner-list .icon-btn {
    top: -7px;
    right: -7px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    box-shadow: var(--shadow);
}
.marketing-editor .block-image-pair {
    gap: 10px;
    width: 100%;
}
.marketing-editor .block-image-pair .file-pick,
.marketing-editor .block-image-tools > .file-pick {
    justify-content: center;
    min-height: 42px;
    border-radius: 8px;
    background: var(--surface-2);
}
.marketing-editor .block-image-pair .block-image-preview {
    width: 100%;
    height: 112px;
    margin-bottom: 8px;
    border-radius: 8px;
}
@media (max-width: 767px) {
    .marketing-editor .editor-section:has(.block-editor) .block-editor { padding: 12px; }
    .marketing-editor .block-banner-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .marketing-editor .block-banner-list .block-image-preview { height: 82px; }
}

/* 活动画布内联编辑：组件配置以浮层呈现，底层表单保留为状态与上传源。 */
.marketing-editor .editor-section:has(.block-editor) > .block-editor { display: none; }
.activity-builder-canvas { position: relative; }
.activity-builder-popover {
    position: sticky;
    bottom: 10px;
    z-index: 8;
    margin: 10px 0 0;
    padding: 12px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: var(--shadow-lg);
}
.activity-builder-popover-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; color: var(--text); font-size: 13px; font-weight: 700; }
.activity-builder-popover-fields { display: grid; gap: 9px; }
.activity-builder-popover .field { margin: 0; }
.activity-builder-popover .field-label { margin-bottom: 4px; }
.activity-builder-popover-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.activity-builder-popover .file-pick { min-height: 36px; }
/* 活动画布组件设置：使用系统标准弹窗，保存后统一回写底层配置并刷新预览。 */
.activity-page-editor .modal-head { justify-content: flex-start; min-height: 58px; gap: 10px; padding: 0 14px; border-bottom-color: var(--line); background: var(--surface); color: var(--text); }
.activity-page-editor .modal-head .modal-title { display: inline-flex; flex: 1; align-items: center; gap: 8px; font-size: calc(16px * var(--jx-fs)); font-weight: 700; }
.activity-page-editor .modal-head .icon-btn { color: var(--text-2); }
.activity-page-editor .modal-head .icon-btn:hover, .activity-page-editor .modal-head .icon-btn:active { background: var(--hover); color: var(--text); }
.activity-builder-settings-dialog { width: 100%; max-width: 560px; }
@media (max-width: 559px) {
    .activity-builder-settings-mask { align-items: flex-end; }
    .activity-builder-settings-dialog { width: 100%; max-width: none; max-height: 88dvh; border-radius: 16px 16px 0 0; }
    .activity-builder-settings-dialog .modal-head { border-radius: 16px 16px 0 0; }
}
.activity-builder-settings-body { display: grid; gap: 14px; }
.activity-builder-settings-body .field { margin: 0; }
.activity-builder-layout-field { display: grid; gap: 8px; }
.activity-builder-layout-field .field-label { display: inline-flex; align-items: center; gap: 6px; }
.activity-builder-layout-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.activity-builder-layout-options label { display: flex; align-items: center; justify-content: center; gap: 7px; min-height: 48px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); color: var(--text); font-size: calc(13px * var(--jx-fs)); cursor: pointer; }
.activity-builder-layout-options input { width: 16px; height: 16px; margin: 0; accent-color: var(--primary); }
.activity-builder-layout-preview { display: inline-flex; width: 22px; height: 22px; flex: 0 0 auto; color: var(--text-2); }
.activity-builder-layout-preview.is-reverse { transform: scaleX(-1); }
.activity-builder-layout-preview svg { width: 100%; height: 100%; fill: currentColor; }
.activity-builder-layout-options label:has(input:checked) { border-color: var(--primary); background: var(--primary-light); color: var(--primary-text); font-weight: 700; }
.activity-builder-layout-options label:has(input:checked) .activity-builder-layout-preview { color: var(--primary); }
.activity-builder-image-settings { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.activity-builder-image-field { display: grid; min-width: 0; gap: 6px; }
.activity-builder-image-field .field-label { overflow: hidden; color: var(--text-2); font-size: calc(12px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.activity-builder-image-preview { display: flex; aspect-ratio: 1; min-height: 0; align-items: center; justify-content: center; overflow: hidden; border: 1px dashed var(--line-strong); border-radius: 8px; background: var(--surface-2); color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.activity-builder-image-preview img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: center; }
.activity-builder-image-field .btn { width: 100%; min-width: 0; min-height: 34px; padding: 0 6px; font-size: calc(12px * var(--jx-fs)); white-space: nowrap; }
.activity-builder-settings-upload { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 2px; }
.activity-builder-settings-upload .btn { flex: 1 1 140px; min-height: 40px; }
.activity-builder-settings-mask .modal-foot { position: sticky; bottom: 0; }
.activity-builder-block.is-active { border-color: var(--primary); box-shadow: var(--ring); }
@media (min-width: 768px) {
    .marketing-editor { width: min(1080px, calc(100vw - 48px)); }
    .marketing-editor .modal-body { display: grid; grid-template-columns: minmax(280px, .9fr) minmax(380px, 1.25fr); gap: 20px; align-items: start; }
    .marketing-editor .modal-body > .form-grid { position: sticky; top: 72px; }
    .marketing-editor .modal-body > .editor-section:has(.block-editor) { min-width: 0; }
    .activity-builder-canvas { margin: 0; }
}

.activity-page-editor .modal-body > .activity-basics { display: none; }
.activity-builder-basics { display: flex; width: 100%; min-height: 64px; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.activity-builder-basics:hover, .activity-builder-basics:focus-visible { border-color: var(--primary); box-shadow: var(--ring); outline: 0; }
.activity-builder-basics > span:first-child { display: grid; min-width: 0; gap: 3px; }
.activity-builder-basics b { font-size: calc(14px * var(--jx-fs)); }
.activity-builder-basics small { overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.activity-builder-basics-action { flex: 0 0 auto; color: var(--primary-text); font-size: calc(12px * var(--jx-fs)); font-weight: 700; }
.activity-page-editor .activity-basics { display: grid; grid-template-columns: minmax(0, 1fr) minmax(104px, .42fr); gap: 14px 12px; }
.activity-page-editor .activity-basics .field { min-width: 0; }
.activity-page-editor .activity-basics .activity-name { grid-column: 1; }
.activity-page-editor .activity-basics .activity-status-field { grid-column: 1 / -1; }
.activity-status-options { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.activity-status-options button { min-height: 38px; padding: 0 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); color: var(--text-2); font: inherit; font-size: calc(13px * var(--jx-fs)); cursor: pointer; }
.activity-status-options button:hover { border-color: var(--primary); color: var(--primary-text); }
.activity-status-options button.on { border-color: var(--primary); background: var(--primary); color: var(--on-accent); font-weight: 700; }
.activity-status-options button:focus-visible { outline: 0; box-shadow: var(--ring); }
.activity-page-editor .activity-basics .activity-start-at { grid-column: 1; }
.activity-page-editor .activity-basics .activity-end-at { grid-column: 2; }
.activity-page-editor .activity-basics .field.full { grid-column: 1 / -1; }
.activity-page-editor .activity-basics input[type="datetime-local"] { min-width: 0; padding-right: 6px; }
@media (max-width: 360px) {
    .activity-page-editor .activity-basics { grid-template-columns: minmax(0, 1fr) minmax(92px, .38fr); gap: 12px 8px; }
    .activity-page-editor .activity-basics input[type="datetime-local"] { font-size: 12px; }
}
/* 活动可视化搭建画布：预览与配置同源，点击预览可直接定位编辑。 */
.activity-builder-canvas {
    margin: 0 0 18px;
    padding: 10px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface-2);
}
.activity-builder-hero {
    position: relative;
    display: flex;
    width: 100%;
    min-height: 154px;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 5px;
    padding: 18px;
    overflow: hidden;
    border: 0;
    border-radius: 11px;
    background: var(--grad-brand);
    color: var(--on-accent);
    text-align: left;
    cursor: pointer;
}
.activity-builder-hero::before {
    position: absolute;
    top: -72px;
    right: -36px;
    width: 170px;
    height: 170px;
    border: 1px solid var(--hero-tile-line);
    border-radius: 50%;
    box-shadow: 0 0 0 28px var(--hero-tile-bg), 0 0 0 56px var(--hero-tile-bg);
    content: "";
}
.activity-builder-hero > * { position: relative; z-index: 1; }
.activity-builder-hero span { padding: 3px 8px; border: 1px solid var(--hero-tile-line); border-radius: 999px; background: var(--hero-tile-bg); font-size: 11px; font-weight: 700; }
.activity-builder-hero strong { font-size: 24px; line-height: 1.25; }
.activity-builder-hero small { max-width: 80%; color: var(--hero-fg-muted); font-size: 12px; line-height: 1.45; }
.activity-builder-hero em,
.builder-block-edit { opacity: 0; font-style: normal; transition: opacity .15s; }
.activity-builder-hero:hover em,
.activity-builder-hero:focus-visible em,
.activity-builder-block:hover .builder-block-edit,
.activity-builder-block:focus-visible .builder-block-edit { opacity: 1; }
.activity-builder-hero em { position: absolute; top: 10px; right: 10px; padding: 4px 7px; border-radius: 999px; background: var(--activity-shade-24); color: var(--on-accent); font-size: 11px; }
.activity-builder-flow { display: grid; gap: 8px; margin-top: 8px; }
.activity-builder-block {
    position: relative;
    display: flex;
    width: 100%;
    min-height: 72px;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 5px;
    padding: 14px;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 11px;
    background: var(--surface);
    color: var(--text);
    text-align: left;
    cursor: pointer;
}
.activity-builder-block:hover,
.activity-builder-block:focus-visible { border-color: var(--primary); box-shadow: var(--ring); outline: 0; }
.activity-builder-block.is-text strong { color: var(--primary-text); font-size: 16px; }
.activity-builder-block.is-text small { color: var(--text-2); font-size: 13px; }
.activity-builder-block.is-image { min-height: 0; padding: 0; aspect-ratio: 16 / 9; background: var(--surface-3); }
.activity-builder-block.is-image img { display: block; width: 100%; height: 100%; object-fit: cover; }
.activity-builder-block.is-banner { min-height: 132px; padding: 0; align-items: stretch; justify-content: flex-end; background: var(--primary-dark); color: var(--on-accent); }
.activity-builder-block.is-banner > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .82; }
.activity-builder-block.is-banner::after { position: absolute; inset: 0; background: var(--activity-shade-22); content: ""; }
.builder-banner-mark,
.builder-banner-dots { position: relative; z-index: 1; }
.builder-banner-mark { margin: 0 12px 8px; font-size: 13px; font-weight: 700; }
.builder-banner-dots { display: inline-flex; align-self: center; gap: 7px; margin-bottom: 12px; }
.builder-banner-dots i { display: inline-flex; width: 23px; height: 23px; align-items: center; justify-content: center; border: 1px solid var(--activity-fg-54); border-radius: 50%; background: var(--activity-shade-24); color: var(--on-accent); font-size: 11px; font-style: normal; font-weight: 700; }
.builder-banner-dots i.on { border-color: var(--on-accent); background: var(--on-accent); color: var(--primary-dark); }
.public-banner-dot { position: relative; width: 28px; height: 28px; background: transparent; }
.public-banner-dot::before { position: absolute; top: 50%; left: 50%; width: 7px; height: 7px; border-radius: 50%; background: var(--activity-fg-58); content: ""; transform: translate(-50%, -50%); }
.public-banner-dot.active { width: 28px; border-radius: 50%; background: transparent; }
.public-banner-dot.active::before { width: 18px; border-radius: 4px; background: var(--on-accent); }
.public-three { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; width: 100%; aspect-ratio: 3 / 2; min-height: 0; }
.public-three-main, .public-three-side > div { min-width: 0; min-height: 0; overflow: hidden; border-radius: 24px; background-color: var(--surface-3); background-position: center; background-repeat: no-repeat; background-size: cover; }
.public-three-side { display: grid; min-width: 0; min-height: 0; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 20px; }
.public-three.public-three-reverse > .public-three-main { grid-column: 2; grid-row: 1; }
.public-three.public-three-reverse > .public-three-side { grid-column: 1; grid-row: 1; }
.activity-builder-block.is-pair.is-empty .builder-pair-cell img { display: none; }
.builder-pair-label { position: absolute; top: 16px; left: 16px; z-index: 2; color: var(--text); font-size: calc(15px * var(--jx-fs)); font-weight: 700; }
.builder-triple-label { position: absolute; top: 16px; left: 16px; z-index: 2; color: var(--text); font-size: calc(15px * var(--jx-fs)); font-weight: 700; }
.activity-builder-block.is-triple.triple-right .builder-triple-main { grid-column: 2; grid-row: 1; }
.activity-builder-block.is-triple.triple-right .builder-triple-side { grid-column: 1; grid-row: 1; }
.activity-builder-block.is-triple { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); aspect-ratio: 3 / 2; min-height: 0; padding: 0; gap: 12px; overflow: visible; border: 0; background: transparent; }
.builder-triple-main, .builder-triple-side > span { display: block; min-width: 0; min-height: 0; overflow: hidden; border-radius: 16px; background-color: var(--surface-2); background-position: center; background-repeat: no-repeat; background-size: cover; }
.builder-triple-side { display: grid; min-width: 0; min-height: 0; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 12px; overflow: hidden; }
.builder-triple-side > span { height: 100%; }
.activity-builder-block.is-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); min-height: 118px; padding: 0; gap: 8px; overflow: visible; border: 0; background: transparent; }
.builder-pair-cell { display: block; min-width: 0; min-height: 118px; overflow: hidden; border: 1px solid var(--line); border-radius: 11px; background: var(--surface-3); }
.builder-pair-cell img { display: block; width: 100%; height: 118px; object-fit: cover; }
.activity-builder-block.is-media { min-height: 104px; align-items: center; background: var(--surface-3); color: var(--text-muted); text-align: center; }
.builder-block-icon { display: inline-flex; width: 28px; height: 28px; align-items: center; justify-content: center; border: 1px dashed var(--primary); border-radius: 8px; color: var(--primary-text); font-size: 18px; }
.activity-builder-block.is-media strong { color: var(--text-2); font-size: 13px; }
.activity-builder-block.is-media small { font-size: 12px; }
.activity-builder-hero.has-cover { background-position: center; background-size: cover; }
.activity-builder-hero.has-cover::before { border-color: var(--activity-fg-30); box-shadow: 0 0 0 28px var(--activity-shade-16), 0 0 0 56px var(--activity-shade-10); }
.activity-builder-hero.has-cover::after { position: absolute; inset: 0; z-index: 0; background: var(--activity-shade-24); content: ""; }
.activity-builder-hero.has-cover > * { z-index: 1; }
.activity-builder-hero.is-empty { min-height: 154px; justify-content: flex-start; background: var(--surface-3); color: var(--text); }
.activity-builder-hero.is-empty::before { display: none; }
.activity-builder-hero.is-empty .builder-empty-label { border: 0; border-radius: 0; padding: 0; background: transparent; color: var(--text); font-size: calc(14px * var(--jx-fs)); }
.activity-builder-hero.is-empty small { max-width: none; margin-top: auto; color: var(--text-muted); }
.activity-builder-block .builder-block-edit { display: none; }
.builder-block-actions { position: absolute; top: 8px; right: 8px; z-index: 3; display: inline-flex; align-items: center; gap: 7px; }
.builder-block-action { display: inline-flex; width: 20px; height: 20px; align-items: center; justify-content: center; padding: 0; border: 0; background: transparent; color: var(--text-2); font: inherit; font-size: 11px; line-height: 1; cursor: pointer; }
.builder-block-action:hover { color: var(--primary); }
.builder-block-action.danger { color: var(--danger-text); font-size: 16px; }
.activity-builder-block.is-media .builder-block-actions { top: 8px; right: 8px; }
.activity-builder-block.is-pair .builder-block-actions { top: 8px; right: 8px; }
.builder-block-edit { position: absolute; top: 8px; right: 8px; padding: 3px 7px; border-radius: 999px; background: var(--primary); color: var(--on-accent); font-size: 11px; font-weight: 700; }
.block-editor.is-builder-selected { border-color: var(--primary) !important; box-shadow: var(--ring) !important; }
.activity-builder-add { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.activity-builder-add > span { width: 100%; color: var(--text-muted); font-size: 12px; font-weight: 700; }
.activity-builder-add button { min-height: 30px; padding: 0 10px; border: 1px dashed var(--line-strong); border-radius: 999px; background: var(--surface); color: var(--primary-text); font: inherit; font-size: 12px; cursor: pointer; }
.activity-builder-add button:hover { border-color: var(--primary); background: var(--primary-light); }
.activity-page-editor .editor-section:has(.activity-builder-canvas) > .editor-section-head { display: none; }
.activity-page-editor .editor-section-head > .btn-row { display: none; }
.marketing-editor .editor-section:has(.block-editor) > .editor-section-head > .btn-row { display: none; }
@media (max-width: 767px) {
    .marketing-toolbar { align-items: flex-start; flex-direction: column; gap: 10px; padding: 2px 0; }
    .marketing-toolbar-actions { width: 100%; }
    .marketing-search { flex: 1 1 auto; min-width: 0; }
    .marketing-primary-actions { flex: 0 0 auto; }
    .marketing-primary-actions .btn { min-width: 0; padding: 0 12px; }
    .activity-builder-canvas { margin-bottom: 14px; padding: 8px; }
    .activity-builder-hero { min-height: 136px; padding: 16px; }
    .activity-builder-hero strong { font-size: 21px; }
    .activity-builder-block { min-height: 62px; padding: 12px; }
    .builder-pair-cell,
    .builder-pair-cell img { min-height: 96px; height: 96px; }
}
/* Activity and form visual editors. Local theme variables deliberately do not modify html[data-theme]. */
.marketing-empty { grid-column: 1 / -1; display: grid; justify-items: center; gap: 10px; min-height: 180px; }
.editor-shell { display: grid; grid-template-columns: minmax(360px, 1.08fr) minmax(330px, .92fr); gap: 18px; min-height: 0; padding: 16px !important; background: var(--bg) !important; }
.activity-page-editor, .form-page-editor { width: min(1240px, calc(100vw - 32px)); height: min(900px, calc(100dvh - 28px)); max-height: none; }
.activity-page-editor .modal-body, .form-page-editor .modal-body { overflow: hidden; }
.editor-preview-pane, .editor-property-pane { display: flex; min-width: 0; min-height: 0; flex-direction: column; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); overflow: hidden; }
.editor-pane-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; min-height: 48px; padding: 0 14px; border-bottom: 1px solid var(--line); }
.editor-pane-head strong { color: var(--text); font-size: calc(14px * var(--jx-fs)); }
.editor-pane-head span { overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.editor-property-scroll { min-height: 0; padding: 14px; overflow: auto; }
.editor-property-scroll > .field + .field { margin-top: 14px; }
.property-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.activity-preview { width: min(100%, 540px); margin: 16px auto; border: 0; border-radius: 0; background: transparent; overflow: visible; box-shadow: none; }
.activity-preview-flow { display: grid; gap: 8px; padding: 0; }
.preview-block.preview-cover { min-height: 170px; border-radius: 6px; }
.editor-preview-pane { overflow: auto; }
.activity-preview-hero { display: flex; width: 100%; min-height: 0; aspect-ratio: 1 / 1; align-items: flex-start; justify-content: flex-end; flex-direction: column; gap: 8px; padding: 22px; border: 0; background: var(--primary-dark); background-position: center; background-size: cover; color: var(--on-accent); font: inherit; text-align: left; cursor: pointer; }
.activity-preview-hero span, .activity-preview-hero strong, .activity-preview-hero small { color: var(--on-accent); }
.activity-page-editor .activity-preview-hero { align-items: flex-start; justify-content: flex-end; text-align: left; }
.public-activity .public-hero { min-height: 0; aspect-ratio: 1 / 1; color: var(--on-accent); }
.public-activity .public-hero.has-cover::before, .public-activity .public-hero.has-cover::after { display: none; }
.public-activity .public-hero .activity-hero-copy, .public-activity .public-hero .activity-hero-copy h1, .public-activity .public-hero .activity-hero-copy p { color: var(--on-accent); text-shadow: 0 1px 3px var(--activity-shade-35); }
.activity-preview-hero span { font-size: 12px; opacity: .88; }
.activity-preview-hero strong { font-size: 24px; line-height: 1.25; }
.activity-preview-hero small { max-width: 90%; font-size: 13px; line-height: 1.5; }
.activity-preview-flow { display: grid; gap: 8px; padding: 0; }
.preview-block { position: relative; display: flex; width: 100%; min-height: 72px; align-items: flex-start; justify-content: center; flex-direction: column; gap: 5px; padding: 14px; overflow: hidden; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.preview-block:hover, .preview-block.active { border-color: var(--primary); box-shadow: var(--ring); }
.preview-block.disabled { opacity: .55; }
.preview-block em { position: absolute; top: 8px; right: 8px; color: var(--text-muted); font-size: 11px; font-style: normal; }
.preview-block span { color: var(--text-muted); font-size: 12px; line-height: 1.45; }
.preview-block.preview-image, .preview-block.preview-banner { min-height: 132px; padding: 0; align-items: center; background: var(--surface-3); }
.preview-block.preview-image img, .preview-block.preview-banner img { width: 100%; height: 132px; object-fit: cover; }
.preview-block.preview-form { align-items: center; background: var(--primary-light); color: var(--primary-text); text-align: center; }
.preview-empty { display: grid; min-height: 150px; place-items: center; align-content: center; gap: 8px; color: var(--text-muted); font-size: 13px; }
.selected-object-actions { display: flex; align-items: center; gap: 7px; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.selected-object-actions .btn { margin-left: auto; }
.editor-choice { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); overflow: hidden; border: 1px solid var(--line); border-radius: 6px; }
.editor-choice button { min-height: 36px; border: 0; border-right: 1px solid var(--line); background: var(--surface); color: var(--text-2); font: inherit; cursor: pointer; }
.editor-choice button:last-child { border-right: 0; }
.editor-choice button.on { background: var(--primary-light); color: var(--primary-text); font-weight: 700; }
.activity-theme-picker { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.activity-theme-picker button { position: relative; display: flex; min-width: 0; min-height: 50px; flex-direction: column; justify-content: center; gap: 5px; padding: 7px 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.activity-theme-picker button.on { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-light); }
.activity-theme-picker button > span { width: 100%; height: 6px; border-radius: 999px; background: var(--activity-theme-classic); }
.activity-theme-picker .theme-swatch-fresh > span { background: var(--activity-theme-fresh-swatch); }.activity-theme-picker .theme-swatch-rustic > span { background: var(--activity-theme-rustic-swatch); }.activity-theme-picker .theme-swatch-romance > span { background: var(--activity-theme-romance-swatch); }
.activity-theme-picker b { overflow: hidden; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }.activity-theme-picker small { display: none; }.activity-theme-picker .ico { position: absolute; top: 5px; right: 5px; color: var(--primary); }
/* 基础设置中只保留第一处封面文字颜色，避免重复渲染。 */
.activity-settings-dialog .field:has(.hero-text-color-picker) ~ .field:has(.hero-text-color-picker) { display: none; }
.image-chip-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }.image-chip-list span { position: relative; width: 66px; height: 50px; overflow: hidden; border-radius: 5px; background: var(--surface-2); }.image-chip-list img { width: 100%; height: 100%; object-fit: cover; }.image-chip-list button { position: absolute; top: 2px; right: 2px; display: grid; width: 20px; height: 20px; place-items: center; border: 0; border-radius: 50%; background: var(--activity-shade-60); color: var(--on-accent); cursor: pointer; }
.editor-add-block { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }.editor-add-block strong { width: 100%; color: var(--text-2); font-size: 12px; }.editor-add-block button { display: inline-flex; min-height: 34px; align-items: center; gap: 5px; padding: 0 9px; border: 1px dashed var(--line-strong); border-radius: 6px; background: var(--surface); color: var(--primary-text); font: inherit; font-size: 12px; cursor: pointer; }.editor-add-block button:hover { border-color: var(--primary); background: var(--primary-light); }
.form-preview { width: min(100%, 480px); margin: 16px auto; padding: 20px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }.form-preview h3 { margin: 0; color: var(--text); font-size: 19px; }.form-preview > p { margin: 6px 0 16px; color: var(--text-muted); font-size: 13px; }.form-preview-field { display: block; width: 100%; margin: 0 0 12px; padding: 10px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer; }.form-preview-field.active { border-color: var(--primary); background: var(--primary-light); }.form-preview-field label { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 700; }.form-preview-field label i, .field-label i { color: var(--danger); font-style: normal; }.form-preview-field .input, .form-preview-field .textarea { pointer-events: none; }.form-choice-preview { display: flex; flex-wrap: wrap; gap: 8px; }.form-choice-preview span { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; }.form-choice-preview i { width: 13px; height: 13px; border: 1px solid var(--line-strong); border-radius: 50%; }.form-image-placeholder { display: flex; min-height: 56px; align-items: center; justify-content: center; gap: 6px; border: 1px dashed var(--line-strong); color: var(--text-muted); font-size: 12px; }.form-preview-submit { width: 100%; min-height: 42px; }.check-row { display: inline-flex; align-items: center; gap: 7px; color: var(--text); font-size: 13px; cursor: pointer; }.check-row input { width: 16px; height: 16px; accent-color: var(--primary); }
.activity-theme-classic { --activity-accent: var(--activity-theme-classic); --activity-soft: var(--activity-theme-classic-soft); }.activity-theme-fresh { --activity-accent: var(--activity-theme-fresh); --activity-soft: var(--activity-theme-fresh-soft); }.activity-theme-rustic { --activity-accent: var(--activity-theme-rustic); --activity-soft: var(--activity-theme-rustic-soft); }.activity-theme-romance { --activity-accent: var(--activity-theme-romance); --activity-soft: var(--activity-theme-romance-soft); }.activity-preview.activity-theme-classic .activity-preview-hero, .public-activity.activity-theme-classic .public-hero { background-color: var(--activity-theme-classic); }.activity-preview.activity-theme-fresh .activity-preview-hero, .public-activity.activity-theme-fresh .public-hero { background-color: var(--activity-theme-fresh); }.activity-preview.activity-theme-rustic .activity-preview-hero, .public-activity.activity-theme-rustic .public-hero { background-color: var(--activity-theme-rustic); }.activity-preview.activity-theme-romance .activity-preview-hero, .public-activity.activity-theme-romance .public-hero { background-color: var(--activity-theme-romance); }
.public-activity .activity-page { max-width: 760px; margin: 0 auto; }.public-activity .public-hero { min-height: 250px; display: flex; align-items: end; padding: 28px; background-position: center; background-size: cover; color: var(--on-accent); }.public-activity .activity-hero-copy { max-width: 620px; }.public-activity .activity-hero-copy h1 { margin: 7px 0; font-size: 30px; }.public-activity .activity-content { padding: 16px; }.public-activity .public-block { margin-bottom: 12px; padding: 18px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }.public-activity .public-block h2 { margin-top: 0; }.public-activity .public-block p { white-space: pre-wrap; line-height: 1.75; }.public-activity .public-block img { display: block; width: 100%; max-height: 460px; object-fit: cover; }.public-activity .public-image-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }.public-activity .public-image-pair img { aspect-ratio: 1; }.public-activity .public-image-triple { display: grid; grid-template-columns: 1.2fr .8fr; gap: 8px; }.public-activity .public-image-triple.is-reverse { grid-template-columns: .8fr 1.2fr; }.public-activity .public-image-triple.is-reverse > img { order: 2; }.public-activity .public-image-triple.is-reverse > div { order: 1; }.public-activity .public-image-triple > img { height: 100%; min-height: 180px; }.public-activity .public-image-triple > div { display: grid; gap: 8px; }.public-activity .public-image-triple > div img { aspect-ratio: 1.45; }.public-media-placeholder { min-height: 120px; display: grid; place-items: center; background: var(--surface-2); color: var(--text-muted); }.public-signup-bar { position: sticky; bottom: 12px; display: block; width: calc(100% - 32px); max-width: 728px; min-height: 48px; margin: 0 auto 12px; border: 0; border-radius: 6px; background: var(--activity-accent, var(--primary)); color: var(--on-accent); font: inherit; font-weight: 700; cursor: pointer; box-shadow: 0 8px 22px var(--activity-shade-16); }.public-field-options { display: grid; gap: 8px; }.public-field-options label { display: inline-flex; align-items: center; gap: 7px; }.public-signup-modal { width: min(520px, calc(100vw - 28px)); }
@media (max-width: 900px) { .editor-shell { grid-template-columns: minmax(300px, 1fr) minmax(300px, .9fr); gap: 12px; padding: 12px !important; }.activity-page-editor, .form-page-editor { width: calc(100vw - 18px); } }


@media (min-width: 900px) { .marketing-editor .modal-body.editor-shell { display: grid; grid-template-columns: minmax(360px, 1.08fr) minmax(330px, .92fr); gap: 18px; align-items: stretch; } }
@media (max-width: 899px) { .activity-page-editor, .form-page-editor { width: 100%; height: 100dvh; border-radius: 0; }.activity-page-editor .modal-head, .form-page-editor .modal-head { gap: 7px; padding: 0 10px; }.modal-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.editor-shell { display: block; padding: 10px !important; overflow: auto !important; }.editor-preview-pane, .editor-property-pane { min-height: auto; overflow: visible; }.editor-preview-pane { margin-bottom: 10px; }.editor-preview-pane .editor-pane-head { position: sticky; top: 0; z-index: 2; background: var(--surface); }.editor-property-scroll { overflow: visible; }.activity-preview { margin: 10px auto; }.property-grid { grid-template-columns: 1fr; }.editor-add-block button { flex: 1 1 calc(50% - 7px); justify-content: center; }.form-preview { margin: 10px auto; }.public-activity .public-hero { min-height: 210px; padding: 20px; }.public-activity .activity-hero-copy h1 { font-size: 25px; }.public-activity .public-image-triple, .public-activity .public-image-triple.is-reverse { grid-template-columns: 1fr; }.public-activity .public-image-triple > img, .public-activity .public-image-triple.is-reverse > img { order: 0; min-height: 0; aspect-ratio: 1.25; }.public-activity .public-image-triple > div, .public-activity .public-image-triple.is-reverse > div { order: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* 活动编辑器日期时间：复用 ui-date / ui-select，不使用浏览器原生日期时间控件。 */
.datetime-wrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 104px auto;
    gap: 6px;
    align-items: center;
}
.datetime-wrap .date-field,
.datetime-wrap .time-field {
    min-height: 40px;
    font-size: max(16px, calc(13px * var(--jx-fs)));
}
.datetime-wrap .datetime-clear {
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
}
.datetime-wrap .date-field:focus-visible,
.datetime-wrap .time-field:focus-visible {
    border-color: var(--primary-text);
    outline: none;
    box-shadow: var(--ring);
}
@media (max-width: 480px) {
    .datetime-wrap { grid-template-columns: minmax(0, 1fr) 96px auto; }
}

/* 活动画布只保留实际内容；基础数据和组件属性按需以设置面板出现。 */
.activity-page-editor .editor-shell { display: block; position: relative; overflow: auto; }
.activity-page-editor .editor-preview-pane { min-height: 100%; border: 0; border-radius: 0; background: transparent; overflow: visible; }
.activity-cover-hint { display: inline-flex; width: min(100%, 540px); align-items: center; gap: 6px; margin: 16px auto 0; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.activity-cover-hint .ico { color: var(--primary); }
.activity-basics-card { display: flex; width: min(100%, 540px); min-height: 42px; align-items: center; justify-content: space-between; gap: 12px; margin: 16px auto 0; padding: 10px 13px; border: 0; border-radius: 6px; background: var(--grad-hero); color: var(--on-accent); font: inherit; font-size: calc(13px * var(--jx-fs)); font-weight: 700; text-align: left; cursor: pointer; }
.activity-basics-card:hover { filter: brightness(.96); }
.activity-basics-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.activity-basics-card .ico { color: var(--on-accent); }
.activity-settings-dialog.settings-base .activity-cover-settings { display: none; }
.activity-settings-dialog.settings-cover .editor-property-scroll > .field,
.activity-settings-dialog.settings-cover .editor-property-scroll > .property-grid:not(.activity-cover-settings) { display: none; }
.activity-settings-dialog.settings-cover .activity-cover-settings { display: grid; grid-template-columns: 1fr; gap: 16px; }
.activity-settings-dialog.settings-cover .cover-upload { min-height: 118px; }
.activity-settings-dialog.settings-cover .hero-text-color-picker { min-height: 42px; }
.activity-settings-mask { z-index: 90; padding: 16px; }
.activity-page-editor .activity-settings-dialog { position: static; inset: auto; width: min(440px, 100%); max-height: min(720px, calc(100dvh - 32px)); transform: none; box-shadow: var(--shadow-lg); }
.activity-page-editor .activity-settings-dialog .editor-property-scroll { min-height: 0; padding: 16px; overflow: auto; }
.activity-page-editor .activity-settings-dialog .modal-head > strong { flex: 1; }
.activity-share-tracking { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 3px 8px; align-items: center; padding: 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2); cursor: pointer; }
.activity-share-tracking input { width: 16px; height: 16px; margin: 0; accent-color: var(--primary); }
.activity-share-tracking span { color: var(--text); font-size: calc(13px * var(--jx-fs)); font-weight: 600; }
.activity-share-tracking small { grid-column: 2; color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); line-height: 1.45; }
.activity-form-picker { display: grid; width: 100%; gap: 8px; }
.activity-form-tabs { width: 100%; max-width: none; margin: 0; }
.activity-form-tabs .slide-tabs-item { min-height: 34px; font-size: calc(13px * var(--jx-fs)); }
.activity-form-list { display: grid; max-height: 224px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.activity-form-option { display: grid; grid-template-columns: minmax(0, 1fr) auto; min-height: 58px; align-items: center; gap: 10px; padding: 9px 11px; border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.activity-form-option:last-child { border-bottom: 0; }
.activity-form-option:hover { background: var(--hover); }
.activity-form-option.on { background: var(--primary-light); color: var(--primary-text); }
.activity-form-option > span { display: grid; min-width: 0; gap: 3px; }
.activity-form-option b, .activity-form-option small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activity-form-option b { font-size: calc(13px * var(--jx-fs)); }
.activity-form-option small { color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); }
.activity-form-empty { display: grid; min-height: 72px; place-items: center; padding: 10px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.activity-settings-actions { display: inline-flex; align-items: center; gap: 4px; }
.activity-settings-actions .icon-btn { flex: 0 0 auto; }
.activity-settings-actions .icon-btn.danger { color: var(--danger-light); }
.block-media-slots { display: grid; gap: 8px; }
.block-media-slot { position: relative; display: flex; min-height: 54px; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 11px; overflow: hidden; border: 1px dashed var(--line-strong); border-radius: 7px; background: var(--surface-2); color: var(--primary-text); cursor: pointer; }
.block-media-slot:hover { border-color: var(--primary); background: var(--primary-light); }
.block-media-slot > span { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 7px; }
.block-media-slot b { font-size: calc(13px * var(--jx-fs)); }
.block-media-slot small { position: relative; z-index: 1; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.block-media-slot input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.block-media-slot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .32; }
.block-media-slot:has(img) > span, .block-media-slot:has(img) > small { color: var(--text); text-shadow: 0 1px 2px var(--surface); }
.cover-upload { position: relative; display: grid; min-height: 88px; place-items: center; overflow: hidden; border: 1px dashed var(--line-strong); border-radius: 7px; background: var(--surface-2); color: var(--primary-text); cursor: pointer; }
.cover-upload:hover { border-color: var(--primary); background: var(--primary-light); }
.cover-upload > span { position: relative; z-index: 1; display: grid; justify-items: center; gap: 4px; }
.cover-upload b { font-size: calc(13px * var(--jx-fs)); }
.cover-upload small { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.cover-upload input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.cover-upload img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .34; }
.cover-upload.has-cover > span { color: var(--text); text-shadow: 0 1px 2px var(--surface); }
.preview-block.preview-two_image, .preview-block.preview-three_image { display: block; min-height: 0; padding: 0; background: transparent; }
.preview-media-grid { --preview-grid-gap: 8px; display: grid; width: 100%; gap: var(--preview-grid-gap); }
.preview-two-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); height: 180px; }
.preview-three-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); height: 260px; }
.preview-three-grid > .card-left { grid-column: 1; grid-row: 1 / span 2; }
.preview-three-grid > .preview-media-card:nth-child(2) { grid-column: 2; grid-row: 1; }
.preview-three-grid > .preview-media-card:nth-child(3) { grid-column: 2; grid-row: 2; }
.preview-three-grid.reverse > .card-left { grid-column: 2; grid-row: 1 / span 2; }
.preview-three-grid.reverse > .preview-media-card:nth-child(2) { grid-column: 1; grid-row: 1; }
.preview-three-grid.reverse > .preview-media-card:nth-child(3) { grid-column: 1; grid-row: 2; }
.preview-two-grid > .preview-media-card, .preview-media-grid > span, .preview-media-grid > div { position: relative; display: grid; min-width: 0; min-height: 0; place-items: center; overflow: hidden; border-radius: 8px; background-color: var(--surface-3); color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.activity-preview .preview-two-grid > .preview-media-card, .activity-preview .preview-three-grid > .preview-media-card { background-color: var(--surface-3); background-position: center; background-repeat: no-repeat; background-size: cover; }
.preview-single-card { display: block; width: 100%; height: auto; border-radius: 8px; }
.preview-three-side { display: grid !important; min-height: 0; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: var(--preview-grid-gap); }
.preview-three-side > div { min-height: 0; }
@media (max-width: 767px) { .preview-three-grid { height: 230px; } }
.public-activity .public-media-card { min-width: 0; min-height: 0; border-radius: 8px; background-color: var(--surface-3); background-position: center; background-repeat: no-repeat; background-size: cover; object-fit: cover; }
.public-activity .public-image-pair > img, .public-activity .public-image-triple > img { width: 100%; height: 100%; max-height: none; }
.banner-image-field { position: relative; display: grid; grid-template-columns: 66px minmax(0, 1fr); align-items: center; gap: 8px; width: 100%; min-height: 50px; padding-right: 26px; }
.banner-image-field img { width: 66px; height: 50px; border-radius: 5px; object-fit: cover; }
.banner-image-field .input { min-width: 0; }
.banner-image-field button { position: absolute; top: 2px; right: 2px; display: grid; width: 20px; height: 20px; place-items: center; border: 0; border-radius: 50%; background: var(--activity-shade-60); color: var(--on-accent); cursor: pointer; }
.public-activity .public-image-single { display: block; width: 100%; height: auto; max-height: none; object-fit: contain; }
.public-activity .public-image-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; height: 220px; }
.public-activity .public-image-triple { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 8px; height: 260px; }
.public-activity .public-image-triple > .card-left { grid-column: 1; grid-row: 1 / span 2; }
.public-activity .public-image-triple > .public-media-card:nth-child(2) { grid-column: 2; grid-row: 1; }
.public-activity .public-image-triple > .public-media-card:nth-child(3) { grid-column: 2; grid-row: 2; }
.public-activity .public-image-triple.is-reverse > .card-left { grid-column: 2; grid-row: 1 / span 2; }
.public-activity .public-image-triple.is-reverse > .public-media-card:nth-child(2) { grid-column: 1; grid-row: 1; }
.public-activity .public-image-triple.is-reverse > .public-media-card:nth-child(3) { grid-column: 1; grid-row: 2; }
/* 分享页三图：三个背景图卡片直接参与同一个两列两行网格。 */
.public-activity .activity-section-three_image .public-image-triple > .public-media-card { grid-row: auto; }
.public-activity .activity-section-three_image .public-image-triple > .card-left { grid-row: 1 / span 2; }
.public-activity .activity-section-three_image .public-image-triple.is-reverse > .card-left { grid-column: 2; }
.public-activity .activity-section-three_image .public-image-triple > .public-media-card { background-position: center; background-repeat: no-repeat; background-size: cover; }
.public-activity .public-three-side { display: grid; min-width: 0; min-height: 0; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 767px) { .public-activity .public-image-pair { height: 180px; } .public-activity .public-image-triple { height: 230px; } }
.three-image-layout-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.three-image-layout-options button { display: flex; min-height: 64px; align-items: center; justify-content: center; gap: 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--text-2); font: inherit; font-size: calc(12px * var(--jx-fs)); cursor: pointer; }
.three-image-layout-options button.on { border-color: var(--primary); background: var(--primary-light); color: var(--primary-text); box-shadow: var(--ring); }
.three-image-layout-options .is-reverse { transform: scaleX(-1); }
.activity-page-editor .activity-settings-dialog::before { content: none; }
.activity-page-editor .editor-add-block { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: min(100%, 540px); margin: 0 auto 16px; padding: 14px 10px 10px; }
.activity-page-editor .editor-add-block strong { grid-column: 1 / -1; }
.activity-page-editor .editor-add-block button { min-width: 0; justify-content: center; padding: 0 6px; white-space: nowrap; }
/* 公开活动使用无框内容流；文字组件单独保留内容卡片。 */
.public-activity .activity-content { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; background: transparent; }
.public-activity .public-hero { margin-top: 6px; }
.public-activity .activity-content .public-block { margin: 8px 0 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.public-activity .activity-content .activity-section-text { padding: 22px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); box-shadow: var(--shadow); }
.public-activity .activity-content .activity-section-image,
.public-activity .activity-content .activity-section-two_image,
.public-activity .activity-content .activity-section-three_image,
.public-activity .activity-content .activity-section-banner,
.public-activity .activity-content .activity-section-form { overflow: visible; }
.public-activity .activity-content .activity-section-image { overflow: hidden; border-radius: 8px; }
.public-activity .activity-content .activity-section-image > img { display: block; border-radius: 8px; }
.public-activity .activity-content .public-two,
.public-activity .activity-content .public-image-triple,
.public-activity .activity-content .public-banner { width: 100%; }
/* 报名入口固定在公开活动页底部，避免随内容流滚出视口。 */
.public-activity { padding-bottom: 112px; }
.public-activity .public-signup-bar { position: fixed; right: 16px; bottom: max(16px, env(safe-area-inset-bottom)); left: 16px; z-index: 60; display: block; width: auto; max-width: 728px; min-height: 50px; margin: 0 auto; border: 0; border-radius: 8px; background: var(--activity-accent, var(--primary)); color: var(--on-accent); font: inherit; font-weight: 700; box-shadow: 0 10px 24px var(--activity-shade-20); cursor: pointer; }
.public-activity .public-signup-bar:hover { filter: brightness(.96); }
.public-activity .public-signup-bar:active { transform: translateY(1px); }
@media (min-width: 760px) { .public-activity .public-signup-bar { right: 50%; left: auto; width: min(728px, calc(100vw - 32px)); transform: translateX(50%); } .public-activity .public-signup-bar:active { transform: translateX(50%) translateY(1px); } }
@media (max-width: 767px) {
    .public-activity .activity-content .activity-section-text { padding: 18px; }
}
@media (max-width: 899px) {
    .activity-page-editor .editor-preview-pane { margin-bottom: 0; }
    .activity-page-editor .activity-settings-dialog { overflow: hidden; }
    .activity-page-editor .editor-add-block { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .activity-page-editor .editor-add-block button { flex: none; }
    .public-activity .activity-section-three_image .public-image-triple,
    .public-activity .activity-section-three_image .public-image-triple.is-reverse { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-template-rows: repeat(2, minmax(0, 1fr)) !important; gap: 8px; }
    .public-activity .activity-section-three_image .public-image-triple > .public-media-card { display: block !important; min-height: 0; }
    .public-activity .activity-section-three_image .public-image-triple > .card-left { grid-column: 1 !important; grid-row: 1 / span 2 !important; }
    .public-activity .activity-section-three_image .public-image-triple > .public-media-card:nth-child(2) { grid-column: 2 !important; grid-row: 1 !important; }
    .public-activity .activity-section-three_image .public-image-triple > .public-media-card:nth-child(3) { grid-column: 2 !important; grid-row: 2 !important; }
    .public-activity .activity-section-three_image .public-image-triple.is-reverse > .card-left { grid-column: 2 !important; }
    .public-activity .activity-section-three_image .public-image-triple.is-reverse > .public-media-card:nth-child(2) { grid-column: 1 !important; grid-row: 1 !important; }
    .public-activity .activity-section-three_image .public-image-triple.is-reverse > .public-media-card:nth-child(3) { grid-column: 1 !important; grid-row: 2 !important; }
}
/* 表单编辑不再重复预览：基础信息置顶，字段选择与属性在同一工作区完成。 */
.form-page-editor .editor-shell { display: block; overflow: auto; }
.form-page-editor .editor-preview-pane { display: none; }
.form-page-editor .editor-property-pane { min-height: 100%; border: 0; border-radius: 0; background: transparent; overflow: visible; }
.form-page-editor .editor-property-pane .editor-pane-head { display: none; }
.form-page-editor .editor-property-scroll { max-width: 920px; margin: 0 auto; padding: 0; overflow: visible; }
.form-editor-basics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0 0 14px; padding: 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--student-profile-bg); }
.form-editor-basics .field { margin: 0; }
.form-editor-basics .field-label { margin-bottom: 6px; }
.form-field-card { min-width: 0; margin: 0 0 14px; padding: 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.form-field-list { display: grid; gap: 8px; margin-bottom: 12px; }
.form-field-list-card { display: grid; grid-template-columns: 24px 18px minmax(0, 1fr) auto; min-height: 46px; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--text-2); font: inherit; text-align: left; cursor: pointer; }
.form-field-list-card em { display: grid; width: 22px; height: 22px; place-items: center; border-radius: 50%; background: var(--surface-3); color: var(--text-muted); font-size: 11px; font-style: normal; }
.form-field-list-card b { overflow: hidden; color: var(--text); font-size: calc(13px * var(--jx-fs)); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.form-field-list-card small { color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); white-space: nowrap; }
.form-field-list-card.on { border-color: var(--primary); background: var(--primary-light); }
.form-field-list-card.on em { background: var(--primary); color: var(--on-accent); }
.form-field-list-card.on .ico { color: var(--primary-text); }
.form-field-card .selected-object-actions { margin-bottom: 14px; }
.form-page-editor .editor-add-block { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin: 0; padding: 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.form-page-editor .editor-add-block strong { grid-column: 1 / -1; }
.form-page-editor .editor-add-block button { min-width: 0; justify-content: center; }
@media (max-width: 767px) { .form-page-editor .editor-shell { padding: 10px !important; } .form-page-editor .editor-property-scroll { width: 100%; max-width: none; } .form-editor-basics { grid-template-columns: 1fr; } .form-page-editor .editor-add-block { grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: start; } .form-page-editor .editor-add-block button { min-height: 38px; padding: 4px 2px; gap: 3px; font-size: calc(11px * var(--jx-fs)); white-space: nowrap; } }
@media (min-width: 900px) {
    .activity-page-editor { width: min(1240px, calc(100vw - 32px)); height: min(900px, calc(100dvh - 28px)); max-width: none; max-height: none; border-radius: 16px; }
    .activity-page-editor .editor-shell:has(.activity-settings-mask) { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr); gap: 18px; align-items: stretch; }
    .activity-page-editor .activity-settings-mask { position: static; inset: auto; z-index: auto; display: block; min-width: 0; min-height: 0; align-self: stretch; padding: 0; background: transparent; }
    .activity-page-editor .activity-settings-dialog { position: static; z-index: 2; box-sizing: border-box; width: 100%; height: fit-content !important; min-height: 0; max-width: none; max-height: none; align-self: start; flex: 0 0 auto; transform: none; box-shadow: none; }
    .activity-page-editor .activity-settings-dialog .editor-property-scroll { flex: none; overflow: visible; }
}
@media (hover: hover) and (pointer: fine) {
    .activity-page-editor .editor-shell:has(.activity-settings-mask) { display: grid !important; grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr); gap: 18px; align-items: stretch; }
    .activity-page-editor .activity-settings-mask { position: static; min-width: 0; min-height: 0; align-self: stretch; padding: 0; background: transparent; }
    .activity-page-editor .activity-settings-dialog { position: static; box-sizing: border-box; width: 100%; height: fit-content !important; min-width: 0; min-height: 0; max-width: none; max-height: none; transform: none; box-shadow: none; }
}
@media (max-width: 899px) {
    .modal-mask:has(.activity-page-editor) { align-items: stretch; padding: 0; background: var(--bg); }
    .modal-mask:has(.activity-page-editor) .activity-page-editor { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; border-radius: 0; }
}
@media (min-width: 900px) {
    .public-activity .activity-section-three_image .public-image-triple,
    .public-activity .activity-section-three_image .public-image-triple.is-reverse { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; grid-template-rows: repeat(2, minmax(0, 1fr)) !important; grid-auto-flow: row !important; gap: 8px; }
    .public-activity .activity-section-three_image .public-image-triple > .public-media-card { display: block !important; min-height: 0; }
    .public-activity .activity-section-three_image .public-image-triple > .card-left { grid-column: 1 !important; grid-row: 1 / span 2 !important; }
    .public-activity .activity-section-three_image .public-image-triple > .public-media-card:nth-child(2) { grid-column: 2 !important; grid-row: 1 !important; }
    .public-activity .activity-section-three_image .public-image-triple > .public-media-card:nth-child(3) { grid-column: 2 !important; grid-row: 2 !important; }
    .public-activity .activity-section-three_image .public-image-triple.is-reverse > .card-left { grid-column: 2 !important; }
    .public-activity .activity-section-three_image .public-image-triple.is-reverse > .public-media-card:nth-child(2) { grid-column: 1 !important; grid-row: 1 !important; }
    .public-activity .activity-section-three_image .public-image-triple.is-reverse > .public-media-card:nth-child(3) { grid-column: 1 !important; grid-row: 2 !important; }
}
@media (max-width: 767px) {
    .activity-settings-mask { padding: 0; }
    .activity-page-editor .activity-settings-dialog { width: 100%; max-height: 92dvh; border-radius: 16px 16px 0 0; }
    .modal-mask:has(.public-poster-modal),
    .modal-mask:has(.public-signup-modal) { padding: 0; }
    .modal-mask:has(.public-poster-modal) .public-poster-modal,
    .modal-mask:has(.public-signup-modal) .public-signup-modal { width: 100%; max-width: none; max-height: 92dvh; margin: 0; border-radius: 16px 16px 0 0; }
}

/* 封面图片的文字颜色：预览与公开页使用同一个活动配置。 */
/* 活动图片上传：点击整张卡片上传或更换，不显示浏览器原生文件控件。 */
.activity-image-upload { position: relative; display: grid; min-height: 154px; place-items: center; overflow: hidden; border: 1px dashed var(--line-strong); border-radius: 10px; background: var(--surface-2); color: var(--primary-text); cursor: pointer; }
.activity-image-upload:hover { border-color: var(--primary); background: var(--primary-light); }
.activity-image-upload input { position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.activity-image-upload > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.activity-image-upload::after { position: absolute; inset: 0; background: var(--activity-shade-0); content: ""; transition: background .15s; }
.activity-image-upload.hasImage:hover::after { background: var(--activity-shade-30); }
.activity-image-upload > span { position: relative; z-index: 2; display: grid; justify-items: center; gap: 5px; padding: 12px; color: var(--primary-text); text-align: center; }
.activity-image-upload.hasImage > span { opacity: 0; color: var(--on-accent); text-shadow: 0 1px 2px var(--activity-shade-48); transition: opacity .15s; }
.activity-image-upload.hasImage:hover > span,
.activity-image-upload.hasImage:focus-within > span { opacity: 1; }
.activity-image-upload b { font-size: calc(13px * var(--jx-fs)); }
.activity-image-upload small { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.activity-image-upload.hasImage small { color: var(--activity-fg-86); }

.hero-text-color-picker { display: inline-flex; min-height: 40px; align-items: center; gap: 9px; padding: 0 10px 0 7px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); color: var(--text-2); font-size: calc(13px * var(--jx-fs)); }
.hero-text-color-picker input { width: 25px; height: 25px; padding: 0; border: 0; border-radius: 6px; background: transparent; cursor: pointer; }
.hero-text-color-picker span { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 12px; }
.activity-preview-hero,
.activity-preview-hero span,
.activity-preview-hero strong,
.activity-preview-hero small { color: var(--activity-hero-fg, var(--on-accent)); }
.public-activity .public-hero .activity-hero-copy,
.public-activity .public-hero .activity-hero-copy h1,
.public-activity .public-hero .activity-hero-copy p { color: var(--activity-hero-fg, var(--on-accent)); }

/* 分享归因与海报：公开页的主次操作按 7:3 稳定分配。 */
.form-track-sharer { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 3px 8px; align-items: center; padding: 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2); cursor: pointer; }
.form-track-sharer input { width: 16px; height: 16px; margin: 0; accent-color: var(--primary); }
.form-track-sharer span { color: var(--text); font-size: calc(13px * var(--jx-fs)); font-weight: 600; }
.form-track-sharer small { grid-column: 2; color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); line-height: 1.45; }
.public-activity .public-action-bar { position: fixed; right: 16px; bottom: max(16px, env(safe-area-inset-bottom)); left: 16px; z-index: 60; display: flex; gap: 8px; max-width: 728px; margin: 0 auto; }
.public-activity .public-action-bar .public-signup-bar, .public-activity .public-action-bar .public-poster-bar { position: static; min-width: 0; min-height: 50px; margin: 0; border: 0; border-radius: 8px; font: inherit; font-weight: 700; cursor: pointer; }
.public-activity .public-action-bar .public-signup-bar { flex: 7 1 0; width: auto; transform: none; background: var(--activity-accent, var(--primary)); color: var(--on-accent); box-shadow: 0 10px 24px var(--activity-shade-20); }
.public-activity .public-action-bar .public-poster-bar { flex: 3 1 0; background: var(--surface); color: var(--activity-accent, var(--primary)); border: 1px solid var(--activity-accent, var(--primary)); }
.public-activity .public-action-bar:not(.has-poster) .public-signup-bar { flex: 1; }
.public-poster-modal { width: min(480px, calc(100vw - 28px)); }
.public-poster-modal .modal-body { display: grid; gap: 14px; }
.public-orders-modal { width: min(560px, calc(100vw - 24px)); }
.public-orders-body { display: grid; gap: 10px; max-height: min(68dvh, 560px); overflow: auto; }
.public-order-card { display: grid; gap: 9px; padding: 13px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.public-order-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.public-order-head strong { min-width: 0; overflow: hidden; color: var(--text); font-size: calc(14px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.public-order-meta { display: flex; flex-wrap: wrap; gap: 4px 10px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.public-order-answer { display: grid; grid-template-columns: minmax(72px, .35fr) minmax(0, 1fr); gap: 10px; padding-top: 8px; border-top: 1px solid var(--line); font-size: calc(12px * var(--jx-fs)); }
.public-order-answer span { color: var(--text-muted); }
.public-order-answer b { overflow-wrap: anywhere; color: var(--text); font-weight: 500; }
.public-poster-image { display: block; width: 100%; height: auto; border-radius: 6px; background: var(--surface-2); }
@media (min-width: 760px) { .public-activity .public-action-bar { right: 50%; left: auto; width: min(728px, calc(100vw - 32px)); transform: translateX(50%); } }

/* 公开报名图片上传：缩略图与添加入口同屏呈现。 */
.public-image-uploader { display: grid; gap: 8px; }
.public-image-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.public-image-thumb { position: relative; aspect-ratio: 1; overflow: hidden; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2); }
.public-image-thumb img { width: 100%; height: 100%; max-height: none !important; object-fit: cover; }
.public-image-thumb button { position: absolute; top: 4px; right: 4px; display: grid; width: 24px; height: 24px; place-items: center; border: 0; border-radius: 50%; background: var(--activity-shade-58); color: var(--on-accent); cursor: pointer; }
.public-image-pick { display: grid; min-height: 88px; place-items: center; gap: 3px; padding: 10px; border: 1px dashed var(--activity-accent, var(--primary)); border-radius: 8px; background: var(--surface-2); color: var(--activity-accent, var(--primary)); cursor: pointer; text-align: center; }
.public-image-pick input { position: absolute; width: 1px; height: 1px; overflow: hidden; opacity: 0; }
.public-image-pick span { color: var(--text); font-size: calc(13px * var(--jx-fs)); font-weight: 600; }
.public-image-pick small { color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); }
.public-image-pick.disabled { border-color: var(--line); color: var(--text-muted); cursor: not-allowed; }
@media (max-width: 420px) { .public-image-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }



/* 封面颜色与图片在手机端也保持并排，避免基础设置出现无效空白。 */
@media (max-width: 899px) {
    .activity-cover-settings { grid-template-columns: minmax(104px, .72fr) minmax(0, 1.28fr); align-items: start; }
    .activity-cover-settings .cover-upload { min-height: 88px; }
}

/* 报名数据：默认单行摘要；点击一条后只展开其完整信息。 */
.submissions-modal .stat-grid.compact {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    margin-bottom: 14px;
}

.submissions-modal .stat-grid.compact .stat {
    min-width: 0;
    padding: 10px;
}

.submissions-modal .stat-grid.compact .stat-num {
    font-size: calc(18px * var(--jx-fs));
}

.submissions-modal .stat-grid.compact .stat-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.submissions-modal .list {
    display: grid;
    gap: 8px;
    background: transparent;
}

.submission-card {
    position: relative;
    align-items: stretch;
    min-height: 0;
    margin: 0;
    padding: 9px 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    cursor: pointer;
    transition: background .15s, border-color .15s, box-shadow .15s;
}

.submission-card:last-child {
    border-bottom: 1px solid var(--line);
}

.submission-card:hover {
    border-color: var(--line-2);
    background: var(--surface-2);
}

.submission-card.expanded {
    border-color: var(--primary);
    background: var(--surface-2);
    box-shadow: 0 0 0 1px var(--primary-light);
}

.submission-card .list-item-main {
    min-width: 0;
}

.submission-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.submission-card-head .list-item-title {
    display: flex;
    align-items: center;
    min-width: 0;
    gap: 6px;
    margin: 0;
    font-size: calc(13.5px * var(--jx-fs));
}

.submission-card-head .tag {
    flex: 0 0 auto;
}

.submission-card-actions {
    display: none;
    flex: 0 0 auto;
    align-items: center;
    gap: 5px;
}

.submission-card.expanded .submission-card-actions {
    display: flex;
}

.submission-card-actions .icon-btn {
    width: 26px;
    min-width: 26px;
    height: 26px;
    min-height: 26px;
    padding: 0;
    border-radius: 50%;
    background: var(--surface);
}

.submission-card-actions .icon-btn.on {
    border-color: var(--ok);
    background: var(--ok-light);
    color: var(--ok-text);
}

.submission-card-actions .icon-btn.danger {
    color: var(--danger-text);
}

.submission-card-actions .icon-btn.danger.on {
    border-color: var(--danger);
    background: var(--danger-light);
    color: var(--danger-text);
}

.submission-card .list-item-sub {
    display: flex;
    gap: 4px 10px;
    margin-top: 2px;
    overflow: hidden;
    color: var(--text-muted);
    font-size: calc(11.5px * var(--jx-fs));
    white-space: nowrap;
}

.submission-card .submission-sharer {
    display: none;
}

.submission-card.expanded .submission-sharer {
    display: inline;
}

.submission-answer-list {
    display: grid;
    gap: 8px;
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px solid var(--line);
}

.submission-answer {
    display: grid;
    grid-template-columns: minmax(74px, .34fr) minmax(0, 1fr);
    gap: 9px;
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.45;
}

.submission-answer > span {
    color: var(--text-muted);
}

.submission-answer-value {
    min-width: 0;
}

.submission-answer-value > b {
    display: block;
    overflow-wrap: anywhere;
    color: var(--text);
    font-weight: 500;
}

.submission-image-list {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin-top: 7px;
}

.submission-image-list a {
    display: block;
    width: 68px;
    height: 68px;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface-3);
}

.submission-image-list img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 767px) {
    .list-item.stack.submission-card {
        flex-direction: row;
        align-items: stretch;
        gap: 0;
    }
}

/* 报名数据：手机为全宽贴底面板，iPad/桌面保持独立的居中数据窗口。 */
@media (max-width: 767px) {
    .modal-mask:has(.submissions-modal) { align-items: flex-end; padding: 0; }
    .submissions-modal { width: 100vw; max-width: none; max-height: 88dvh; margin: 0; border-radius: 16px 16px 0 0; }
    .submissions-modal .modal-head { border-radius: 16px 16px 0 0; }
    .submissions-modal .modal-body { padding: 14px; }
}
@media (min-width: 768px) {
    .modal-mask:has(.submissions-modal) { align-items: center; padding: 24px; }
    .submissions-modal { width: min(720px, calc(100vw - 48px)); max-width: 720px; max-height: min(760px, calc(100dvh - 48px)); margin: 0; border-radius: 14px; }
    .submissions-modal .modal-head { border-radius: 14px 14px 0 0; }
    .submissions-modal .stat-grid.compact { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 微信通知：桌面和 iPad 以两个工作区域并列呈现；手机保持原有单列清单。 */
.wx-notify-card .card-body { display: grid; gap: 16px; }
.wx-notify-section { min-width: 0; padding: 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
.wx-notify-section > .field-label { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--text); font-weight: 700; }
.wx-notify-section > .field-hint { min-height: 38px; margin-top: 5px; }
.wx-notify-recipient-list { display: grid; gap: 8px; }
.wx-notify-recipient-list .list-item { min-width: 0; margin: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); }
.wx-notify-recipient-list .list-item-main { min-width: 0; }
.wx-notify-recipient-list .list-item-title { flex-wrap: wrap; }
.wx-notify-recipient-list .btn { align-self: flex-start; }
.wx-notify-overdue .form-grid { max-width: 360px; }
.wx-notify-overdue .form-actions { margin-bottom: 0; }

/* 公开活动弹窗：标题、关闭图标和主操作均继承活动主题色。 */
.public-poster-modal .modal-head,
.public-signup-modal .modal-head {
    position: relative;
    padding-right: 60px;
    background: var(--activity-accent, var(--primary));
    color: var(--on-accent);
}

.public-poster-modal .modal-head > .icon-btn,
.public-poster-modal .modal-head > .close,
.public-signup-modal .modal-head > .icon-btn,
.public-signup-modal .modal-head > .close {
    position: absolute;
    top: 50%;
    right: 12px;
    width: 36px;
    height: 36px;
    min-width: 36px;
    padding: 0;
    transform: translateY(-50%);
    color: var(--on-accent);
}

.public-poster-modal .modal-head > .icon-btn:hover,
.public-poster-modal .modal-head > .icon-btn:active,
.public-poster-modal .modal-head > .close:hover,
.public-poster-modal .modal-head > .close:active,
.public-signup-modal .modal-head > .icon-btn:hover,
.public-signup-modal .modal-head > .icon-btn:active,
.public-signup-modal .modal-head > .close:hover,
.public-signup-modal .modal-head > .close:active {
    background: var(--activity-fg-18);
    color: var(--on-accent);
}

.public-poster-modal .btn-primary,
.public-signup-modal .btn-primary {
    background: var(--activity-accent, var(--primary));
    color: var(--on-accent);
}

.public-poster-modal .btn-primary:hover,
.public-signup-modal .btn-primary:hover {
    filter: brightness(.96);
}

/* 公开活动报名：仅 iPad/桌面使用居中双列弹窗；手机继续使用原底部单列面板。 */
@media (min-width: 768px) {
    .modal-mask:has(.public-signup-modal) { align-items: center; padding: 24px; }
    .public-signup-modal { width: min(820px, calc(100vw - 48px)); max-width: 820px; max-height: min(780px, calc(100dvh - 48px)); margin: 0; border-radius: 10px; }
    .public-signup-modal .modal-head { padding: 16px 60px 16px 20px; }
    .public-signup-modal .modal-body:not(.empty) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 18px; padding: 20px; }
    .public-signup-modal .modal-body > p,
    .public-signup-modal .modal-body > .field:has(textarea),
    .public-signup-modal .modal-body > .field:has(.public-image-uploader),
    .public-signup-modal .modal-body > .btn { grid-column: 1 / -1; }
    .public-signup-modal .modal-body > p { margin: 0; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
    .public-signup-modal .modal-body > .field { min-width: 0; margin: 0; }
    .public-signup-modal .modal-body > .btn { min-height: 46px; margin-top: 4px; }
}

@media (min-width: 768px) {
    .wx-notify-card .card-body { grid-template-columns: minmax(0, 1.25fr) minmax(280px, .9fr); align-items: start; }
    .wx-notify-recipient-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .wx-notify-teacher-list { grid-template-columns: 1fr; max-height: 326px; overflow-y: auto; }
    .wx-notify-overdue .form-grid { margin-top: 16px; }
}

@media (max-width: 767px) {
    .wx-notify-card .card-body { gap: 12px; }
    .wx-notify-section { padding: 0; border: 0; border-radius: 0; background: transparent; }
    .wx-notify-section > .field-hint { min-height: 0; }
    .wx-notify-overdue { padding-top: 14px; border-top: 1px solid var(--line); }
    .wx-notify-recipient-list .list-item { border-right: 0; border-left: 0; border-radius: 0; background: transparent; }
}

/* 活动编辑器：电脑与 iPad 回归居中弹窗；手机仍沿用上方的全屏编辑规则。 */
@media (min-width: 768px) {
    .modal-mask:has(.activity-page-editor) { align-items: center; padding: 24px; background: var(--overlay); }
    .activity-page-editor { width: min(1080px, calc(100vw - 48px)); height: min(860px, calc(100dvh - 48px)); max-width: 1080px; max-height: 860px; margin: 0; border-radius: 10px; box-shadow: var(--shadow-lg); }
    .activity-page-editor .modal-head { border-radius: 10px 10px 0 0; }
    .activity-page-editor .modal-body.editor-shell { overflow: auto; }
    .activity-page-editor .editor-preview-pane { min-height: 0; }
}

/* 微信通知人员行与扫码结果：状态、操作和反馈在同一视觉层级内。 */
.wx-notify-recipient-list .list-item { padding: 12px; box-shadow: none; }
.wx-notify-recipient-list .list-item-title { align-items: center; gap: 6px; }
.wx-notify-recipient-list .list-item-title > span:first-child { color: var(--text); font-weight: 700; }
.wx-notify-recipient-list .tag { flex: 0 0 auto; }
.wx-notify-recipient-list .btn { margin-top: 9px; }
.wx-bind-modal .modal-body { display: flex; min-width: 0; flex-direction: column; align-items: center; }
.wx-bind-modal .input { width: 100%; }
.wx-bind-modal canvas { margin-top: 12px; }
.wx-bind-state { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; margin-top: 10px; padding: 0 10px; border-radius: 7px; font-size: calc(13px * var(--jx-fs)); font-weight: 700; }
.wx-bind-state.ok { background: var(--ok-light); color: var(--ok-text); }
.wx-bind-state.warn { background: var(--warn-light); color: var(--warn-text); }

@media (min-width: 768px) {
    .wx-notify-card .card-head { min-height: 54px; }
    .wx-notify-section { padding: 16px; }
    .wx-notify-recipient-list .list-item { min-height: 118px; }
}

@media (max-width: 767px) {
    .wx-notify-card { border-radius: 0; border-right: 0; border-left: 0; }
    .wx-notify-card .card-body { padding: 14px 16px 18px; }
    .wx-notify-section { padding: 0; }
    .wx-notify-section > .field-label { font-size: calc(14px * var(--jx-fs)); }
    .wx-notify-overdue { margin-top: 4px; padding-top: 18px; }
    .wx-notify-recipient-list { gap: 10px; }
    .wx-notify-recipient-list .list-item { padding: 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
    .wx-notify-teacher-list { max-height: none; overflow: visible; }
    .wx-notify-overdue .form-grid { max-width: none; }
}

/* 微信通知设置：iPhone 设置页式分组与设置行。 */
.wx-settings-panel { margin-top: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); overflow: hidden; }
.wx-settings-title { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.wx-settings-title > div, .wx-group-head > div, .wx-person-main, .wx-delay-row > div { min-width: 0; }
.wx-settings-title strong, .wx-group-head strong, .wx-person-main strong, .wx-delay-row strong { display: block; color: var(--text); font-size: calc(14px * var(--jx-fs)); font-weight: 700; line-height: 1.3; }
.wx-settings-title small, .wx-group-head small, .wx-person-main span, .wx-delay-row small { display: block; margin-top: 2px; overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.wx-settings-icon, .wx-group-icon { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; border-radius: 8px; }
.wx-settings-icon { width: 32px; height: 32px; background: var(--primary-light); color: var(--primary-text); }
.wx-settings-groups { display: grid; gap: 12px; padding: 12px; background: var(--surface-2); }
.wx-settings-group { min-width: 0; }
.wx-group-head { display: flex; align-items: center; gap: 9px; margin: 0 2px 8px; }
.wx-group-icon { width: 28px; height: 28px; background: var(--info-light); color: var(--info-text); }
.wx-group-icon.complete { background: var(--ok-light); color: var(--ok-text); }
.wx-group-icon.overdue { background: var(--warn-light); color: var(--warn-text); }
.wx-settings-list { overflow: hidden; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.wx-settings-person { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 10px; min-height: 58px; padding: 9px 11px; border-bottom: 1px solid var(--line); cursor: default; }
.wx-notify-complete .wx-settings-person { cursor: pointer; }
.wx-settings-person:last-child { border-bottom: 0; }
.wx-settings-person.selected { background: var(--primary-light); }
.wx-bind-action { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-height: 28px; padding: 0 8px; border: 0; border-radius: 6px; background: transparent; color: var(--primary-text); font: inherit; font-size: calc(12px * var(--jx-fs)); font-weight: 600; cursor: pointer; }
.wx-bind-action:hover { background: var(--primary-light); }
.wx-bind-action:disabled { opacity: .45; cursor: not-allowed; }
.wx-choice { display: inline-flex; width: 20px; height: 20px; align-items: center; justify-content: center; border: 1px solid var(--line-2); border-radius: 50%; color: transparent; }
.wx-choice.on { border-color: var(--primary); background: var(--primary); color: var(--on-accent); }
.wx-notify-recipient-person { grid-template-columns: minmax(0, 1fr) auto; gap: 9px 10px; align-items: center; }
.wx-notify-recipient-person .wx-bind-action { min-width: 52px; }
.wx-notify-recipient-options { display: grid; grid-column: 1 / -1; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
.wx-notify-recipient-options .check { justify-content: center; min-width: 0; min-height: 32px; padding: 0 6px; white-space: nowrap; }
@media (max-width: 767px) { .wx-notify-recipient-person { grid-template-columns: minmax(0, 1fr) auto; gap: 8px; } .wx-notify-recipient-person .wx-bind-action { min-width: 42px; } .wx-notify-recipient-options { gap: 5px; } .wx-notify-recipient-options .check { padding: 0 3px; font-size: calc(11px * var(--jx-fs)); } }
.wx-settings-empty { min-height: 58px; display: flex; align-items: center; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--text-muted); font-size: calc(12.5px * var(--jx-fs)); }
.wx-delay-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 62px; margin-top: 10px; padding: 10px 11px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.wx-delay-row label { display: flex; flex: 0 0 auto; align-items: center; gap: 6px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.wx-delay-row .input { width: 68px; min-height: 34px; padding: 5px 8px; text-align: center; }
.wx-save-notify { width: 100%; min-height: 40px; margin-top: 10px; }
@media (min-width: 768px) { .wx-settings-groups { grid-template-columns: minmax(0, 1.15fr) minmax(300px, .85fr); align-items: start; gap: 16px; padding: 16px; } .wx-notify-teacher-list { max-height: 210px; overflow-y: auto; } }
@media (max-width: 767px) { .wx-settings-panel { margin-right: -10px; margin-left: -10px; border-right: 0; border-left: 0; border-radius: 0; } .wx-settings-title { padding: 14px 16px; } .wx-settings-groups { gap: 16px; padding: 12px 16px 18px; } .wx-settings-person { min-height: 60px; padding: 10px; } .wx-settings-title small, .wx-group-head small, .wx-person-main span, .wx-delay-row small { white-space: normal; } .wx-bind-action { min-width: 42px; padding: 0 6px; } }

/* 设置模块内的独立页面切换。 */
.settings-tabs { display: inline-flex; gap: 2px; margin-top: 12px; padding: 4px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
.settings-tabs button { display: inline-flex; min-height: 42px; align-items: center; justify-content: center; gap: 6px; padding: 0 14px; border: 0; border-radius: 6px; background: transparent; color: var(--text-muted); font: inherit; font-size: calc(13px * var(--jx-fs)); font-weight: 600; cursor: pointer; }
.settings-tabs button.on { background: var(--surface); color: var(--primary-text); box-shadow: var(--shadow); }
@media (max-width: 767px) { .settings-tabs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: 100%; } .settings-tabs button { min-width: 0; } }

/* 系统设置与微信对接共用同一套设置面板语言。 */
.settings-general-panel,
.wx-settings-panel {
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
}

.settings-panel-title,
.wx-settings-title {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 15px 16px;
    border-bottom: 1px solid var(--line);
}

.settings-panel-title > div,
.wx-settings-title > div {
    min-width: 0;
}

.settings-panel-title strong,
.wx-settings-title strong {
    display: block;
    color: var(--text);
    font-size: calc(14px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.3;
}

.settings-panel-title small,
.wx-settings-title small {
    display: block;
    margin-top: 2px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.35;
}

.settings-panel-icon,
.wx-settings-icon {
    display: inline-flex;
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--primary-light);
    color: var(--primary-text);
}

.settings-panel-list {
    display: grid;
    gap: 8px;
    padding: 12px;
    background: var(--surface-2);
}

.settings-general-panel .list-item.settings-row {
    grid-template-columns: 32px minmax(0, 1fr);
    gap: 8px 10px;
    margin: 0;
    padding: 10px;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
}

.settings-general-panel .settings-icon {
    display: inline-flex;
    width: 32px;
    height: 32px;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 8px;
    background: var(--info-light);
    color: var(--info-text);
}

.settings-general-panel .settings-copy .field-label {
    margin: 1px 0 2px;
    color: var(--text);
    font-size: calc(13.5px * var(--jx-fs));
}

.settings-general-panel .settings-desc {
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.4;
}

.settings-general-panel .settings-control {
    grid-column: 2;
    min-height: 34px;
    margin-top: 4px;
}

.settings-general-panel .settings-actions .btn {
    min-height: 30px;
    padding: 0 8px;
    border-color: transparent;
    background: var(--surface-2);
    color: var(--text-2);
}

.settings-general-panel .settings-actions .btn:hover {
    background: var(--hover);
    color: var(--text);
}

.settings-general-panel .settings-field .check {
    min-height: 32px;
    padding: 0 9px;
    border-radius: 7px;
}

.settings-general-panel .settings-input {
    max-width: 144px;
    min-height: 34px;
}

@media (min-width: 768px) {
    .settings-panel-list {
        padding: 16px;
    }

    .settings-general-panel .list-item.settings-row {
        grid-template-columns: 32px minmax(0, 1fr) minmax(270px, 320px);
        min-height: 64px;
        gap: 14px;
        padding: 11px 12px;
    }

    .settings-general-panel .settings-control {
        grid-column: 3;
        justify-content: flex-end;
        margin-top: 0;
    }
}

@media (max-width: 767px) {
    .settings-general-panel,
    .wx-settings-panel {
        margin: 0;
        border: 1px solid var(--line);
        border-radius: 10px;
    }

    .settings-panel-title,
    .wx-settings-title {
        padding: 14px 16px;
    }

    .settings-panel-list {
        padding: 12px 16px 18px;
    }
}

/* 设置页顶部与内容面板遵循同一条内容轴。 */
.settings-page .page-head {
    margin-bottom: 8px;
}

.settings-page .locked-tip {
    margin: 0 0 10px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-2);
}

.settings-page .locked-tip .ico {
    color: var(--primary-text);
}

.settings-page .settings-tabs {
    width: 100%;
    margin: 0 0 10px;
    background: var(--surface-2);
}

.settings-page .settings-general-panel,
.settings-page .wx-settings-panel {
    margin-top: 0;
}

/* 停课日期：机构级日期范围，不单独创建审批或排课页面。 */
.settings-page .lesson-closure-panel {
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
}

.lesson-closure-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-bottom: 1px solid var(--line);
}

.lesson-closure-head .settings-panel-title {
    flex: 1 1 auto;
    min-width: 0;
    border-bottom: 0;
}

.lesson-closure-head > .btn {
    flex: 0 0 auto;
    margin-right: 14px;
}

.lesson-closure-list {
    background: var(--surface-2);
}

.lesson-closure-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    min-height: 62px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
}

.lesson-closure-row:last-child { border-bottom: 0; }
.lesson-closure-row strong { display: block; color: var(--text); font-size: calc(13.5px * var(--jx-fs)); }
.lesson-closure-row span { display: inline-flex; align-items: center; gap: 5px; margin-top: 4px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.lesson-closure-actions { display: inline-flex; align-items: center; gap: 5px; }
.lesson-closure-empty { min-height: 180px; }
.lesson-closure-modal .property-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (max-width: 767px) {
    .lesson-closure-head { align-items: flex-start; }
    .lesson-closure-head .settings-panel-title { padding-right: 4px; }
    .lesson-closure-head > .btn { margin: 14px 12px 0 0; white-space: nowrap; }
    .lesson-closure-row { padding: 11px 12px; }
}

/* 系统设置保存条固定在页面底部，始终可见。 */
.settings-page.has-submit-bar {
    padding-bottom: calc(92px + var(--tabbar-h) + env(safe-area-inset-bottom));
}

.settings-page .submit-bar {
    position: fixed;
    right: 0;
    bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
    left: 0;
    margin: 0;
    padding: 12px 14px;
    border: 0;
    border-top: 1px solid var(--line);
    border-radius: 0;
    background: var(--surface);
    box-shadow: none;
}

@media (min-width: 1024px) {
    .settings-page .submit-bar {
        bottom: 0;
        left: var(--sidebar-w);
    }
}

/* 成长日志：列表入口保持为紧凑文字，页面内是完整时间轴。 */
.student-growth-btn {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    min-height: 24px;
    margin: 0;
    padding: 0 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--primary-light);
    color: var(--primary-text);
    font: inherit;
    font-size: calc(11px * var(--jx-fs));
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
}

.student-growth-btn:active {
    background: var(--primary-light);
}

.growth-layout {
    min-width: 0;
}

.growth-side {
    padding: 14px;
}

.growth-side-person {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.growth-side-person > div {
    min-width: 0;
}

.growth-side-name {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    font-weight: 700;
}

.growth-side-meta {
    margin-top: 3px;
    overflow: hidden;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
    text-overflow: ellipsis;
    white-space: nowrap;
}

.growth-side-extra {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
}

.growth-side-stat {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.growth-side-stat strong {
    font-size: calc(22px * var(--jx-fs));
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.growth-side-stat span,
.growth-side-flag {
    color: var(--text-2);
    font-size: calc(12px * var(--jx-fs));
    line-height: 1.5;
}

.growth-side-flag {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-top: 8px;
}

.growth-side-flag.off {
    color: var(--text-muted);
}

.growth-timeline {
    display: grid;
    gap: 14px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.growth-item {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    gap: 14px;
    min-width: 0;
}

.growth-rail {
    position: relative;
    min-width: 0;
    padding-top: 2px;
}

.growth-rail time {
    display: grid;
    gap: 2px;
    color: var(--text);
    font-size: calc(13px * var(--jx-fs));
    font-weight: 700;
    line-height: 1.25;
}

.growth-rail time small {
    color: var(--text-muted);
    font-size: calc(11px * var(--jx-fs));
    font-weight: 500;
}

.growth-item:not(:last-child) .growth-rail::after {
    position: absolute;
    top: 18px;
    right: -4px;
    bottom: -22px;
    width: 1px;
    background: var(--line);
    content: "";
}

.growth-rail.is-follow {
    min-height: 28px;
}

.growth-dot {
    position: absolute;
    top: 6px;
    right: -8px;
    display: block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-light);
}

.growth-rail.is-follow .growth-dot {
    top: 8px;
    width: 7px;
    height: 7px;
    border: 2px solid var(--primary);
    background: var(--surface);
    box-shadow: none;
}

.growth-card {
    min-width: 0;
    padding: 12px 14px 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
}

.growth-card-head {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    min-height: 32px;
    margin: -4px -6px 8px;
}

.growth-card-head strong {
    flex: 1;
    min-width: 0;
    font-size: calc(15px * var(--jx-fs));
    line-height: 1.45;
}

.growth-card-heading {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.growth-source-tag {
    flex: none;
    gap: 3px;
}

.growth-page-hint {
    color: var(--text-muted);
}

.growth-card-tools {
    display: flex;
    flex: none;
    gap: 2px;
}

.growth-card-text {
    margin: 8px 0 0;
    color: var(--text);
    font-size: calc(14px * var(--jx-fs));
    line-height: 1.7;
    white-space: pre-wrap;
    word-break: break-word;
}

.growth-photos {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    margin-top: 10px;
}

.growth-photo {
    display: block;
    aspect-ratio: 1;
    padding: 0;
    overflow: hidden;
    border: 0;
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text-muted);
    font: inherit;
    font-size: calc(11px * var(--jx-fs));
    cursor: pointer;
}

.growth-photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.growth-card-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin-top: 10px;
    color: var(--text-muted);
    font-size: calc(12px * var(--jx-fs));
}

.growth-more {
    width: 100%;
    min-height: 40px;
    margin-top: 12px;
}

.growth-textarea {
    min-height: 88px;
}

.growth-lightbox {
    align-items: center;
    padding: 18px;
    background: var(--activity-shade-72);
}

.growth-lightbox img {
    display: block;
    width: auto;
    max-width: min(1000px, 100%);
    max-height: calc(100dvh - 36px);
    object-fit: contain;
    border-radius: 8px;
}

.growth-lightbox-close {
    position: absolute;
    top: 12px;
    right: 12px;
    background: var(--activity-shade-46);
    color: var(--on-accent);
}

.growth-parent {
    margin-top: 12px;
}

@media (max-width: 767px) {
    .growth-manage .page-actions {
        width: 100%;
        margin-left: 0;
    }

    .growth-manage .page-actions .btn {
        flex: 1 1 0;
        min-height: 42px;
    }

    .growth-side-stat,
    .growth-side .field-hint {
        display: none;
    }

    .growth-side-extra {
        margin-top: 8px;
        padding-top: 8px;
    }

    .growth-timeline {
        gap: 16px;
        margin-left: 7px;
        padding-left: 16px;
        border-left: 2px solid var(--line);
    }

    .growth-item {
        display: block;
    }

    .growth-rail {
        display: flex;
        align-items: baseline;
        margin: 0 0 6px;
    }

    .growth-rail::before,
    .growth-rail::after {
        display: none;
    }

    .growth-dot {
        top: 6px;
        right: auto;
        left: -24px;
    }

    .growth-rail time {
        display: inline-flex;
        align-items: baseline;
        gap: 6px;
    }

    .growth-rail.is-follow .growth-dot {
        top: 8px;
        left: -23px;
    }

    .growth-rail.is-follow {
        display: block;
        min-height: 14px;
        margin-bottom: 4px;
    }

    .growth-photos {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .modal-mask:has(.growth-form-modal) {
        align-items: flex-end;
        padding: 0;
    }

    .growth-form-modal {
        width: 100%;
        max-width: none;
        max-height: 92dvh;
        border-radius: 16px 16px 0 0;
    }

    .growth-lightbox {
        padding: 0;
    }

    .growth-lightbox img {
        width: 100%;
        max-width: none;
        max-height: 100dvh;
        border-radius: 0;
    }
}

@media (min-width: 768px) and (max-width: 1023px) {
    .growth-layout,
    .growth-parent {
        max-width: 760px;
        margin-right: auto;
        margin-left: auto;
    }

    .growth-side {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
        margin-bottom: 16px;
    }

    .growth-side-extra {
        flex: none;
        max-width: 240px;
        margin: 0;
        padding: 0;
        border: 0;
        text-align: right;
    }

    .growth-side-stat,
    .growth-side .field-hint {
        display: none;
    }

    .growth-side-flag {
        margin: 0;
    }

    .growth-main .growth-more,
    .growth-parent .growth-more {
        width: auto;
        margin-left: 106px;
    }
}

@media (min-width: 768px) {
    .growth-form-modal {
        width: min(640px, calc(100vw - 48px));
        max-width: 640px;
    }
}

@media (min-width: 1024px) {
    .growth-layout {
        display: grid;
        grid-template-columns: 260px minmax(0, 720px);
        gap: 18px;
        align-items: start;
        justify-content: start;
    }

    .growth-side {
        position: sticky;
        top: 12px;
    }

    .growth-photos {
        grid-template-columns: repeat(4, minmax(0, 96px));
    }

    .growth-main .growth-more {
        width: auto;
        margin-left: 106px;
    }

    .growth-parent {
        max-width: 760px;
    }
}

@media (hover: hover) and (min-width: 768px) {
    .student-growth-btn:hover {
        border-color: var(--primary);
        background: var(--primary-light);
    }

    .growth-card:hover {
        border-color: var(--line-strong);
    }

    .growth-photo:hover img {
        transform: scale(1.03);
    }

    .growth-photo img {
        transition: transform .18s ease;
    }
}

/* Desktop form editor: separate field navigation from the active field settings. */
@media (min-width: 900px) {
    .form-page-editor {
        width: min(1120px, calc(100vw - 72px), calc((100dvh - 72px) / 3 * 4));
        height: min(840px, calc(100dvh - 72px), calc((100vw - 72px) * 3 / 4));
        max-width: none;
        max-height: none;
        aspect-ratio: 4 / 3;
    }

    .modal-mask:has(.form-page-editor) {
        align-items: center;
        padding: 24px;
    }

    .form-page-editor .modal-body.editor-shell {
        display: block;
        padding: 20px !important;
    }

    .form-page-editor .editor-property-pane,
    .form-page-editor .editor-property-scroll {
        width: 100%;
    }

    .form-page-editor .editor-property-scroll {
        max-width: 1120px;
    }

    .form-editor-basics {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
        gap: 16px;
        margin-bottom: 16px;
        padding: 16px 18px;
    }

    .form-field-card {
        display: grid;
        grid-template-columns: minmax(280px, .72fr) minmax(400px, 1.28fr);
        column-gap: 22px;
        align-items: start;
        padding: 18px;
    }

    .form-field-card .form-field-list {
        grid-column: 1;
        grid-row: 1 / span 12;
        margin: 0;
        padding-right: 18px;
        border-right: 1px solid var(--line);
    }

    .form-field-list-card {
        min-height: 50px;
        padding: 9px 11px;
    }

    .form-field-card .selected-object-actions,
    .form-field-card > .field {
        grid-column: 2;
    }

    .form-field-card .selected-object-actions {
        min-height: 36px;
        margin-bottom: 16px;
        padding-bottom: 14px;
    }

    .form-field-card > .field + .field {
        margin-top: 14px;
    }

    .form-page-editor .editor-add-block {
        grid-template-columns: repeat(7, minmax(0, 1fr));
        gap: 10px;
        padding: 16px 18px;
    }

    .form-page-editor .editor-add-block button {
        min-height: 42px;
        padding: 0 8px;
        white-space: nowrap;
    }
}

/* ==========================================================================
   39. 管理页筛选控制面：课时核销式的虚实层次
   --------------------------------------------------------------------------
   班级页把星期快捷项与状态/搜索归入一个实体控制面：圆形星期用于快速跳转，
   标准圆角字段用于筛选和输入，两层之间只用细线分隔。
   学员页保留同一外框内的搜索与筛选两级，避免不同操作在视觉上混成一排。
   教师页沿用无框单行检索，作为更轻的一级工具栏。
   ========================================================================== */
.class-filter-panel {
    display: grid;
    gap: 0;
    margin-bottom: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}

.class-filter-panel .class-week-row {
    margin: 0;
    padding: 8px 10px;
    border-bottom: 1px solid var(--line);
}

.class-filter-panel .class-filter-row {
    padding: 8px 10px;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.class-filter-panel .class-status-tabs .seg-pill.sm,
.class-filter-panel .class-search-input,
.class-filter-panel .class-search-btn {
    box-sizing: border-box;
    min-height: 34px;
    height: 34px;
    border-radius: var(--radius-sm);
}

.class-filter-panel .class-search-input {
    background: var(--surface-2);
}

.student-control-bar {
    gap: 0;
}

.student-control-bar .student-search-row {
    padding-bottom: 7px;
}

.student-control-bar .student-filter-row {
    padding-top: 7px;
    border-top: 1px solid var(--line);
}

@media (max-width: 767px) {
    .class-filter-panel .class-week-row {
        padding: 7px 8px;
    }

    .class-filter-panel .class-filter-row {
        padding: 7px 8px;
    }

    .class-filter-panel .class-status-tabs .seg-pill.sm,
    .class-filter-panel .class-search-input,
    .class-filter-panel .class-search-btn {
        min-height: 40px;
        height: 40px;
    }

    .student-control-bar .student-search-row {
        padding-bottom: 7px;
    }

    .student-control-bar .student-filter-row {
        padding-top: 7px;
    }

    .student-filter-row .class-status-tabs .seg-pill.sm,
    .student-filter-row .student-filter-select .select-field {
        min-height: 40px;
        height: 40px;
    }
}

/* 班级页直接沿用课时核销的“紧凑工具组 + 独立星期条”骨架。 */
.class-filter-panel {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.class-filter-panel > .class-filter-panel {
    order: 2;
    display: flex;
    flex-direction: row;
    gap: 4px;
    flex-wrap: nowrap;
    margin: 0;
    padding: 8px 0 12px;
    border: 0;
    border-radius: 0;
    background: transparent;
    overflow: visible;
}

.class-filter-panel > .class-filter-panel > .seg-pill {
    flex: 1;
    padding: 0 4px;
}

.class-filter-panel > .class-filter-row {
    order: 1;
    margin: 0;
    padding: 5px 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.class-filter-panel > .class-filter-row .class-search-input {
    background: var(--surface);
}

@media (max-width: 767px) {
    .class-filter-panel > .class-filter-panel {
        gap: 2px;
        justify-content: space-between;
        padding: 6px 0 10px;
    }

    .class-filter-panel > .class-filter-panel > .seg-pill,
    .class-filter-panel > .class-filter-panel > .seg-pill.sm {
        flex: 0 1 40px;
        width: 40px;
        min-width: 0;
        min-height: 40px;
        height: 40px;
        padding: 0;
        border-radius: 50%;
    }

    .class-filter-panel > .class-filter-row {
        padding: 5px;
    }
}

@media (max-width: 359px) {
    .class-filter-panel > .class-filter-panel > .seg-pill,
    .class-filter-panel > .class-filter-panel > .seg-pill.sm {
        flex-basis: 34px;
        width: 34px;
        min-height: 34px;
        height: 34px;
    }
}

/* 班级管理：状态改为单一启用/停用切换，新增操作紧跟搜索。 */
.class-page-actions {
    display: none;
}

.class-filter-panel > .class-filter-row .class-status-tabs > .seg-pill:nth-child(n + 2) {
    display: none;
}

.class-create-btn {
    flex: 0 0 auto;
    min-height: 34px;
    padding: 0 10px;
    border-radius: var(--radius-sm);
    white-space: nowrap;
}

@media (max-width: 767px) {
    .class-create-btn {
        min-height: 40px;
        height: 40px;
        padding: 0 10px;
    }
}

@media (max-width: 767px) {
    .core-card {
        min-height: 68px;
        padding: 10px;
        gap: 8px;
    }

    .core-card > .ico:last-child,
    .core-card .core-main small {
        display: none;
    }

    .core-icon {
        width: 34px;
        height: 34px;
    }

    .core-card-primary .core-main { padding-right: 27px; }

    .core-badge {
        top: 7px;
        right: 7px;
        transform: none;
    }
}

/* 活动中心：能力入口使用内容卡片，后续可按同一结构继续扩展。 */
.activity-center-page { max-width: 920px; }

.activity-tool-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.activity-tool-card {
    display: grid;
    grid-template-columns: 46px minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    min-width: 0;
    min-height: 112px;
    padding: 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    color: var(--text);
    text-align: left;
    font: inherit;
    cursor: pointer;
    transition: border-color .15s, background .15s, transform .1s;
}

.activity-tool-card:hover,
.activity-tool-card:focus-visible {
    border-color: var(--primary);
    background: var(--primary-light);
    outline: 0;
}

.activity-tool-card:active { transform: scale(.985); }

.activity-tool-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border-radius: 8px;
}

.activity-tool-signup .activity-tool-icon {
    background: var(--ok-light);
    color: var(--ok-text);
}

.activity-tool-forms .activity-tool-icon {
    background: var(--info-light);
    color: var(--primary-text);
}

.activity-tool-copy {
    display: flex;
    flex-direction: column;
    min-width: 0;
    gap: 5px;
}

.activity-tool-copy strong { font-size: calc(15px * var(--jx-fs)); }

.activity-tool-copy small {
    color: var(--text-muted);
    font-size: calc(12.5px * var(--jx-fs));
    line-height: 1.5;
}

.activity-tool-arrow { color: var(--text-muted); }

@media (max-width: 767px) {
    .activity-tool-grid { grid-template-columns: minmax(0, 1fr); gap: 8px; }
    .activity-tool-card { min-height: 92px; padding: 14px; }
}

/* 首页常用功能：无标题的固定四列两行卡片。 */
.quick-card-common {
    padding: 8px;
}

.home-core-anchor,
.quick-card-side {
    display: none;
}

.quick-card-common > .card-head {
    display: none;
}

.quick-card-common > .card-body {
    padding: 0;
}

.quick-card-common .quick-grid-common {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
}

.quick-card-common .quick-item {
    min-height: 84px;
    gap: 6px;
    padding: 7px 3px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.quick-card-common .quick-icon,
.quick-card-common .quick-item .quick-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
}

.quick-card-common .quick-label {
    font-size: calc(12px * var(--jx-fs));
}

@media (max-width: 767px) {
    .quick-card-common {
        padding: 8px;
    }

    .quick-card-common .quick-grid-common {
        gap: 6px;
    }

    .quick-card-common .quick-item {
        min-height: 82px;
    }

    .quick-card-common .quick-icon,
    .quick-card-common .quick-item .quick-icon {
        width: 38px;
        height: 38px;
        border-radius: 10px;
    }
}

/* P0 财务工作台：信息密度为桌面录单优化，窄屏自动变成单列任务流。 */
.finance-page { max-width: 1320px; }
.finance-head { align-items: center; }
.finance-head .page-sub { margin-top: 3px; }
.finance-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: 16px; }
.finance-kpi { min-height: 86px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); display: grid; align-content: space-between; }
.finance-kpi span { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.finance-kpi b { font-size: calc(22px * var(--jx-fs)); font-variant-numeric: tabular-nums; }
.finance-kpi.warn b { color: var(--danger-text); }
.finance-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(310px, .65fr); gap: 16px; align-items: start; }
.cashier-form .card-body { padding-top: 16px; }
.finance-package-preview { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 10px; padding: 11px 12px; border: 1px solid var(--ok); border-radius: var(--radius-sm); background: var(--ok-light); }
.finance-package-preview strong { min-width: 0; color: var(--text); }
.finance-package-preview span { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.finance-package-preview em { grid-row: 1 / 3; grid-column: 2; align-self: center; color: var(--ok-text); font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums; }
.finance-list { min-width: 0; }
.finance-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; min-height: 64px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.finance-row:last-child { border-bottom: 0; }
.finance-row > div:first-child { min-width: 0; display: grid; gap: 4px; }
.finance-row b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.finance-row span, .finance-row small { overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.finance-row strong { font-variant-numeric: tabular-nums; }
.finance-amount { display: grid; gap: 3px; justify-items: end; white-space: nowrap; }
.finance-amount small { color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); }
.refund-row .btn-row { display: flex; flex-shrink: 0; gap: 6px; }
.renew-row small { display: block; }

.refund-estimate { display: grid; grid-template-columns: 1fr auto; gap: 10px 18px; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.refund-estimate span { color: var(--text-muted); font-size: calc(13px * var(--jx-fs)); }
.refund-estimate b, .refund-estimate strong { justify-self: end; font-variant-numeric: tabular-nums; }
.refund-estimate strong { color: var(--danger-text); font-size: calc(18px * var(--jx-fs)); }
.empty-inline { padding: 26px 16px; color: var(--text-muted); text-align: center; font-size: calc(13px * var(--jx-fs)); }
.finance-modal { width: min(620px, calc(100vw - 32px)); }
@media (max-width: 767px) {
    .finance-editor-modal {
        width: 100vw;
        max-width: none;
        max-height: 100dvh;
        border-radius: 16px 16px 0 0;
    }
}
@media (max-width: 767px) {
    .finance-head { align-items: flex-start; gap: 12px; }
    .finance-head .btn { flex: 0 0 auto; }
    .finance-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .finance-kpi { min-height: 76px; padding: 11px 12px; }
    .finance-kpi b { font-size: calc(19px * var(--jx-fs)); }
    .finance-grid { grid-template-columns: 1fr; gap: 12px; }
    .cashier-form .card-foot { display: grid; gap: 10px; }
    .cashier-form .card-foot .btn { width: 100%; }
    .finance-row { min-height: 70px; padding: 12px; gap: 8px; }
    .finance-row.stack-mobile { align-items: flex-start; }
    .finance-row.stack-mobile .finance-amount { margin-top: 2px; }
    .refund-row { align-items: flex-start; }
    .refund-row .btn-row { align-self: center; }
    .finance-package-preview { grid-template-columns: 1fr; }
    .finance-package-preview em { grid-row: auto; grid-column: auto; justify-self: start; }
}

/* 微信对接的能力分区：把基础公众号与资金配置明确隔离。 */
.seg-tabs { display: inline-flex; max-width: 100%; overflow: auto; gap: 2px; padding: 3px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.seg-tabs button { min-height: 34px; padding: 0 13px; border: 0; border-radius: calc(var(--radius-sm) - 2px); background: transparent; color: var(--text-muted); font: inherit; font-size: calc(13px * var(--jx-fs)); cursor: pointer; white-space: nowrap; }
.seg-tabs button.active { background: var(--surface); color: var(--primary-text); box-shadow: var(--shadow); font-weight: 650; }
@media (max-width: 767px) { .seg-tabs { display: grid; width: 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); } .seg-tabs button { min-height: 42px; padding: 0 8px; } }

/* 家长统一会员中心：机构入口可汇总，课时、券和推荐奖励始终留在所属机构。 */
.parent-center, .parent-referral-page { max-width: 720px; margin: 0 auto; padding: 16px 14px calc(28px + env(safe-area-inset-bottom)); }
.parent-welcome { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 10px 2px 18px; }
.parent-eyeline { color: var(--primary-text); font-size: calc(12px * var(--jx-fs)); font-weight: 700; letter-spacing: .06em; }
.parent-welcome h1, .parent-page-nav h1 { margin: 5px 0 4px; color: var(--text); font-size: calc(25px * var(--jx-fs)); line-height: 1.16; letter-spacing: 0; }
.parent-welcome p { margin: 0; color: var(--text-muted); font-size: calc(13px * var(--jx-fs)); line-height: 1.6; }
.parent-refresh, .parent-arrow-btn, .parent-back-btn { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 44px; height: 44px; border: 1px solid var(--line); border-radius: 50%; background: var(--surface); color: var(--text-2); cursor: pointer; }
.parent-refresh:focus-visible, .parent-arrow-btn:focus-visible, .parent-back-btn:focus-visible, .parent-child-card:focus-visible, .parent-activity:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.parent-scope { display: flex; align-items: flex-start; gap: 8px; padding: 10px 11px; border: 1px solid color-mix(in srgb, var(--primary) 28%, var(--line)); border-radius: var(--radius-sm); background: var(--primary-light); color: var(--primary-text); font-size: calc(12px * var(--jx-fs)); line-height: 1.55; }
.parent-scope .ico { flex: 0 0 auto; margin-top: 1px; }
.parent-referral-callout { display: grid; grid-template-columns: 44px minmax(0, 1fr) 36px; align-items: center; gap: 11px; margin: 14px 0 22px; padding: 14px; border: 1px solid color-mix(in srgb, var(--ok) 38%, var(--line)); border-radius: var(--radius); background: color-mix(in srgb, var(--ok-light) 70%, var(--surface)); box-shadow: var(--shadow-lg); }
.parent-callout-icon, .parent-reward-icon { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 12px; background: var(--ok); color: var(--on-accent); }
.parent-callout-copy { min-width: 0; display: grid; gap: 3px; text-align: left; }
.parent-callout-copy strong { color: var(--text); font-size: calc(15px * var(--jx-fs)); }
.parent-callout-copy span { color: var(--text-2); font-size: calc(12px * var(--jx-fs)); line-height: 1.5; }
.parent-arrow-btn { width: 36px; height: 36px; border-color: transparent; background: transparent; color: var(--ok-text); }
.parent-section { margin-top: 22px; }
.parent-section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 0 2px 9px; }
.parent-section-head h2 { margin: 0; color: var(--text); font-size: calc(16px * var(--jx-fs)); line-height: 1.3; }
.parent-section-head span { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); white-space: nowrap; }
.parent-notice { display: flex; align-items: flex-start; gap: 8px; padding: 12px; border: 1px solid color-mix(in srgb, var(--warn) 35%, var(--line)); border-radius: var(--radius-sm); background: var(--warn-light); color: var(--warn-text); font-size: calc(13px * var(--jx-fs)); line-height: 1.55; }
.parent-notice .ico { flex: 0 0 auto; margin-top: 1px; }
.parent-child-card, .parent-activity { width: 100%; margin-bottom: 9px; padding: 13px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font: inherit; text-align: left; cursor: pointer; transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease; }
.parent-child-card:hover, .parent-activity:hover { transform: translateY(-1px); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); box-shadow: var(--shadow-lg); }
.parent-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.parent-org { min-width: 0; display: inline-flex; align-items: center; gap: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.parent-child-main { display: grid; grid-template-columns: 42px minmax(0, 1fr) minmax(92px, auto); align-items: center; gap: 10px; margin: 12px 0 9px; }
.parent-avatar { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 50%; background: var(--primary-light); color: var(--primary-text); font-size: calc(17px * var(--jx-fs)); font-weight: 700; }
.parent-child-copy { min-width: 0; display: grid; gap: 4px; }
.parent-child-copy strong { overflow: hidden; color: var(--text); font-size: calc(16px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.parent-child-copy span { overflow: hidden; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.parent-hours { display: inline-flex; align-items: baseline; justify-content: flex-end; gap: 4px; min-width: 0; white-space: nowrap; }
.parent-hours b { color: var(--primary-text); font-size: calc(21px * var(--jx-fs)); font-variant-numeric: tabular-nums; }
.parent-hours small { color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); }
.parent-asset-note { min-width: 0; display: flex; align-items: center; gap: 5px; padding-top: 9px; border-top: 1px solid var(--line); color: var(--text-muted); font-size: calc(11.5px * var(--jx-fs)); line-height: 1.4; white-space: nowrap; }.parent-asset-note .ico { flex: 0 0 auto; }.parent-asset-note > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }.parent-asset-note::after { content: ''; min-width: 0; }
.parent-activity { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 62px; }
.parent-activity div { min-width: 0; display: grid; gap: 4px; }
.parent-activity strong, .parent-activity span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.parent-activity strong { font-size: calc(14px * var(--jx-fs)); }
.parent-activity span { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.parent-activity .ico { flex: 0 0 auto; color: var(--primary-text); }
.parent-empty-state, .parent-referral-empty { display: grid; justify-items: center; gap: 8px; padding: 38px 20px; color: var(--text-muted); text-align: center; }
.parent-empty-mark { display: inline-flex; align-items: center; justify-content: center; width: 54px; height: 54px; border-radius: 17px; background: var(--surface-2); color: var(--primary-text); }
.parent-empty-state strong, .parent-referral-empty strong { color: var(--text); font-size: calc(15px * var(--jx-fs)); }
.parent-empty-state span, .parent-referral-empty span { max-width: 340px; font-size: calc(13px * var(--jx-fs)); line-height: 1.6; }
.parent-page-nav { display: grid; grid-template-columns: 44px minmax(0, 1fr); align-items: center; gap: 10px; margin: 3px 0 17px; }
.parent-page-nav > div { min-width: 0; }
.parent-page-nav > div > span { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.parent-page-nav h1 { font-size: calc(22px * var(--jx-fs)); }
.parent-referral-hero { position: relative; overflow: hidden; padding: 22px 18px 18px; border-radius: var(--radius); background: var(--grad-hero); color: var(--on-accent); box-shadow: var(--shadow-lg); }
.parent-referral-hero::after { content: ''; position: absolute; width: 180px; height: 180px; right: -58px; top: -70px; border: 1px solid var(--hero-tile-line); border-radius: 50%; box-shadow: 0 0 0 22px var(--hero-tile-bg), 0 0 0 44px var(--hero-tile-bg); pointer-events: none; }
.parent-referral-hero > * { position: relative; z-index: 1; }
.parent-referral-spark { display: inline-flex; align-items: center; justify-content: center; width: 45px; height: 45px; margin-bottom: 13px; border-radius: 14px; background: var(--warn); color: var(--on-accent); }
.parent-referral-hero > span { display: block; margin-bottom: 7px; color: var(--hero-fg-muted); font-size: calc(12px * var(--jx-fs)); font-weight: 700; }
.parent-referral-hero h2 { margin: 0; color: var(--on-accent); font-size: calc(24px * var(--jx-fs)); line-height: 1.22; letter-spacing: 0; }
.parent-referral-hero p { max-width: 350px; margin: 9px 0 16px; color: var(--hero-fg-muted); font-size: calc(12.5px * var(--jx-fs)); line-height: 1.6; }
.parent-share-btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 0 14px; border: 0; border-radius: var(--radius-sm); background: var(--warn); color: var(--on-accent); font: inherit; font-size: calc(13px * var(--jx-fs)); font-weight: 700; cursor: pointer; }
.parent-referral-scope { margin-top: 12px; }
.parent-institution-picker { margin-top: 20px; }.parent-institution-tabs { display: grid; gap: 8px; }.parent-institution-tabs button { width: 100%; display: grid; grid-template-columns: 18px minmax(0, 1fr); column-gap: 7px; align-items: center; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-2); font: inherit; text-align: left; cursor: pointer; }.parent-institution-tabs button span { overflow: hidden; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }.parent-institution-tabs button small { grid-column: 2; overflow: hidden; color: var(--text-muted); font-size: calc(11.5px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }.parent-institution-tabs button.on { border-color: var(--primary); background: var(--primary-light); color: var(--primary-text); }.parent-referral-activity { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; margin-bottom: 9px; padding: 13px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }.parent-referral-activity > div { min-width: 0; display: grid; gap: 4px; }.parent-referral-activity strong, .parent-referral-activity span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.parent-referral-activity strong { color: var(--text); font-size: calc(14px * var(--jx-fs)); }.parent-referral-activity span { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }.parent-referral-empty.compact { padding: 24px 18px; border: 1px dashed var(--line); border-radius: var(--radius-sm); }
.parent-referral-scope { margin-top: 12px; }
.parent-referral-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 22px 0 2px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.parent-referral-stats > div { min-width: 0; display: grid; justify-items: center; gap: 4px; padding: 14px 6px; border-right: 1px solid var(--line); }
.parent-referral-stats > div:last-child { border-right: 0; }
.parent-referral-stats b { color: var(--text); font-size: calc(21px * var(--jx-fs)); font-variant-numeric: tabular-nums; }
.parent-referral-stats span { overflow: hidden; max-width: 100%; color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.parent-reward-group { margin-bottom: 9px; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.parent-reward-org { display: flex; align-items: center; gap: 5px; padding: 10px 12px; border-bottom: 1px solid var(--line); background: var(--surface-2); color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.parent-reward-org strong { color: var(--text-2); }
.parent-reward-row { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; align-items: center; gap: 9px; padding: 11px 12px; border-bottom: 1px solid var(--line); }
.parent-reward-row:last-child { border-bottom: 0; }
.parent-reward-row .parent-reward-icon { width: 34px; height: 34px; border-radius: 10px; background: var(--primary-light); color: var(--primary-text); }
.parent-reward-row > div:nth-child(2) { min-width: 0; display: grid; gap: 3px; }
.parent-reward-row strong, .parent-reward-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.parent-reward-row strong { color: var(--text); font-size: calc(13px * var(--jx-fs)); }
.parent-reward-row span { color: var(--text-muted); font-size: calc(11.5px * var(--jx-fs)); }
.parent-reward-row > b { color: var(--ok-text); font-size: calc(13px * var(--jx-fs)); font-variant-numeric: tabular-nums; white-space: nowrap; }
.parent-referral-row { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 12px 3px; border-bottom: 1px solid var(--line); }
.parent-progress-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--warn); }
.parent-progress-dot.is-success { background: var(--ok); }.parent-progress-dot.is-muted { background: var(--text-muted); }
.parent-referral-row > div:nth-child(2) { min-width: 0; display: grid; gap: 4px; }
.parent-referral-row strong, .parent-referral-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.parent-referral-row strong { color: var(--text); font-size: calc(13px * var(--jx-fs)); }.parent-referral-row span { color: var(--text-muted); font-size: calc(11.5px * var(--jx-fs)); }
.parent-referral-row em { padding: 4px 7px; border-radius: var(--radius-pill); background: var(--warn-light); color: var(--warn-text); font-size: calc(11px * var(--jx-fs)); font-style: normal; white-space: nowrap; }.parent-referral-row em.is-success { background: var(--ok-light); color: var(--ok-text); }.parent-referral-row em.is-muted { background: var(--surface-2); color: var(--text-muted); }
@media (max-width: 420px) { .parent-center, .parent-referral-page { padding-right: 12px; padding-left: 12px; }.parent-referral-hero h2 { font-size: calc(22px * var(--jx-fs)); }.parent-child-main { grid-template-columns: 38px minmax(0, 1fr) minmax(86px, auto); gap: 8px; }.parent-avatar { width: 38px; height: 38px; }.parent-hours b { font-size: calc(19px * var(--jx-fs)); } }
@media (prefers-reduced-motion: reduce) { .parent-child-card, .parent-activity { transition-duration: .01ms !important; } }

/* 推荐与试听工作台：高密度待办优先，线索详情按阶段操作。 */
.referral-crm-page { max-width: 1120px; margin: 0 auto; }
.referral-crm-head { align-items: flex-start; }
.referral-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin: 0 0 16px; }
.referral-kpi { min-height: 88px; display: grid; align-content: start; gap: 2px; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.referral-kpi:hover { border-color: var(--primary); background: var(--primary-light); }
.referral-kpi span, .referral-kpi small { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.referral-kpi b { color: var(--primary-text); font-size: calc(24px * var(--jx-fs)); line-height: 1.1; font-variant-numeric: tabular-nums; }
.referral-kpi.amber b { color: var(--warn-text); }.referral-kpi.teal b { color: var(--ok-text); }.referral-kpi.slate b { color: var(--text-2); }
.referral-workspace { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.referral-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
.referral-tabs { flex: 1; max-width: 500px; }.referral-tabs .slide-tabs-thumb { width: calc((100% - 2 * var(--st-pad) - 3 * var(--st-gap)) / 4); }.referral-filter { display: flex; align-items: center; gap: 8px; }.referral-filter .select-wrap { min-width: 130px; }
.referral-lead-list { display: grid; }
.referral-lead { display: grid; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--line); cursor: pointer; }.referral-lead:last-child { border-bottom: 0; }.referral-lead:hover { background: var(--surface-2); }
.referral-lead-top, .referral-lead-meta, .referral-lead-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.referral-lead-top > div, .referral-lead-meta { min-width: 0; }.referral-lead-top strong { margin-left: 8px; color: var(--text); }.referral-lead-top small { margin-left: 8px; color: var(--text-muted); }
.referral-lead-meta { justify-content: flex-start; flex-wrap: wrap; color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }.referral-lead-meta span { display: inline-flex; align-items: center; gap: 4px; }
.referral-due { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); white-space: nowrap; }.referral-due.late { color: var(--danger); font-weight: 600; }.referral-lead-actions { color: var(--text-muted); font-size: calc(12px * var(--jx-fs)); }
.referral-detail-modal { width: min(760px, calc(100vw - 28px)); }.referral-detail-ident { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding: 12px; border-radius: var(--radius-sm); background: var(--surface-2); }.referral-detail-ident div { min-width: 0; display: grid; gap: 3px; }.referral-detail-ident span { color: var(--text-muted); font-size: calc(11px * var(--jx-fs)); }.referral-detail-ident b { overflow: hidden; color: var(--text); font-size: calc(13px * var(--jx-fs)); text-overflow: ellipsis; white-space: nowrap; }
.referral-detail-section { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }.status-stepper { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 8px; }.status-stepper button { min-height: 38px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-muted); font: inherit; font-size: calc(12px * var(--jx-fs)); cursor: pointer; }.status-stepper button.on { border-color: var(--primary); background: var(--primary-light); color: var(--primary-text); font-weight: 650; }.rule-list p { margin: 10px 0; color: var(--text-2); font-size: calc(13px * var(--jx-fs)); }
@media (max-width: 767px) {
    .referral-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .referral-kpi { min-height: 80px; padding: 10px; }
    .referral-toolbar { display: grid; gap: 10px; padding: 10px; }
    .referral-tabs { max-width: none; }
    .referral-filter { display: grid; grid-template-columns: minmax(0, 1fr) clamp(88px, 27vw, 104px); min-width: 0; gap: 8px; }
    .referral-filter .marketing-search { width: 100%; min-width: 0; }
    .referral-filter .marketing-search .input { flex: 1 1 0; width: 0; }
    .referral-filter .select-wrap { min-width: 0; width: 100%; }
    .referral-lead { padding: 13px; }
    .referral-lead-top { align-items: flex-start; }
    .referral-lead-top small { display: inline-block; margin: 4px 0 0 8px; }
    .referral-due { max-width: 112px; overflow: hidden; text-align: right; text-overflow: ellipsis; }
    .referral-detail-ident { grid-template-columns: 1fr; }
    .status-stepper { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
