/* ============================================================
   墨泓斋 · 公共主题层（玻璃终端 Glass Terminal）
   ------------------------------------------------------------
   五站共用的一层：调色板、字体、形状与通用组件都在这里。
   子站只需在自己的样式表之前引一次（engstudy / huafans 的 core.js
   会自动注入，故这两个子站的每个页面都会命中本层）：

     <link rel="stylesheet" href="/common/css/mz_theme.css?v=47">

   设计方向（2026 改版）
   1. 骨架：终端 —— 面板分层、等宽小标签、状态灯、点阵底纹。
   2. 质感：玻璃 —— 半透明面板 + 背景模糊 + 顶部高光边 + 柔投影。
   3. 明暗：由 <html data-theme="light|dark"> 驱动（theme_init.js 写入，
      用户三档偏好存在 localStorage 的 mz_theme 键里）。本层只用
      [data-theme="dark"] 覆盖令牌，跟随系统由 theme_init.js 负责判断。

   兼容约定（改本文件前必读）
   · 旧令牌全部保留为别名（--mz-cinnabar / --red / --teal / --seal /
     --accent / --ink* / --paper / --bg / --surface / --card / --line*），
     指向新的玻璃令牌，因此未改写的旧页面也会自动换肤，不要在这里删掉
     任何旧类名。
   ------------------------------------------------------------
   第 102 轮：玻璃三级令牌、卡片与按钮的底色统一收在
   /common/css/mz_surface.css —— 文件顶部已 @import 它，是唯一真源；
   本文件末尾的「第 102 轮 · 表面层收口」块只重复选择器、不重复色值。
   改色值请只改 mz_surface.css。
   ============================================================ */

/* 表面层（玻璃令牌 + 卡片/组件底色）的唯一真源。
   @import 必须排在所有规则之前，所以放在这里。 */
@import url("mz_surface.css?v=5");

/* ---------- 零、基础重置 ----------
   只做最低限度的重置：盒模型、贴边、图片与媒体不溢出容器、表格不裂开。
   各站自己写的 * 重置都已删除，统一走这里。 */

*,
*::before,
*::after {
    box-sizing: border-box;
}

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

/* ---------- 一、令牌：浅色（默认） ---------- */
:root {
    color-scheme: light;

    /* 底与光 */
    --mz-bg: #e7eef2;
    --mz-bg-2: #dde7ee;
    --mz-glow-1: rgba(84, 190, 198, .34);
    --mz-glow-2: rgba(112, 132, 236, .26);
    --mz-glow-3: rgba(132, 202, 184, .22);
    --mz-dot: rgba(8, 25, 32, .085);

    /* 玻璃三级令牌（--mz-glass* / --mz-surface-* / --mz-blur*）由文件顶部的
       @import url("mz_surface.css") 提供，是全站唯一真源 */

    /* 文字 */
    --mz-ink: #08131a;
    --mz-ink-2: #34454e;
    --mz-ink-3: #5c6f78;
    --mz-ink-4: #8497a0;

    /* 线 */
    --mz-line: rgba(8, 25, 32, .12);
    --mz-line-2: rgba(8, 25, 32, .07);
    --mz-line-strong: rgba(8, 25, 32, .22);

    /* 强调 */
    --mz-accent: #0a6f7b;
    --mz-accent-deep: #085761;
    --mz-accent-wash: rgba(10, 111, 123, .12);
    --mz-accent-line: rgba(10, 111, 123, .4);
    --mz-btn-ink: #ffffff;

    /* 语义色 */
    --mz-ok: #17795a;
    --mz-warn: #8a590f;
    --mz-danger: #b03a2e;
    --mz-gold: #8a6420;

    /* 形状与阴影 */
    --mz-radius: 12px;
    --mz-radius-l: 18px;
    --mz-radius-pill: 999px;
    --mz-shadow-s: 0 1px 2px rgba(8, 34, 42, .06);
    --mz-shadow: 0 26px 54px -40px rgba(8, 34, 42, .55), inset 0 1px 0 var(--mz-bhair);
    --mz-shadow-lift: 0 34px 66px -36px rgba(8, 34, 42, .48), inset 0 1px 0 var(--mz-bhair);

    /* 字体 */
    --mz-sans: "HarmonyOS Sans SC", -apple-system, BlinkMacSystemFont,
               "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    --mz-serif: var(--mz-sans);
    --mz-display: var(--mz-sans);
    --mz-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
               "Liberation Mono", monospace;

    /* 版式基准 */
    --mz-page: 1280px;      /* 全站页面宽度基准（2026 改版：1180 → 1280） */
    --mz-wrap: 1280px;      /* 规范别名，新代码一律用 --mz-wrap */
    --mz-gutter: 24px;
    --mz-topbar-h: 64px;    /* 默认值；运行时由 mz-crumb.js 量出真实高度后覆盖 */

    /* ---- 吸顶件避让顶栏的「渐变模糊」（全站原则 · 261101）----
       顶栏下沿铺了一条「模糊 + 向下渐隐」的过渡带（见 `.mz-topbar::after`：
       高度 = 顶栏高 + 72px，窄屏 + 48px，到底部渐隐为 0）。
       任何吸顶组件若照旧写 `top: var(--mz-topbar-h)`，就会正好贴在这条带里被糊掉。
       所以：**全站吸顶件一律用 --mz-sticky-top 定位**，不要再手写 --mz-topbar-h。
       非吸顶组件要让位时，用 margin/padding-top: 同一条算式。
       让位量只取渐隐带的三分之一（--mz-sticky-avoid）：这条带的下段本就淡到看不出，
       整条都让开会把吸顶件推得离顶栏太远；261101 按你的实测反馈从 ½ 收到 ⅓。 */
    --mz-topbar-fade: 72px;
    --mz-sticky-avoid: calc(var(--mz-topbar-fade) / 3);
    --mz-sticky-gap: 4px;
    --mz-sticky-top: calc(var(--mz-topbar-h) + var(--mz-sticky-avoid) + var(--mz-sticky-gap));

    /* ---- 旧令牌别名：让未改写的页面取到同一套颜色 ---- */
    --mz-paper: var(--mz-bg);
    --mz-paper-2: var(--mz-glass);
    --mz-paper-3: var(--mz-glass-3);
    --mz-card: var(--mz-glass);

    --mz-cinnabar: var(--mz-accent);
    --mz-cinnabar-deep: var(--mz-accent-deep);
    --mz-cinnabar-wash: var(--mz-accent-wash);
    --mz-gold-wash: rgba(138, 100, 32, .12);

    --red: var(--mz-accent);
    --red-deep: var(--mz-accent-deep);
    --red-soft: var(--mz-accent-wash);
    --teal: var(--mz-accent);
    --teal-ink: var(--mz-accent-deep);
    --teal-soft: var(--mz-accent-wash);
    --seal: var(--mz-accent);
    --seal-deep: var(--mz-accent-deep);
    --seal-soft: var(--mz-accent-wash);
    --seal-line: var(--mz-accent-line);
    --accent: var(--mz-accent);
    --accent-wash: var(--mz-accent-wash);

    --ink: var(--mz-ink);
    --ink-2: var(--mz-ink-2);
    --ink-3: var(--mz-ink-3);
    --ink-4: var(--mz-ink-4);
    --text: var(--mz-ink);
    --text-2: var(--mz-ink-2);
    --text-3: var(--mz-ink-3);
    --paper: var(--mz-bg);
    --bg: var(--mz-bg);
    --surface: var(--mz-glass);
    --card: var(--mz-glass);
    --line: var(--mz-line);
    --line-2: var(--mz-line-2);
}

/* ---------- 二、令牌：深色 ---------- */
[data-theme="dark"],
html[data-theme="dark"],
html[data-theme="ink"],
[data-cc-theme="dark"] {
    color-scheme: dark;

    --mz-bg: #05090d;
    --mz-bg-2: #04080b;
    --mz-glow-1: rgba(24, 170, 190, .34);
    --mz-glow-2: rgba(88, 90, 230, .3);
    --mz-glow-3: rgba(20, 130, 140, .26);
    --mz-dot: rgba(255, 255, 255, .055);

    /* 深色玻璃令牌（--mz-glass* / --mz-surface-*）由 mz_surface.css 的深色块给出 */

    --mz-ink: #e8f2f6;
    --mz-ink-2: #aebfc9;
    --mz-ink-3: #7d8f9a;
    --mz-ink-4: #5c6c77;

    --mz-line: rgba(255, 255, 255, .1);
    --mz-line-2: rgba(255, 255, 255, .06);
    --mz-line-strong: rgba(255, 255, 255, .2);

    --mz-accent: #3fdcea;
    --mz-accent-deep: #7ceef8;
    --mz-accent-wash: rgba(63, 220, 234, .14);
    --mz-accent-line: rgba(63, 220, 234, .42);
    --mz-btn-ink: #04161a;

    --mz-ok: #4ad9a4;
    --mz-warn: #f5b544;
    --mz-danger: #ff8a7a;
    --mz-gold: #e0bb74;

    --mz-shadow-s: 0 1px 2px rgba(0, 0, 0, .5);
    --mz-shadow: 0 30px 70px -44px rgba(0, 0, 0, .95), inset 0 1px 0 var(--mz-bhair);
    --mz-shadow-lift: 0 40px 80px -34px rgba(0, 0, 0, .9), inset 0 1px 0 var(--mz-bhair);
}

/* ---------- 三、底：冷光 + 点阵 ---------- */
html {
    /* 底色只上一层纯色；冷光与点阵交给 body::before 的固定层去画 ——
       background-attachment: fixed 在滚动时会让浏览器反复重绘整页背景，
       固定定位的伪元素则是一次绘制、滚动时不再参与重排。 */
    background-color: var(--mz-bg);
    min-height: 100%;
}

body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        radial-gradient(circle at 12% -10%, var(--mz-glow-1), transparent 46%),
        radial-gradient(circle at 92% -4%, var(--mz-glow-2), transparent 44%),
        radial-gradient(circle at 50% 108%, var(--mz-glow-3), transparent 52%),
        radial-gradient(var(--mz-dot) 1px, transparent 1px);
    background-size: 100% 100%, 100% 100%, 100% 100%, 22px 22px;
    background-repeat: no-repeat, no-repeat, no-repeat, repeat;
}

body {
    background: transparent;
    font-family: var(--mz-sans);
    color: var(--mz-ink);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* ---------- 四、排版 ---------- */
h1, h2, h3, h4, h5 {
    font-family: var(--mz-display);
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.25;
}

a { color: inherit; text-decoration-color: var(--mz-accent-line); text-underline-offset: 3px; }
a:hover { text-decoration-color: var(--mz-accent); }

::selection { background: var(--mz-accent-wash); }

:focus-visible {
    outline: 2px solid var(--mz-accent);
    outline-offset: 3px;
    border-radius: var(--mz-radius);
}

code, kbd, pre, .mono, .mz-mono { font-family: var(--mz-mono); }

/* 小标：等宽大写，终端味 */
.mz-kicker,
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--mz-mono);
    font-size: .68rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--mz-ink-3);
}

.mz-kicker::before,
.eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--mz-accent);
    box-shadow: 0 0 0 4px var(--mz-accent-wash);
}

.mz-lead,
.lede { color: var(--mz-ink-2); line-height: 1.85; }

hr, .mz-rule { border: 0; border-top: 1px solid var(--mz-line); }

.mz-muted, .mz-dim, .muted, .field-hint { color: var(--mz-ink-3); }

/* ---------- 五、玻璃基件 ---------- */
.mz-glass {
    background:
        linear-gradient(160deg, var(--mz-sheet), rgba(255, 255, 255, 0) 46%),
        var(--mz-glass);
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    box-shadow: var(--mz-shadow);
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
}

/* ---------- 六、按钮 ----------
   胶囊形态，底色取组件的玻璃浓度（--mz-surface-comp），模糊取 --mz-blur，
   不再各写 blur(14px) saturate(140%) 这类字面量。 */
.mz-btn,
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 18px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink);
    font-family: inherit;
    font-size: .9rem;
    font-weight: 700;
    letter-spacing: .02em;
    line-height: 1.2;
    cursor: pointer;
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    transition: background .2s, color .2s, border-color .2s, transform .2s, box-shadow .2s;
}

.mz-btn:hover,
.btn:hover {
    border-color: var(--mz-accent);
    color: var(--mz-accent);
    transform: translateY(-1px);
}

.mz-btn--primary,
.mz-btn.is-primary,
.btn--pri,
.btn-primary,
.btn-seal {
    background: var(--mz-accent);
    border-color: var(--mz-accent);
    color: var(--mz-btn-ink);
    box-shadow: 0 14px 30px -16px var(--mz-accent-line);
}

.mz-btn--primary:hover,
.mz-btn.is-primary:hover,
.btn--pri:hover,
.btn-primary:hover,
.btn-seal:hover {
    background: var(--mz-accent-deep);
    border-color: var(--mz-accent-deep);
    color: var(--mz-btn-ink);
    box-shadow: 0 20px 36px -16px var(--mz-accent-line);
}

.mz-btn--ghost,
.mz-btn--quiet,
.btn--quiet,
.btn-ghost,
.btn-quiet {
    background: transparent;
    border-color: var(--mz-line);
    color: var(--mz-ink-2);
}

.mz-btn--ghost:hover,
.mz-btn--quiet:hover,
.btn--quiet:hover,
.btn-ghost:hover,
.btn-quiet:hover {
    border-color: var(--mz-accent);
    color: var(--mz-accent);
    background: var(--mz-accent-wash);
}

.btn-sm, .mz-btn--sm { padding: 7px 14px; font-size: .82rem; }
.btn-lg, .mz-btn--lg { padding: 12px 22px; font-size: .96rem; }
.btn-block, .mz-btn--block { width: 100%; }

/* 图标按钮（明暗切换、汉堡、关闭） */
.mz-theme-btn,
.mz-iconbtn,
.mz-burger,
.ibtn,
.drawer-btn {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    cursor: pointer;
    transition: border-color .18s, color .18s, background .18s;
}

.mz-theme-btn:hover,
.mz-iconbtn:hover,
.mz-burger:hover,
.ibtn:hover,
.drawer-btn:hover {
    border-color: var(--mz-accent);
    color: var(--mz-accent);
    background: var(--mz-accent-wash);
}

.mz-theme-btn svg,
.mz-iconbtn svg,
.ibtn svg { width: 17px; height: 17px; }

/* 汉堡：常显（点开是玻璃抽屉）。
   旧层里 .mz-burger 被上面这条 display:inline-grid 顶成常显，
   但总站的 .mz-drawer 又被按 360px 面板规则推到屏幕外，
   点开只剩一层看不见的遮罩 —— 页面看起来就「卡死」了。
   现在抽屉已按 data-mz-drawer 钉回整屏，汉堡可以正常用了。 */
.mz-burger,
.drawer-btn { display: inline-grid; }

/* ---------- 七、站头 / 导航（终端悬浮胶囊） ----------
   四个子站原先各写了一套页头骨架（.mz-topbar / .top / .mz-header），
   这里统一成同一枚玻璃胶囊 —— 与 theme-preview/b-terminal 的导航完全一致：
   外壳退成透明贴条，内层是圆角胶囊，滚动时内容从胶囊底下穿过。 */

.mz-topbar,
.top,
.mz-header,
.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    height: auto;
    min-height: 0;
    padding: 14px 0 0;
    border: 0;
    background: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

.mz-topbar > .mz-topbar__inner,
.top > .top__in,
.mz-header > .mz-header-inner,
.site-header > .site-header__in {
    display: flex;
    align-items: center;
    gap: 14px;
    max-width: var(--mz-page);
    height: 56px;
    min-height: 56px;
    margin: 0 auto;
    /* 左右内边距取页边（--mz-gutter）：品牌位与最右的动作位
       正好落在正文同一条竖线上，胶囊本身仍比正文宽出一圈。 */
    padding: 8px var(--mz-gutter);
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    /* 261101：顶栏胶囊比卡片更透一档（glass-2），再配更厚的磨砂 ——
       卡片的 glass 在浅色下接近奶白，导航做成同一档就成了"一条白杠"，
       透明一档之后才像浮在页面上的玻璃条，下面的内容能隐约透上来。 */
    background: var(--mz-surface-comp);
    box-shadow: var(--mz-shadow);
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
}

/* 品牌：沿用站点自己的 logo.png，只调尺寸不裁不拉 —— 按原始比例缩到固定高度 */
.mz-brand,
.brand {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    flex: none;
    color: var(--mz-ink);
    text-decoration: none;
}

.mz-brand > img,
.brand > img,
.brand-logo {
    display: block;
    width: auto !important;
    height: 30px !important;
    max-width: 132px;
    max-height: 34px;
    object-fit: contain !important;
    object-position: left center;
    border-radius: 8px;
    flex: none;
}

/* 旧标记里的行内 SVG（英语教研的印）也按同一尺寸排，不做拉伸 */
.brand > svg,
.brand__mark {
    display: block;
    height: 28px;
    width: auto;
    flex: none;
}

.mz-brand__text,
.mz-brand-text,
.brand__txt,
.brand-txt {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.mz-brand__name,
.mz-brand-text b,
.brand__txt b,
.brand-txt {
    font-size: .95rem;
    font-weight: 700;
    letter-spacing: .1em;
    color: var(--mz-ink);
}

.mz-brand__sub,
.mz-brand-text i,
.brand__txt i,
.brand-txt i {
    font-family: var(--mz-mono);
    font-style: normal;
    font-size: .56rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.mz-nav,
.nav {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: auto;
    min-width: 0;
}

.mz-nav a,
.nav__a {
    padding: 7px 12px;
    border-radius: var(--mz-radius-pill);
    font-size: .87rem;
    color: var(--mz-ink-2);
    white-space: nowrap;
    text-decoration: none;
    transition: background .18s, color .18s;
}

.mz-nav a:hover,
.nav__a:hover { background: var(--mz-accent-wash); color: var(--mz-accent); }

.mz-nav a.is-active,
.nav__a[aria-current="page"],
.mz-nav a[aria-current="page"],
.mz-nav a[data-current="1"] {
    background: var(--mz-accent-wash);
    color: var(--mz-accent);
    font-weight: 700;
}

.nav__a[aria-current="page"]::after { content: none !important; }

/* 页头登录按钮：三站同一个样子（实心强调色胶囊） */
.top__act .js-login,
.mz-actions .js-login,
.mz-actions .btn-primary,
.mz-header .mz-actions .btn-primary {
    background: var(--mz-accent);
    border-color: var(--mz-accent);
    color: var(--mz-btn-ink);
    box-shadow: 0 14px 30px -16px var(--mz-accent-line);
}

.top__act .js-login:hover,
.mz-actions .js-login:hover,
.mz-header .mz-actions .btn-primary:hover {
    background: var(--mz-accent-deep);
    border-color: var(--mz-accent-deep);
    color: var(--mz-btn-ink);
}

/* 当前页下划线标记统一收成「胶囊底色」，不再单独画横线 */
.mz-nav a[aria-current="page"]::after,
.mz-nav a.is-active::after { content: none !important; }

/* 顶栏外壳：清掉各站 base/pages 里残留的「满幅玻璃底板」。
   花粉同城的 pages.css 用 `header.mz-header`（元素 + 类）给整个页头刷了一层
   背景与模糊，比上面这条 .mz-header 更具体，于是胶囊后面会多出一块遮罩 ——
   这里按元素 + 类把外壳的底板一次清干净，只留里面那枚胶囊。 */
header.mz-topbar,
header.mz-header,
header.top,
header.topbar,
header.site-header,
.mz-subbar {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
}

.mz-subbar { display: none !important; }

/* 花粉同城 / 英语教研的品牌位：与总站一样用站点 logo */
.mz-brand > img.mz-brand__logo,
.brand > img.brand__logo {
    display: block;
    width: 34px;
    height: 34px;
    object-fit: cover;
    object-position: left center;
    border-radius: 10px;
    flex: none;
}

.mz-topbar__actions,
.mz-actions,
.top__act {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

/* 用户胶囊 */
.mz-user,
.uchip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px 4px 4px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    font-size: .84rem;
    color: var(--mz-ink-2);
}

.mz-user:hover { border-color: var(--mz-accent); color: var(--mz-accent); }

.mz-avatar,
.mz-user__avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    object-position: left center;
    background: var(--mz-accent-wash);
    flex: none;
}

.mz-avatar-fallback {
    display: grid;
    place-items: center;
    background: var(--mz-accent);
    color: var(--mz-btn-ink);
    font-size: .76rem;
    font-weight: 700;
}

/* ---------- 八、徽标 / 胶囊 ---------- */
.mz-chip,
.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    font-size: .78rem;
    line-height: 1.6;
}

.mz-chip.is-active,
.badge.is-active,
.badge--accent {
    background: var(--mz-accent-wash);
    border-color: var(--mz-accent);
    color: var(--mz-accent);
}

.mz-badge--mineral { color: var(--mz-ink-3); }
.mz-badge--gold, .badge-bronze { border-color: var(--mz-gold); color: var(--mz-gold); }

/* ---------- 九、表单 ---------- */
input[type="text"], input[type="search"], input[type="number"],
input[type="email"], input[type="password"], input[type="url"],
input[type="tel"], input[type="date"], select, textarea {
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-sect);
    color: var(--mz-ink);
    font-family: inherit;
    padding: 10px 13px;
    transition: border-color .18s, box-shadow .18s, background .18s;
}

input::placeholder, textarea::placeholder { color: var(--mz-ink-4); }

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--mz-accent);
    box-shadow: 0 0 0 4px var(--mz-accent-wash);
}

label { color: var(--mz-ink-2); }

/* ---------- 九之二、原生控件的主题适配（下拉弹层 / 日期 / 文件 / 勾选） ----------
   原生 <select> 的候选列表、日期时间选择器、取色器、文件按钮都是浏览器自己的
   控件：它们不吃站内背景，只认三样东西 —— `color-scheme`、`option` 的颜色、
   以及 `::file-selector-button` 之类的少量钩子。不显式声明时，深色主题里就会
   弹出一张白纸（截图里那个白底下拉框就是这么来的）。
   这里一次收口：
     1) 令牌 --mz-popup-*：弹层底与字色，浅深各一档；data-theme 挂在 html 或
        body 上都认；
     2) option / optgroup 显式上色 —— Chrome / Edge / Firefox 桌面端会照做；
     3) 勾选、单选、滑块、进度条统一 accent-color，不再一个浏览器一个色；
     4) 日期 / 时间 / 取色 / 文件这些系统小图标，深色下反相，否则黑图标贴深底。 */
:root {
    --mz-popup-bg: #ffffff;
    --mz-popup-ink: #0b1a20;
    --mz-popup-hover: rgba(10, 111, 123, .14);
}

[data-theme="dark"],
html[data-theme="dark"],
html[data-theme="ink"],
body[data-theme="dark"],
[data-cc-theme="dark"],
html[data-cc-theme="dark"] {
    --mz-popup-bg: #0b1218;
    --mz-popup-ink: #e8f2f6;
    --mz-popup-hover: rgba(63, 220, 234, .18);
}

/* 下拉框本体：跟随所在页的主题（不写死色值，仍走 --mz-surface-sect） */
select {
    color-scheme: inherit;
}

/* 候选列表：整块弹层与每一行都显式上色 */
select option,
select optgroup {
    background-color: var(--mz-popup-bg);
    color: var(--mz-popup-ink);
}

select optgroup {
    font-style: normal;
    font-weight: 700;
}

/* 选中行 / 悬停行：给一档强调色，白底黑字那种「系统感」就没有了 */
select option:checked,
select option:hover {
    background-color: var(--mz-popup-hover);
    color: var(--mz-accent-deep);
}

/* 勾选、单选、滑块、进度：统一强调色 */
input[type="checkbox"],
input[type="radio"],
input[type="range"],
progress,
meter {
    accent-color: var(--mz-accent);
}

/* 文件按钮：默认那颗灰按钮在深色主题里像一块贴纸，换成站内胶囊 */
input[type="file"] {
    color: var(--mz-ink-2);
}

input[type="file"]::file-selector-button {
    margin-right: 10px;
    padding: 8px 13px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-comp);
    color: var(--mz-ink);
    font: inherit;
    cursor: pointer;
    transition: border-color .18s, color .18s, background .18s;
}

input[type="file"]::file-selector-button:hover {
    border-color: var(--mz-accent-line);
    background: var(--mz-accent-wash);
    color: var(--mz-accent-deep);
}

/* 日期 / 时间 / 取色 / 搜索清除等系统图标：深色下反相 */
[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="datetime-local"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="month"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="week"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] input[type="search"]::-webkit-search-cancel-button,
[data-cc-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-cc-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator,
[data-cc-theme="dark"] input[type="datetime-local"]::-webkit-calendar-picker-indicator,
[data-cc-theme="dark"] input[type="month"]::-webkit-calendar-picker-indicator,
[data-cc-theme="dark"] input[type="week"]::-webkit-calendar-picker-indicator,
[data-cc-theme="dark"] input[type="search"]::-webkit-search-cancel-button {
    filter: invert(1) opacity(.82);
}

/* ---------- 九之三、站内弹窗（MZUI）：浮层档，深浅两色自动跟随 ----------
   engstudy 的页内 alert/confirm/prompt 统一走 /engstudy/js/ui_dialog.js，
   它以前把配色写成行内样式（--mz-flat 实底 + 写死的青绿按钮），深色下偏硬、
   也不跟主题走。现在 JS 只留结构与类名，配色全部在这里给：
   与 .mz-dialog__panel 同一档浮层（--mz-surface-float + 强磨砂），
   按钮用与全站 .btn 同族的胶囊，遮罩与别的弹层同浓度。 */
.mzui-mask {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 18px;
    background: color-mix(in srgb, #04090d 52%, transparent);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

.mzui-box {
    width: min(440px, 100%);
    max-height: 86vh;
    max-height: 86dvh;
    overflow: auto;
    padding: 20px 20px 16px;
    background: var(--mz-surface-float);
    color: var(--mz-ink);
    border: 1px solid var(--mz-line);
    box-shadow: 0 24px 60px -30px rgba(0, 0, 0, .65);
    -webkit-backdrop-filter: blur(var(--mz-blur-float, 48px)) saturate(var(--mz-blur-float-sat, 180%));
    backdrop-filter: blur(var(--mz-blur-float, 48px)) saturate(var(--mz-blur-float-sat, 180%));
    animation: mzui-rise .18s cubic-bezier(.2, .8, .3, 1);
}

@keyframes mzui-rise {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .mzui-box { animation: none; }
}

.mzui-title {
    margin-bottom: 8px;
    font-size: 15px;
    font-weight: 700;
    color: var(--mz-ink);
}

.mzui-msg {
    font-size: 14px;
    line-height: 1.75;
    color: var(--mz-ink-2);
    white-space: pre-wrap;
    word-break: break-word;
}

.mzui-input {
    width: 100%;
    margin-top: 10px;
    height: 38px;
    padding: 0 11px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-sect);
    color: var(--mz-ink);
    font: inherit;
}

.mzui-input:focus {
    outline: none;
    border-color: var(--mz-accent);
    box-shadow: 0 0 0 3px var(--mz-accent-wash);
}

.mzui-bar {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 16px;
}

.mzui-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    padding: 0 16px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, color .16s ease;
}

.mzui-btn:hover {
    border-color: var(--mz-accent-line);
    color: var(--mz-accent-deep);
}

.mzui-btn:focus-visible {
    outline: 2px solid var(--mz-accent);
    outline-offset: 2px;
}

.mzui-btn--ok {
    background: var(--mz-accent);
    border-color: transparent;
    color: var(--mz-btn-ink, #04161a);
    font-weight: 600;
}

.mzui-btn--ok:hover {
    background: var(--mz-accent-deep);
    color: var(--mz-btn-ink, #04161a);
}

.mzui-btn--danger {
    background: var(--mz-danger);
    border-color: transparent;
    color: #1a0d0b;
}

.mzui-btn--danger:hover {
    background: var(--mz-danger);
    color: #1a0d0b;
    opacity: .9;
}

/* 原生 <dialog> 的弹层（随机选择页的新建 / 编辑选择库）：
   它自带 UA 底色与一层「卡片」玻璃，压在正文上同样会透字，
   这里换成与上面同一档浮层（深浅主题自动跟随）。 */
.dlg__in {
    background: var(--mz-surface-float, var(--mz-glass));
    -webkit-backdrop-filter: blur(var(--mz-blur-float, 48px)) saturate(var(--mz-blur-float-sat, 180%));
    backdrop-filter: blur(var(--mz-blur-float, 48px)) saturate(var(--mz-blur-float-sat, 180%));
}

/* ---------- 十、表格 ---------- */
table { border-collapse: collapse; width: 100%; }
th, td { border-bottom: 1px solid var(--mz-line-2); padding: 10px 12px; text-align: left; }
th { font-family: var(--mz-mono); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--mz-ink-3); font-weight: 400; }

/* ---------- 十一、长文 ---------- */
.mz-prose,
.doc {
    font-size: 1rem;
    line-height: 2;
    color: var(--mz-ink-2);
    max-width: 68ch;
}

.mz-prose h2, .doc h2 {
    color: var(--mz-ink);
    font-size: 1.16rem;
    margin: 32px 0 10px;
    padding-top: 18px;
    border-top: 1px solid var(--mz-line-2);
}

.mz-prose p, .doc p { margin: 0 0 20px; }
.mz-prose a, .doc a { color: var(--mz-accent); }
.mz-prose img, .doc img { max-width: 100%; height: auto; border-radius: var(--mz-radius); }

/* ---------- 十二、空态 ---------- */
.mz-empty, .cc-empty {
    border: 1px dashed var(--mz-line);
    border-radius: var(--mz-radius);
    color: var(--mz-ink-4);
    padding: 24px 20px;
    text-align: center;
}

/* ---------- 十三、抽屉与遮罩 ----------
   两套实现：
   · 花粉同城 · 英语教研：<aside class="mz-drawer" data-open>，本身就是面板；
   · 总站：<div class="mz-drawer" data-mz-drawer>，是一个整屏容器，里面再放遮罩与面板。
   后者必须按属性钉回「整屏」，否则会被上面这条面板规则挤成 360px 宽、推到屏幕外，
   点开汉堡后只剩一层看不见的遮罩，页面看起来就「卡死」了。 */
.mz-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    width: min(360px, 88vw);
    padding: 18px;
    overflow-y: auto;
    background: var(--mz-surface-float);
    border-left: 1px solid var(--mz-line);
    box-shadow: var(--mz-shadow);
    -webkit-backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    transform: translateX(102%);
    visibility: hidden;
    transition: transform .28s cubic-bezier(.2, .7, .3, 1), visibility .28s;
}

.mz-drawer[data-open="true"] { transform: none; visibility: visible; }

/* 总站：整屏容器版 */
.mz-drawer[data-mz-drawer] {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: none;
    width: auto;
    max-width: none;
    padding: 0;
    overflow: visible;
    background: none;
    border: 0;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    transform: none;
    visibility: visible;
    transition: none;
}

.mz-drawer[data-mz-drawer].is-open { display: block; }

.mz-drawer[data-mz-drawer] .mz-drawer__mask {
    position: absolute;
    inset: 0;
    background: rgba(4, 12, 16, .5);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}

.mz-drawer[data-mz-drawer] .mz-drawer__panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(340px, 88vw);
    padding: 22px;
    overflow-y: auto;
    background: var(--mz-surface-float);
    border-left: 1px solid var(--mz-line);
    box-shadow: var(--mz-shadow);
    -webkit-backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    animation: mz-drawer-in .26s cubic-bezier(.2, .7, .3, 1);
}

@keyframes mz-drawer-in { from { transform: translateX(100%); } to { transform: none; } }

.mz-drawer__close {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    margin-left: auto;
    border: 1px solid var(--mz-line);
    border-radius: 999px;
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    font-size: 1rem;
    line-height: 1;
}

.mz-drawer__group { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--mz-line-2); }
.mz-drawer__group:first-of-type { border-top: 0; }

.mz-drawer__label {
    font-family: var(--mz-mono);
    font-size: .62rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
    margin-bottom: 8px;
}

.mz-drawer__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px;
    border-radius: var(--mz-radius);
    font-size: .92rem;
    color: var(--mz-ink-2);
}

.mz-drawer__link:hover { background: var(--mz-accent-wash); color: var(--mz-accent); }
.mz-drawer__link[aria-current="page"] { color: var(--mz-accent); font-weight: 700; }

.mz-drawer-group { padding: 14px 4px; border-top: 1px solid var(--mz-line-2); }
.mz-drawer-group:first-of-type { border-top: 0; }

.mz-drawer-group h3 {
    margin: 0 0 8px;
    font-family: var(--mz-mono);
    font-size: .66rem;
    font-weight: 400;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.mz-drawer-group a {
    display: block;
    padding: 8px 10px;
    border-radius: var(--mz-radius);
    font-size: .92rem;
    color: var(--mz-ink-2);
}

.mz-drawer-group a:hover { background: var(--mz-accent-wash); color: var(--mz-accent); }

.mz-drawer-head { display: flex; justify-content: flex-end; padding-bottom: 6px; }

.mz-scrim {
    position: fixed;
    inset: 0;
    z-index: 80;
    background: rgba(4, 12, 16, .5);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s, visibility .28s;
}

.mz-scrim[data-open="true"] { opacity: 1; visibility: visible; }

/* ---------- 十四、站脚 ----------
   页脚只留文字，不画底框（底色与上边线都去掉）：
   内容不满一屏时由 mz-crumb.js 的 stickFooter() 把它沉到视口底部。 */
.foot,
.mz-footer,
.site-footer {
    position: relative;
    border-top: 0;
    margin-top: 56px;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

.foot__in,
.mz-footer__inner,
.site-footer__in {
    max-width: var(--mz-page);
    margin: 0 auto;
    padding: 24px var(--mz-gutter) 32px;
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
    justify-content: space-between;
    color: var(--mz-ink-3);
    font-size: .84rem;
}

.mz-footer-grid {
    display: grid;
    grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr));
    gap: 28px;
    padding: 34px 0 26px;
}

.mz-footer-brand p { margin: 0; color: var(--mz-ink-3); font-size: .88rem; line-height: 1.85; max-width: 40ch; }
.mz-footer-brand b { color: var(--mz-ink); }

.mz-footer-col h3 {
    margin: 0 0 10px;
    font-family: var(--mz-mono);
    font-size: .66rem;
    font-weight: 400;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.mz-footer-col a {
    display: block;
    padding: 4px 0;
    font-size: .86rem;
    color: var(--mz-ink-2);
}

.mz-footer-col a:hover { color: var(--mz-accent); }

.mz-footer-bottom {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    justify-content: space-between;
    padding-top: 18px;
    border-top: 1px solid var(--mz-line);
    font-family: var(--mz-mono);
    font-size: .7rem;
    letter-spacing: .04em;
    color: var(--mz-ink-4);
}

/* ---------- 十五、版式基准 ---------- */
.wrap,
.mz-wrap,
.page__in,
main > .wrap {
    width: 100%;
    max-width: var(--mz-page);
    margin: 0 auto;
    padding-left: var(--mz-gutter);
    padding-right: var(--mz-gutter);
}

.section,
.sec,
.mz-section { margin-top: 48px; }

.section:first-of-type,
.sec:first-of-type,
.mz-section:first-of-type { margin-top: 0; }

.sec__head,
.section__head {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding-bottom: 12px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--mz-line);
}

.sec__head h2,
.section__head h2,
.sec__title {
    margin: 0;
    font-size: clamp(1.1rem, 2vw, 1.35rem);
    font-weight: 700;
    letter-spacing: -.01em;
}

.sec__note {
    font-family: var(--mz-mono);
    font-size: .68rem;
    letter-spacing: .12em;
    color: var(--mz-ink-4);
}

.sec__more {
    margin-left: auto;
    font-size: .84rem;
    color: var(--mz-accent);
    white-space: nowrap;
}

/* 区头右侧动作区：「刷新 + 更多文章」的统一容器（三站同一套，页面里不再写内联样式） */
.sec__acts {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ---------- 十六、跳到正文 ---------- */
.mz-sr, .skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: 10px 16px;
    background: var(--mz-accent);
    color: var(--mz-btn-ink);
    border-radius: 0 0 var(--mz-radius) 0;
}

.mz-sr:focus, .skip-link:focus { left: 0; }

/* 页头下沿：渐进模糊（261025-09）
   页头是吸顶的、胶囊本身只占中间那段，正文从上下左右穿过去会显得很乱。
   这里在页头整块区域铺一层「blur + 向下渐隐」的过渡带：
   顶部最强（正好盖住胶囊与顶部留白），到页头下方 70px 处完全消失。 */
.mz-topbar::after,
.top::after,
.mz-header::after,
.site-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: calc(100% + 72px);
    z-index: -1;
    pointer-events: none;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    -webkit-mask-image: linear-gradient(to bottom,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 1) calc(100% - 72px),
        rgba(0, 0, 0, .55) calc(100% - 34px),
        rgba(0, 0, 0, 0) 100%);
    mask-image: linear-gradient(to bottom,
        rgba(0, 0, 0, 1) 0%,
        rgba(0, 0, 0, 1) calc(100% - 72px),
        rgba(0, 0, 0, .55) calc(100% - 34px),
        rgba(0, 0, 0, 0) 100%);
}

@media (max-width: 720px) {
    .mz-topbar::after,
    .top::after,
    .mz-header::after,
    .site-header::after {
        height: calc(100% + 48px);
        -webkit-backdrop-filter: blur(10px);
        backdrop-filter: blur(10px);
        -webkit-mask-image: linear-gradient(to bottom,
            rgba(0, 0, 0, 1) 0%,
            rgba(0, 0, 0, 1) calc(100% - 48px),
            rgba(0, 0, 0, 0) 100%);
        mask-image: linear-gradient(to bottom,
            rgba(0, 0, 0, 1) 0%,
            rgba(0, 0, 0, 1) calc(100% - 48px),
            rgba(0, 0, 0, 0) 100%);
    }
}

/* ---------- 十七、窄屏 ---------- */
@media (max-width: 900px) {
    .mz-footer-grid { grid-template-columns: 1fr 1fr; }
    .mz-nav { display: none; }
}

@media (max-width: 720px) {
    :root { --mz-gutter: 18px; --mz-topbar-h: 58px; --mz-topbar-fade: 48px; }
    .mz-footer-grid { grid-template-columns: 1fr; gap: 18px; }
    .mz-brand__sub { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ============================================================
   十八、终端页区块（tz-*）
   ------------------------------------------------------------
   四个站点的「主页面」共用同一套区块，全部照 theme-preview/b-terminal
   的骨架落位（左文案 + 右频道面板 / 等宽标签 / 日志流 / 玻璃面板）：

     .tz-hero   两栏主视觉        .tz-panel  频道状态面板
     .tz-sect   区块              .tz-log    日志流列表
     .tz-grid   卡片栅格          .tz-card   快捷入口卡

   页面自己的样式表不必再为首页写一套，避免四站各行其是。
   ============================================================ */

.tz-wrap {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: var(--mz-page);
    margin: 0 auto;
    padding-left: var(--mz-gutter);
    padding-right: var(--mz-gutter);
}

.tz-mono {
    font-family: var(--mz-mono);
    font-size: .7rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-3);
}

/* ── 主视觉 ──
   注意：.tz-hero 常与 .tz-wrap 同挂一个元素，这里只写 padding-block；
   一写 padding 简写就会把 .tz-wrap 的左右页边清零，主视觉比下面的区块多出 24px。 */
.tz-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
    gap: clamp(28px, 5vw, 60px);
    align-items: center;
    padding-block: clamp(44px, 6vw, 78px) clamp(28px, 4vw, 44px);
}

.tz-statusline {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    font-family: var(--mz-mono);
    font-size: .7rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-3);
}

.tz-dot {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: 50%;
    background: var(--mz-accent);
    box-shadow: 0 0 0 3px var(--mz-accent-wash);
    animation: tz-pulse 2.6s ease-in-out infinite;
}

@keyframes tz-pulse {
    0%, 100% { box-shadow: 0 0 0 3px var(--mz-accent-wash); }
    50% { box-shadow: 0 0 0 8px transparent; }
}

.tz-title {
    margin: 20px 0 0;
    font-size: clamp(2.1rem, 4.6vw, 3.4rem);
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: -.02em;
    color: var(--mz-ink);
}

.tz-title em {
    font-style: normal;
    color: var(--mz-accent);
}

.tz-lede {
    margin: 20px 0 0;
    max-width: 44ch;
    font-size: .97rem;
    line-height: 1.85;
    color: var(--mz-ink-2);
}

.tz-act {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 28px;
}

/* ── 频道状态面板 ── */
.tz-panel {
    overflow: hidden;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-surface-card);
    box-shadow: var(--mz-shadow);
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
}

.tz-panel__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--mz-line);
    background: var(--mz-surface-comp);
}

.tz-panel__head .tz-mono { color: var(--mz-ink-2); }
.tz-panel__head .tz-mono--right { margin-left: auto; color: var(--mz-ink-3); }

.tz-ch {
    display: grid;
    grid-template-columns: 10px minmax(0, 1fr) auto;
    align-items: center;
    gap: 4px 13px;
    padding: 13px 18px;
    border-bottom: 1px solid var(--mz-line);
    color: inherit;
    text-decoration: none;
    transition: background .18s;
}

.tz-ch:last-child { border-bottom: 0; }
.tz-ch:hover { background: var(--mz-accent-wash); }

.tz-ch__bar {
    width: 3px;
    height: 24px;
    border-radius: 2px;
    background: var(--mz-accent);
    box-shadow: 0 0 10px var(--mz-accent-wash);
}

.tz-ch__name {
    font-size: .93rem;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--mz-ink);
}

.tz-ch__id {
    display: block;
    font-family: var(--mz-mono);
    font-size: .6rem;
    font-weight: 400;
    letter-spacing: .14em;
    color: var(--mz-ink-4);
}

.tz-ch__state {
    font-family: var(--mz-mono);
    font-size: .62rem;
    letter-spacing: .1em;
    color: var(--mz-accent);
    text-transform: uppercase;
    white-space: nowrap;
}

.tz-ch__state--warn { color: var(--mz-warn); }

/* ── 区块 ──
   同上：只写 padding-block，左右页边留给 .tz-wrap / .tz-page。 */
.tz-sect { padding-block: clamp(30px, 4vw, 50px) 0; }

.tz-sect__head {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}

.tz-sect__head h2 {
    margin: 0;
    font-size: clamp(1.16rem, 2vw, 1.4rem);
    font-weight: 700;
    letter-spacing: -.01em;
}

.tz-sect__head .tz-mono { margin-left: auto; }
.tz-sect__head a.tz-mono { color: var(--mz-accent); margin-left: 0; }
.tz-sect__head a.tz-mono:last-child { margin-left: auto; }

/* ── 日志流：卡片档（底色 / 描边 / 圆角 / 模糊来自第五节）── */
.tz-log {
    overflow: hidden;
}

.tz-log > a,
.tz-log__row {
    display: grid;
    /* 时间列与键值对共用 --mz-label-w：同一屏里「时间 / 标签」竖线对齐 */
    grid-template-columns: var(--mz-label-w, 136px) minmax(0, 1fr) auto;
    align-items: center;
    gap: 16px;
    padding: 15px 18px;
    border-bottom: 1px solid var(--mz-line);
    color: inherit;
    text-decoration: none;
    transition: background .18s;
}

.tz-log > a:last-child { border-bottom: 0; }
.tz-log > a:hover { background: var(--mz-surface-comp); }

.tz-log time {
    font-family: var(--mz-mono);
    font-size: .72rem;
    letter-spacing: .05em;
    color: var(--mz-ink-4);
}

.tz-log span { font-size: .95rem; }
.tz-log > a:hover span { color: var(--mz-accent); }

.tz-log b {
    font-family: var(--mz-mono);
    font-size: .64rem;
    font-weight: 400;
    letter-spacing: .1em;
    padding: 3px 9px;
    border-radius: var(--mz-radius-pill);
    border: 1px solid var(--mz-line);
    color: var(--mz-ink-3);
}

/* 列表里的分隔行（feed 渲染出来的行也按同一节奏排） */
.tz-log .mz-feed,
.tz-log .hf-shell,
.tz-log [data-mz-feed] { display: block; }

/* ── 卡片栅格 ── */
.tz-grid {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

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

.tz-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 20px;
    color: inherit;
    text-decoration: none;
    transition: transform .22s cubic-bezier(.2, .7, .3, 1), border-color .2s, box-shadow .22s;
}

.tz-card:hover {
    transform: translateY(-2px);
    border-color: var(--mz-accent-line);
    box-shadow: var(--mz-shadow-lift);
}

.tz-card__kicker {
    font-family: var(--mz-mono);
    font-size: .62rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.tz-card__title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--mz-ink);
}

.tz-card__desc {
    margin: 0;
    font-size: .86rem;
    line-height: 1.75;
    color: var(--mz-ink-2);
}

.tz-card__go {
    margin-top: auto;
    padding-top: 10px;
    font-family: var(--mz-mono);
    font-size: .72rem;
    letter-spacing: .08em;
    color: var(--mz-accent);
}

/* ── 底部签名行 ── */
.tz-footsign {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 22px;
    margin-top: clamp(28px, 4vw, 44px);
    padding-top: 18px;
    border-top: 1px solid var(--mz-line);
    font-family: var(--mz-mono);
    font-size: .7rem;
    letter-spacing: .08em;
    color: var(--mz-ink-4);
}

/* ── 窄屏 ── */
@media (max-width: 900px) {
    .tz-hero { grid-template-columns: minmax(0, 1fr); gap: 28px; }
    .tz-grid { grid-template-columns: minmax(0, 1fr); }
    .tz-log > a,
    .tz-log__row { grid-template-columns: minmax(0, 1fr) auto; }
    .tz-log time { grid-column: 1 / -1; }
    .tz-sect__head .tz-mono { margin-left: 0; }
}

/* 单栏页容器（英语教研首页等去掉页边栏的页面用） */
.tz-page {
    width: 100%;
    max-width: var(--mz-page);
    margin: 0 auto;
    padding: 0 var(--mz-gutter) 64px;
}

/* ============================================================
   十九、英语教研子页：与其它三站同一套单栏骨架
   ------------------------------------------------------------
   英语教研的子页原先用「页边批注栏 + 主栏」两栏骨架，花粉同城与总站
   都是单栏，同样功能的页面（推送列表、通知、工具）在四站里长短不一。
   这里把 engstudy 的 .shell 收敛成单栏，批注信息仍留在正文里；
   只对带 data-page 的 engstudy 页面生效（工作台同名 .shell 不受影响）。
   ============================================================ */
html[data-page] .shell {
    display: block;
    max-width: var(--mz-page);
    margin: 0 auto;
    padding: 0 var(--mz-gutter) 64px;
}

html[data-page] .rail { display: none; }

/* ============================================================
   二十、字体：全站只用 HarmonyOS Sans SC
   ------------------------------------------------------------
   站内自持的字体只有 HarmonyOS Sans SC 一套子集（common/font/font.css），
   但各站历史样式里还散着 ui-monospace / 楷体 / 宋体 等族名与 --*-mono
   变量，页面上就会出现「同一屏里两种字」。
   这里一次收口：先把所有相关变量指回 Harmony，再用一条兜底规则盖住
   仍写死族名的零散选择器（代码块、等宽小标也在内）。
   ============================================================ */

:root,
[data-theme],
[data-theme="dark"],
[data-site] {
    --mz-sans: "HarmonyOS Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    --mz-serif: var(--mz-sans);
    --mz-display: var(--mz-sans);
    --mz-mono: var(--mz-sans);
    --mz-code: var(--mz-sans);

    --f-sans: var(--mz-sans);
    --f-serif: var(--mz-sans);
    --f-mono: var(--mz-sans);
    --f-code: var(--mz-sans);

    --mono: var(--mz-sans);
    --code: var(--mz-sans);

    --font-mono: var(--mz-sans);
    --font-kai: var(--mz-sans);
    --font-song: var(--mz-sans);
    --font-sans: var(--mz-sans);
    --font-display: var(--mz-sans);

    --cc-mono: var(--mz-sans);
    --cc-code: var(--mz-sans);
}

/* 兜底：把仍写死族名的零散选择器（代码块、等宽小标）收进 Harmony。
   注意不要用 `body *` —— 给每个元素都强塞一条 !important 的 font-family，
   会让浏览器在每次样式重算时逐元素匹配一次，页面越复杂越慢。 */
html,
body,
button,
input,
select,
textarea,
optgroup,
code,
kbd,
pre,
samp,
.mono,
.mz-mono,
.tz-mono,
.mz-kicker {
    font-family: "HarmonyOS Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
}

body code,
body kbd,
body pre,
body samp,
.mono,
.mz-mono,
.tz-mono {
    font-family: var(--mz-sans) !important;
}

/* 等宽小标仍保留字距与大小写，只换字形族 */
.mono,
.mz-mono,
.tz-mono {
    font-variant-ligatures: none;
}

/* ---------- 二十一、页脚：三站同一套结构（收口补充） ---------- */
.mz-footer-note {
    margin: 10px 0 0;
    font-size: .78rem;
    letter-spacing: .08em;
    color: var(--mz-ink-4);
}

.mz-footer-grid .mz-footer-col a { color: var(--mz-ink-2); }
.mz-footer-grid .mz-footer-col a:hover { color: var(--mz-accent); }
.mz-footer-brand b { color: var(--mz-ink); }

@media (max-width: 900px) {
    .mz-footer-grid { grid-template-columns: 1fr 1fr; gap: 20px; }
    .mz-footer-brand { grid-column: 1 / -1; }
}

/* ============================================================
   二十二、工作台外壳：与其它三站同一枚胶囊页头
   ------------------------------------------------------------
   工作台原来的页头是「满幅玻璃条 + 分隔线」，正文也没有收进同一根栏宽，
   放在四站里看着不是一套东西。这里只改外壳三件：
     .rail（页头）· .topbar（正文页头）· .foot（页脚）
   视图部件与交互代码一律不动，避免影响任务面板。
   ============================================================ */

@media (min-width: 900px) {
    .shell {
        display: block;
        padding: 0 !important;
    }

    /* 页头：整条收成悬浮胶囊 */
    .rail {
        position: sticky !important;
        top: 0;
        z-index: 40;
        display: flex;
        align-items: center;
        gap: 14px;
        width: 100% !important;
        max-width: var(--mz-page);
        height: auto !important;
        min-height: 0 !important;
        margin: 14px auto 0 !important;
        padding: 8px 10px 8px 16px !important;
        border: 1px solid var(--mz-line) !important;
        border-radius: var(--mz-radius-pill) !important;
        background: var(--mz-surface-comp) !important;
        box-shadow: var(--mz-shadow);
        -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
        backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    }

    .brand {
        padding: 0 !important;
        border: 0 !important;
        gap: 10px !important;
    }

    .brand-logo { width: 32px !important; height: 32px !important; }

    .brand-txt { font-size: .95rem !important; letter-spacing: .1em !important; }

    .brand-txt i {
        font-size: .56rem !important;
        letter-spacing: .18em !important;
        color: var(--mz-ink-4) !important;
    }

    /* 分区导航：与总站的 .mz-nav 同一个药丸节奏 */
    .rail-nav {
        flex-direction: row;
        align-items: center;
        gap: 2px;
        margin-left: auto !important;
    }

    .nav-btn {
        width: auto !important;
        flex-direction: row !important;
        align-items: center;
        gap: 7px;
        padding: 7px 12px !important;
        border: 1px solid transparent !important;
        border-radius: var(--mz-radius-pill) !important;
        font-size: .87rem !important;
        letter-spacing: 0 !important;
        color: var(--mz-ink-2) !important;
        background: none !important;
    }

    .nav-btn .nav-glyph {
        display: grid;
        place-items: center;
        width: 22px !important;
        height: 22px !important;
        border: 0 !important;
        border-radius: 7px !important;
        background: var(--mz-accent-wash) !important;
        color: var(--mz-accent) !important;
        font-size: .74rem !important;
        box-shadow: none !important;
    }

    .nav-btn:hover { background: var(--mz-accent-wash) !important; color: var(--mz-accent) !important; }

    .nav-btn.is-on {
        background: var(--mz-accent-wash) !important;
        color: var(--mz-accent) !important;
        font-weight: 700 !important;
    }

    .nav-btn.is-on .nav-glyph {
        background: var(--mz-accent) !important;
        color: var(--mz-btn-ink) !important;
    }

    .rail-foot {
        margin: 0 0 0 8px !important;
        flex-direction: row !important;
        align-items: center;
        gap: 8px !important;
    }

    /* 正文页头：不再是满幅玻璃条，收进同一根栏宽 */
    .topbar {
        display: flex;
        width: 100%;
        align-items: flex-end;
        justify-content: space-between;
        gap: 16px;
        max-width: var(--mz-page);
        margin: 0 auto;
        padding: 26px var(--mz-gutter) 12px !important;
        border: 0 !important;
        background: transparent !important;
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
    }

    .topbar-head { min-width: 0; }
    .topbar > .topbar-head { flex: 1 1 auto; }

    .topbar-side { display: flex; align-items: center; gap: 10px; }

    #page-title {
        margin: 4px 0 0;
        font-size: clamp(1.4rem, 2.4vw, 1.9rem);
        letter-spacing: -.01em;
    }

    /* 页脚：贴着正文的那条，不再是浮在底部的胶囊 */
    .foot {
        position: static !important;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        gap: 10px 22px;
        max-width: var(--mz-page);
        margin: 40px auto 0 !important;
        padding: 18px var(--mz-gutter) 28px !important;
        border: 0 !important;
        border-top: 1px solid var(--mz-line) !important;
        border-radius: 0 !important;
        background: transparent !important;
        box-shadow: none !important;
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
    }

    .foot-links { gap: 14px; color: var(--mz-ink-4); }
    .foot-brand { color: var(--mz-ink-2); }
    .foot a:hover { color: var(--mz-accent); }
}

/* ---------- 二十三、品牌位去重 ----------
   总站的品牌文字本来就叫「墨泓斋」，而 logo.png 里已经写了同样的字，
   两者并排会重复一遍。总站只留 logo，子站（英语教研 / 花粉同城 / 工作台）
   保留「logo + 站名」，因为 logo 说的是墨泓斋，站名另有其字。 */
.mz-topbar .mz-brand__text { display: none; }

/* ============================================================
   二十四、全站唯一一套图标
   ------------------------------------------------------------
   图标只存在 /common/image/icons.svg 一处（symbol 版），
   四个站点用 <svg class="mz-i"><use href="/common/image/icons.svg#menu"></use></svg>
   引用同一个形状；颜色与线宽由 .mz-i 统一给，所以明暗两套主题下
   图标自动跟着 currentColor 走，不需要各站再画一份。

   现有页面里还留着几处老写法（总站的 span 汉堡、英语教研与花粉同城
   各自的行内 SVG），下面用同尺寸把它们收到同一视觉规格上。
   ============================================================ */

.mz-i,
.mz-theme-btn svg,
.mz-iconbtn svg,
.ibtn svg,
.mz-burger svg {
    width: 17px;
    height: 17px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* 总站的汉堡是三个 span：线宽 / 长度 / 间距对齐 SVG 版 */
.mz-burger span {
    display: block;
    width: 16px;
    height: 1.7px;
    margin: 3.4px auto;
    border-radius: 2px;
    background: currentColor;
}

.mz-burger span:first-child { margin-top: 0; }
.mz-burger span:last-child { margin-bottom: 0; }

/* 页头图标按钮统一 36×36 圆胶囊，图标居中 */
.mz-theme-btn,
.mz-iconbtn,
.mz-burger,
.ibtn,
.drawer-btn {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
}

/* 头像胶囊右侧的展开箭头：走统一图标，不再用 ▼ 文字字符（字符易缺字变豆腐块） */
.mz-user__caret {
    width: 14px;
    height: 14px;
    color: var(--mz-ink-4);
    flex: none;
}

/* ============================================================
   二十五、文章详情（全站共用）
   ------------------------------------------------------------
   文章、通知、登录是三处跨站共用的功能，样式与结构按同一口径放在这里，
   页面只负责取数与填空：
     · 封面   .mz-article-cover（有封面才出现，16:9 等比裁切，取不到则整块隐藏）
     · 标题区 由各页原有的 .article-head 提供，字号/间距沿用主题层
   以后其它站新增文章详情页，只要引入 common 并复用这两个类名即可。
   ============================================================ */

.mz-article-cover {
    margin: 24px 0 6px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-surface-comp);
    box-shadow: var(--mz-shadow);
}

.mz-article-cover[hidden] { display: none; }

.mz-article-cover img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 720px) {
    .mz-article-cover { aspect-ratio: 4 / 3; margin-top: 18px; }
}

/* ============================================================
   二十六、性能：把「毛玻璃」用在刀刃上
   ------------------------------------------------------------
   backdrop-filter 的代价是：只要元素背后有内容变化（滚动、动画、列表重绘），
   浏览器就要把背后那块画面重新做一次模糊。页头胶囊是吸顶的，页面上又同时
   有十几个玻璃面板，于是每滚一帧都在反复模糊整屏 —— 这就是「卡」的主因。

   这里按「值不值得」分级：
     · 常驻的面板、卡片、页头、页脚 → 换成半透明实底，去掉模糊
       （视觉上仍是同一种玻璃感：描边 + 顶部高光 + 柔和投影都还在）
     · 抽屉、弹窗、遮罩等临时层 → 保留模糊（出现时才渲染，几乎不占滚动帧）
   ============================================================ */

:root {
    --mz-flat: #f1f5f8;
    --mz-flat-2: #e9f0f5;
}

[data-theme="dark"],
html[data-theme="dark"],
html[data-theme="ink"] {
    --mz-flat: #0d1318;
    --mz-flat-2: #080e13;
}

/* 原先这里还挂着一条「常驻卡片、面板换不透明实底并去掉模糊」的规则，
   第 102 轮改成全站统一玻璃后该条已删除，否则会把卡片的 backdrop-filter
   抵消掉；只有吸顶页头与页脚仍取贴近底色的一档（见下）。 */
/* 吸顶页头与各站自绘的页头内条：统一取「组件档」玻璃（--mz-surface-comp），
   不再刷不透明实底 —— 第 102 轮之前这里用 var(--mz-flat) !important，
   会把胶囊刚设好的玻璃底重新糊成一块实色。 */
.mz-topbar__inner,
.top > .top__in,
.mz-header > .mz-header-inner,
.rail {
    background: var(--mz-surface-comp) !important;
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat)) !important;
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat)) !important;
}

/* 页脚不画底框，直接落在页面底上（原先这里还刷一层 --mz-flat-2） */
.mz-footer,
.foot,
.site-footer {
    background: none !important;
    border-top: 0 !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* 页脚是 body 的直接子元素时（门户、404、协议页…），
   用 flex 把它压到视口底部；嵌在别的容器里的由 mz-crumb.js 兜。 */
body:has(> footer.foot),
body:has(> footer.mz-footer),
body:has(> footer.site-footer) {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

body:has(> footer.foot) > footer.foot,
body:has(> footer.mz-footer) > footer.mz-footer,
body:has(> footer.site-footer) > footer.site-footer {
    margin-top: auto !important;
    /* 交叉轴上的 auto 外边距会让它「缩成内容宽」，这里撑回整栏 */
    align-self: stretch;
    width: 100%;
    box-sizing: border-box;
}

/* 临时层（抽屉 / 弹窗 / 遮罩）保留模糊，并提升为独立图层，
   打开时只渲染一次，不参与正文滚动 */
.mz-drawer,
.mz-drawer__panel,
.drawer__panel,
.mz-dialog__panel {
    will-change: transform;
}

/* 长列表里每行都带 transition 会造成大量样式重算，只保留背景色变化 */
.tz-log > a,
.tz-log__row,
.mz-log a {
    transition: background-color .15s linear;
}

/* 尊重系统的"减少动态效果"：关掉脉冲与位移 */
@media (prefers-reduced-motion: reduce) {
    .tz-dot,
    .mz-theme-btn,
    .tz-card,
    .mz-btn {
        animation: none !important;
        transition: none !important;
    }
}

/* ---------- 二十七、字体兜底与字体栈收口 ----------
   HarmonyOS 子集只覆盖汉字与常用拉丁；昵称里若带 emoji 或生僻符号，
   没有兜底族就会渲染成「方框」。这里把系统 emoji 族补在末尾，
   既不影响汉字字形，也不会再出现豆腐块。 */
:root {
    --mz-sans: "HarmonyOS Sans SC", -apple-system, BlinkMacSystemFont,
        "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
        "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;
}

html,
body,
button,
input,
select,
textarea,
optgroup,
code,
kbd,
pre,
samp,
.mono,
.mz-mono,
.tz-mono,
.mz-kicker,
.mz-user__name {
    font-family: var(--mz-sans);
}

/* ---------- 二十八、汉堡按钮：与外观按钮同一规格 ----------
   之前总站的汉堡用的是三个 span，在圆钮里按网格行均分，
   线长线距会被拉得不齐；再加上点过之后残留的 hover/focus 高亮，
   看上去就是「一个又大又亮、线条还歪的按钮」。这里改成
   固定 flex 列 + 等距等长细线，并让它与外观按钮完全相同的大小、
   描边、配色与悬停表现。 */
.mz-burger,
.drawer-btn {
    display: inline-flex !important;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 36px;
    height: 36px;
    padding: 0;
    flex: none;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    box-shadow: none;
}

.mz-burger span {
    display: block;
    width: 16px;
    height: 2px;
    margin: 0;
    flex: none;
    border-radius: 1px;
    background: currentColor;
}

.mz-burger svg { width: 17px; height: 17px; }

/* 与外观按钮同一套交互态：悬停变强调色，点过之后不残留高亮 */
.mz-burger:hover,
.drawer-btn:hover {
    border-color: var(--mz-accent);
    color: var(--mz-accent);
    background: var(--mz-accent-wash);
}

.mz-burger[aria-expanded="true"] {
    border-color: var(--mz-line);
    color: var(--mz-ink-2);
}

.mz-burger:focus { outline: none; }
.mz-burger:focus-visible { outline: 2px solid var(--mz-accent); outline-offset: 2px; }

/* ---------- 二十七、跟随系统兜底 ----------
   公共层原先只在 [data-theme="dark"] 上覆盖令牌，页面若没引首屏脚本
   就会停在浅色。这里把基础令牌在「系统深色且没有显式主题」时同样换掉，
   其余别名（--mz-paper / --mz-cinnabar / --ink / --line …）都指回这些基础令牌，
   会自动跟着变。 */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
        color-scheme: dark;
        --mz-bg: #05090d;
        --mz-bg-2: #04080b;
        --mz-glow-1: rgba(24, 170, 190, .34);
        --mz-glow-2: rgba(88, 90, 230, .3);
        --mz-glow-3: rgba(20, 130, 140, .26);
        --mz-dot: rgba(255, 255, 255, .055);
        --mz-glass: rgba(255, 255, 255, .055);
        --mz-glass-2: rgba(255, 255, 255, .03);
        --mz-glass-3: rgba(255, 255, 255, .02);
        --mz-bhair: rgba(255, 255, 255, .085);
        --mz-ink: #e8f2f6;
        --mz-ink-2: #aebfc9;
        --mz-ink-3: #7d8f9a;
        --mz-ink-4: #5c6c77;
        --mz-line: rgba(255, 255, 255, .1);
        --mz-line-2: rgba(255, 255, 255, .06);
        --mz-line-strong: rgba(255, 255, 255, .2);
        --mz-accent: #3fdcea;
        --mz-accent-deep: #7ceef8;
        --mz-accent-wash: rgba(63, 220, 234, .14);
        --mz-accent-line: rgba(63, 220, 234, .42);
        --mz-btn-ink: #04161a;
        --mz-ok: #4ad9a4;
        --mz-warn: #f5b544;
        --mz-danger: #ff8a7a;
        --mz-gold: #e0bb74;
        --mz-shadow-s: 0 1px 2px rgba(0, 0, 0, .5);
        --mz-shadow: 0 30px 70px -44px rgba(0, 0, 0, .95), inset 0 1px 0 var(--mz-bhair);
        --mz-shadow-lift: 0 40px 80px -34px rgba(0, 0, 0, .9), inset 0 1px 0 var(--mz-bhair);
        --mz-flat: #0d1318;
        --mz-flat-2: #080e13;
    }
}

/* ---------- 二十八、页头用户胶囊：四站同一形状 ----------
   英语的 .uchip、总站的 .mz-user、工作台的 .mine 收成一套：
   高 34、头像 26、间距 8、圆角胶囊、右内边距 12。
   登录按钮已在上面统一为实心强调色胶囊。 */
.uchip,
.mz-user__btn,
.wb-mine .mine {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    max-width: 180px;
    padding: 3px 12px 3px 3px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    font-size: .84rem;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: border-color .18s, color .18s, background .18s;
}

.uchip:hover,
.mz-user__btn:hover,
.wb-mine .mine:hover {
    border-color: var(--mz-accent);
    color: var(--mz-accent);
}

/* 容器本身只负责定位，不要再画一层框（否则会出现「双框」） */
.mz-user,
.wb-mine {
    display: inline-flex;
    align-items: center;
    border: 0;
    background: none;
    box-shadow: none;
}

.uchip img,
.uchip .uchip__ph,
.mz-user .mz-user__avatar,
.mz-user .mz-avatar,
.wb-mine .mine-avatar,
.wb-mine .mine-seal {
    width: 26px;
    height: 26px;
    flex: none;
    display: grid;
    place-items: center;
    overflow: hidden;
    border-radius: 50%;
    object-fit: cover;
    background: var(--mz-accent);
    color: var(--mz-btn-ink);
    font-size: .74rem;
    font-weight: 700;
}

.uchip span,
.mz-user__name,
.wb-mine .mine-name {
    max-width: 11ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.uchip span { font-size: .82rem; }

/* ---------- 二十八附、用户弹层（头像下方那张卡） ----------
   位置挂在胶囊下方；大小头像同源，展开时大头像从顶栏那枚「飞」下来长开。
   内容分四段：身份 / 三项数字 / 快捷入口 / 外观 + 退出。 */
.mz-user {
    position: relative;
    /* 261101：顶栏头像改成块级 + 定尺，修「头像比旁边的按钮低一截」的错位
       （内联图片默认坐在文字基线上，会多出几像素的下缘空白） */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.mz-user > img,
.mz-user > .mz-user__avatar {
    display: block;
    width: 30px;
    height: 30px;
    border-radius: 999px;
    object-fit: cover;
    flex: 0 0 auto;
}

.mz-user__menu {
    position: absolute;
    /* 以头像为中心展开。搜索框移到顶栏最右之后，胶囊整体左移，
       居中也不再出屏；万一真的越界，由 mz-user.js 的 clampPanel() 兜底。 */
    left: 50%;
    top: calc(100% + 16px);
    transform: translateX(-50%);
    z-index: 70;
    width: min(304px, calc(100vw - 24px));
    max-width: calc(100vw - 24px);
    box-sizing: border-box;
    padding: 0 15px 14px;
    border: 1px solid var(--mz-line);
    border-radius: 20px;
    /* 261101：用户菜单也是浮层 —— 与下拉菜单同一档（--mz-surface-float），
       原来这里是 var(--mz-flat) 实底，透明后必须靠浮层浓度 + 强磨砂顶住可读性 */
    background: var(--mz-surface-float);
    -webkit-backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    box-shadow: var(--mz-shadow-lift, var(--mz-shadow));
    text-align: center;
    display: none;
}

.mz-user.is-open .mz-user__menu {
    display: block;
    animation: mz-user-pop .18s ease;
}

@keyframes mz-user-pop {
    from { opacity: 0; }
}

/* 窄屏：弹层已统一贴右缘（见上面的基类规则），这里不再重复定位 */

/* 遮罩：挂在 body 上（胶囊带 backdrop-filter，内部 fixed 会按胶囊定位），
   只在小屏的底部弹窗里出现 */
.mz-user__mask {
    display: none;
}

.mz-user__mask[hidden] {
    display: none !important;
}

/* 窄屏：用户弹层改成底部弹出，卡片样式与桌面一致 */
@media (max-width: 760px) {
    .mz-user__mask:not([hidden]) {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 69;
        background: rgba(6, 14, 20, .55);
        -webkit-backdrop-filter: blur(3px);
        backdrop-filter: blur(3px);
    }

    .mz-user__menu.is-sheet {
        display: block;
        position: fixed;
        left: 12px;
        right: 12px;
        top: auto;
        bottom: calc(12px + env(safe-area-inset-bottom, 0px));
        width: auto;
        max-height: none;
        overflow: visible;
        padding: 14px 14px 12px;
        transform: none;
        animation: mz-user-sheet .26s cubic-bezier(.2, .8, .2, 1);
    }

    /* 登录后：头像在左，昵称与账号在右（省一大截高度） */
    .mz-user__menu.is-sheet .mz-user__panel:not(.mz-user__panel--guest) {
        display: grid;
        grid-template-columns: 52px minmax(0, 1fr);
        align-items: center;
        column-gap: 12px;
        text-align: left;
    }

    .mz-user__menu.is-sheet .mz-user__big {
        grid-column: 1;
        grid-row: 1 / span 2;
        width: 52px;
        height: 52px;
        margin: 0;
        border-width: 2px;
    }

    .mz-user__menu.is-sheet .mz-user__nick {
        grid-column: 2;
        grid-row: 1;
        justify-content: flex-start;
    }

    .mz-user__menu.is-sheet .mz-user__sub {
        grid-column: 2;
        grid-row: 2;
        margin-top: 2px;
        text-align: left;
    }

    .mz-user__menu.is-sheet .mz-user__stats,
    .mz-user__menu.is-sheet .mz-user__links,
    .mz-user__menu.is-sheet .mz-user__themes,
    .mz-user__menu.is-sheet .mz-user__logout {
        grid-column: 1 / -1;
    }

    /* 纵向收一收：每块都留够点按高度，但不堆空白 */
    .mz-user__menu.is-sheet .mz-user__stats {
        margin-top: 12px;
        padding: 9px 0;
    }

    .mz-user__menu.is-sheet .mz-user__links {
        padding: 5px 0;
    }

    .mz-user__menu.is-sheet .mz-user__links a {
        padding: 7px 8px;
        font-size: .86rem;
    }

    .mz-user__menu.is-sheet .mz-user__themes {
        padding-top: 8px;
    }

    .mz-user__menu.is-sheet .mz-user__theme {
        min-height: 30px;
    }

    .mz-user__menu.is-sheet .mz-user__logout {
        margin-top: 8px;
        min-height: 36px;
    }

    /* 弹层自己已经有上内边距，未登录面板不用再加一层 */
    .mz-user__menu.is-sheet .mz-user__panel--guest {
        padding-top: 2px;
    }
}

@keyframes mz-user-sheet {
    from { opacity: 0; transform: translateY(24px); }
}

html.mz-user-open {
    overflow: hidden;
}

/* 身份：头像探出弹层上沿，昵称与账号居中 */
.mz-user__big {
    display: block;
    width: 66px;
    height: 66px;
    margin: -33px auto 7px;
    overflow: hidden;
    border: 3px solid var(--mz-flat);
    border-radius: 50%;
    background: var(--mz-accent-wash);
    box-shadow: 0 0 0 1px var(--mz-line);
}

.mz-user__big-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    will-change: transform;
}

/* 窄屏底部弹窗里大头像回到居中（与桌面一致） */
@media (max-width: 760px) {
    .mz-user__big {
        margin: -33px auto 8px;
    }
}

/* 展开时顶栏那枚小头像先隐去，让「飞下去」的大头像看起来是同一枚 */
.mz-user__avatar {
    transition: opacity .12s linear;
}

.mz-user.is-open .mz-user__avatar {
    opacity: 0;
}

/* 登录后展开时，原来的胶囊框整块让位（头像已经飞进弹层，不留空框） */
.mz-user__btn {
    transition: opacity .14s linear, border-color .18s, color .18s, background .18s;
}

.mz-user.is-open.is-user > .mz-user__btn {
    opacity: 0;
    pointer-events: none;
}

.mz-user__nick {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--mz-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mz-user__sub {
    display: block;
    margin-top: 3px;
    font-family: var(--mz-mono);
    font-size: .66rem;
    line-height: 1.5;
    color: var(--mz-ink-4);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 三项数字：未读 / 登录次数 / 最近登录 */
.mz-user__stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    margin-top: 13px;
    padding: 11px 0;
    border-top: 1px solid var(--mz-line-2);
    border-bottom: 1px solid var(--mz-line-2);
}

.mz-user__stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 2px 0;
    border-radius: 10px;
    color: var(--mz-ink-4);
    text-decoration: none;
}

a.mz-user__stat:hover { background: var(--mz-accent-wash); }

.mz-user__stat b {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--mz-ink);
    font-variant-numeric: tabular-nums;
}

.mz-user__stat span {
    font-family: var(--mz-mono);
    font-size: .62rem;
    letter-spacing: .04em;
    white-space: nowrap;
}

/* 快捷入口：图标 + 名称 + 右箭头 */
.mz-user__links {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 6px 0;
    text-align: left;
}

.mz-user__links a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: 10px;
    font-size: .88rem;
    color: var(--mz-ink-2);
    text-decoration: none;
}

.mz-user__links a > .mz-i {
    width: 16px;
    height: 16px;
    color: var(--mz-ink-4);
}

.mz-user__links a:hover {
    background: var(--mz-accent-wash);
    color: var(--mz-accent);
}

.mz-user__links a:hover > .mz-i {
    color: var(--mz-accent);
}

.mz-user__chev {
    margin-left: auto;
    width: 14px !important;
    height: 14px !important;
    color: var(--mz-ink-4);
    opacity: .7;
}

.mz-user__badge {
    margin-left: auto;
    font-size: .68rem;
    color: var(--mz-btn-ink);
    background: var(--mz-accent);
    border-radius: 999px;
    padding: 1px 7px;
}

.mz-user__links .mz-user__badge + .mz-user__chev {
    margin-left: 6px;
}

/* 外观三档 */
.mz-user__themes {
    display: flex;
    gap: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--mz-line-2);
}

.mz-user__menu .mz-user__theme {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    padding: 0 4px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-3);
    font-family: inherit;
    font-size: .74rem;
    white-space: nowrap;
    cursor: pointer;
}

.mz-user__menu .mz-user__theme:hover {
    border-color: var(--mz-accent);
    color: var(--mz-accent);
}

.mz-user__menu .mz-user__theme.is-on {
    border-color: var(--mz-accent-line);
    background: var(--mz-accent-wash);
    color: var(--mz-accent);
    font-weight: 700;
}

/* 登录 / 退出 */
.mz-user__menu [hidden] {
    display: none !important;
}

.mz-user__menu .mz-user__login,
.mz-user__menu .mz-user__logout {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 38px;
    border-radius: var(--mz-radius-pill);
    font-family: inherit;
    font-size: .86rem;
    cursor: pointer;
}

.mz-user__menu .mz-user__logout {
    margin-top: 10px;
    border: 1px solid var(--mz-line);
    background: transparent;
    color: var(--mz-ink-3);
}

.mz-user__menu .mz-user__logout:hover {
    border-color: var(--mz-danger, #b03a2e);
    color: var(--mz-danger, #b03a2e);
}

/* ---------- 已读协议勾选 + 取消（未登录面板，261101） ---------- */
.mz-user__agree {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 12px;
    font-size: .78rem;
    line-height: 1.55;
    color: var(--mz-ink-3);
    cursor: pointer;
    text-align: left;
}

.mz-user__agree input {
    margin: 2px 0 0;
    flex: 0 0 auto;
    accent-color: var(--mz-accent);
}

.mz-user__agree a {
    color: var(--mz-accent);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.mz-user__menu .mz-user__login[disabled],
.mz-user__menu .mz-user__login.is-disabled {
    opacity: .5;
    cursor: not-allowed;
}

.mz-user__menu .mz-user__cancel {
    margin-top: 8px;
    width: 100%;
    min-height: 36px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill, 999px);
    background: transparent;
    color: var(--mz-ink-3);
    font-family: inherit;
    font-size: .84rem;
    cursor: pointer;
}

.mz-user__menu .mz-user__cancel:hover {
    border-color: var(--mz-ink-3);
    color: var(--mz-ink);
}

/* 【华为账号登录】按钮：按华为规范（文字不可改、居中、全圆角、高 44、字号 16、
   宽 ≥150、内安全边距 ≥16）+ 华为红底 + 白色华为标识（带标志和文本样式） */
.mz-user__menu .mz-user__login {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-width: 150px;
    min-height: 44px;
    margin-top: 12px;
    padding: 0 16px;
    border: 0;
    border-radius: 999px;
    background: #e8232a;
    color: #fff;
    font-family: inherit;
    font-size: 16px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
}

.mz-user__menu .mz-user__login:hover {
    background: #cf1b22;
}

.mz-user__hwlogo {
    display: block;
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
}

/* ---------- 未登录面板头：网站 logo + 站名（华为规范的「应用图标/品牌标志」） ---------- */
.mz-user__guest-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-bottom: 12px;
}

.mz-user__guest-brand img {
    display: block;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    object-fit: contain;
}

.mz-user__guest-brand span {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--mz-ink);
}

/* ---------- 未登录：说明 + 四条能力 + 立即登录 ---------- */
.mz-user__panel--guest {
    padding-top: 16px;
}

.mz-user__promo {
    margin: 0 0 12px;
    font-size: .82rem;
    color: var(--mz-ink-3);
    text-align: left;
}

.mz-user__benefits {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 12px;
    text-align: left;
}

.mz-user__benefit {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: .8rem;
    line-height: 1.4;
    color: var(--mz-ink-2);
}

.mz-user__benefit .mz-i {
    flex: none;
    width: 16px;
    height: 16px;
    color: var(--mz-accent);
}

.mz-user__tip {
    margin: 12px 0 0;
    font-size: .7rem;
    line-height: 1.6;
    color: var(--mz-ink-4);
}

/* 未登录时胶囊里不留占位头像 */
.mz-user:not(.is-user) .mz-user__avatar {
    display: none;
}

.mz-user:not(.is-user) .mz-user__btn {
    padding-inline: 13px;
    gap: 6px;
}

/* ---------- 二十九、面包屑：页头胶囊正下方 ----------
   只读一行小字：五站入口 › 节点 › 当前页；与页头同一根栏宽与边距。 */
.mz-crumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    max-width: var(--mz-page, 1180px);
    margin: 10px auto 0;
    padding: 0 var(--mz-gutter, 24px);
    font-family: var(--mz-mono);
    font-size: .72rem;
    letter-spacing: .04em;
    line-height: 1.6;
    color: var(--mz-ink-4);
}

.mz-crumb a {
    color: var(--mz-ink-3);
    text-decoration: none;
    transition: color .18s;
}

.mz-crumb a:hover { color: var(--mz-accent); }

.mz-crumb .sep { color: var(--mz-line-strong); }

.mz-crumb .here { color: var(--mz-ink-2); }

@media (max-width: 640px) {
    .mz-crumb { margin-top: 8px; font-size: .68rem; }
}

/* ---------- 三十、元素关系收口：遮罩、列表间距、多余框 ---------- */

/* 1) 抽屉与弹窗遮罩：深色下加深，保证底下内容不串字 */
.mz-drawer__mask,
.drawer__scrim,
.mz-drawer-scrim,
.mz-sheet__mask {
    background: rgba(6, 14, 20, .58) !important;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

html[data-theme="dark"] .mz-drawer__mask,
html[data-theme="dark"] .drawer__scrim,
html[data-theme="dark"] .mz-drawer-scrim,
html[data-theme="ink"] .mz-drawer__mask,
html[data-theme="ink"] .drawer__scrim,
html[data-theme="ink"] .mz-drawer-scrim {
    background: rgba(0, 0, 0, .74) !important;
}

/* 2) 推送 / 文章列表：卡片之间只留一致间距，不再相互压住 */
.feed-list,
.mz-feed,
.hf-feed {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.feed-item,
.mz-feed__row,
.feed-card-item {
    margin: 0 !important;
    position: static;
}

.feed-item + .feed-item,
.mz-feed__row + .mz-feed__row,
.feed-card-item + .feed-card-item {
    margin-top: 12px !important;
}

.feed-item .feed-head {
    border-radius: var(--mz-radius-l);
    overflow: hidden;
}

.feed-item .feed-thumb,
.feed-item .feed-card-cover {
    border-radius: var(--mz-radius);
    overflow: hidden;
}

/* 3) 课程页小节导航：一条线分节，不再一项一个框 */
.course-nav a {
    margin: 0 !important;
    border: 0 !important;
    border-bottom: 1px solid var(--mz-line-2) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background-image: none !important;
}

.course-nav a:last-child { border-bottom: 0 !important; }

.course-nav a.is-on {
    background: var(--mz-accent-wash) !important;
    box-shadow: inset 3px 0 0 var(--mz-accent) !important;
}

/* 4) 作答页底部操作条：吸底玻璃条在 17.22 统一给（见 .hw__bar / .ex__foot），
   这里只压掉按钮阴影，避免和吸底那一层打架 */
.hw__bar .btn { box-shadow: none; }

/* ============================================================
   三十一、视觉对齐（261025-06）
   ------------------------------------------------------------
   一把尺子：栏宽 --mz-page、页边 --mz-gutter。
   · 页头胶囊的内边距也取 --mz-gutter，品牌位与最右动作位
     正好落在正文这条竖线上；
   · 主视觉 / 区块只写 padding-block，不许用 padding 简写把手写页边清零；
   · 同列文字共用一个标签列宽（--mz-label-w）；
   · 该居中的（空态、门禁、提示、备案行）显式居中；
   · 图标先盒内居中，再按视觉重心压半像素。
   ============================================================ */

:root {
    /* 「标签 / 时间」列的公共宽度：键值对、日志流、按时间排的列表共用 */
    --mz-label-w: 136px;
}

/* ---------- 1. 同列文字：标签列定宽，内容左起点一致 ---------- */

.mz-kv {
    grid-template-columns: var(--mz-label-w) minmax(0, 1fr);
}

.mz-kv dt {
    padding-top: 1px;          /* 让标签与值的第一行基线看起来齐平 */
    line-height: 1.75;
}

/* ---------- 2. 该居中的居中 ---------- */

.mz-empty,
.mz-state,
.mz-inline-state,
.mz-gate,
.mz-loading,
.mz-skeleton-block {
    text-align: center;
}

.mz-gate {
    margin-inline: auto;
}

.mz-empty > p,
.mz-state__desc,
.mz-gate__desc {
    margin-inline: auto;
}

.mz-empty > img,
.mz-state > img,
.mz-gate img,
.mz-qr,
.qr {
    display: block;
    margin-inline: auto;
}

/* ---------- 3. 图标：盒内居中 + 按重心微调半像素 ---------- */

/* 行内图标与文字中线对齐，基线下方不留 2–3px 空白 */
.mz-i {
    vertical-align: -.125em;
}

/* 月亮本体（缺口在右上）视觉重心偏左下，往右、往上各压半像素 */
.mz-theme-btn svg {
    transform: translate(.5px, -.5px);
}

/* 页头胶囊里的品牌图与左侧页边对齐，不受 logo 自带留白影响 */
.mz-brand > img {
    margin-inline-start: -1px;
}

/* ---------- 4. 窄屏：页脚品牌与备案行居中（链接列仍左对齐） ---------- */

@media (max-width: 720px) {
    .mz-footer-bottom,
    .foot__in,
    .inv-foot {
        justify-content: center;
        text-align: center;
    }

    .mz-footer-brand {
        margin-inline: auto;
        text-align: center;
    }

    .mz-footer-brand b,
    .mz-footer-brand p {
        margin-inline: auto;
    }
}

/* ============================================================
   三十二、华为账号登录弹窗（261025-10）
   ------------------------------------------------------------
   按《华为账号开放登录》里「样式一 · 带文本的按钮」实现：
     · 「华为账号登录」六个字不可改、按钮内居中
     · 华为红底白字，是第一个也是唯一的主登录选项
     · 高 44（规范 28–60）、字 16（高度 36%）、全圆角、宽 ≥150、内边距 16
     · 必须能拒绝登录：右上关闭 + 取消按钮
     · 必须能看《华为账号用户认证协议》原文
   桌面居中弹窗，≤760 收成底部 sheet。
   ============================================================ */

html.mz-login-open {
    overflow: hidden;
}

.mz-login {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: grid;
    place-items: center;
    padding: 20px;
}

.mz-login[hidden] { display: none; }

.mz-login__mask {
    position: absolute;
    inset: 0;
    background: rgba(6, 14, 20, .55);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}

.mz-login__panel {
    position: relative;
    width: min(392px, 100%);
    padding: 30px 28px 20px;
    border: 1px solid var(--mz-line);
    border-radius: 22px;
    /* 261101：登录弹层与用户菜单同档浮层 —— 背后是正文，必须压得住 */
    background: var(--mz-surface-float);
    -webkit-backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    box-shadow: var(--mz-shadow-lift, var(--mz-shadow));
    text-align: center;
    animation: mz-login-in .22s cubic-bezier(.2, .8, .2, 1);
}

@keyframes mz-login-in {
    from { opacity: 0; transform: translateY(10px) scale(.99); }
}

.mz-login__x {
    position: absolute;
    top: 10px;
    right: 10px;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--mz-ink-4);
    cursor: pointer;
}

.mz-login__x:hover {
    background: var(--mz-surface-comp);
    color: var(--mz-ink);
}

.mz-login__brand {
    display: inline-flex;
    justify-content: center;
}

.mz-login__brand img {
    display: block;
    height: 44px;
    width: auto;
    max-width: 168px;
    object-fit: contain;
    border-radius: 10px;
}

.mz-login__title {
    margin: 14px 0 0;
    font-size: 1.24rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--mz-ink);
}

.mz-login__sub {
    margin: 6px 0 0;
    font-size: .82rem;
    line-height: 1.6;
    color: var(--mz-ink-4);
}

/* 规范「样式一」：华为红底、白字、居中、全圆角 */
.mz-login__hw {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-width: 150px;
    height: 44px;
    margin-top: 22px;
    padding: 0 16px;
    border: 0;
    border-radius: 999px;
    background: #e40000;
    color: #fff;
    font-family: inherit;
    font-size: 16px;
    font-weight: 500;
    letter-spacing: .02em;
    white-space: nowrap;
    cursor: pointer;
    transition: background .18s;
}

.mz-login__hw:hover { background: #c40000; }

.mz-login__hw:focus-visible {
    outline: 2px solid var(--mz-ink);
    outline-offset: 3px;
}

.mz-login__cancel {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 40px;
    margin-top: 10px;
    padding: 0 16px;
    border: 1px solid var(--mz-line);
    border-radius: 999px;
    background: transparent;
    color: var(--mz-ink-3);
    font-family: inherit;
    font-size: .84rem;
    cursor: pointer;
}

.mz-login__cancel:hover {
    border-color: var(--mz-line-strong);
    color: var(--mz-ink);
}

.mz-login__terms {
    margin: 16px 0 0;
    font-size: .72rem;
    line-height: 1.75;
    color: var(--mz-ink-4);
}

.mz-login__terms a {
    color: var(--mz-accent);
    text-decoration: none;
}

.mz-login__terms a:hover { text-decoration: underline; }

/* 窄屏：点击后从底部弹出，卡片样式与桌面一致（四角全圆、内边距与按钮尺寸不变），
   只是位置落到屏幕底部、四周留 16 的安全间距 */
@media (max-width: 760px) {
    .mz-login {
        place-items: end center;
        padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    }

    .mz-login__panel {
        width: 100%;
        max-width: 392px;
        border-radius: 22px;
        animation: mz-login-up .24s cubic-bezier(.2, .8, .2, 1);
    }
}

@keyframes mz-login-up {
    from { opacity: 0; transform: translateY(20px); }
}

/* ============================================================
   三十三、组件规格统一（261025-13）
   ------------------------------------------------------------
   同一类组件全站只留一套数值，页面上不再各写一份：
     · 圆角：胶囊 999 / 卡片与面板 18 / 输入框与内嵌块 12 / 缩略图 10
     · 按钮：常规 36 高（窄屏 44）、小号 30（窄屏 36）、大号 44
     · 图标钮：36 方（窄屏 40）、图标 17
     · 输入：40 高（窄屏 44）、圆角 12、字号 16
     · 列表行：可点的行一律 44 高，行内小按钮 32
   这些值来自主题令牌，各站样式表里的历史写法由这一段统一覆盖。
   ============================================================ */

/* ---------- 一、卡片 / 面板 / 弹窗：圆角 18 ---------- */

.mz-card,
.mz-panel,
.card,
.panel,
.tz-card,
.tz-panel,
.tz-log,
.tz-sect,
.quick,
.site,
.entry-card,
.course-panel,
.feed-item,
.feed-card-item,
.hf-card,
.mz-social,
.mz-side__block,
.mz-doc,
.mz-doc__toc,
.cc-card,
.cc-panel {
    border-radius: var(--mz-radius-l, 18px) !important;
}

/* 弹窗与浮层：同一档 18 */
.mz-dialog__panel,
.mz-clip-pop,
.mz-user__menu,
.mz-login__panel,
.dialog,
.mzui-box {
    border-radius: var(--mz-radius-l, 18px) !important;
}

/* 内嵌小块、缩略图、输入类：12 */
.mz-detail,
.hw__passage,
.ex__passage,
.mz-qr,
.mz-doc__item,
.mz-field,
.cc-field,
.file-thumb,
.file-ext,
.mz-timeline__item {
    border-radius: var(--mz-radius, 12px);
}

/* 胶囊：标签、药丸、开关、头像 */
.mz-chip,
.badge,
.mz-badge,
.chip,
.tag,
.seg__a,
.site__go,
.mz-btn,
.btn,
.mz-avatar,
.mz-user,
.uchip,
.mz-drawer__link,
.topicChip,
.mz-theme-opt {
    border-radius: var(--mz-radius-pill, 999px);
}

/* ---------- 二、按钮高度 ---------- */

.mz-btn,
.btn {
    min-height: 36px;
}

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

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

/* 行内小按钮：不超过 32，也不再各自 28 / 34 / 38 混用 */
.btn-sm,
.mz-btn--sm,
.mz-user__theme,
.mz-crumb__back,
.tz-mono .btn {
    line-height: 1.2;
}

@media (max-width: 760px) {
    .mz-btn,
    .btn {
        min-height: 44px;
    }

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

/* ---------- 三、图标按钮与图标尺寸 ---------- */

.mz-theme-btn,
.mz-iconbtn,
.ibtn,
.drawer-btn,
.cc-theme-btn,
.cc-burger {
    display: inline-grid;
    place-items: center;
}

/* 汉堡是三条 span 竖排，得留 4px 缝，不能跟着其它按钮 gap: 0；
   双类选择器保证压得住窄屏那份 gap: 0 */
.mz-burger {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
}

.mz-burger.mz-burger,
.drawer-btn.drawer-btn {
    gap: 4px;
}

.mz-theme-btn,
.mz-iconbtn,
.mz-burger,
.ibtn,
.drawer-btn,
.cc-theme-btn,
.cc-burger {
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
    padding: 0;
    border-radius: 50%;
}

@media (max-width: 760px) {
    .mz-theme-btn,
    .mz-iconbtn,
    .mz-burger,
    .ibtn,
    .drawer-btn {
        width: 40px;
        height: 40px;
        min-width: 40px;
        min-height: 40px;
    }
}

.mz-btn .mz-i,
.btn .mz-i,
.mz-theme-btn .mz-i,
.mz-iconbtn .mz-i,
.mz-burger .mz-i,
.ibtn .mz-i,
.drawer-btn .mz-i {
    width: 17px;
    height: 17px;
    flex: none;
}

/* ---------- 四、输入类 ---------- */

.mz-input,
.mz-select,
.mz-textarea,
.field input,
.field select,
.field textarea,
input.inp,
.inp,
.cc-input,
.cc-select,
.cc-textarea {
    min-height: 40px;
    padding: 8px 13px;
    border-radius: var(--mz-radius, 12px);
    font-size: .9rem;
}

textarea.mz-textarea,
textarea.inp,
.field textarea,
.cc-textarea {
    min-height: 96px;
    line-height: 1.85;
}

@media (max-width: 760px) {
    .mz-input,
    .mz-select,
    .field input,
    .field select,
    input.inp,
    .inp,
    .cc-input,
    .cc-select {
        min-height: 44px;
    }

    .mz-textarea,
    .field textarea,
    textarea.inp,
    .cc-textarea {
        font-size: 16px;
    }
}

/* ---------- 五、可点的列表行：一律 44 高 ---------- */

.mz-drawer__link,
.drawer__a,
.mz-drawer-group a,
.mz-footer-col a,
.tz-ch,
.tz-log > a,
.tz-log__row,
.feed-item,
.mz-feed__row,
.mz-user__links a,
.course-nav a,
.mz-side__list a,
.mz-side__list button,
.mz-user__stat {
    min-height: 44px;
}

/* 行内的开关、复选、文本框保持自身高度，不被拉高 */
.mz-user__themes,
.mz-user__stats,
.mz-user__links {
    align-items: stretch;
}

/* ============================================================
   十七、二级页骨架（全站唯一一套）
   ------------------------------------------------------------
   四段式：面板页头（眉标 + 标题 + 一句说明）→ 分节导航（横向胶囊）
          → 内容区 → 页脚。
   这一节是「第 1 步 · 标准与样板」的落地件：原来三套写法
   （教研 / 花粉的 .page__head、总站的 .mz-section + .mz-kicker、
   管理的 .cc-toolbar）从今往后并成这一套，新页面只用这里的类名。
   可运行的规范样本：/limit/ref/sample-page.html

   规则（来自规格，改这一节前必读）
   · 页头一律四行以内：眉标、标题、一句说明、（可选）右侧操作；
   · 分节导航只有胶囊一种形态，<button class="mz-chip" aria-pressed>，
     选中加 is-active，计数徽章用 .mz-chip__n，触控高 ≥36，窄屏横滑不换行；
   · 内容区栅格列一律 minmax(0,1fr)，禁止 max-width / width:auto 撑宽；
   · 参数尺寸全部取 --mz-* 令牌，不在这里写死颜色。
   ============================================================ */

/* ---------- 17.1 面板页头 ---------- */
.mz-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px 24px;
    flex-wrap: wrap;
    padding: 0 0 16px;
    margin: 0 0 20px;
    border-bottom: 1px solid var(--mz-line);
}

.mz-head__main { min-width: 0; flex: 1 1 auto; }

.mz-head__kicker {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--mz-mono);
    font-size: .68rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.mz-head__kicker::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--mz-accent);
    flex: 0 0 auto;
}

.mz-head__title {
    margin: 8px 0 0;
    font-size: clamp(1.5rem, 2.6vw, 2rem);
    line-height: 1.24;
    letter-spacing: -.012em;
    font-weight: 800;
    color: var(--mz-ink);
}

.mz-head__title em { font-style: normal; color: var(--mz-accent); }

.mz-head__desc {
    margin: 8px 0 0;
    max-width: 78ch;
    font-size: .94rem;
    line-height: 1.78;
    color: var(--mz-ink-3);
}

.mz-head__acts {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    flex: 0 0 auto;
}

/* ---------- 17.2 分节导航：横向胶囊 ---------- */
.mz-chips {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding: 2px 1px 10px;
    margin: 0 0 20px;
    scrollbar-width: thin;
}

.mz-chips::-webkit-scrollbar { height: 6px; }
.mz-chips::-webkit-scrollbar-thumb { background: var(--mz-line-strong); border-radius: 3px; }

button.mz-chip,
.mz-chips .mz-chip {
    flex: 0 0 auto;
    min-height: 36px;
    padding: 7px 14px;
    font-family: inherit;
    font-size: .86rem;
    line-height: 1.3;
    color: var(--mz-ink-2);
    background: var(--mz-surface-comp);
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-pill);
    appearance: none;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color .16s ease, color .16s ease, background .16s ease;
}

button.mz-chip:hover,
.mz-chips .mz-chip:hover { border-color: var(--mz-line-strong); color: var(--mz-ink); }

/* 胶囊也可能是链接（门户的域面板入口、社交平台的筛选）：一律不带下划线 */
a.mz-chip { text-decoration: none; }

button.mz-chip:focus-visible {
    outline: 2px solid var(--mz-accent);
    outline-offset: 2px;
}

.mz-chip__n {
    font-family: var(--mz-mono);
    font-size: .72rem;
    color: var(--mz-ink-4);
}

.mz-chips .mz-chip.is-active .mz-chip__n,
button.mz-chip.is-active .mz-chip__n { color: var(--mz-accent); }

/* 二级胶囊（个人中心的「协议」「英语教研」）：比一级小一档、缩进一档，
   用弱一档的底色把层级拉开——同一条横向胶囊，两级不要长得一样。 */
.mz-chips--sub {
    margin: -8px 0 18px;
    padding-left: 10px;
    position: relative;
}

.mz-chips--sub::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    bottom: 12px;
    width: 2px;
    border-radius: 2px;
    background: var(--mz-line);
}

.mz-chips--sub .mz-chip {
    min-height: 30px;
    padding: 4px 12px;
    font-size: .78rem;
    background: transparent;
}

.mz-chips--sub .mz-chip.is-active {
    background: var(--mz-surface-comp);
    border-color: var(--mz-accent);
}

/* ---------- 17.3 内容区栅格 ---------- */
.mz-grid {
    display: grid;
    gap: 16px;
    grid-template-columns: minmax(0, 1fr);
}

.mz-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mz-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mz-grid--split { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }

@media (max-width: 900px) {
    .mz-grid--2,
    .mz-grid--3,
    .mz-grid--split { grid-template-columns: minmax(0, 1fr); }
}

/* 二级页正文区：与页脚之间留出统一间距（只改下边距，左右交给 .wrap，别再动 padding 简写） */
.mz-body { padding-bottom: 72px; }

/* 二级页里的空态：一句说明居中，不铺底色 */
.mz-empty {
    display: grid;
    place-items: center;
    gap: 8px;
    padding: 40px 20px;
    border: 1px dashed var(--mz-line);
    border-radius: var(--mz-radius);
    color: var(--mz-ink-4);
    font-size: .9rem;
    text-align: center;
}

/* ---------- 17.4 页脚声明：三列 + 两行底部 ---------- */
/* .mz-footer 的骨架在第九节；这里只补二级页需要的底部对齐 */
.mz-footer { margin-top: 0; }
.mz-footer-grid { align-items: start; }

/* ---------- 17.5 三种卡片（组件层，任何站点不再各写一份） ---------- */
/* ① 交互卡与② 基础卡共用 .quick 的外观；
      可点性必须由修饰类 .quick--link 显式表达（照「卡片」规范），
      不靠「里面有个箭头」或「元素恰好是 <a>」这种隐式约定。
      没有 .quick--link 的 .quick 就是基础卡：不抬升、无指针、无箭头位移。 */
.quick {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 20px 22px;
    color: inherit;
    text-decoration: none;
    transition: border-color .22s, box-shadow .22s, transform .22s;
}

.quick--link { cursor: pointer; }

.quick--link:hover,
.quick--link:focus-visible {
    border-color: var(--mz-accent);
    box-shadow: var(--mz-shadow-lift);
    transform: translateY(-2px);
}

.quick__kicker {
    font-family: var(--mz-mono);
    font-size: .62rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.quick__title {
    font-size: 1.04rem;
    font-weight: 700;
    letter-spacing: .01em;
}

.quick__desc {
    margin: 0;
    font-size: .9rem;
    line-height: 1.72;
    color: var(--mz-ink-2);
}

.quick__go {
    margin-top: auto;
    padding-top: 8px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .84rem;
    font-weight: 700;
    color: var(--mz-accent);
}

.quick__go span { transition: transform .22s; }
.quick--link:hover .quick__go span { transform: translateX(4px); }

/* ③ 单一文字卡：.mz-card 的底色与圆角来自第五节，这里只补内部排版 */
.mz-card { padding: 20px 22px; }

.mz-card__kicker {
    margin: 0 0 6px;
    font-family: var(--mz-mono);
    font-size: .62rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

.mz-card__title {
    margin: 0;
    font-size: 1.04rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--mz-ink);
}

.mz-card__body {
    margin: 8px 0 0;
    font-size: .9rem;
    line-height: 1.78;
    color: var(--mz-ink-2);
}

.mz-card--wash { background: var(--mz-surface-sect); }

.mz-card--notch {
    border-top-right-radius: 4px;
}

/* 顶栏账号区：未登录是按钮，已登录是头像胶囊（+ 管理员多一个「管理」入口） */
.mz-user-slot {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

.mz-user-slot .mz-user {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--mz-line);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    font-size: .82rem;
    font-weight: 700;
    text-decoration: none;
    overflow: hidden;
}

.mz-user-slot .mz-user img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.mz-user-slot .mz-user:hover { border-color: var(--mz-accent); color: var(--mz-accent); }

/* ---------- 17.6 移动端菜单（公共外壳自带，不依赖各站 core.js） ---------- */
.mz-sheet {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 1210;
    width: min(320px, 86vw);
    height: 100%;
    padding: 16px 16px 28px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* 261101：移动菜单是「浮层」—— 与下拉同一档，压住底下正文 */
    background: var(--mz-surface-float);
    -webkit-backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    border-left: 1px solid var(--mz-line);
    box-shadow: -20px 0 50px -30px rgba(4, 12, 18, .55);
    transform: translateX(102%);
    transition: transform .26s cubic-bezier(.2, .7, .2, 1);
    overflow-y: auto;
}

.mz-sheet[data-open="true"] { transform: none; }

.mz-sheet__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--mz-line);
}

.mz-sheet__head b { font-size: 1rem; }

.mz-sheet__close {
    appearance: none;
    width: 32px;
    height: 32px;
    border: 1px solid var(--mz-line);
    border-radius: 50%;
    background: transparent;
    color: var(--mz-ink-2);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.mz-sheet__nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.mz-sheet__nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 12px;
    border-radius: var(--mz-radius);
    color: var(--mz-ink-2);
    text-decoration: none;
    font-size: .95rem;
}

.mz-sheet__nav a:hover {
    background: var(--mz-surface-comp);
    color: var(--mz-ink);
}

/* 菜单分组：账号等简单分组（第 82 轮） */
.mz-sheet__group + .mz-sheet__group {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--mz-line-2);
}

.mz-sheet__group h3 {
    margin: 0 0 4px;
    padding: 0 12px;
    font-family: var(--mz-mono);
    font-size: .66rem;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mz-ink-4);
}

/* 菜单：一级 = 四个节点（点整行展开二级），二级 = 该节点的页面（第 86 轮） */
.mz-sheet__stack {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.mz-sheet__site-btn {
    appearance: none;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 46px;
    padding: 0 12px;
    border: 0;
    border-radius: var(--mz-radius);
    background: transparent;
    color: var(--mz-ink);
    font-family: inherit;
    font-size: .98rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.mz-sheet__site-btn:hover {
    background: var(--mz-surface-comp);
}

.mz-sheet__site.is-open > .mz-sheet__site-btn {
    color: var(--mz-accent);
    background: var(--mz-accent-wash);
}

.mz-sheet__site-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mz-sheet__site-btn .mz-i {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    opacity: .7;
    transition: transform .18s;
}

.mz-sheet__site.is-open > .mz-sheet__site-btn .mz-i {
    transform: rotate(180deg);
}

.mz-sheet__sub {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 2px 0 6px 10px;
}

.mz-sheet__sub a {
    display: flex;
    align-items: center;
    min-height: 40px;
    padding: 0 12px;
    border-radius: var(--mz-radius);
    color: var(--mz-ink-2);
    font-size: .9rem;
    text-decoration: none;
}

.mz-sheet__sub a:hover {
    background: var(--mz-surface-comp);
    color: var(--mz-ink);
}

.mz-sheet__sub a[aria-current="page"] {
    color: var(--mz-accent);
    font-weight: 700;
    background: var(--mz-accent-wash);
}

.mz-sheet__sub a span {
    margin-left: auto;
    font-size: .72rem;
    color: var(--mz-ink-4);
}

.mz-scrim {
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: rgba(6, 14, 20, .42);
    opacity: 0;
    visibility: hidden;
    transition: opacity .22s ease, visibility .22s ease;
}

.mz-scrim[data-open="true"] {
    opacity: 1;
    visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
    .mz-sheet, .mz-scrim { transition: none; }
}

/* ---------- 17.7 全局兜底 ---------- */
/* 组件层给容器写了 display（grid / flex），会盖掉浏览器默认的 [hidden]，
   导致「用 hidden 切换面板」失效。这里统一兜住，切换面板一律靠 hidden。 */
[hidden] { display: none !important; }

/* ---------- 17.8 卡片里的元信息行与未读态（通知、列表类页面共用） ---------- */
.quick__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: auto;
    padding-top: 10px;
}

.quick__meta .mz-chip {
    font-size: .74rem;
    line-height: 1.5;
    padding: 2px 8px;
}

.quick__ts {
    margin-left: auto;
    font-family: var(--mz-mono);
    font-size: .74rem;
    letter-spacing: .04em;
    color: var(--mz-ink-4);
}

/* 未读：左侧一道强调线，不改底色（一屏只允许一种底色层级） */
.quick.is-unread {
    border-left: 3px solid var(--mz-accent);
    padding-left: 19px;
}

/* 可聚焦的卡片（打开弹窗的列表条目） */
article.quick[tabindex]:focus-visible {
    outline: 2px solid var(--mz-accent);
    outline-offset: 2px;
}

/* 空容器不留白：未登录时条数胶囊与发件箱导航都没有内容 */
.mz-head__acts .mz-chip:empty,
.mz-chips:empty { display: none; }

/* ---------- 17.9 轻提示与「灰置入口」 ---------- */
/* 一句轻提示：底部居中、自动消失。深色下自动反相，不另写一套。 */
.mz-toast {
    position: fixed;
    left: 50%;
    bottom: 28px;
    z-index: 2147483000;
    max-width: min(560px, calc(100vw - 32px));
    padding: 12px 18px;
    border-radius: var(--mz-radius-pill);
    background: var(--mz-ink);
    color: var(--mz-bg);
    font-size: .9rem;
    line-height: 1.55;
    text-align: center;
    box-shadow: var(--mz-shadow-lift);
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, 12px);
    transition: opacity .2s ease, transform .2s ease, visibility .2s ease;
}

.mz-toast[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

/* 无权限的入口：灰置、不可点，点击由页面脚本给提示 */
[data-admin-only].is-locked {
    opacity: .55;
    cursor: not-allowed;
}

.quick.is-locked:hover {
    transform: none;
    border-color: var(--mz-line);
    box-shadow: none;
}

.tz-ch.is-locked .tz-ch__state { color: var(--mz-ink-4); }

/* ---------- 新用户「去填表领标识」一次性提示（common/js/mz-tag-tip.js） ----------
   右下角一张卡：不挡正文，可关掉；关掉/点进去都会在服务端留标记，不再出现。
   它压在正文上、里面是要读的话，所以取浮层档（--mz-surface-float），
   不跟着卡片档走 —— 否则底下的正文会从卡里透出来。 */
.mz-tagtip {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 900;
    width: min(360px, calc(100vw - 32px));
    padding: 16px 18px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-surface-float);
    box-shadow: var(--mz-shadow-lift);
    -webkit-backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    backdrop-filter: blur(var(--mz-blur-float)) saturate(var(--mz-blur-float-sat));
    color: var(--mz-ink);
    animation: mz-tagtip-in .28s ease both;
}

.mz-tagtip__head {
    font-size: .96rem;
    font-weight: 700;
    letter-spacing: -.01em;
}

.mz-tagtip__body {
    margin: 8px 0 0;
    font-size: .84rem;
    line-height: 1.72;
    color: var(--mz-ink-3);
}

.mz-tagtip__acts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

@keyframes mz-tagtip-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

@media (max-width: 560px) {
    .mz-tagtip { right: 12px; left: 12px; bottom: 12px; width: auto; }
}

@media (prefers-reduced-motion: reduce) {
    .mz-tagtip { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
    .mz-toast { transition: none; }
}

/* ---------- 17.10 表单字段（表单中心 / 同城小信箱共用） ----------
   字段一律「标签在上、控件在下」单列排布；进两列栅格时由 .mz-grid 管列宽。
   这类样式原先散在各站 pages.css / apps.css 里，才出现标签与输入框挤在一行、
   文本域飘到右边的情况。 */
.mz-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    margin: 0 0 14px;
}

.mz-field__label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .86rem;
    font-weight: 650;
    color: var(--mz-ink-2);
}

.mz-field__req { color: var(--mz-accent); }

.mz-field__hint {
    font-size: .74rem;
    font-weight: 400;
    color: var(--mz-ink-4);
}

.mz-field .mz-input,
.mz-field .mz-select,
.mz-field .mz-textarea { width: 100%; }

.mz-textarea {
    resize: vertical;
    min-height: 96px;
    line-height: 1.7;
}

.mz-field.is-invalid .mz-input,
.mz-field.is-invalid .mz-select,
.mz-field.is-invalid .mz-textarea { border-color: var(--mz-accent); }

.mz-field__err {
    min-height: 1em;
    font-size: .78rem;
    color: var(--mz-accent);
}

.mz-counter {
    align-self: flex-end;
    font-family: var(--mz-mono);
    font-size: .72rem;
    color: var(--mz-ink-4);
}

.mz-counter.is-over { color: var(--mz-accent); }

.mz-choice {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
}

.mz-choice label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .9rem;
}

/* 两列栅格里的字段：纵向间距交给栅格，不再各自撑开 */
.mz-grid .mz-field { margin-bottom: 0; }

/* ---------- 17.11 协议正文（个人中心内嵌阅读） ----------
   正文来自 /common/data/agreements/ 的种子片段，类名沿用旧稿的 .pr-*，
   这里只把排版收进公共层，不再依赖各站旧样式表。 */
.mz-agreement {
    line-height: 1.85;
    color: var(--mz-ink-2);
}

.mz-agreement h2,
.mz-agreement h3 {
    margin: 26px 0 10px;
    font-size: 1.06rem;
    font-weight: 700;
    color: var(--mz-ink);
}

.mz-agreement h2:first-child,
.mz-agreement h3:first-child { margin-top: 0; }

.mz-agreement p { margin: 0 0 14px; }

.mz-agreement ul,
.mz-agreement ol {
    margin: 0 0 16px;
    padding-left: 1.4em;
}

.mz-agreement li { margin: 0 0 6px; }

.mz-agreement a {
    color: var(--mz-accent);
    text-decoration: none;
    border-bottom: 1px solid var(--mz-line);
}

.mz-agreement a:hover { border-color: var(--mz-accent); }

.mz-agreement strong { color: var(--mz-ink); }

.mz-agreement hr {
    margin: 22px 0;
    border: 0;
    border-top: 1px solid var(--mz-line);
}

/* 旧稿里的「要点 / 相关文件」小方块 */
.mz-agreement .pr-summary,
.mz-agreement .pr-cross {
    margin: 0 0 18px;
    padding: 14px 16px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-sect);
    font-size: .9rem;
}

.mz-agreement .pr-cross-label {
    margin-right: 6px;
    color: var(--mz-ink-4);
    font-size: .82rem;
}

.mz-agreement .pr-cross a { margin-right: 10px; }

.mz-agreement .pr-toc {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin: 0 0 20px;
    padding: 12px 16px;
    border: 1px dashed var(--mz-line);
    border-radius: var(--mz-radius);
    font-size: .86rem;
}

/* ---------- 17.12 列表状态行（各站 feed 共用的那一句） ---------- */
/* 原先这条样式在 huafans/pages/push.html、engstudy/pages/push.html 的内联 <style> 里各写一份 */
.feed-status {
    margin: 0 0 14px;
    font-size: .86rem;
    line-height: 1.6;
    color: var(--mz-ink-3);
}

.feed-status.is-error { color: var(--mz-warn); }

/* ---------- 17.13 排版小工具（替代内联 style，页面里只准用这几个） ---------- */
.mz-ml-auto { margin-left: auto; }
.mz-center { justify-content: center; }
.mz-mt-lg { margin-top: 22px; }
.mz-mt-md { margin-top: 14px; }
.mz-mt-sm { margin-top: 8px; }
.mz-gap-lg { gap: 20px; }

/* ---------- 17.14 表单容器 / 提示条 / 字段脚注（小信箱等表单页共用） ---------- */
.mz-form {
    display: grid;
    gap: 18px;
}

.mz-form__acts {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.mz-field__foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.mz-note {
    margin: 0 0 18px;
    padding: 12px 16px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-sect);
    color: var(--mz-ink-2);
    font-size: .9rem;
    line-height: 1.7;
}

/* 提交成功后的小回执 */
.mz-result {
    margin-top: 20px;
    padding: 20px 22px;
    border: 1px solid var(--mz-line);
    border-left: 3px solid var(--mz-accent);
    border-radius: var(--mz-radius-l);
    background: var(--mz-glass);
}

.mz-result h3 {
    margin: 0 0 8px;
    font-size: 1.02rem;
    color: var(--mz-ink);
}

.mz-result p {
    margin: 0;
    font-size: .92rem;
    line-height: 1.8;
    color: var(--mz-ink-2);
}

.mz-result .mz-result__id {
    margin-top: 8px;
    font-family: var(--mz-mono);
    font-size: .8rem;
    color: var(--mz-ink-4);
}

/* 兼容两种标记写法：JS 里既用 class 也用过 data-* 属性 */
.mz-counter[data-over="true"],
.mz-counter.is-over { color: var(--mz-accent); }

.mz-field[data-invalid="true"] .mz-input,
.mz-field[data-invalid="true"] .mz-select,
.mz-field[data-invalid="true"] .mz-textarea,
.mz-field.is-invalid .mz-input,
.mz-field.is-invalid .mz-select,
.mz-field.is-invalid .mz-textarea { border-color: var(--mz-accent); }

.mz-field[data-invalid="true"] .mz-field__err,
.mz-field.is-invalid .mz-field__err { display: block; }

/* ---------- 17.15 阅读排版（讲义正文 / 文章正文 / 讨论正文共用） ----------
   自 engstudy/pages/lesson.html 的内联 <style> 搬来并并入公共层：
   .lesson-body 是课节正文，.mz-prose 是文章与协议正文，两者同一套排版。 */
.lesson-body,
.mz-prose.lesson-body {
    font-size: .96rem;
    line-height: 1.95;
    color: var(--mz-ink);
}

.lesson-body h1,
.lesson-body h2,
.lesson-body h3,
.lesson-body h4 {
    margin: 1.6em 0 .6em;
    line-height: 1.45;
    color: var(--mz-ink);
}

.lesson-body h1 { font-size: 1.4rem; }
.lesson-body h2 { font-size: 1.2rem; }
.lesson-body h3 { font-size: 1.04rem; }

.lesson-body p { margin: .8em 0; }

.lesson-body ul,
.lesson-body ol { margin: .8em 0 .8em 1.4em; }

.lesson-body li { margin: .35em 0; }

.lesson-body blockquote {
    margin: 1.2em 0;
    padding: 12px 16px;
    border-left: 3px solid var(--mz-accent-line);
    border-radius: 0 var(--mz-radius) var(--mz-radius) 0;
    background: var(--mz-accent-wash);
    color: var(--mz-ink-2);
}

.lesson-body table {
    width: 100%;
    margin: 1.2em 0;
    border-collapse: collapse;
    font-size: .88rem;
}

.lesson-body th,
.lesson-body td {
    padding: 8px 10px;
    border: 1px solid var(--mz-line);
    text-align: left;
    vertical-align: top;
}

.lesson-body th {
    background: var(--mz-surface-comp);
    font-weight: 700;
}

.lesson-body img {
    max-width: 100%;
    height: auto;
    border-radius: var(--mz-radius);
}

.lesson-body code,
.lesson-body pre {
    padding: 2px 6px;
    border-radius: 6px;
    background: var(--mz-surface-comp);
}

.lesson-body pre {
    padding: 12px 14px;
    overflow: auto;
}

/* 窄屏表格允许横滚，不撑破 1280 容器 */
@media (max-width: 760px) {
    .lesson-body table {
        display: block;
        overflow-x: auto;
        white-space: nowrap;
    }
}

/* ---------- 17.16 无外壳页容器（data-mz-chrome="none" 专用） ----------
   作业详情、考试详情这两页不注入顶栏 / 面包屑 / 页脚，
   所以页边、上间距与背景必须自己保证（规格原话：
   「原页头去掉后不能露出空白」）。 */
.mz-bare {
    box-sizing: border-box;
    min-height: 100vh;
    padding: clamp(22px, 3.6vw, 42px) var(--mz-gutter) 64px;
}

.mz-bare > .mz-head:first-child { margin-top: 0; }

/* 带吸底条的作答页（考试 / 作业）：容器底部不留白，
   否则滚到卷尾时吸底条会「浮」在距页底 64px 的位置 */
.mz-bare:has(.ex__foot),
.mz-bare:has(.hw__bar) {
    padding-bottom: 0;
}

/* ---------- 17.17 居中单卡页（登录落点 / 提示页） ---------- */
.mz-center-page {
    display: grid;
    place-items: center;
    min-height: 100vh;
    padding: var(--mz-gutter);
    box-sizing: border-box;
}

.mz-card--narrow {
    width: 100%;
    max-width: 480px;
    text-align: center;
    padding: 36px 28px;
}

.mz-card--narrow .mz-brand-mark {
    width: 44px;
    height: 44px;
    margin: 0 auto 12px;
    display: block;
    color: var(--mz-ink-2);
}

.mz-card--narrow .mz-card__title { font-size: 1.24rem; }
.mz-card--narrow .mz-card__body { color: var(--mz-ink-3); }

/* ---------- 17.18 页头与吸顶导航的安全距 ----------
   各站 .main / .wrap 没有上内边距时，页头的眉标会被吸顶导航的渐变层压住
   （实测 tool-countdown / tool-picker 都出现眉标发灰被切）。统一给首屏页头
   留 14px 上边距，避免逐页加工具类。 */
/* 首屏页头：留出安全距，并抬到吸顶渐变的上一层（否则眉标会被压得发灰） */
.main > .mz-head:first-child,
.wrap > .mz-head:first-child {
    margin-top: 18px;
    position: relative;
    z-index: 2;
}

/* ---------- 17.19 胶囊的两种变体：计数池 / 已抽划掉 ----------
   随机选择的「选择库」与「条目」原来是 .pk__pool / .pk__item 两条私有规则，
   现改为公共胶囊的两个修饰类（标记由 tool_picker.js 生成）。 */
.mz-chip--pool {
    gap: 6px;
    max-width: 100%;
}

.mz-chip--pool b {
    font-family: var(--mz-mono);
    font-size: .72rem;
    font-weight: 600;
    color: var(--mz-ink-4);
}

.mz-chip--pool.is-active b { color: var(--mz-accent); }

/* 已抽中：划掉 + 虚线边，不换底色 */
.mz-chip.is-struck {
    text-decoration: line-through;
    color: var(--mz-ink-4);
    border-style: dashed;
}

/* ---------- 17.20 带封面的交互卡（课程卡等） ----------
   课程卡原来是 .course-card__cover / __name / __meta / __desc 一套私有类，
   现并入 .quick：加 .quick--media 即「上图下文」，封面缺省时显示首字。 */
.quick--media { padding: 0; overflow: hidden; }

.quick__media {
    display: block;
    aspect-ratio: 240 / 130;
    overflow: hidden;
    background: var(--mz-accent-wash);
}

.quick__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.quick__media--none {
    display: grid;
    place-items: center;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: .1em;
    color: var(--mz-accent);
}

.quick__body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px 16px 16px;
}

/* ---------- 17.21 胶囊选中态：实底强调（原来只有淡底 + 描边，弱到看不见） ---------- */
.mz-chip.is-active,
button.mz-chip.is-active,
.mz-chips .mz-chip.is-active {
    background: var(--mz-accent);
    border-color: var(--mz-accent);
    color: #fff;
    font-weight: 650;
}

.mz-chip.is-active .mz-chip__n,
button.mz-chip.is-active .mz-chip__n {
    color: rgba(255, 255, 255, .86);
}

.mz-chip.is-active:hover {
    background: var(--mz-accent-deep, var(--mz-accent));
    border-color: var(--mz-accent-deep, var(--mz-accent));
    color: #fff;
}

/* ---------- 17.22 作业答题控件（.hw__*）—— 自 engstudy/classroom.css 上收公共层 ----------
   九种题型（单选/多选/判断/填空/完型/选词/连线/排序/改错）由 answer_kit.js 生成，
   类名保持不变，只把规则从站级搬到公共层，作业与考试共用同一份。 */
.hw__opts, .hw__blanks, .hw__pairs, .hw__order, .hw__fix { display: grid; gap: 8px; margin-top: 10px; }

.hw__opt {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 9px 11px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-sect);
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease;
}

.hw__opt.is-on {
    border-color: var(--mz-accent);
    background: var(--mz-accent-wash);
}

.hw__opt input { margin-top: 3px; }
.hw__opt b { min-width: 18px; }

.hw__blankrow, .hw__pairrow, .hw__orderrow, .hw__fixrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hw__blankno, .hw__pairno { min-width: 62px; font-size: 13px; color: var(--mz-ink-3); }
.hw__pairtext { flex: 1 1 220px; }
.hw__pairsel, .hw__ordersel { max-width: 220px; }
.hw__fixno { max-width: 76px; }

.hw__bank { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 12px; }
.hw__bank span {
    padding: 4px 10px;
    border: 1px dashed var(--mz-line);
    border-radius: 999px;
    font-size: 13px;
    color: var(--mz-ink-2);
}

.hw__blk { margin: 18px 0 6px; }
.hw__passage {
    margin: 10px 0 14px;
    padding: 14px 16px;
    border-left: 3px solid var(--mz-accent);
    border-radius: 0 var(--mz-radius) var(--mz-radius) 0;
    background: var(--mz-surface-sect);
    color: var(--mz-ink-2);
}
.hw__q { padding: 14px 0; border-bottom: 1px dashed var(--mz-line); }
.hw__q:last-child { border-bottom: 0; }
.hw__qh { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.hw__qh b { color: var(--mz-accent); }
.hw__stem { margin: 6px 0 2px; }

.hw__bar {
    position: sticky;
    bottom: 0;
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 16px;
    padding: 12px 2px calc(12px + env(safe-area-inset-bottom));
    /* 261103：与考卷的 .ex__foot 同一口径 —— 底部按钮行只留一条上发丝线分界，
       不再铺玻璃底、不再模糊（那层底色会把按钮糊成一块灰板）。 */
    border-top: 1px solid var(--mz-line);
    background: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
.hw__bar .sp { flex: 1; }
.hw__hint { font-size: 13px; color: var(--mz-ink-3); }

/* 窄屏：让「返回 / 保存 / 交卷」留在同一行，提示文字挪到下一行。
   （2688：原来 .sp 占位把三个按钮挤成两行，按钮还被包在一块灰底里） */
@media (max-width: 700px) {
    .hw__bar { row-gap: 8px; }
    .hw__bar .sp { display: none; }
    .hw__bar .hw__hint { order: 9; flex: 1 1 100%; margin: 0; }
    .hw__bar .btn { flex: 0 0 auto; }
}

/* ---------- 17.23 旧令牌别名桥（迁移期专用） ----------
   engstudy 的 classroom.css / teach.css 里还有一批旧别名（--card / --teal /
   --r-l / --r-pill / --ink-4 / --amber / --top-h …），它们的定义原本只在
   engstudy/base.css 里。任何「把站级规则搬到公共层」的动作都会因缺定义而失效，
   所以先在公共层做一层桥接——值一律指向 --mz-* 令牌，不引入第二套颜色。
   等这些站级文件最终删除时，本段可一并删掉。 */
:root {
    --card: var(--mz-glass);
    --card-2: var(--mz-glass-2);
    --line: var(--mz-line);
    --line-2: var(--mz-line-2);
    --ink: var(--mz-ink);
    --ink-2: var(--mz-ink-2);
    --ink-3: var(--mz-ink-3);
    --ink-4: var(--mz-ink-4);
    --teal: var(--mz-accent);
    --teal-ink: var(--mz-accent-deep);
    --teal-soft: var(--mz-accent-wash);
    --amber: var(--mz-warn);
    --amber-soft: rgba(138, 89, 15, .12);
    --red: var(--mz-accent);
    --red-soft: rgba(10, 111, 123, .12);
    --r-m: var(--mz-radius);
    --r-l: var(--mz-radius-l);
    --r-pill: var(--mz-radius-pill);
    --top-h: var(--mz-topbar-h);
    --f-mono: var(--mz-mono);
    --f-sans: var(--mz-sans);
    --shadow-1: var(--mz-shadow);
    --shadow-2: var(--mz-shadow-lift);
}

[data-theme="dark"] {
    --amber-soft: rgba(214, 168, 74, .16);
    --red-soft: rgba(92, 198, 207, .16);
}

/* ---------- 17.24 考卷卷头与倒计时（.ex__head / .ex__timer） ----------
   自 engstudy/classroom.css 上收公共层（族 4 第一小段）。
   旧别名已由 17.23 的令牌桥指向 --mz-*，这里保持类名不变，exam.js 无需改动。 */
.ex__head {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    padding: 4px 2px;
}

.ex__head b { font-size: 16px; }

.ex__timer {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 4px 13px;
    border-radius: var(--mz-radius-pill);
    background: var(--mz-accent-wash);
    color: var(--mz-accent-deep);
    font-family: var(--mz-mono);
    font-size: 18px;
    font-weight: 700;
    white-space: nowrap;
}

.ex__timer.is-warn {
    background: rgba(138, 89, 15, .14);
    color: var(--mz-warn);
}

.ex__timer.is-final {
    background: rgba(10, 111, 123, .16);
    color: var(--mz-accent);
}

/* ---------- 17.25 考卷题号栏（.ex__navbar / .ex__qbar / .ex__qn-btn） ----------
   自 engstudy/classroom.css 上收公共层（族 4 第二小段）。
   旧别名换成 --mz-*；`.ex__passage` 的两条滚动条规则仍留在站级，未拆动。 */
.ex__navbar {
    position: sticky;
    top: var(--mz-topbar-h);
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: color-mix(in srgb, var(--mz-glass) 94%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    box-shadow: var(--mz-shadow);
}

.ex__qbar {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    padding: 2px 2px 4px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--mz-ink-4) 40%, transparent) transparent;
}

.ex__qbar::-webkit-scrollbar { height: 6px; }
.ex__qbar::-webkit-scrollbar-track { background: transparent; }

.ex__qbar::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--mz-ink-4) 35%, transparent);
    border-radius: 6px;
}

.ex__qbar::-webkit-scrollbar-thumb:hover { background: var(--mz-ink-4); }

.ex__qn-btn {
    flex: 0 0 auto;
    min-width: 34px;
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-surface-comp);
    color: var(--mz-ink-2);
    font-family: var(--mz-mono);
    font-size: 13px;
    cursor: pointer;
}

.ex__qn-btn:hover { border-color: var(--mz-ink-4); }

.ex__qn-btn.is-done {
    border-color: color-mix(in srgb, var(--mz-accent) 45%, var(--mz-line));
    background: var(--mz-accent-wash);
    color: var(--mz-accent-deep);
}

.ex__qn-btn.is-on {
    border-color: var(--mz-accent);
    background: var(--mz-accent);
    color: #fff;
    font-weight: 700;
}

/* ---------- 17.26 考卷卷体与题块（.ex__body / .ex__passage / .ex__item / .ex__opt …） ----------
   自 engstudy/classroom.css 上收公共层（族 4 第三小段）。
   旧别名换成 --mz-*；exam.js / answer_kit.js 的类名保持不变。 */
.ex__body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    align-items: stretch;
}

.ex__passage {
    max-height: 38vh;
    overflow: auto;
    padding: 18px 20px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-glass);
    font-size: 15px;
    line-height: 1.95;
    white-space: pre-wrap;
    word-break: break-word;
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--mz-ink-4) 35%, transparent) transparent;
}

.ex__passage::-webkit-scrollbar { width: 8px; }
.ex__passage::-webkit-scrollbar-track { background: transparent; }

.ex__passage::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--mz-ink-4) 30%, transparent);
    border-radius: 8px;
}

.ex__passage::-webkit-scrollbar-thumb:hover { background: var(--mz-ink-4); }

.ex__qs {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.ex__item {
    padding: 18px 20px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-glass);
}

.ex__item.is-cur { border-color: var(--mz-accent); }

.ex__i-h {
    display: flex;
    align-items: baseline;
    gap: 9px;
    margin-bottom: 9px;
}

.ex__i-n {
    font-family: var(--mz-mono);
    font-weight: 700;
    color: var(--mz-accent-deep);
}

.ex__i-s {
    margin-left: auto;
    font-size: 12px;
    color: var(--mz-ink-4);
    font-family: var(--mz-mono);
}

.ex__stem {
    font-size: 16px;
    line-height: 1.8;
    white-space: pre-wrap;
    word-break: break-word;
}

.ex__opts {
    display: flex;
    flex-direction: column;
    gap: 7px;
    margin-top: 11px;
}

.ex__opt {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 13px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    cursor: pointer;
    font-size: 15px;
    line-height: 1.7;
    transition: border-color .16s ease, background .16s ease;
}

.ex__opt:hover { border-color: var(--mz-ink-4); }

.ex__opt input {
    margin-top: .35em;
    accent-color: var(--mz-accent);
}

.ex__opt.is-on {
    border-color: var(--mz-accent);
    background: var(--mz-accent-wash);
}

.ex__opt b {
    font-family: var(--mz-mono);
    color: var(--mz-accent-deep);
}

.ex__ans { margin-top: 11px; }

.ex__ans .inp,
.ex__ans .ta { font-size: 15px; }

.ex__fix {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ex__fixrow {
    display: flex;
    gap: 8px;
    align-items: center;
}

.ex__fixrow input:first-child {
    width: 86px;
    text-align: center;
    font-family: var(--mz-mono);
}

/* ---------- 17.27 交卷成绩块（.ex__score / .ex__big / .ex__detrow） ----------
   自 engstudy/classroom.css 上收公共层（族 4 第四小段·成绩部分）。
   移动端「一屏作答」那段仍留在站级，待与倒计时表盘一并处理。 */
.ex__score {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 24px;
    align-items: center;
    padding: 24px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-glass);
}

.ex__big {
    font-family: var(--mz-mono);
    font-size: clamp(40px, 9vw, 64px);
    font-weight: 700;
    line-height: 1;
}

.ex__big small {
    font-size: 18px;
    color: var(--mz-ink-4);
    font-family: var(--mz-sans);
    font-weight: 400;
}

.ex__stats {
    display: flex;
    gap: 22px;
    flex-wrap: wrap;
}

.ex__stat b {
    display: block;
    font-family: var(--mz-mono);
    font-size: 20px;
}

.ex__stat span {
    font-size: 12.5px;
    color: var(--mz-ink-4);
}

.ex__det {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 4px;
}

.ex__detrow {
    display: flex;
    gap: 10px;
    align-items: baseline;
    padding: 8px 12px;
    border: 1px solid var(--mz-line-2);
    border-radius: var(--mz-radius);
    font-size: 13.5px;
}

.ex__detrow.is-ok { border-left: 3px solid var(--mz-accent); }
.ex__detrow.is-bad { border-left: 3px solid var(--mz-warn); }
.ex__detrow .mono { color: var(--mz-ink-3); }

/* ---------- 17.27a 无顶栏的作答页：顶栏占位归零 ----------
   exam.html / homework.html / discuss.html 三页是 data-mz-chrome="none"，
   页面上根本没有顶栏；但 :root 里的 --mz-topbar-h 仍是 64px（窄屏 58px）。
   17.33 的「一屏之内」用 100dvh 减它，于是题号栏永远矮一截、底部翻题条
   被挤出屏幕。这里只在无外壳页上归零，别的页面不受影响。 */
html[data-mz-chrome="none"] { --mz-topbar-h: 0px; }

/* ---------- 17.27b 卷头与页内工具条 ----------
   页头（.mz-head）从这三页删掉后，卷头 .ex__head 就是首屏第一行，
   它要顶住三件事：这是什么卷、还要多久、存到什么程度。 */
.ex__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px 10px;
    margin-bottom: 10px;
}

.ex__head > b {
    font-size: 19px;
    line-height: 1.35;
    letter-spacing: -.01em;
}

/* 讨论页顶部的「回课程」：一行小工具，不抢话题本身的注意力 */
.ex__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

/* ---------- 17.27c 底部翻题条（.ex__foot / .ex__pos / .ex__quit） ----------
   原来只在 17.33 的窄屏段里复位过，桌面态一条规则都没有：
   四个按钮和一个计数干挤在一排、没有分隔、滚到卷尾才看得见。
   这里补桌面态——一条吸底的翻题条，任何位置都能翻题、能暂离。 */
.ex__foot {
    position: sticky;
    bottom: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
    padding: 10px 2px calc(10px + env(safe-area-inset-bottom));
    /* 261103：翻题条不再自己铺一块玻璃底 —— 它就是页面上的最后一行按钮，
       底色、描边、投影、模糊整层清掉，只有按钮本身是实体。 */
    border: 0;
    border-radius: 0;
    background: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: none;
}

.ex__foot .btn { min-height: 38px; }

/* 中间的计数兼「跳到下一道没答的题」：一颗安静的可点胶囊 */
.ex__pos {
    flex: 1 1 auto;
    min-width: 0;
    padding: 6px 10px;
    border: 1px solid transparent;
    border-radius: var(--mz-radius-pill);
    background: transparent;
    color: var(--mz-ink-3);
    font-family: var(--mz-mono);
    font-size: 13px;
    line-height: 1.4;
    text-align: center;
    cursor: pointer;
    transition: color .16s ease, border-color .16s ease, background .16s ease;
}

.ex__pos:hover {
    color: var(--mz-accent-deep);
    border-color: var(--mz-accent-line);
    background: var(--mz-accent-wash);
}

.ex__pos:focus-visible { outline: 2px solid var(--mz-accent); outline-offset: 1px; }

/* 全答完了：计数转成强调色，提示可以交卷了 */
.ex__pos.is-clear { color: var(--mz-accent-deep); }

/* 「暂离」站在最右、比翻题按钮再安静一级：它是退路，不是主操作 */
.ex__quit {
    margin-left: auto;
    padding-inline: 10px;
    color: var(--mz-ink-4);
}

.ex__quit:hover { color: var(--mz-ink-2); }

/* 卷尾提示：一行小字；没内容时整块收起（exam.js 用 .hide 控制） */
.ex__notice {
    margin-top: 12px;
    padding: 10px 13px;
    border: 1px dashed var(--mz-line);
    border-radius: var(--mz-radius);
    font-size: 12.5px;
    line-height: 1.7;
    color: var(--mz-ink-4);
}

/* ---------- 17.27d 拍照与附件上传组件（.ex__ph* / .ans-*） ----------
   这一族原来只有 17.32 的窄屏覆盖（图标收到 42px），桌面态规则一条都没有：
   「上传图片」是个裸按钮、隐藏用的 <input type="file"> 没被藏起来（页面上多出
   一个系统「选择文件」控件）、缩略图没有尺寸、底部说明是裸 <p>。
   以下补齐基础态，17.32 继续在它之上做窄屏收拢。 */
.ex__ph {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.ex__ph-h {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 9px;
}

/* 系统文件控件藏起来：真按钮是 .ex__ph-pick，点它转调这个 input */
.ex__ph-file {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    opacity: 0;
    pointer-events: none;
}

.ex__ph-pick {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 38px;
    padding: 0 15px;
    border: 1px dashed var(--mz-accent-line);
    border-radius: var(--mz-radius);
    background: var(--mz-accent-wash);
    color: var(--mz-accent-deep);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease, color .16s ease;
}

.ex__ph-pick:hover:not(:disabled) { border-color: var(--mz-accent); }
.ex__ph-pick:focus-visible { outline: 2px solid var(--mz-accent); outline-offset: 2px; }

/* 到张数上限、或这一题已锁定：退成灰描边，但仍然看得清能看懂 */
.ex__ph-pick.is-off,
.ex__ph-pick:disabled {
    border-color: var(--mz-line);
    background: transparent;
    color: var(--mz-ink-4);
    cursor: not-allowed;
}

.ex__ph-ico { width: 18px; height: 18px; flex: 0 0 auto; }

.ex__ph-n {
    font-family: var(--mz-mono);
    font-size: 12.5px;
    color: var(--mz-ink-3);
}

.ex__ph-hint {
    flex: 1 1 200px;
    font-size: 12px;
    line-height: 1.6;
    color: var(--mz-ink-4);
    text-decoration: none;
    border-bottom: 1px dotted var(--mz-line-strong);
}

.ex__ph-hint:hover { color: var(--mz-accent-deep); }

.ex__ph-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* 缩略图：正方小卡；底部「原图」在左、删除在右 */
.ex__th {
    position: relative;
    display: block;
    margin: 0;
    width: 96px;
    height: 96px;
    overflow: hidden;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius);
    background: var(--mz-accent-wash);
}

.ex__th img { display: block; width: 100%; height: 100%; object-fit: cover; }

.ex__th.is-loading { display: grid; place-items: center; }

.ex__th.is-bad::after {
    content: "读不出来";
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 11.5px;
    color: var(--mz-ink-4);
}

.ex__th-open,
.ex__th-del {
    position: absolute;
    bottom: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 22px;
    border: 0;
    background: rgba(8, 19, 26, .62);
    color: #fff;
    font-size: 11.5px;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background .16s ease;
}

.ex__th-open { left: 0; right: 26px; }
.ex__th-open:hover { background: rgba(8, 19, 26, .84); }

.ex__th-del { right: 0; width: 26px; font-size: 15px; background: rgba(138, 46, 30, .82); }
.ex__th-del:hover:not(:disabled) { background: rgba(138, 46, 30, 1); }
.ex__th-del:disabled { opacity: .5; cursor: not-allowed; }

/* 组件底部那行说明：上传前是「压到 1600px、最多 N 张」，交卷后是「只能查看」 */
.ex__ph-tip {
    margin: 0;
    padding: 8px 11px;
    border-left: 3px solid var(--mz-accent-line);
    border-radius: 0 var(--mz-radius) var(--mz-radius) 0;
    background: var(--mz-accent-wash);
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--mz-ink-3);
}

/* 成绩页的「某某的照片」小标题 */
.ex__ph-line { margin-top: 12px; }

.ex__ph-key {
    display: block;
    margin-bottom: 6px;
    font-family: var(--mz-mono);
    font-size: 12px;
    color: var(--mz-ink-4);
}

/* ---------- 17.27e 主观题工具栏与字数提示（.ans-bar / .ans-tool / .ans-tip） ----------
   原来在 answer_kit.js 里用一大串内联 cssText 拼出来，底部提示则是一个
   没有类名的 <p class="small dim">：桌面看还行，手机上一碰就散，也跟不上主题。
   改由这里统一定尺——粗体/斜体/下划线是三个小组件，上传文件单独靠右。 */
.ans-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
}

.ans-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    min-height: 32px;
    padding: 0 11px;
    border: 1px solid var(--mz-line);
    border-radius: 9px;
    background: transparent;
    color: var(--mz-ink-2);
    font: inherit;
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease, color .16s ease;
}

.ans-tool:hover:not(:disabled) {
    border-color: var(--mz-accent-line);
    background: var(--mz-accent-wash);
    color: var(--mz-accent-deep);
}

.ans-tool:focus-visible { outline: 2px solid var(--mz-accent); outline-offset: 1px; }
.ans-tool:disabled { opacity: .55; cursor: not-allowed; }

.ans-tool--b { font-weight: 700; }
.ans-tool--i { font-style: italic; }
.ans-tool--u { text-decoration: underline; }

/* 上传附件靠右站：与左边的三个排版小工具分开，不会看成一排 */
.ans-tool--file { margin-left: auto; border-style: dashed; }
.ans-tool--file::before { content: "📎"; font-size: 12px; }

.ans-tip {
    margin: 7px 0 0;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--mz-ink-4);
    font-variant-numeric: tabular-nums;
}

/* 窄屏：工具栏放大到能舒服点，翻题条压到屏幕边上、留出手指的余地 */
@media (max-width: 700px) {
    .ex__head > b { font-size: 17px; }

    .ex__foot {
        gap: 7px;
        margin-top: 12px;
        padding: 8px 0 calc(8px + env(safe-area-inset-bottom));
    }

    .ex__foot .btn {
        min-height: 42px;
        padding: 0 11px;
        font-size: 13.5px;
    }

    .ex__pos {
        padding: 6px 4px;
        font-size: 12px;
    }

    /* 窄屏：翻题按钮一行、进度文字一行 —— 文字挤在按钮中间时会被压成两三行，
       整条操作区跟着长高（考卷那一屏本来就不够用） */
    .ex__foot { flex-wrap: wrap; row-gap: 6px; }
    .ex__pos {
        order: 9;
        flex: 1 1 100%;
        text-align: left;
        padding: 2px 2px 0;
    }

    .ans-tool { min-height: 36px; padding: 0 12px; font-size: 13.5px; }
    .ans-tip { margin-top: 6px; font-size: 12px; }
    .ex__ph-tip { font-size: 12px; }
}

/* ---------- 17.28 随机选择的容器（.pk__pools / .pk__list） ----------
   上一批把 .pk__item / .pk__pool 换成了公共胶囊，但这两个「装胶囊的容器」
   仍是必要的布局规则，误删会让条目挤成一团、列表不能滚动。这里补回。 */
.pk__pools {
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
}

.pk__list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 218px;
    overflow: auto;
    padding: 2px;
}

/* ---------- 17.29 协议正文拉满屏宽 ----------
   文章正文的 .pr-paper 自带 max-width，读协议时内容只占屏幕中间一条。
   规格要求页面左右撑满，所以协议阅读区一律拉满。 */
.mz-agreement,
.mz-agreement .pr-paper,
.mz-agreement article {
    width: 100%;
    max-width: none;
}

/* 正文内的目录与要点块同样拉满，不再二次限宽 */
.mz-agreement .pr-toc,
.mz-agreement .pr-summary,
.mz-agreement .pr-cross {
    max-width: none;
}

/* ---------- 17.30 顶栏头像与用户弹层（261101 重写） ----------
   旧写法有三个毛病，一并修掉：
   ① 胶囊没有定尺，`img{width:100%}` 在没有宽高的父元素里塌成空圈（未悬停时看不到头像）；
   ② `.mz-user-slot .mz-user img` 这条后代选择器把弹层里的大头像也套上了 `display:grid`，
      大图因此偏离圆心；
   ③ 弹层打开时胶囊没有隐藏，与大头像重叠。 */

/* 顶栏胶囊：用属性选择器定位（`.mz-user-slot` 这个类名历史上并没有挂到 DOM 上，
   旧规则一直没生效，所以未悬停时胶囊是空圈）。定尺 30×30、圆形，
   并把站标作为背景垫底——头像加载失败时至少还有 logo。 */
[data-mz-user] > a.mz-user {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex: 0 0 auto;
    border-radius: 50%;
    overflow: hidden;
    padding: 0;
    background: url('/common/image/logo.png') center / 60% no-repeat, var(--mz-flat, #eef1f4);
}

[data-mz-user] > a.mz-user > img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    object-position: center;
}

/* 弹层打开时胶囊隐藏（规格：原有胶囊隐藏不显示）；
   只隐可见性、仍占位，避免一隐藏就触发 mouseleave 把面板关掉 */
[data-mz-user].is-open > a.mz-user {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

/* 弹层里的品牌位：回到圆心，图片铺满裁切，不受上面那条后代选择器影响 */
.mz-user__menu .mz-user__big {
    display: block;
    width: 66px;
    height: 66px;
    margin: -33px auto 7px;
    border-radius: 50%;
    overflow: hidden;
}

.mz-user__menu .mz-user__big-img {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    object-fit: cover;
    object-position: center;
    border-radius: 50%;
}

/* ---------- 17.31 考卷在窄屏的收窄（@media 900px 第一段） ----------
   自 engstudy/classroom.css 上收公共层（族 4 · A 段之一）。
   只含已上收的 .ex__passage / .ex__item / .ex__timer / .ex__navbar / .ex__score，
   与公共层 17.24–17.27 对应的桌面规则成对出现。 */
@media (max-width: 900px) {
    .ex__passage {
        max-height: 34vh;
        padding: 14px 15px;
    }

    .ex__item {
        padding: 15px;
    }

    .ex__timer {
        font-size: 16px;
        padding: 4px 10px;
    }

    .ex__navbar {
        gap: 8px;
        padding: 7px 9px;
    }

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

/* ---------- 17.32 移动端作答区：编辑器在上、拍照行在下（@media 700px） ----------
   原来是「拍照按钮收成 42px 图标 + 输入框同排」的写法：`.is-photo` 变成 flex 行，
   输入框 `flex: 1 1 0`，于是窄屏上作答框被挤成一条竖缝（占位文字竖着排），
   拍照按钮反而占了正经位置 —— 手写长答案根本没法看。
   现在改成纵向：工具栏 → 全宽作答框 → 拍照/附件一行 → 说明。
   按钮仍在，只是回到它该在的下一行。 */
@media (max-width: 700px) {
    .ex__ans > .is-photo {
        display: block;
    }

    .ex__ans > .is-photo > .ex__ph {
        display: flex;
        flex-direction: column;
        gap: 8px;
        margin-top: 10px;
        padding-top: 10px;
        border-top: 1px dashed var(--mz-line);
    }

    .ex__ans > .is-photo > .ex__ph > .ex__ph-h {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 8px;
    }

    /* 作答框：吃掉整行、给足高度，别被拍照按钮挤窄 */
    .ex__ans > .is-photo > .ta,
    .ex__ans > .is-photo > .inp {
        width: 100%;
        min-width: 0;
    }

    .ex__ans > .is-photo > .ta {
        min-height: 132px;
    }

    .ex__ph-pick {
        min-height: 40px;
        padding: 0 14px;
    }

    .ex__ph-ico { width: 18px; height: 18px; }

    .ex__ph-hint {
        flex: 1 1 100%;
        margin-left: 0;
        font-size: 11.5px;
    }

    .ex__ph-tip { margin-top: 2px; }

    .ex__th { width: 78px; height: 78px; }
}

/* ---------- 17.33 移动端作答「一屏之内完成」（@media 900px，:has 判定） ----------
   自 engstudy/classroom.css 上收公共层（族 4 · A 段之二之二）。
   进入作答（#viewExam 可见）后：整页不滚，题号栏/卷头/翻题条固定，
   只有语篇与当前题所在区域自己滚，手不用离开屏幕。 */
@media (max-width: 900px) {
    body:has(#viewExam:not(.hide)) { overflow: hidden; }

    body:has(#viewExam:not(.hide)) .page__head,
    body:has(#viewExam:not(.hide)) #viewList,
    body:has(#viewExam:not(.hide)) .mz-footer,
    body:has(#viewExam:not(.hide)) .rail { display: none !important; }

    body:has(#viewExam:not(.hide)) .shell {
        display: block;
        max-width: none;
        padding: 0;
        min-height: 0;
    }

    body:has(#viewExam:not(.hide)) .main { padding: 0 12px; }

    #viewExam:not(.hide) {
        display: flex;
        flex-direction: column;
        height: calc(100dvh - var(--mz-topbar-h, 110px) - 10px);
        min-height: 420px;
    }

    /* 顶部三行与底部翻题条：固定，不参与滚动 */
    #viewExam .ex__navbar,
    #viewExam .ex__head,
    #viewExam .ex__foot {
        flex: 0 0 auto;
        position: static;
        margin: 0;
    }

    #viewExam .ex__navbar { margin-bottom: 8px; }
    #viewExam .ex__head { padding: 0 2px 8px; }

    /* 语篇 + 当前题：唯一的滚动区 */
    #viewExam .ex__body {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 6px;
    }

    /* 卷尾提示在作答时占地方，收进「暂离」前的确认里 */
    #viewExam .ex__notice { display: none; }

    /* 语篇在窄屏不再单独限高，跟着作答区一起滚 */
    #viewExam .ex__passage { max-height: none; }

    /* 底部留出翻题条的余量，最后一道题不被挡住 */
    #viewExam .ex__body::after {
        content: "";
        display: block;
        height: 8px;
    }
}

/* ---------- 17.34 倒计时右侧控制区（.cd__side / __block / __bt / __ctrl / __presets / __custom / __nodes / __hint） ----------
   自 engstudy/classroom.css 上收公共层（族 4 · B 段之一）。
   环形表盘与投影态仍留在站级，下一小段处理。 */
.cd__side {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.cd__block {
    padding: 16px 18px;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background: var(--mz-glass);
}

.cd__bt {
    margin-bottom: 11px;
    font-size: 12px;
    letter-spacing: .14em;
    color: var(--mz-ink-4);
}

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

.cd__ctrl .btn {
    min-height: 46px;
    padding: 0 22px;
    font-size: 16px;
}

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

.cd__presets .chip {
    min-height: 36px;
    padding: 0 15px;
    font-size: 14px;
}

.cd__custom {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 11px;
    flex-wrap: wrap;
}

.cd__custom .inp {
    width: 92px;
    min-height: 36px;
}

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

.cd__hint {
    margin-top: 10px;
    font-size: 12.5px;
    line-height: 1.7;
    color: var(--mz-ink-4);
}

/* ---------- 17.35 倒计时环形表盘与投影态（.cd / .cd__stage / .cd.is-proj …） ----------
   自 engstudy/classroom.css 上收公共层（族 4 · B 段之二）。
   tool_countdown.js 只操作 id 与既有类名，未改一行；令牌已换成 --mz-*。 */
.cd {
    display: grid;
    grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    gap: 34px;
    align-items: start;
}

.cd__stage {
    position: relative;
    display: grid;
    place-items: center;
    width: 100%;
    max-width: 420px;
    aspect-ratio: 1 / 1;
    margin: 0 auto;
    border: 1px solid var(--mz-line);
    border-radius: 50%;
    background: radial-gradient(circle at 50% 42%, var(--mz-glass) 0 58%, var(--mz-accent-wash) 100%);
    box-shadow: var(--mz-shadow-lift);
}

.cd__ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.cd__ring circle { fill: none; stroke-linecap: round; }
.cd__track { stroke: var(--mz-line); stroke-width: 4; }

.cd__bar {
    stroke: var(--mz-accent);
    stroke-width: 4;
    transition: stroke-dashoffset .25s linear, stroke .3s ease;
}

.cd__mid { position: relative; padding: 0 14%; text-align: center; }

.cd__time {
    display: block;
    font-family: var(--mz-mono);
    font-size: clamp(40px, 9.5vw, 74px);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.cd__label {
    display: block;
    margin-top: 6px;
    font-size: 14px;
    letter-spacing: .08em;
    color: var(--mz-ink-3);
}

.cd__state {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding: 3px 11px;
    border-radius: var(--mz-radius-pill);
    background: var(--mz-accent-wash);
    color: var(--mz-accent-deep);
    font-size: 12px;
}

.cd__stage.is-warn .cd__bar { stroke: var(--mz-warn); }
.cd__stage.is-final .cd__bar { stroke: var(--mz-accent); }
.cd__stage.is-final .cd__time { color: var(--mz-accent); }
.cd__stage.is-done { animation: cd-pulse 1.1s ease 3; }
.cd__stage.is-done .cd__bar { stroke: var(--mz-accent); }

@keyframes cd-pulse {
    50% { box-shadow: 0 0 0 16px var(--mz-accent-wash); }
}

/* 投影态：整屏深底、超大数字、隐藏侧栏 */
.cd.is-proj {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    place-items: center;
    padding: 3vh 4vw;
    background: #0b1213;
    grid-template-columns: minmax(0, 1fr);
}

.cd.is-proj .cd__stage {
    width: min(78vh, 92vw);
    max-width: none;
    border: 0;
    box-shadow: none;
    background: radial-gradient(circle at 50% 45%, #12262a 0 55%, #0b1213 100%);
}

.cd.is-proj .cd__track { stroke: #20343a; }

.cd.is-proj .cd__time {
    font-size: clamp(64px, 17vmin, 260px);
    color: #eaf4f1;
}

.cd.is-proj .cd__label,
.cd.is-proj .cd__state {
    font-size: clamp(14px, 2.4vmin, 26px);
    color: #9fbdba;
    background: none;
}

.cd.is-proj .cd__side { display: none; }

.cd__exit {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 210;
    display: none;
}

.cd.is-proj .cd__exit { display: inline-flex; }

/* 节点提醒的浮层大字 */
.cd__flash {
    position: fixed;
    left: 50%;
    top: 8vh;
    z-index: 220;
    padding: 12px 26px;
    border-radius: var(--mz-radius-pill);
    background: var(--mz-accent);
    color: #fff;
    font-size: clamp(15px, 2.6vmin, 28px);
    font-weight: 700;
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, -12px);
    transition: opacity .25s, transform .25s;
}

.cd__flash.is-on {
    opacity: 1;
    transform: translate(-50%, 0);
}

@media (max-width: 900px) {
    .cd {
        grid-template-columns: minmax(0, 1fr);
        gap: 22px;
    }

    .cd__stage { max-width: 320px; }
}

/* ---------- 17.36 随机选择的布局与投影态（.pk / .pk__stage / .pk__out …） ----------
   自 engstudy/classroom.css 上收公共层（族 4 · C 段之一）。
   选库与条目的胶囊已在此前的 17.19 / 17.28 归位，这里补布局与投影。 */
.pk {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 26px;
    align-items: start;
}

/* 结果区：定高定宽，长名字不再把布局撑开 */
.pk__stage {
    display: grid;
    place-items: center;
    height: 320px;
    min-height: 320px;
    padding: 30px 22px;
    overflow: hidden;
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    background:
        repeating-linear-gradient(135deg, transparent 0 12px, var(--mz-accent-wash) 12px 13px),
        var(--mz-glass);
    text-align: center;
    box-shadow: var(--mz-shadow-lift);
}

.pk__out {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    max-width: 100%;
    font-size: clamp(30px, 7vw, 58px);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -.01em;
    word-break: break-word;
}

.pk__out.is-spin {
    color: var(--mz-accent);
    opacity: .82;
}

.pk__sub {
    margin-top: 10px;
    font-size: 13.5px;
    color: var(--mz-ink-3);
}

.pk__side {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.pk__stat {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    font-family: var(--mz-mono);
    font-size: 12.5px;
    color: var(--mz-ink-4);
}

/* 投影态：整屏深底、超大结果 */
.pk__stage.is-proj {
    position: fixed;
    inset: 0;
    z-index: 200;
    min-height: 0;
    height: auto;
    padding: 5vh 6vw;
    border: 0;
    border-radius: 0;
    background: #0b1213;
    box-shadow: none;
}

.pk__stage.is-proj .pk__out {
    font-size: clamp(56px, 15vmin, 220px);
    color: #eaf4f1;
}

.pk__stage.is-proj .pk__sub {
    font-size: clamp(14px, 2.2vmin, 24px);
    color: #9fbdba;
}

@media (max-width: 900px) {
    .pk { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- 17.32 文章列表（长条行 / 卡片，四站共用） ----------
   自 home/css/pages.css 上收公共层：这套类名由 feed.js 生成，
   总站「最新动态」等不引站级 css 的页面此前拿不到样式（列表被拉成一张大图）。
   颜色一律取 --mz-* 令牌，站点不再各写一份。 */
.mz-feed {
    display: flex;
    flex-direction: column;
}

.mz-feed__row {
    display: grid;
    grid-template-columns: 118px minmax(0, 1fr);
    gap: 20px;
    padding: 20px 6px;
    border-bottom: 1px solid var(--mz-line);
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .18s ease;
}

/* 卡片是整块 <a>：文字区自己成列，标题/摘要/元信息依次排列 */
.mz-feed__text {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.mz-feed__row:first-child { border-top: 1px solid var(--mz-line); }
.mz-feed__row:hover { background: var(--mz-accent-wash); }

.mz-feed__thumb {
    width: 118px;
    height: 84px;
    object-fit: cover;
    border-radius: var(--mz-radius);
    border: 1px solid var(--mz-line-2);
    background: var(--mz-surface-sect);
}

.mz-feed__thumb--text {
    display: grid;
    place-items: center;
    font-family: var(--mz-serif);
    font-size: 1.5rem;
    color: var(--mz-ink-3);
    background: var(--mz-surface-sect);
    border: 0;
    letter-spacing: .06em;
}

.mz-feed__title {
    font-family: var(--mz-serif);
    font-size: 1.1rem;
    line-height: 1.5;
    color: var(--mz-ink);
}

.mz-feed__row:hover .mz-feed__title { color: var(--mz-accent); }

.mz-feed__desc {
    margin-top: 8px;
    font-size: .92rem;
    color: var(--mz-ink-3);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.mz-feed__meta {
    margin-top: 12px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    font-size: .78rem;
    color: var(--mz-ink-4);
}

.mz-feed__meta .mz-badge { font-size: .72rem; }
.mz-feed__pin { color: var(--mz-accent); font-weight: 700; }

/* 卡片形态：feed.js 的 data-mz-layout="card" */
.mz-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
    gap: 20px;
}

.mz-card-art {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: inherit;
    text-decoration: none;
    background: var(--mz-glass);
    border: 1px solid var(--mz-line);
    border-radius: var(--mz-radius-l);
    cursor: pointer;
    transition: border-color .2s, box-shadow .2s, transform .2s;
}

.mz-card-art:hover {
    border-color: var(--mz-line-strong);
    box-shadow: var(--mz-shadow);
    transform: translateY(-3px);
}

.mz-card-art__cover {
    aspect-ratio: 16 / 9;
    width: 100%;
    object-fit: cover;
    background: var(--mz-surface-sect);
}

.mz-card-art__cover--text {
    display: grid;
    place-items: center;
    font-family: var(--mz-serif);
    font-size: 2rem;
    color: var(--mz-ink-3);
    background: var(--mz-surface-sect);
    letter-spacing: .1em;
}

.mz-card-art__body {
    padding: 20px;
    display: flex;
    flex-direction: column;
    flex: 1;
}

.mz-card-art__kicker {
    font-size: .72rem;
    letter-spacing: .2em;
    color: var(--mz-accent);
    text-transform: uppercase;
}

.mz-card-art__title {
    font-family: var(--mz-serif);
    font-size: 1.1rem;
    margin-top: 10px;
    line-height: 1.5;
    color: var(--mz-ink);
}

.mz-card-art__desc {
    margin-top: 10px;
    font-size: .9rem;
    color: var(--mz-ink-3);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.mz-card-art__foot {
    margin-top: auto;
    padding-top: 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: .78rem;
    color: var(--mz-ink-4);
}

@media (max-width: 700px) {
    .mz-feed__row { grid-template-columns: minmax(0, 1fr); }
    .mz-feed__thumb { width: 100%; height: 168px; }
}

/* ---------- 17.33 状态块：加载 / 空 / 错误 / 登录门 ----------
   自 home/css/base.css 上收公共层：这几块由 MZ.state() / MZ.requireLogin()
   生成，四站都在用，但样式原先只挂在总站 css 上 ——
   不引站级 css 的页面（例如 /home/pages/latest.html）就只能看到裸文字。 */
.mz-state {
    padding: 40px 20px;
    text-align: center;
    color: var(--mz-ink-3);
}

.mz-state__icon { font-size: 1.6rem; opacity: .5; }

.mz-state__title {
    font-family: var(--mz-serif);
    font-size: 1.06rem;
    margin-top: 12px;
    color: var(--mz-ink-2);
}

.mz-state__desc {
    font-size: .88rem;
    margin-top: 8px;
    color: var(--mz-ink-4);
}

.mz-state__actions {
    margin-top: 18px;
    display: flex;
    gap: 10px;
    justify-content: center;
    flex-wrap: wrap;
}

.mz-inline-state {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 26px 12px;
    color: var(--mz-ink-3);
    font-size: .9rem;
}

.mz-spinner {
    display: inline-block;
    width: 15px;
    height: 15px;
    vertical-align: -2px;
    border: 2px solid var(--mz-line-strong);
    border-top-color: var(--mz-accent);
    border-radius: 50%;
    animation: mz-spin .7s linear infinite;
}

@keyframes mz-spin { to { transform: rotate(360deg); } }

.mz-skeleton {
    background: var(--mz-surface-sect);
    border-radius: var(--mz-radius);
    animation: mz-pulse 1.6s ease-in-out infinite;
}

.mz-skeleton--line { height: 12px; margin-bottom: 10px; }

@keyframes mz-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

html {
    scrollbar-gutter: stable;
}

/* ---------- 17.35 页面级文本容器宽度 ----------
   同一段文字在不同页面断行位置不同，往往不是组件问题，而是「有的页有滚动条、
   有的没有」——滚动条一出现就少掉 15px。这里统一预留滚动条槽位，
   让全站的可用宽度一致，同一段文字在哪一页都断在同一处。 */

/* 登录门 / 需要登录的区块
   尺寸一律用 px 且自带上限宽度：三站页面容器的宽度与根字号并不相同
   （花粉的推送列表容器更窄、根字号也更小），用 rem/百分比会让同一个组件
   在三处量出三种大小 —— 这里是「全站长得一样」的硬要求，所以写死。 */
.mz-gate {
    box-sizing: border-box;
    width: 100%;
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
    padding: 30px 24px;
    border: 1px dashed var(--mz-line-strong);
    border-radius: var(--mz-radius-l);
    background: var(--mz-surface-comp);
    text-align: center;
}

.mz-gate__title {
    font-family: var(--mz-serif);
    font-size: 17px;
    line-height: 1.5;
    letter-spacing: 0;
    color: var(--mz-ink);
}

.mz-gate__desc {
    margin-top: 8px;
    font-family: var(--mz-sans);
    font-size: 14px;
    line-height: 1.75;
    letter-spacing: 0;
    color: var(--mz-ink-4);
}

.mz-gate__actions {
    margin-top: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* 按钮也按同一尺寸写死，避免各站 rem 基数不同导致一大一小 */
.mz-gate__actions .mz-btn,
.mz-gate__actions .btn {
    min-height: 38px;
    padding: 8px 20px;
    font-size: 14px;
    line-height: 1.3;
}


/* ---------- 17.34 详情页正文拉满 ----------
   .mz-prose 默认 68ch（适合手机阅读），但文章详情页按规格要「页面左右撑满」，
   所以详情页那一处改用 .mz-prose--full，仅放开行宽上限，不改字号与行高。 */
.mz-prose--full,
.mz-prose--full.doc {
    max-width: none;
}
/* ============================================================
   第 102 轮 · 表面层收口（补丁块，勿删）
   ------------------------------------------------------------
   本轮要「全站一块纸、同一枚胶囊」。玻璃令牌与卡片/组件定义在
   /common/css/mz_surface.css（管理节点直接引它，前台由本文件顶部 @import
   引入，两份是同一个源）：

     · 卡片 / 面板的唯一一份底色（选择器清单与 mz_surface.css 第 3 节逐条一致，
       值一律取令牌，本块不写任何色值）
   ------------------------------------------------------------
   令牌本身来自文件顶部的 @import url("mz_surface.css")。本块之所以还要
   重复一遍选择器，是因为 @import 的内容排在所有规则之前，各站后来写的
   .card / .panel 底色会把它们盖掉；只有放在文件末尾才压得住。
   改色值请只改 mz_surface.css。
   ============================================================ */

/* 令牌（--mz-glass* / --mz-surface-* / --mz-blur* / 明暗两档 / 窄屏降档）
   都来自顶部的 @import url("mz_surface.css")，这里不再重复一份。 */

/* 深色两档同样取 mz_surface.css 的值，见上面的说明。 */

/* ---------- 卡片 / 面板：全站唯一一份底色 ---------- */
.mz-card,
.card,
.mz-panel,
.panel,
.tool,
.entry-card,
.quick,
.hf-card,
.site,
.tz-card,
.tz-panel,
.tz-log,
.tz-sect,
.cc-card,
.cc-panel,
.course-panel,
.course-card,
.mz-tile,
.mz-widecard,
.hero-mark,
.ask,
.mz-social,
.mz-side__block,
.mz-qr,
.mz-doc__toc,
.mz-doc,
.feed-item,
.feed-card-item,
.notice-item,
.mail-form {
    background: var(--mz-surface-card);
    border: 1px solid var(--mz-line, color-mix(in srgb, currentColor 13%, transparent));
    border-radius: var(--mz-radius-l, 18px);
    box-shadow: var(--mz-shadow, 0 24px 56px -42px rgba(8, 25, 32, .5));
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
}

/* 可点的卡片才抬一下，静态卡片不动 */
.quick--link:hover,
.hf-card:hover,
.entry-card:hover,
.cc-card--link:hover {
    transform: translateY(-2px);
}

/* 玻璃块（页头胶囊、抽屉面板等）不再各写一份 blur 值 */
.mz-glass {
    -webkit-backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
    backdrop-filter: blur(var(--mz-blur)) saturate(var(--mz-blur-sat));
}

/* 按钮（.mz-btn / .btn）的定义回到第六节，用同一套令牌；
   吸顶页头与页脚的实底见第二十六节，这里不再重复一份。 *//* ============================================================
   细滚动条：一套样式，全站跟随主题
   ------------------------------------------------------------
   出处：「图二 · 滑动条适配网站主题」——原先溢出的横向标签条、
   代码块、表格在深色主题下露的是系统默认亮灰条，跟主题打架。
   这里统一：轨道透明 + 滑块用主题墨色（--mz-ink-4，深浅主题自动
   换算），悬停加深；宽度 8px 的圆头细条，不抢内容。
   单个组件若不想露滚动条（.mz-nav / .mz-tabs / .qe-tools），
   照旧用 scrollbar-width:none + ::-webkit-scrollbar{display:none} 覆盖。
   ============================================================ */

html {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--mz-ink-4) 45%, transparent) transparent;
}

*::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
    background: transparent;
}

*::-webkit-scrollbar-thumb {
    border-radius: 999px;
    background: color-mix(in srgb, var(--mz-ink-4) 35%, transparent);
}

*::-webkit-scrollbar-thumb:hover {
    background: var(--mz-ink-4);
}