/* study 学习平台 —— PC 端样式 */

:root {
    /* ==========================================================
     * 设计令牌。颜色、圆角、阴影、间距、字号只从这里取值，
     * 具体规则里不写死数值——整站换肤 / 调节奏改这一处即可。
     * ========================================================== */

    /* ---------- 主色：靛蓝。导航、主按钮、链接、当前态 ---------- */
    --primary: #4f46e5;
    --primary-dark: #4338ca;
    --primary-light: #eef2ff;
    --primary-border: #c7d2fe;

    /* ---------- 强调色：暖橙。只给进度、激励、必会标记，用少才醒目 ---------- */
    --accent: #f97316;
    --accent-dark: #c2410c;
    --accent-light: #fff7ed;
    --accent-border: #fed7aa;

    /* ---------- 语义色 ---------- */
    --success: #10b981;
    --success-dark: #047857;
    --success-light: #ecfdf5;
    --success-border: #a7f3d0;
    --warning: #f59e0b;
    --warning-light: #fffbeb;
    --warning-border: #fde68a;
    --danger: #ef4444;
    --danger-dark: #b91c1c;
    --danger-light: #fef2f2;
    --danger-border: #fecaca;

    /* ---------- 中性色 ---------- */
    --text: #18181b;
    --text-secondary: #52525b;
    --text-muted: #a1a1aa;
    --border: #e4e4e7;
    --border-strong: #d4d4d8;
    --bg: #fafafa;
    --bg-subtle: #f4f4f5;
    --white: #fff;

    /* ---------- 元素周期表的类别底色 ----------
     * 118 个格子必须靠底色分出金属 / 非金属 / 稀有气体，这是周期表的读法。
     * 所以三个值都取到极浅（和 .summary-box 一个量级）：
     * 铺满整张表也不抢戏，格子里唯一的彩色仍是那枚暖橙的化合价。 */
    --element-metal: #f5f7ff;
    --element-nonmetal: #f2fbf6;
    --element-noble: #faf5ff;

    /* ---------- 圆角。比原来更圆，观感更柔和 ---------- */
    --radius-sm: 8px;
    --radius: 12px;
    --radius-lg: 16px;
    --radius-pill: 999px;

    /* ---------- 阴影。压低不透明度、加大扩散，避免「贴纸感」 ---------- */
    --shadow-sm: 0 1px 2px rgba(24, 24, 27, .04);
    --shadow: 0 1px 3px rgba(24, 24, 27, .04), 0 8px 24px rgba(24, 24, 27, .05);
    --shadow-lg: 0 2px 8px rgba(24, 24, 27, .05), 0 16px 40px rgba(24, 24, 27, .07);

    /*
     * 布局宽度：**左右各预留 10%，中间 80% 自适应视口**。
     * 顶部导航、每一页的内容、页脚共用这一个 10%，所以三者左右边缘始终对齐，
     * 页与页之间切换时内容不会忽宽忽窄——这一条是硬约束，别给个别页面另设边距。
     *
     * 用百分比而不是固定上限：窄屏（1280）留白不至于把内容挤成一条，
     * 宽屏（1920 以上）留白跟着屏幕一起长，卡片栅格自动多排一列。
     * 曾经是固定 1200px，再往前是「铺满视口 + 24px 边距」——
     * 铺满那一版的问题不是宽，而是导航收在中间、内容顶到边上，两条边缘对不齐；
     * 现在三者同用一个百分比，这个问题不存在了。
     *
     * 要逐字读的长正文与题干在此之上**再**收一档（见 .prose-card 与 --measure-max），
     * 宽屏上 80% 一行能排一百多个汉字，长文必须自己收窄。
     *
     * 百分比的内边距是按**宽度**算的，所以 --layout-gutter 只能写在左右两侧，
     * 上下内边距一律用 --space-* 的固定值（写成 padding: var(--layout-gutter) 会让
     * 1920 的屏上下各撑出 192px 空白）。
     */
    --layout-gutter: 10%;
    /* 要给超宽屏加个绝对上限就改这里；none = 宽度完全跟着视口走 */
    --layout-max: none;
    /* 中轴列（首页介绍段落）不吃百分比，用固定边距，否则 760px 的轴会被再切掉 152px */
    --gutter-fixed: var(--space-6);
    --measure-max: 1040px;
    /* ---------- 间距刻度。统一 4 的倍数，卡片留白比原来大一档 ---------- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;

    /*
     * 字号阶梯。使用者是初中生，长时间盯着背单词、读古文，
     * 正文一律不小于 15px、标签类不小于 12px；行高也比常规再放宽一点。
     */
    --font-xs: 12px;
    --font-sm: 13px;
    --font-base: 15px;
    --font-md: 16px;
    --font-lg: 17px;
    --font-xl: 19px;
    --font-2xl: 21px;
    --font-3xl: 23px;
    --font-4xl: 26px;
    --font-5xl: 30px;

    /*
     * 动效。学习页面的动画只做两件事：告诉你「这个能点」（hover 抬一下）、
     * 告诉你「内容来了」（列表逐个浮现）。时长统一 .18s，
     * 再长就显得页面拖沓——学生一天要点几十次。
     */
    --dur: .18s;
    --dur-slow: .4s;
    --ease: cubic-bezier(.4, 0, .2, 1);
}

/* 系统设置里关掉动效的，一律不动——前庭失调的人看动画会不适 */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
}


* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    font-size: var(--font-md);
    /* 中文长文本行距紧了很累，正文统一放宽到 1.7 */
    line-height: 1.7;
    color: var(--text);
    background: var(--bg);
    /* 纵向 flex + 页脚 margin-top:auto，内容不足一屏时页脚仍贴底 */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* dvh 写在后面覆盖 vh：移动端地址栏收起 / 展开时 100vh 是不变的那个大值，
       会让页面凭空多出一截可滚动的空白。不认 dvh 的旧浏览器仍按上一行的 vh 走 */
    min-height: 100dvh;
}

/*
 * 自己声明了 display 的元素会盖掉 [hidden] 自带的 display:none，
 * 于是 `el.hidden = true` 看着像没生效——`.chip-row`（话题筛选条）与
 * `.subject-picker`（整卷作答页的学科选择器）都踩过这个坑。
 * 这一条全局兜住，新组件不必再按类各补一次。
 */
[hidden] {
    display: none !important;
}

a {
    color: inherit;
    text-decoration: none;
}

/* ---------- 顶部导航 ---------- */
.header {
    background: var(--white);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 100;
}

.header-inner {
    max-width: var(--layout-max);
    margin: 0 auto;
    padding: 0 var(--layout-gutter);
    /* 高度自适应：常态仍是 60px 一行，写成 min-height 是为了字号放大 / 内容变高时
       整条导航跟着长，而不是把里面的东西裁掉。
       **不要在这里加 flex-wrap: wrap**：科目多的时候由 .nav 自己横向滚动
       （见下面 .nav 的 overflow-x），换行会把右上角的账号区甩到第二行 */
    min-height: 60px;
    display: flex;
    align-items: center;
    gap: 20px;
}

.logo {
    font-size: var(--font-2xl);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
}

.logo-mark {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    background: var(--primary);
    color: var(--white);
    display: grid;
    place-items: center;
    font-size: var(--font-lg);
}

.nav {
    display: flex;
    flex-wrap: nowrap;
    gap: 4px;
    flex: 1;
    /* 高中科目较多，窄屏时横向滚动而不是把导航撑高 */
    overflow-x: auto;
    scrollbar-width: none;
}

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

.nav a {
    padding: 6px 14px;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    white-space: nowrap;
}

.nav a:hover {
    background: var(--bg);
    color: var(--text);
}

.nav a.active {
    background: var(--primary-light);
    color: var(--primary);
    font-weight: 500;
}

/*
 * 窄屏收紧导航间距。正文字号调大后导航更容易撑满，
 * 宁可挤一点也不要让学生为了点科目先横向滚动。
 */
@media (max-width: 1100px) {
    .nav {
        gap: 2px;
    }

    .nav a {
        padding: 6px 9px;
    }
}

/* 学段切换，样式与 .tabs 一致但更紧凑 */
.stage-switch {
    display: inline-flex;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 2px;
    flex-shrink: 0;
}

.stage-switch button {
    border: 0;
    background: transparent;
    padding: 5px 14px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--font-base);
    color: var(--text-secondary);
    font-family: inherit;
    white-space: nowrap;
}

.stage-switch button.active {
    background: var(--primary);
    color: var(--white);
    font-weight: 500;
}

/* ==========================================================
 * 首页（平台介绍页）
 *
 * 两条约束：
 * 1) **内容不横铺**。首页是一段一段读下去的介绍，不是需要多排几列的列表，
 *    所以内容收在一条 --home-measure 宽的中轴列里，不跟着外壳铺满视口。
 *    站内其它页面铺满是为了让列表多排几列，那条理由在这里不成立。
 * 2) **靠版式分段**，不靠分隔线：卡点是编号条目、四步是竖向时间轴、
 *    方法是带小标题的条目。通栏色带只负责把段落切开，内容始终在中轴上。
 * ========================================================== */
.home {
    flex: 1;
    width: 100%;
}

.home {
    /* 一行 30 来个汉字，比正文的 --measure-max 再窄一档：
       介绍页的段落短，收窄之后眼睛不用来回横扫 */
    --home-measure: 760px;
}

.band {
    padding: var(--space-10) 0;
    background: var(--white);
}

.band-tint {
    background: var(--bg);
}

/* 中轴列：所有段落共用同一条轴线与同一个宽度。
   这里用固定边距而不是 10%——轴本身只有 760px，再按百分比切掉两边就没剩多少了 */
.band-inner {
    max-width: var(--home-measure);
    margin: 0 auto;
    padding: 0 var(--gutter-fixed);
}

.band-title {
    margin: 0 0 var(--space-3);
    font-size: var(--font-2xl);
    text-align: center;
}

.band-lead {
    margin: 0 auto var(--space-8);
    text-align: center;
    color: var(--text-secondary);
    line-height: 1.9;
}

/* ---------- 首屏 ---------- */
.band-hero {
    padding: calc(var(--space-10) * 1.8) 0 calc(var(--space-10) * 1.2);
    text-align: center;
}

.hero-title {
    margin: 0 0 var(--space-6);
    font-size: var(--font-4xl);
    line-height: 1.4;
}

.hero-sub {
    margin: 0;
    font-size: var(--font-lg);
    line-height: 1.95;
    color: var(--text-secondary);
}


/* ---------- 卡点：竖向编号条目 ---------- */
.pain-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.pain {
    display: grid;
    grid-template-columns: 3.2em 1fr;
    gap: var(--space-4);
    padding: var(--space-5) 0;
    border-top: 1px solid var(--border);
}

.pain:last-child {
    border-bottom: 1px solid var(--border);
}

/* 大号浅色序号，只做视觉锚点，不抢正文 */
.pain-no {
    font-size: var(--font-2xl);
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: .04em;
    line-height: 1.4;
}

.pain h3 {
    margin: 0 0 var(--space-2);
    font-size: var(--font-lg);
}

.pain p,
.step p {
    margin: 0;
    color: var(--text-secondary);
    line-height: 1.9;
}

/* ---------- 四步法：竖向时间轴 ---------- */
.steps {
    margin: 0;
    padding: 0;
    list-style: none;
}

.step {
    position: relative;
    display: grid;
    grid-template-columns: 36px 1fr;
    column-gap: var(--space-5);
    padding-bottom: var(--space-6);
}

/* 竖线从序号圆心往下连到下一步，最后一步不画 */
.step::before {
    content: "";
    position: absolute;
    left: 17px;
    top: 36px;
    bottom: 0;
    width: 2px;
    background: var(--border);
}

.step:last-child {
    padding-bottom: 0;
}

.step:last-child::before {
    display: none;
}

.step-no {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-pill);
    background: var(--primary);
    color: var(--white);
    font-size: var(--font-md);
    font-weight: 600;
}

.step h3 {
    margin: 2px 0 var(--space-2);
    font-size: var(--font-lg);
}

/* ---------- 学习方法：竖向条目 ---------- */
/* 不用卡片盒子：一列六张卡在窄轴上会变成六个空荡的方框，
   改成条目 + 分隔线，读起来像一份清单，更贴合「照着做」这件事 */
.methods {
    display: grid;
    gap: var(--space-6);
}

.method {
    padding-left: var(--space-5);
    border-left: 3px solid var(--primary-border);
}

.method h3 {
    margin: 0 0 var(--space-3);
    font-size: var(--font-lg);
}

.method-how {
    margin: 0 0 var(--space-3);
    line-height: 1.9;
}

/* 「为什么有用」压低一档：想直接照做的人看上面一段就够了 */
.method-why {
    margin: 0;
    font-size: var(--font-sm);
    color: var(--text-secondary);
    line-height: 1.85;
}

/* ---------- 收尾行动条 ---------- */
.band-cta {
    background: var(--primary-light);
    border-top: 1px solid var(--primary-border);
    text-align: center;
}

/* 这一条色带现在只剩一句收尾的话，没有按钮，所以不留下边距 */
.cta-title {
    margin: 0;
    font-size: var(--font-xl);
}

/* ---------- 登录弹层 ---------- */
.modal-mask {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-5);
    background: rgba(24, 24, 27, .45);
}

.modal-panel {
    position: relative;
    width: 100%;
    max-width: 420px;
    /* 矮窗口（笔记本横屏 700px 上下）里表单要能整块滚动，不能被裁掉 */
    max-height: 90vh;
    max-height: 90dvh;
    overflow-y: auto;
    background: var(--white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

/* 宽面板：元素详情这类字段较多的内容，420px 会把化合价挤成两行 */
.modal-panel-wide {
    max-width: 560px;
}

.modal-body {
    padding: var(--space-8) var(--space-6) var(--space-6);
}

.modal-close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    width: 32px;
    height: 32px;
    line-height: 1;
    font-size: var(--font-2xl);
    color: var(--text-muted);
    background: transparent;
    border: 0;
    border-radius: var(--radius-pill);
    cursor: pointer;
}

.modal-close:hover {
    color: var(--text);
    background: var(--bg-subtle);
}

/* 弹层里的表单比独立页面紧凑一档：弹层本来就是要一眼看完的 */
.modal-body .auth-head {
    margin-bottom: var(--space-4);
}

.modal-body .auth-head h2 {
    margin: 0 0 var(--space-2);
    font-size: var(--font-xl);
}

.modal-body .auth-head p {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.7;
}

/* 首页那个「登录 / 注册」是 button（要弹层，不跳页），
   按钮默认字体不继承，这里补上，免得和链接态长得不一样 */
button.home-entry {
    font-family: inherit;
    cursor: pointer;
}

/* ---------- 首页专属页头 ---------- */
/* 只有 logo 和一个入口：这一页面向还没进入平台的人，
   导航、学段、地区标签都是「已经在用」之后才有意义的东西 */
.header-plain .header-inner {
    justify-content: space-between;
}

.home-entry {
    display: inline-block;
    font-size: var(--font-base);
    color: var(--primary);
    background: var(--primary-light);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-pill);
    padding: 6px 20px;
    text-decoration: none;
    white-space: nowrap;
}

.home-entry:hover {
    background: var(--white);
}

@media (max-width: 640px) {
    .band,
    .band-hero,
    .band-cta {
        padding: var(--space-8) 0;
    }

    .hero-title {
        font-size: var(--font-3xl);
    }

    .pain {
        grid-template-columns: 1fr;
        gap: var(--space-2);
    }
}

/*
 * 页头窄屏换行。原来固定 60px 高、不换行，加上右上角账号区之后
 * 右侧被挤出视口，整页出现横向滚动条。
 * 放在这里而不是某个页面的样式里——这是页头自己的事，全站都受用。
 */
@media (max-width: 720px) {
    .header-inner {
        height: auto;
        flex-wrap: wrap;
        gap: var(--space-3);
        padding-top: var(--space-3);
        padding-bottom: var(--space-3);
    }

    /* 「浙江省」是装饰信息，窄屏让位给学段切换与账号区 */
    .header-inner .region-tag {
        display: none;
    }
}

/* ==========================================================
 * 学习交流区
 * 帖子是逐字读的长文本，所以详情页套 .prose-card 收窄；
 * 列表是扫一眼的卡片，跟着外壳铺开。
 * ========================================================== */
.post-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(420px, 100%), 1fr));
    gap: var(--space-5);
}

.post-card {
    display: flex;
    flex-direction: column;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: inherit;
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
    /* 和学科卡片同一种「排进来」的出场，两页节奏一致 */
    animation: card-rise var(--dur-slow) var(--ease) both;
}

.post-card:has(.post-main):hover {
    transform: translateY(-2px);
    border-color: var(--primary-border);
    box-shadow: var(--shadow);
}

/* 卡片上半部分是链接，底部一行（点赞在那儿）留在链接外面 */
.post-main {
    display: flex;
    flex-direction: column;
    flex: 1;
    color: inherit;
}

/* 头一行：谁在说话。头像是最快的识别线索，所以放在标题之上 */
.post-top {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.avatar {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--white);
    font-size: var(--font-md);
    font-weight: 600;
    background: var(--primary);
}

.post-who {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.35;
}

.post-who b {
    font-size: var(--font-base);
    font-weight: 500;
}

.post-time {
    font-size: var(--font-xs);
    color: var(--text-muted);
}

/* 话题标签：话题色只上在文字与极浅的底色上，不做成实心色块 */
.topic-pill {
    margin-left: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px var(--space-3);
    border-radius: var(--radius-pill);
    border: 1px solid var(--border);
    background: var(--bg-subtle);
    color: var(--topic, var(--text-secondary));
    font-size: var(--font-xs);
    white-space: nowrap;
}

.post-card-title {
    margin: 0 0 var(--space-3);
    font-size: var(--font-xl);
    color: var(--text);
    line-height: 1.5;
    transition: color var(--dur) var(--ease);
}

.post-card:hover .post-card-title {
    color: var(--primary);
}

/*
 * 摘要压到三行。卡片是扫一眼用的，长短不一的摘要会把一行卡片撑得高低不齐；
 * 想看全文点进去就是了。
 */
.post-card-summary {
    margin: 0 0 var(--space-4);
    color: var(--text-secondary);
    line-height: 1.8;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 底部一行：热度、评论、点赞在左，「读一读」在右，贴卡片底 */
.post-foot {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: auto;
    padding-top: var(--space-3);
    border-top: 1px dashed var(--border);
    font-size: var(--font-sm);
}

.post-go {
    margin-left: auto;
    color: var(--primary);
}

/* ---------- 热度与点赞 ---------- */
/*
 * 热度是算出来的（点赞 + 评论×2），所以给它一点暖色——它表示「值得先看」，
 * 正是暖橙负责的那件事；评论与点赞是中性的事实，保持灰色。
 */
.hot-badge {
    color: var(--accent-dark);
    font-weight: 600;
    white-space: nowrap;
}

.post-count,
.mod-stat {
    color: var(--text-muted);
    white-space: nowrap;
}

/* 「最近活跃」时间：大众交流区的排序键，中性灰——它是事实而不是优先级信号 */
.active-time {
    color: var(--text-muted);
    font-size: var(--font-xs);
    white-space: nowrap;
}

/* 点赞按钮：没赞过是灰的描边，赞过了整枚上暖橙 */
.like-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--white);
    color: var(--text-muted);
    font-family: inherit;
    font-size: var(--font-sm);
    cursor: pointer;
    transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease),
                color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.like-btn:hover {
    border-color: var(--accent-border);
    color: var(--accent-dark);
}

.like-btn:active {
    transform: scale(.94);
}

.like-btn.liked {
    border-color: var(--accent-border);
    background: var(--accent-light);
    color: var(--accent-dark);
    font-weight: 600;
}

.like-btn[disabled] {
    opacity: .6;
    cursor: default;
}

.like-icon {
    /* 没赞过时压成灰调，赞过了才还原成彩色的手 */
    filter: grayscale(1);
    opacity: .7;
}

.like-btn.liked .like-icon {
    filter: none;
    opacity: 1;
}

.post-go i {
    font-style: normal;
    display: inline-block;
    transition: transform var(--dur) var(--ease);
}

.post-card:hover .post-go i {
    transform: translateX(4px);
}

/* 元信息一行排开，用细分隔点而不是竖线，视觉更轻 */
.post-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    font-size: var(--font-sm);
    color: var(--text-muted);
    margin-top: auto;
}

.post-meta i {
    font-style: normal;
    color: var(--border-strong);
}

.post-count {
    color: var(--text-muted);
}

/* ---------- 交流区台头 ---------- */
/*
 * 与学科总览的学习台是同一套语言（极浅底 + 一角光晕 + 右侧一个动作），
 * 两页之间来回切不会觉得是两个网站。
 */
.forum-hero {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-6);
    margin-bottom: var(--space-6);
    padding: var(--space-8);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-lg);
    background: var(--primary-light);
}

.forum-hero::after {
    content: '';
    position: absolute;
    /* 同上：装饰光晕压在内容下面，否则「写一篇」按钮会被蒙掉一层 */
    z-index: 0;
    top: -140px;
    right: -80px;
    width: 320px;
    height: 320px;
    border-radius: 50%;
    background: var(--white);
    opacity: .5;
    pointer-events: none;
}

.forum-hero-main {
    position: relative;
    z-index: 1;
    max-width: var(--measure-max);
}

.forum-hero-badge {
    display: inline-block;
    margin-bottom: var(--space-3);
    padding: 2px var(--space-3);
    border-radius: var(--radius-pill);
    background: var(--white);
    border: 1px solid var(--primary-border);
    color: var(--primary);
    font-size: var(--font-xs);
}

.forum-hero-title {
    margin: 0 0 var(--space-2);
    font-size: var(--font-4xl);
    font-weight: 600;
    line-height: 1.4;
}

.forum-hero-sub {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-base);
    line-height: 1.8;
}

.forum-hero-stat {
    margin-top: var(--space-3);
    color: var(--primary);
    font-size: var(--font-sm);
    font-weight: 500;
}

.forum-hero-stat:empty {
    display: none;
}

.forum-hero .btn {
    position: relative;
    z-index: 1;
    flex-shrink: 0;
}

/* tab 与话题筛选并排一行，占的高度只有原来的一半 */
.forum-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
    margin-bottom: var(--space-5);
}

.forum-bar .tabs {
    margin-bottom: 0;
}

.forum-bar .chip-row {
    margin-bottom: 0;
}

/* ---------- 首页：一个话题一个小模块 ---------- */
/*
 * 模块做小是为了**一屏能看到全部话题**，所以模块里只放标题与三个数字，
 * 不放摘要——塞进摘要就又变回长列表了。
 * 模块标题只在图标上用话题色，名字与篇数保持中性：
 * 六个模块六种颜色的标题会让整页看起来像调色板。
 */
.module-board {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
    gap: var(--space-5);
    align-items: start;
}

.topic-module {
    display: flex;
    flex-direction: column;
    padding: var(--space-5);
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
    animation: card-rise var(--dur-slow) var(--ease) both;
}

.topic-module:hover {
    border-color: var(--topic, var(--primary));
    box-shadow: var(--shadow);
}

.mod-head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: 0 0 var(--space-3);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--border);
    font-size: var(--font-lg);
    font-weight: 600;
}

.mod-icon {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    border-radius: var(--radius-sm);
    /* 极浅底 + 一圈话题色描边，色块只有 30 像素见方 */
    background: var(--bg-subtle);
    box-shadow: inset 0 0 0 1px var(--topic, var(--border));
    font-size: var(--font-md);
}

.mod-count {
    margin-left: auto;
    font-size: var(--font-sm);
    font-weight: 400;
    color: var(--text-muted);
}

.mod-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.mod-post {
    padding: var(--space-2) 0;
}

.mod-post + .mod-post {
    border-top: 1px dashed var(--border);
}

.mod-title {
    display: block;
    font-size: var(--font-base);
    line-height: 1.6;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color var(--dur) var(--ease);
}

.mod-title:hover {
    color: var(--primary);
}

.mod-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-1);
    font-size: var(--font-xs);
}

/* 作者被挤到最右，宽度不够时先省略它——数字比名字重要 */
.mod-author {
    margin-left: auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-muted);
}

.mod-meta .like-btn {
    padding: 0 var(--space-2);
    font-size: var(--font-xs);
}

.mod-empty {
    margin: 0;
    padding: var(--space-4) 0;
    color: var(--text-muted);
    font-size: var(--font-sm);
}

/* 「查看全部」贴模块底部，模块高低不齐时这一行仍然对齐 */
.mod-more {
    margin-top: auto;
    padding-top: var(--space-3);
    border: 0;
    background: none;
    text-align: left;
    font-family: inherit;
    font-size: var(--font-sm);
    color: var(--primary);
    cursor: pointer;
}

.mod-more:hover {
    text-decoration: underline;
}

/* 长得像链接的按钮：行内动作用它，不必为了可点而做成一个方块 */
.link-btn {
    border: 0;
    background: none;
    padding: 0;
    font-family: inherit;
    font-size: inherit;
    color: var(--primary);
    cursor: pointer;
}

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

/* 空状态：给图标、给说明、给一个能立刻做的动作，别只写「暂无数据」 */
.forum-empty-state {
    padding: var(--space-10) var(--space-6);
    text-align: center;
    background: var(--white);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-lg);
}

.forum-empty-state .empty-icon {
    font-size: var(--font-5xl);
    line-height: 1.4;
}

.forum-empty-state p {
    margin: var(--space-2) auto var(--space-5);
    max-width: 30em;
    color: var(--text-secondary);
}

/* 详情页的作者行，与列表卡片的头一行是同一种写法 */
.post-byline {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

/* 话题标签在列表卡片里靠右（那里右边没别的），详情页紧跟昵称即可 */
.post-byline .topic-pill {
    margin-left: 0;
}

.byline-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

/* ---------- 角色徽标 ---------- */
/*
 * 管理员用中性深灰、学习委员用主色浅底：这是身份信息，按全站约定走靛蓝一系，
 * 不用暖橙——暖橙留给学习优先级与进度。
 */
.role-badge {
    margin-left: var(--space-2);
    padding: 0 var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--font-xs);
    font-weight: 400;
    white-space: nowrap;
}

.role-committee {
    background: var(--primary-light);
    color: var(--primary-dark);
    border: 1px solid var(--primary-border);
}

.role-admin {
    background: var(--bg-subtle);
    color: var(--text-secondary);
    border: 1px solid var(--border-strong);
}

/* ---------- 学科主页的名言 ---------- */
/*
 * 摆在学科台头右侧，跟着外壳走。**只是一句话，不做成卡片**——
 * 它是顺带看一眼的东西，做成卡片就和下面的内容抢注意力了。
 */
.subject-quote {
    margin-left: auto;
    max-width: 42em;
    padding-left: var(--space-5);
    border-left: 3px solid var(--primary-border);
}

.subject-quote:empty {
    display: none;
}

.quote-text {
    margin: 0;
    font-size: var(--font-md);
    line-height: 1.8;
}

.quote-source {
    margin-left: var(--space-2);
    color: var(--text-muted);
    font-size: var(--font-sm);
    white-space: nowrap;
}

.quote-note {
    margin: var(--space-1) 0 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.7;
}

/* ---------- 交流区首页的三个区 ---------- */
/*
 * 置顶 → 热门区 → 大众交流区，三区各回答一个问题：
 * 该先看什么、大家在看什么、我想找哪一类。
 * 区与区之间靠标题行分隔，不加分隔线——标题本身已经够分了。
 */
.zone + .zone {
    margin-top: var(--space-10);
}

.zone-head {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-4);
}

.zone-icon {
    font-size: var(--font-xl);
    line-height: 1;
}

.zone-name {
    margin: 0;
    font-size: var(--font-2xl);
    font-weight: 600;
}

.zone-note {
    color: var(--text-muted);
    font-size: var(--font-sm);
}

/* ---- 置顶区 ---- */
/*
 * 置顶卡片是全站唯一带暖橙底的成块元素：置顶就那么两三条，
 * 面积小、又必须一眼认出来，正是暖橙该出现的地方。
 */
.pin-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: var(--space-4);
}

.pin-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-5);
    border: 1px solid var(--accent-border);
    border-radius: var(--radius-lg);
    background: var(--accent-light);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.pin-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow);
}

.pin-flag {
    align-self: flex-start;
    padding: 1px var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--accent-dark);
    font-size: var(--font-xs);
    font-weight: 600;
}

.pin-title {
    font-size: var(--font-lg);
    font-weight: 600;
    line-height: 1.5;
}

.pin-summary {
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.8;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.pin-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-1);
    font-size: var(--font-xs);
    color: var(--text-muted);
}

/* 列表与详情页里的置顶标记 */
.tag-pin {
    background: var(--accent-light);
    color: var(--accent-dark);
    border-color: var(--accent-border);
}

/* ---- 热门区 ---- */
.rank-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
    gap: var(--space-4);
}

.rank-card {
    display: flex;
    flex-direction: column;
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--white);
    box-shadow: var(--shadow-sm);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
    animation: card-rise var(--dur-slow) var(--ease) both;
}

.rank-card:hover {
    transform: translateY(-2px);
    border-color: var(--primary-border);
    box-shadow: var(--shadow);
}

.rank-main {
    display: flex;
    gap: var(--space-4);
    flex: 1;
    color: inherit;
}

/* 名次做得大：这一区的组织方式就是名次，它得是第一眼看到的东西 */
.rank-no {
    flex-shrink: 0;
    width: 32px;
    font-size: var(--font-4xl);
    font-weight: 600;
    line-height: 1;
    color: var(--border-strong);
}

.rank-no-top {
    color: var(--accent);
}

.rank-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.rank-title {
    font-size: var(--font-md);
    font-weight: 600;
    line-height: 1.5;
    transition: color var(--dur) var(--ease);
}

.rank-card:hover .rank-title {
    color: var(--primary);
}

.rank-summary {
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.7;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rank-foot {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px dashed var(--border);
    font-size: var(--font-xs);
}

.rank-foot .like-btn {
    padding: 0 var(--space-2);
    font-size: var(--font-xs);
}

.rank-author {
    margin-left: auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-muted);
}

/* 详情页正文下面的一行：点赞 + 热度 + 评论数 */
.post-actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
    font-size: var(--font-sm);
}

.post-actions .like-btn {
    padding: var(--space-2) var(--space-4);
    font-size: var(--font-base);
}

/* 编辑器里的字数计数：写到一半才发现超了很挫败 */
.field-count {
    display: block;
    margin-top: var(--space-1);
    text-align: right;
    font-size: var(--font-xs);
    color: var(--text-muted);
}

/* 列表骨架里的头像与作者名占位 */
.sk-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
}

.sk-name {
    width: 120px;
}

/* 下架占位：中性灰底，不用红色。这不是错误，是作者的正常操作 */
.post-removed {
    padding: var(--space-4);
    border-radius: var(--radius-sm);
    background: var(--bg-subtle);
    border-left: 3px solid var(--border-strong);
    color: var(--text-muted);
    font-size: var(--font-sm);
    line-height: 1.8;
}

.post-removed-lg {
    padding: var(--space-6);
    font-size: var(--font-base);
    text-align: center;
}

.post-card-removed {
    background: var(--bg);
    box-shadow: none;
}

/* 作者/管理员视角下已下架的帖子：整卡压暗一档，与在线的区分开 */
.post-card-dim {
    background: var(--bg);
}

.post-card-dim .post-card-title,
.post-card-dim .post-card-summary {
    color: var(--text-muted);
}

.tag-removed {
    background: var(--bg-subtle);
    color: var(--text-muted);
    border-color: var(--border-strong);
}

/* 「我的评论」卡片：自己的话在上，原帖挂在下面 */
.comment-card .comment-body {
    margin: 0 0 var(--space-3);
    color: var(--text);
    line-height: 1.9;
}

.comment-target {
    display: block;
    margin-top: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-sm);
    background: var(--bg-subtle);
    color: var(--text-secondary);
    font-size: var(--font-sm);
    text-decoration: none;
    line-height: 1.7;
}

.comment-target:hover {
    color: var(--primary);
}

.comment-target-label {
    color: var(--text-muted);
    margin-right: var(--space-2);
}

/* ---------- 发帖表单 ---------- */
.post-editor {
    margin-bottom: var(--space-5);
}

.post-editor textarea,
.comment-form textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    font-size: var(--font-base);
    font-family: inherit;
    line-height: 1.8;
    color: var(--text);
    background: var(--white);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    resize: vertical;
}

.post-editor textarea:focus,
.comment-form textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-light);
}

.editor-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
}

/* 话题选择：小药丸，选中才上主色 */
.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-5);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-sm);
    font-family: inherit;
    color: var(--text-secondary);
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    padding: 5px 14px;
    cursor: pointer;
    transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease),
                background var(--dur) var(--ease);
}

.chip:hover {
    border-color: var(--border-strong);
}

/* 未选中时话题色只上在图标上（几个像素），选中了才整枚上色 */
.chip .chip-icon {
    font-size: var(--font-base);
    line-height: 1;
}

.chip.active {
    color: var(--white);
    background: var(--topic, var(--primary));
    border-color: var(--topic, var(--primary));
}

/* ---------- 详情页 ---------- */
.crumb {
    margin: 0 0 var(--space-4);
    font-size: var(--font-sm);
}

.crumb a {
    color: var(--text-secondary);
    text-decoration: none;
}

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

.post-title {
    margin: 0 0 var(--space-4);
    font-size: var(--font-3xl);
    line-height: 1.45;
}

/* 正文行距放大一档：这是要逐段读的内容 */
.post-content {
    margin-top: var(--space-5);
    line-height: 1.95;
    color: var(--text);
}

.post-content p {
    margin: 0 0 var(--space-4);
}

/* 删除按钮做得克制：低频且不可逆的操作，不该抢视觉 */
.post-del {
    margin-left: auto;
    font-size: var(--font-sm);
    font-family: inherit;
    color: var(--text-muted);
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    padding: 2px 12px;
    cursor: pointer;
}

.post-del:hover {
    color: var(--danger);
    border-color: var(--danger-border);
    background: var(--danger-light);
}

/* ---------- 评论 ---------- */
.comment-h2 {
    margin: 0 0 var(--space-5);
    font-size: var(--font-xl);
}

.comment-h2 span {
    color: var(--text-muted);
    font-weight: 400;
}

.comment-list {
    margin: 0 0 var(--space-5);
    padding: 0;
    list-style: none;
}

/* 头像在左、内容在右缩进对齐，一眼看得出有几个人在说话 */
.comment-item {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-4) 0;
    border-bottom: 1px solid var(--border);
}

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

.avatar-sm {
    width: 30px;
    height: 30px;
    font-size: var(--font-sm);
}

.comment-item:first-child {
    padding-top: 0;
}

.comment-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    font-size: var(--font-sm);
}

.comment-author {
    color: var(--text);
    font-weight: 500;
}

.comment-time {
    color: var(--text-muted);
}

.comment-mine {
    padding: 1px 8px;
}

.comment-item .comment-body {
    margin: 0;
    color: var(--text-secondary);
    line-height: 1.9;
}

.comment-form {
    margin-top: var(--space-5);
}

.comment-form .btn {
    margin-top: var(--space-3);
}

.comment-login {
    margin: var(--space-5) 0 0;
    font-size: var(--font-sm);
}

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

/* ---------- 学科总览页的热议榜 ---------- */
/*
 * 做成「一张主卡 + 一列榜单」而不是五个等权的条目：
 * 谁最热就让它占大位置，剩下的紧凑排一列，主次一眼看得出来，
 * 也比五条一样宽的行有看头。
 * 上面的学科封面是白卡片，这里的主卡走极浅主色底 + 一个巨大的 ghost 数字，
 * 两段内容一眼分得开，不会看成同一片卡片墙。
 */
.forum-board {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

/* ---- 左边的主卡：本周最热的那一篇 ---- */
.fb-feature {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-6);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-lg);
    background: var(--primary-light);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.fb-feature:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow);
}

/* 巨大的 ghost 数字：装饰，压在内容下面 */
.fb-feature::after {
    content: '1';
    position: absolute;
    z-index: 0;
    right: var(--space-4);
    bottom: -28px;
    font-size: 120px;
    font-weight: 700;
    line-height: 1;
    color: var(--white);
    opacity: .6;
    pointer-events: none;
}

.fb-feature > * {
    position: relative;
    z-index: 1;
}

.fb-flag {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 1px var(--space-3);
    border-radius: var(--radius-pill);
    background: var(--white);
    color: var(--accent-dark);
    font-size: var(--font-xs);
    font-weight: 600;
}

.fb-title {
    margin: 0;
    font-size: var(--font-2xl);
    font-weight: 600;
    line-height: 1.5;
}

.fb-feature:hover .fb-title {
    color: var(--primary-dark);
}

.fb-summary {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.8;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.fb-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
    font-size: var(--font-xs);
    color: var(--text-secondary);
}

/* ---- 右边的榜单：2~5 名 + 一格「我也写一篇」 ---- */
.fb-list {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--white);
    overflow: hidden;
}

.fb-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    transition: background var(--dur) var(--ease), padding-left var(--dur) var(--ease);
}

.fb-row + .fb-row {
    border-top: 1px solid var(--border);
}

.fb-row:hover {
    background: var(--bg);
    /* 往右让一点，像是被「挑出来」了 */
    padding-left: var(--space-5);
}

.fb-no {
    flex: none;
    width: 18px;
    color: var(--text-muted);
    font-size: var(--font-sm);
    font-weight: 600;
    text-align: center;
}

.fb-row-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--font-base);
}

.fb-row:hover .fb-row-title {
    color: var(--primary);
}

.fb-row-hot {
    flex: none;
    color: var(--accent-dark);
    font-size: var(--font-xs);
    font-weight: 600;
    white-space: nowrap;
}

/* 最后一格是动作，不是帖子：虚线上边 + 主色文字，一眼分得开 */
.fb-write {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-4);
    border-top: 1px dashed var(--border-strong);
    color: var(--primary);
    font-size: var(--font-base);
    transition: background var(--dur) var(--ease);
}

.fb-write:hover {
    background: var(--primary-light);
}

/* 窄屏两栏并一栏 */
@media (max-width: 900px) {
    .forum-board {
        grid-template-columns: 1fr;
    }
}
/* ---------- 右上角账号区 ---------- */
.account {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}

/* 「登录 / 注册」是身份入口，用靛蓝而不是暖橙——暖橙留给学习优先级 */
.account-login {
    font-size: var(--font-sm);
    color: var(--primary);
    background: var(--primary-light);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-pill);
    padding: 4px 14px;
    text-decoration: none;
    white-space: nowrap;
}

.account-login:hover {
    background: var(--white);
}

.account-name {
    font-size: var(--font-sm);
    color: var(--text-secondary);
    max-width: 8em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.account-logout {
    font-size: var(--font-sm);
    font-family: inherit;
    color: var(--text-muted);
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    padding: 3px 12px;
    cursor: pointer;
    white-space: nowrap;
}

.account-logout:hover {
    color: var(--text);
    border-color: var(--border-strong);
}

/* 管理员的「清缓存」：是个动作而不是学习优先级，所以走靛蓝一系、不用暖橙。
   与「退出」同一个药丸形状，靠颜色区分主次——退出是中性灰、这个是主色浅底。 */
.account-cache {
    font-size: var(--font-sm);
    font-family: inherit;
    color: var(--primary);
    background: var(--primary-light);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-pill);
    padding: 3px 12px;
    cursor: pointer;
    white-space: nowrap;
}

.account-cache:hover:not(:disabled) {
    background: var(--white);
}

/* 清理中与刚清完这两段是禁用的（结果要停一下让人看清），
   但按钮上写的是「清理中…」「已清 N 项」，所以不能压成看不见的灰 */
.account-cache:disabled {
    cursor: default;
    opacity: 0.75;
}

/* ---------- 登录 / 注册页 ---------- */
/* 表单是逐字填的短内容，和长正文一样要收窄，但比正文更窄一档 */
.auth-card {
    max-width: 460px;
    margin: var(--space-8) auto;
}

/* 表单整体居中排布，tab 跟着标题一起居中，不然左对齐的 tab 会把居中的标题拽偏 */
.auth-card .tabs {
    /* .tabs 是 inline-flex，justify-content 管不到它自身的位置；
       按内容取宽再左右 auto 才是把这枚药丸整体居中 */
    display: flex;
    width: fit-content;
    margin: 0 auto var(--space-5);
}

.auth-head {
    text-align: center;
    margin-bottom: var(--space-5);
}

.auth-head h1,
.auth-head h2 {
    margin: 0 0 var(--space-2);
    font-size: var(--font-2xl);
}

.auth-head p {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.7;
}

.auth-field {
    margin-bottom: var(--space-4);
}

.auth-field label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-sm);
    color: var(--text-secondary);
}

/* 输入框在 app.css 里只覆盖了 text/number/select，登录页还要 email/password */
.auth-field input {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    font-size: var(--font-base);
    font-family: inherit;
    color: var(--text);
    background: var(--white);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
}

.auth-field input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-light);
}

/* 验证码：输入框 + 发送按钮同一行 */
.auth-code-row {
    display: flex;
    gap: var(--space-2);
}

.auth-code-row input {
    flex: 1;
    min-width: 0;
}

.auth-code-row button {
    flex-shrink: 0;
    white-space: nowrap;
}

.auth-actions {
    margin-top: var(--space-5);
}

.auth-actions .btn {
    width: 100%;
    justify-content: center;
}

/* 现在只剩「忘记密码？」一个链接，居中比贴边好看；它隐藏时整行不占位 */
.auth-links {
    margin-top: var(--space-4);
    display: flex;
    justify-content: center;
    font-size: var(--font-sm);
}

.auth-links:empty {
    margin-top: 0;
}

.auth-links a {
    color: var(--primary);
    text-decoration: none;
    cursor: pointer;
}

.auth-links a:hover {
    text-decoration: underline;
}

/* 提示条：成功走绿、失败走红，都是浅底 + 左边线那一套注解块样式 */
.auth-msg {
    margin-top: var(--space-4);
    padding: 10px 14px;
    border-radius: var(--radius-sm);
    font-size: var(--font-sm);
    line-height: 1.7;
}

.auth-msg-error {
    color: var(--danger-dark);
    background: var(--danger-light);
    border-left: 3px solid var(--danger);
}

.auth-msg-ok {
    color: var(--success-dark);
    background: var(--success-light);
    border-left: 3px solid var(--success);
}


.region-tag {
    font-size: var(--font-sm);
    color: var(--text-secondary);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    padding: 3px 12px;
    white-space: nowrap;
}

/*
 * 长正文 / 题干这类要逐字读的内容，单独收到可读行宽内。
 * 外壳铺满是为了让列表多排几列，正文跟着铺满反而没人读得下去
 * （1872px 宽一行装 90 多个汉字，眼睛找不到下一行的行首）。
 * 卡片本身收窄而不是卡片里的文字收窄，这样右边留白在卡片外，看着是刻意的一栏文档。
 */
.prose-card {
    max-width: calc(var(--measure-max) + var(--space-6) * 2);
    /* 外壳宽度跟着视口走之后，宽屏上收窄剩下的空白要落在两侧而不是全堆在右边：
       不居中的话 2560 的屏上整篇正文贴着左边缘、右边空出近千像素，看着像没加载完 */
    margin-inline: auto;
}

/* 例外：左栏 + 右栏版式里的正文**不居中**（学科面板的 .panel-card、练习页的题目卡）。
   左边紧挨着选择栏，居中会在栏与正文之间挖出一个洞，正文的左边缘也就和同栏里
   其它块（面包屑、组卷条、卷说明）对不齐；
   侧栏 + 紧贴着的一栏正文本来就是文档站的惯例，留白落在右侧才对。 */
.subject-layout .prose-card {
    margin-inline: 0;
}

/* ---------- 布局 ---------- */
.container {
    max-width: var(--layout-max);
    margin: 0 auto;
    /* 上下固定、左右百分比：百分比内边距是按宽度算的，四边写同一个值会撑出一大片空白 */
    padding: var(--space-6) var(--layout-gutter);
    width: 100%;
    flex: 1;
}


.page-title {
    font-size: var(--font-4xl);
    font-weight: 600;
    margin: 0 0 4px;
}

.page-desc {
    color: var(--text-secondary);
    margin: 0 0 20px;
}

.card {
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.card-body {
    padding: var(--space-6);
}

/* ---------- 页内切换标签 ---------- */
.tabs {
    display: inline-flex;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 4px;
    margin-bottom: 20px;
}

.tabs button {
    border: 0;
    background: transparent;
    padding: 7px 22px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--font-md);
    color: var(--text-secondary);
    font-family: inherit;
}

.tabs button.active {
    background: var(--primary);
    color: var(--white);
    font-weight: 500;
}

/* ---------- 学科卡片 ---------- */
.subject-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-5);
}

.subject-card {
    position: relative;
    overflow: hidden;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.subject-card:hover {
    transform: translateY(-3px);
    /* 边框跟着学科色走，一眼认出是哪一科；没有 --subject 的场合退回主色 */
    border-color: var(--subject, var(--primary));
    box-shadow: var(--shadow-lg);
}

.subject-card h3 {
    margin: 0;
    font-size: var(--font-xl);
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.subject-icon {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--radius);
    display: grid;
    place-items: center;
    font-size: var(--font-xl);
    font-weight: 600;
    color: var(--white);
    background: var(--subject, var(--primary));
    transition: transform var(--dur) var(--ease);
}

.subject-card:hover .subject-icon {
    transform: rotate(-4deg) scale(1.06);
}

.subject-meta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    font-size: var(--font-sm);
    color: var(--text-secondary);
}

.subject-desc {
    color: var(--text-secondary);
    font-size: var(--font-base);
    flex: 1;
    margin: 0;
}

.subject-actions {
    display: flex;
    gap: 8px;
}

/* ---------- 按钮 ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 9px var(--space-4);
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--white);
    color: var(--text);
    cursor: pointer;
    font-size: var(--font-base);
    font-family: inherit;
    font-weight: 500;
    transition: background .15s ease, border-color .15s ease, color .15s ease, transform .1s ease;
    white-space: nowrap;
}

.btn:hover {
    border-color: var(--primary);
    color: var(--primary);
    background: var(--primary-light);
}

/* 按下时轻微下沉，给学生一点操作反馈 */
.btn:active {
    transform: translateY(1px);
}

.btn-primary {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--white);
    box-shadow: 0 1px 2px rgba(79, 70, 229, .25);
}

.btn-primary:hover {
    background: var(--primary-dark);
    border-color: var(--primary-dark);
    color: var(--white);
}

.btn:disabled {
    opacity: .55;
    cursor: not-allowed;
}

.btn-lg {
    padding: 12px var(--space-6);
    font-size: var(--font-md);
}

/* ---------- 标签 ---------- */
/*
 * 标签一律做成胶囊。重要度用颜色分级，学生扫一眼就能排优先级：
 *   红（必考） > 橙（必会 / 教材重点） > 黄（高频） > 绿（已完成）
 */
.tag {
    display: inline-block;
    padding: 2px 10px;
    border-radius: var(--radius-pill);
    font-size: var(--font-sm);
    background: var(--bg-subtle);
    color: var(--text-secondary);
    border: 1px solid var(--border);
    white-space: nowrap;
}

.tag-must {
    background: var(--danger-light);
    color: var(--danger-dark);
    border-color: var(--danger-border);
}

.tag-high {
    background: var(--warning-light);
    color: var(--accent-dark);
    border-color: var(--warning-border);
}

/* 必会 / 教材重点用暖橙——全站最需要被看见的标记 */
.tag-core {
    background: var(--accent-light);
    color: var(--accent-dark);
    border-color: var(--accent-border);
    font-weight: 500;
}

.tag-ok {
    background: var(--success-light);
    color: var(--success-dark);
    border-color: var(--success-border);
}

/* 主色标签：身份 / 分值一类的信息，不参与「重要度」那套颜色分级 */
.tag-primary {
    background: var(--primary-light);
    color: var(--primary-dark);
    border-color: var(--primary-border);
    font-weight: 500;
}

/* ---------- 知识点树布局 ---------- */
.split {
    display: grid;
    grid-template-columns: 340px 1fr;
    gap: 16px;
    align-items: start;
}

.tree {
    max-height: calc(100vh - 160px);
    overflow-y: auto;
    padding: 8px;
}

.tree-node > .tree-label {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    user-select: none;
}

.tree-node > .tree-label:hover {
    background: var(--bg);
}

.tree-node > .tree-label.selected {
    background: var(--primary-light);
    color: var(--primary);
    font-weight: 500;
}

.tree-toggle {
    width: 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: var(--font-xs);
    flex-shrink: 0;
}

.tree-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 树上的年级标记：.tag 的修饰类，压小一档并保持中性，不与重要度标签抢注意力 */
.tree-grade {
    flex-shrink: 0;
    font-size: var(--font-xs);
    color: var(--text-muted);
}

.tree-node > .tree-label.selected .tree-grade {
    background: var(--white);
}

.tree-children {
    padding-left: 18px;
    border-left: 1px dashed var(--border);
    margin-left: 14px;
}

.tree-children.collapsed {
    display: none;
}

/* ---------- 知识点详情 ---------- */
.detail-head {
    border-bottom: 1px solid var(--border);
    padding-bottom: 16px;
    margin-bottom: 16px;
}

.detail-head h2 {
    margin: 0 0 8px;
    font-size: var(--font-3xl);
}

.detail-meta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

.summary-box {
    background: var(--primary-light);
    border-left: 3px solid var(--primary);
    padding: 12px 16px;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    margin-bottom: 20px;
    color: var(--text-secondary);
}

/* Markdown 正文 */
/* 知识点正文是全站最长的连续中文，行距再放宽一点 */
.markdown {
    line-height: 1.8;
}

.markdown h2 {
    font-size: var(--font-xl);
    margin: 24px 0 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}

.markdown h3 {
    font-size: var(--font-lg);
    margin: 18px 0 8px;
}

.markdown p {
    margin: 10px 0;
}

.markdown ul, .markdown ol {
    margin: 10px 0;
    padding-left: 24px;
}

.markdown li {
    margin: 4px 0;
}

.markdown code {
    background: var(--bg-subtle);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    font-family: "SFMono-Regular", Consolas, monospace;
    font-size: var(--font-base);
    color: var(--danger-dark);
}

.markdown blockquote {
    margin: 12px 0;
    padding: 8px 16px;
    background: var(--warning-light);
    border-left: 3px solid var(--warning);
    color: var(--text-secondary);
}

.markdown blockquote p {
    margin: 4px 0;
}

.markdown table {
    border-collapse: collapse;
    width: 100%;
    margin: 12px 0;
    font-size: var(--font-base);
}

.markdown th, .markdown td {
    border: 1px solid var(--border);
    padding: 8px 12px;
    text-align: left;
}

.markdown th {
    background: var(--bg);
    font-weight: 600;
}

.markdown strong {
    color: var(--text);
}

/* ---------- 筛选栏 ---------- */
/* 标题行：左侧标题与说明，右侧学科选择 */
.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
}

/* 学科是页面级的上下文，比普通筛选项更醒目 */
.subject-picker {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    background: var(--primary-light);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius);
    flex-shrink: 0;
}

.subject-picker label {
    font-size: var(--font-base);
    font-weight: 500;
    color: var(--primary);
    white-space: nowrap;
}

.subject-picker select {
    min-width: 160px;
    padding: 7px 12px;
    font-size: var(--font-lg);
    font-weight: 600;
    color: var(--primary);
    border-color: var(--primary-border);
    cursor: pointer;
}

.subject-picker select:hover {
    border-color: var(--primary);
}

.filters {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: 16px;
}

.filters label {
    font-size: var(--font-base);
    color: var(--text-secondary);
}

input[type="text"], input[type="number"], select {
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: var(--font-base);
    font-family: inherit;
    color: var(--text);
    background: var(--white);
    outline: none;
}

input[type="text"]:focus, input[type="number"]:focus, select:focus {
    border-color: var(--primary);
}

/* ---------- 单词表 ---------- */
.word-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 12px;
}

/*
 * 纵向 flex：栅格本来就把同一行的卡片拉成等高，但标记按钮紧跟正文，
 * 释义长短不同就导致按钮高低不齐（一行四张卡时相差七十来像素）。
 * 用 margin-top:auto 把 .word-marks 压到卡片底部，一行卡片的按钮就对齐了。
 */
.word-card {
    display: flex;
    flex-direction: column;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
}

.head-tags {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.word-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.word-text {
    font-size: var(--font-2xl);
    font-weight: 600;
}

.word-phonetic {
    color: var(--text-muted);
    font-size: var(--font-base);
}

/* 高频词背诵表的序号，跟纸质表一一对应，方便对照 */
.word-rank {
    flex-shrink: 0;
    min-width: 34px;
    padding: 2px 6px;
    background: var(--primary-light);
    color: var(--primary);
    border-radius: var(--radius-sm);
    font-size: var(--font-sm);
    font-weight: 600;
    text-align: center;
}

/* 频次档色块条：既是分档概览，也是筛选入口 */
.band-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.band-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    font-size: var(--font-base);
    color: var(--text);
    cursor: pointer;
}

.band-chip:hover {
    border-color: var(--primary);
    color: var(--primary);
}

.band-chip b {
    font-size: var(--font-lg);
    color: var(--primary);
}

.band-chip.active {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--white);
}

.band-chip.active b {
    color: var(--white);
}

.word-meaning {
    margin: 8px 0 0;
}

.word-example {
    margin: 8px 0 0;
    padding-top: 8px;
    border-top: 1px dashed var(--border);
    font-size: var(--font-base);
    color: var(--text-secondary);
}

/* 读音按钮 */
.speak-btn {
    border: 0;
    background: transparent;
    cursor: pointer;
    font-size: var(--font-md);
    line-height: 1;
    padding: 2px 4px;
    border-radius: var(--radius-sm);
    opacity: .55;
}

.speak-btn:hover {
    opacity: 1;
    background: var(--primary-light);
}

/* 学习状态标记 */
.word-marks {
    display: flex;
    gap: 8px;
    /* 贴卡片底部，同一行卡片的按钮看起来一样齐 */
    margin-top: auto;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
}

.mark-btn {
    flex: 1;
    padding: 5px 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--text-secondary);
    cursor: pointer;
    font-size: var(--font-sm);
    font-family: inherit;
}

.mark-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
}

.mark-btn.active-known {
    background: var(--success-light);
    border-color: var(--success);
    color: var(--success);
    font-weight: 500;
}

/* 古诗文列表：正文较长，用更宽的栅格 */
/*
 * 古诗与文言文排成**一栏**，宽度按可读行宽（--measure-max）收。
 * 原来是 minmax(460px) 的多栏栅格：面板里两栏各 450px 上下，
 * 一篇文言文的原文 + 译文 + 考点全挤在这么窄的一条里，每行断七八个字，
 * 读起来很累。这类内容是要逐字读、逐句背的，跟知识点正文一样该走阅读列。
 * 字词是短词条，仍用多栏的 .word-grid。
 */
/*
 * 单栏、且**不额外收窄**：卡片内部已经是左右两栏，再按 --measure-max 收会让
 * 两栏各只剩五百来像素。宽度跟着外壳走，和顶部导航对齐。
 */
.text-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}

/* 诗文正文按原样保留换行 */
.verse {
    white-space: pre-line;
    /* 古诗文正文是背诵对象，比正文再大一档、行距更宽 */
    font-size: var(--font-lg);
    line-height: 2.05;
    color: var(--text);
    padding: 10px 12px;
    background: var(--bg);
    border-radius: var(--radius-sm);
}

.verse-inline {
    white-space: pre-line;
}

/* ---------- 古诗：左原文 / 右考点 ---------- */
.text-split {
    display: grid;
    grid-template-columns: 1.02fr 1fr;
    gap: var(--space-6);
    align-items: start;
    margin-top: var(--space-4);
}

/* 两栏之间一道浅分隔线，比纯靠间距更看得出是左右两块 */
.col-side {
    border-left: 1px solid var(--border);
    padding-left: var(--space-5);
}

/*
 * 诗句整块在左栏里居中，块内各行仍靠左对齐——栏宽放开后诗只占左半边，
 * 挤在栏的最左边会和右栏之间空出一大片。fit-content 让块宽等于最长的一行。
 */
.col-verse {
    display: flex;
    justify-content: center;
}

.verse-inner {
    width: fit-content;
    max-width: 100%;
}

/*
 * 诗句按诗的节奏排：比正文大一档、行距放宽、一句一行。
 * 词的长句（水调歌头有 57 字一句）会折行，用负值 text-indent 做悬挂缩进，
 * 折下来的部分让开一段，一眼能看出哪几行原本是同一句。
 */
.verse-inner .vline {
    margin: 0 0 var(--space-2);
    padding-left: var(--space-5);
    text-indent: calc(var(--space-5) * -1);
    font-size: var(--font-lg);
    line-height: 2.05;
}

/* ---------- 文言文：原文 / 译文逐段对照 ---------- */
.parallel {
    margin-top: var(--space-4);
}

.prow {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-5);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--bg-subtle);
}

.prow-head {
    padding: 0 0 var(--space-2);
    border-bottom: 2px solid var(--primary);
    font-size: var(--font-sm);
    font-weight: 600;
    color: var(--primary-dark);
}

.pcol {
    line-height: 1.95;
    min-width: 0;
}

.pcol .pline {
    margin: 0 0 var(--space-3);
}

.pcol .pline:last-child {
    margin-bottom: 0;
}

.pcol-t {
    color: var(--text-secondary);
}

/* ---------- 考点：分类成块、一条一行 ---------- */
/*
 * 一类考点动辄一两百字，铺成一行既读不下去也记不住。
 * 分类各自成块、块名带条数，块内一条一行、条与条留白。
 */
.kp-blocks {
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

.kp-group {
    margin: 0 0 var(--space-4);
}

.kp-group-title {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    padding-left: var(--space-2);
    border-left: 3px solid var(--primary);
    font-size: var(--font-base);
    font-weight: 600;
    color: var(--primary-dark);
}

.kp-count {
    font-size: var(--font-xs);
    font-weight: 400;
    color: var(--text-muted);
}

.kp-items {
    margin: 0;
    padding-left: var(--space-5);
    list-style: none;
}

.kp-items li {
    position: relative;
    margin-bottom: var(--space-2);
    line-height: 1.8;
    color: var(--text);
}

/* 自绘项目符号：用原生 list-style 时中文行高下圆点会偏上 */
.kp-items li::before {
    content: '';
    position: absolute;
    left: calc(var(--space-4) * -1);
    top: 11px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--primary-border);
}

.kp-items b {
    color: var(--primary-dark);
}

/* 条目又短又多的分组排两栏，一栏会空掉右半边 */
.kp-items-cols {
    columns: 2;
    column-gap: var(--space-6);
}

.kp-items-cols li {
    break-inside: avoid;
}

.kp-prose {
    margin: 0;
    padding-left: var(--space-2);
    line-height: 1.85;
    color: var(--text-secondary);
}

/* 要逐字背下来的那几条单独加底强调 */
.kp-group-recite {
    padding: var(--space-3) var(--space-4) var(--space-2);
    background: var(--primary-light);
    border-radius: var(--radius-sm);
}

.kp-group-recite .kp-items li {
    font-size: var(--font-md);
    line-height: 1.9;
}

.kp-group-recite .kp-items li::before {
    background: var(--primary);
}

/* 屏幕窄到排不下两栏时，左右版式退回上下排 */
@media (max-width: 1100px) {
    .text-split,
    .prow {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-3);
    }

    .col-verse {
        justify-content: flex-start;
    }

    .col-side {
        border-left: 0;
        border-top: 1px solid var(--border);
        padding-left: 0;
        padding-top: var(--space-4);
    }

    .prow-head {
        display: none;
    }

    .pcol-t {
        padding-left: var(--space-3);
        border-left: 2px solid var(--border);
    }
}

/* ---------- 古诗 / 文言文卡片：按长文本的节奏排 ---------- */
.text-card {
    padding: var(--space-6);
}

/* 篇名大一档，和正文拉开层级 */
.text-card .word-text {
    font-size: var(--font-2xl);
}

.text-card .item-meta {
    margin-top: var(--space-1);
}

.text-card .verse {
    margin-top: var(--space-4);
    padding: var(--space-4) var(--space-5);
}

/* 译文是整段白话，行距按长正文给，字号比原文小一档但不小于正文 */
.text-card .word-example {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    font-size: var(--font-md);
    line-height: 1.95;
}

/* 「译文」两个字单独占一行，长段落前面顶着个标签会把首行挤短 */
.text-card .word-example .label {
    display: block;
    margin-bottom: var(--space-1);
    color: var(--text-muted);
}

.text-card .key-points {
    margin-top: var(--space-4);
    padding: var(--space-3) var(--space-4);
}

.text-card .word-marks {
    margin-top: var(--space-5);
    padding-top: var(--space-4);
}

/* 诗文卡有一整行的宽度，标记按钮不必跟着拉长；给个自然宽度靠左放 */
.text-card .mark-btn {
    flex: 0 0 auto;
    min-width: 120px;
    padding: var(--space-1) var(--space-4);
}

/* 语文内容卡片：作者朝代等元信息与考点提示 */
.item-meta {
    color: var(--text-secondary);
    font-size: var(--font-base);
}

/*
 * 考点是**注解**，不是优先级标记。原来整块用暖橙——底色、描边、连正文都是橙的，
 * 一张卡里红色「常考必会」标签再叠一整块暖橙，盯久了刺眼；
 * 而且按配色约定暖橙留给学习优先级与进度，拿它铺大面积会把真正的重点淹掉。
 *
 * 改成与 .summary-box 同一套注解块样式：靛蓝细左边 + 极浅底 + **中性正文**。
 * 最主要的舒适度来自正文不再是彩色字——彩色正文比彩色底色更累眼。
 * 行距再放宽一档，考点是密集短句，挤在一起不好扫。
 */
.key-points {
    /* 与上面的正文块留一档间距，原来两块是贴在一起的 */
    margin-top: var(--space-2);
    background: var(--primary-light);
    border-left: 3px solid var(--primary);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    padding: var(--space-2) var(--space-3);
    font-size: var(--font-base);
    line-height: 1.75;
    color: var(--text-secondary);
}

.key-points .label,
.word-example .label {
    display: inline-block;
    margin-right: 6px;
    font-weight: 600;
}

/* 「考点」二字保留一点色，方便扫；正文本身保持中性 */
.key-points .label {
    color: var(--primary-dark);
}

/* 学习状态统计：数字放大并沿用标记按钮的配色 */
.status-summary {
    margin-left: 8px;
    color: var(--text-secondary);
    white-space: nowrap;
}

.status-summary b {
    font-size: var(--font-2xl);
    font-weight: 600;
    margin: 0 2px;
    vertical-align: -1px;
}

.status-summary .count-known {
    color: var(--success);
}

.status-summary .count-practice {
    color: var(--warning);
}

.mark-btn.active-practice {
    background: var(--accent-light);
    border-color: var(--warning);
    color: var(--warning);
    font-weight: 500;
}

/* ---------- 词形测验 ---------- */
.quiz-head {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    margin-bottom: var(--space-4);
}

.quiz-head-main {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-3);
}

.quiz-task {
    color: var(--text-secondary);
}

.quiz-head-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

/* 抽题范围的 chip 条在这里不再需要下边距 */
.quiz-head-tools .band-strip {
    margin-bottom: 0;
}

.quiz-head-tools .panel-actions {
    margin-left: auto;
}

.quiz-pool {
    color: var(--text-muted);
    font-size: var(--font-sm);
}

/*
 * 词形测验卡整体左对齐：翻开后答案是「标签 + 形式」的两行，
 * 跟着 .quiz-card 的居中排会让两行答案错位。标记按钮靠 margin-top:auto 压到底。
 *
 * 选择器写成 .quiz-card.form-quiz-card：.quiz-card 的定义在本文件更后面，
 * 单靠 .form-quiz-card 会被它的 text-align:center 覆盖回去。
 */
.quiz-card.form-quiz-card {
    align-items: stretch;
    justify-content: flex-start;
    text-align: left;
}

/* 卡片已经是拉伸对齐了，标记按钮跟着占满整行，「后续巩固」四个字才不折行 */
.form-quiz-card .word-marks {
    width: 100%;
}

/* 待默写的原级 / 原形：测验时它是唯一的线索，给到背诵对象那一档字号 */
.form-quiz-card .quiz-base {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-3xl);
    font-weight: 600;
}

.form-quiz-card .quiz-meaning {
    margin-top: var(--space-2);
    color: var(--text-secondary);
    font-size: var(--font-base);
}

/* 翻开后的答案：两种形式各占一行，标签在前，形式加重 */
.quiz-answer {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px dashed var(--border);
    text-align: left;
}

.quiz-answer-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 3px 0;
}

.quiz-answer-label {
    flex-shrink: 0;
    min-width: 68px;
    color: var(--text-muted);
    font-size: var(--font-sm);
}

.quiz-answer-form {
    font-size: var(--font-xl);
    font-weight: 600;
    color: var(--primary);
}

.quiz-answer-none {
    color: var(--text-muted);
}

.quiz-rule {
    margin-top: var(--space-2);
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.7;
}

/* 答案有「标签 + 形式」两列，比单词测验卡需要更宽一点才不折行 */
#quizBody .quiz-grid {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

/* 单词测验翻卡 */
.quiz-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 12px;
}

.quiz-card {
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    min-height: 120px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    cursor: pointer;
}

.quiz-card:hover {
    border-color: var(--primary);
}

.quiz-card .hint {
    color: var(--text-muted);
    font-size: var(--font-sm);
    margin-top: 8px;
}

/* ==========================================================
 * 学习进度可视化
 *
 * 两段式：已会（绿）+ 后续巩固（橙）叠在灰色轨道上，
 * 剩下的灰色就是还没碰过的部分，一眼能看出「学到哪了」。
 * 百分比数字用暖橙，是页面上最该被看见的那个数。
 * ========================================================== */

/* ---- 进度环：用在学科封面 ---- */
.progress-ring {
    --known: 0;
    --practice: 0;
    width: 92px;
    height: 92px;
    flex-shrink: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: conic-gradient(var(--success) 0 calc(var(--known) * 1%),
    var(--accent) calc(var(--known) * 1%) calc((var(--known) + var(--practice)) * 1%),
    var(--bg-subtle) calc((var(--known) + var(--practice)) * 1%) 100%);
}

.progress-ring-hole {
    width: 70px;
    height: 70px;
    border-radius: 50%;
    background: var(--white);
    display: grid;
    place-items: center;
    align-content: center;
    line-height: 1.2;
}

.progress-ring-pct {
    font-size: var(--font-xl);
    font-weight: 600;
    color: var(--accent-dark);
}

.progress-ring-label {
    font-size: var(--font-xs);
    color: var(--text-muted);
}

/* ---- 进度条：用在页头与模块分类 ---- */
.progress-block {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.progress-track {
    flex: 1;
    min-width: 160px;
    height: 10px;
    border-radius: var(--radius-pill);
    background: var(--bg-subtle);
    overflow: hidden;
    display: flex;
}

.progress-track i {
    display: block;
    height: 100%;
    transition: width .3s ease;
}

.progress-track .seg-known {
    background: var(--success);
}

.progress-track .seg-practice {
    background: var(--accent);
}

/* ---- 图例 ---- */
.progress-legend {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    font-size: var(--font-sm);
    color: var(--text-secondary);
    white-space: nowrap;
}

.progress-legend span {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
}

.progress-legend i {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.progress-legend .seg-known {
    background: var(--success);
}

.progress-legend .seg-practice {
    background: var(--accent);
}

.progress-legend .seg-rest {
    background: var(--bg-subtle);
    border: 1px solid var(--border-strong);
}

.progress-legend b {
    color: var(--text);
    font-weight: 600;
}

/* 页头那条进度：占满一行，和标题拉开距离 */
.progress-head {
    margin: 0 0 var(--space-5);
    padding: var(--space-4) var(--space-5);
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}

.progress-head-title {
    font-size: var(--font-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-2);
}

/* 页脚里尚未填写的字段：显式标出来，不要看起来像正常内容 */
.footer-todo {
    color: var(--text-muted);
}

/* ---------- 练习 ---------- */
.question-item {
    padding: var(--space-5);
    border-bottom: 1px solid var(--border);
}

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

.question-stem {
    font-size: var(--font-lg);
    margin-bottom: 12px;
    display: flex;
    gap: 8px;
}

.question-no {
    color: var(--primary);
    font-weight: 600;
    flex-shrink: 0;
}

.option-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-left: 24px;
}

.option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.option:hover {
    border-color: var(--primary);
    background: var(--primary-light);
}

.option.chosen {
    border-color: var(--primary);
    background: var(--primary-light);
}

.option.right {
    border-color: var(--success);
    background: var(--success-light);
}

.option.wrong {
    border-color: var(--danger);
    background: var(--danger-light);
}

/* 交卷后选项不可再选，去掉悬停反馈避免误导 */
.paper-submitted .option {
    cursor: default;
}

.paper-submitted .option:hover {
    border-color: var(--border);
    background: var(--white);
}

.paper-submitted .option.right,
.paper-submitted .option.right:hover {
    border-color: var(--success);
    background: var(--success-light);
}

.paper-submitted .option.wrong,
.paper-submitted .option.wrong:hover {
    border-color: var(--danger);
    background: var(--danger-light);
}

.option-key {
    font-weight: 600;
    flex-shrink: 0;
}

.answer-box {
    margin: 12px 0 0 24px;
    padding: 12px 16px;
    background: var(--bg);
    border-radius: var(--radius-sm);
    font-size: var(--font-base);
}

.answer-box .label {
    color: var(--text-muted);
    margin-right: 6px;
}

.answer-line + .answer-line {
    margin-top: 8px;
}

/*
 * 分步解析要保留数据里的换行。
 * 题干 / 答案 / 解析在前端是经 esc() 直出的纯文本、**不走 Markdown**
 * （见 CLAUDE.md「数学必会内容」），所以换行只能靠 white-space：
 * pre-line 会保留换行、同时把多余空格折叠掉，正好适合中文分步解析。
 * 少了这一条，「① 设…② 由…③ 解得…」会连成一整段，分步就白写了。
 */
.answer-steps,
.key-point-box {
    white-space: pre-line;
    line-height: 1.8;
}

/* 题干同理：新定义 / 阅读理解类题目会先给一段定义再问，分行读起来才清楚 */
.question-stem span:last-child {
    white-space: pre-line;
}

.subjective-input {
    margin-left: 24px;
    width: calc(100% - 24px);
    min-height: 70px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: var(--font-base);
    resize: vertical;
    outline: none;
}

.subjective-input:focus {
    border-color: var(--primary);
}

.score-bar {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 16px 20px;
    background: var(--primary-light);
    border-radius: var(--radius);
    margin-bottom: 16px;
}

.score-num {
    font-size: var(--font-5xl);
    font-weight: 600;
    color: var(--primary);
}

/* ---------- 分页与提示 ---------- */
.pager {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 12px;
    margin-top: 20px;
    color: var(--text-secondary);
    font-size: var(--font-base);
}

.empty, .loading {
    text-align: center;
    padding: 48px 20px;
    color: var(--text-muted);
}

.error {
    background: var(--danger-light);
    border: 1px solid var(--danger-border);
    color: var(--danger);
    padding: 12px 16px;
    border-radius: var(--radius);
    margin-bottom: 16px;
}

.checkbox-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    cursor: pointer;
    font-size: var(--font-base);
    background: var(--white);
}

.checkbox-item:hover {
    border-color: var(--primary);
}

.checkbox-item.checked {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--primary);
}

.footer {
    margin-top: auto;
    background: var(--white);
    border-top: 1px solid var(--border);
    color: var(--text-muted);
    font-size: var(--font-sm);
}

.footer-inner {
    max-width: var(--layout-max);
    margin: 0 auto;
    padding: var(--space-5) var(--layout-gutter);
    text-align: center;
}

.footer-line + .footer-line {
    margin-top: 6px;
}

.footer-brand {
    color: var(--text-secondary);
}

.footer-legal a {
    color: var(--text-muted);
}

.footer-legal a:hover {
    color: var(--primary);
}

/* ---------- 词形变化对照表 ---------- */
.form-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-base);
}

.form-table th,
.form-table td {
    border-bottom: 1px solid var(--border);
    padding: 10px 12px;
    text-align: left;
    vertical-align: top;
}

/*
 * 表头不再 sticky。
 * 表格现在装在 .table-wrap 里（overflow-x: auto 让宽表横向滚动），
 * 浏览器会把它的 overflow-y 也算成 auto，于是 .table-wrap 成了 sticky 的包含块。
 * 包含块本身不纵向滚动，`top: 60px` 只会把表头**向下推 60px 压在第一行上面**：
 * 第一行的原形 / 比较级 / 最高级三格被盖住，标记按钮也点不到。
 * 每页 20 行，翻回去看列名的成本远低于这个副作用，直接去掉。
 */
.form-table th {
    background: var(--bg);
    font-weight: 600;
    white-space: nowrap;
}

.form-table tbody tr:hover {
    background: var(--bg);
}

.form-table tbody tr:last-child td {
    border-bottom: 0;
}

/*
 * 一条词形占两行：上行是三种形式 + 释义 + 规则，下行是例句（跨满六列）。
 * 所以上行不画下边框——分隔线由例句行来收尾，否则一条词形中间多一道线，
 * 看起来像两条不同的词。hover 时两行要一起变色，不然只亮半条。
 */
.form-table tbody tr:not(.form-example-row) td {
    border-bottom: 0;
    padding-bottom: var(--space-1);
}

.form-example-row td {
    padding-top: 0;
}

.form-table tbody tr:not(.form-example-row):hover,
.form-table tbody tr:not(.form-example-row):hover + .form-example-row,
.form-example-row:hover,
.form-table tbody tr:has(+ .form-example-row:hover) {
    background: var(--bg);
}

.form-base {
    /* 原形与变化形式是这张表要记的东西，比表格正文大一档 */
    font-size: var(--font-lg);
    font-weight: 600;
    white-space: nowrap;
}

.form-changed {
    font-size: var(--font-lg);
    color: var(--primary);
    font-weight: 500;
    white-space: nowrap;
}

.rule-note {
    color: var(--text-secondary);
}

.example-zh {
    color: var(--text-secondary);
    margin-top: 2px;
}

/* 例句列要放两条例句，给它更多宽度，否则每句都折三四行 */
.form-table .example-cell {
    width: 38%;
}

/* 例句列一格里放两条例句：第二形式一条、第三形式一条，用细分隔线隔开 */
.example-item + .example-item {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed var(--border);
}

/* 例句用的是哪种形式，靠这个小标签区分 */
.example-label {
    display: inline-block;
    margin-right: 6px;
    padding: 1px 6px;
    background: var(--primary-light);
    color: var(--primary);
    border-radius: var(--radius-sm);
    font-size: var(--font-xs);
    white-space: nowrap;
}

/* ==========================================================
 * 学科总览页
 * 版式从「我」到「学科」再到「同学」：学习台 → 学科卡片 → 交流区入口。
 * ========================================================== */

/* ---------- 学习台 ---------- */
/*
 * 极浅的主色底 + 右上角一团更浅的光晕，是整站唯一一处成块的着色。
 * 它承担「欢迎回来」这件事，所以允许比别处热闹一档；
 * 但正文仍是中性色，只有数字带色——彩色正文比彩色底色累眼得多。
 */
.study-hero {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-6);
    margin-bottom: var(--space-8);
    padding: var(--space-8);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-lg);
    background: var(--primary-light);
}

.study-hero::after {
    content: '';
    position: absolute;
    /* 装饰光晕必须压在内容下面：它是最后一个盒子，不压层会盖在右侧数字卡片上 */
    z-index: 0;
    top: -120px;
    right: -60px;
    width: 320px;
    height: 320px;
    border-radius: 50%;
    background: var(--white);
    opacity: .5;
    pointer-events: none;
}

.hero-main {
    position: relative;
    z-index: 1;
    min-width: 0;
}

.hero-greet {
    margin: 0 0 var(--space-1);
    color: var(--text-secondary);
    font-size: var(--font-base);
}

.hero-greet b {
    color: var(--primary);
}

.hero-title {
    margin: 0 0 var(--space-2);
    font-size: var(--font-4xl);
    font-weight: 600;
    line-height: 1.4;
}

.hero-sub {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
}

/* 继续上次：一整行都可点，图标用学科色，一眼知道是哪一科 */
.hero-resume {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-5);
    padding: var(--space-3) var(--space-5) var(--space-3) var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--white);
    box-shadow: var(--shadow-sm);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.hero-resume:hover {
    transform: translateX(2px);
    box-shadow: var(--shadow);
}

.resume-icon {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--white);
    font-size: var(--font-md);
    background: var(--primary);
}

.resume-text {
    display: flex;
    flex-direction: column;
    line-height: 1.4;
    min-width: 0;
}

.resume-text b {
    font-size: var(--font-sm);
    color: var(--text-secondary);
    font-weight: 500;
}

.resume-text span {
    font-size: var(--font-md);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.resume-go {
    color: var(--primary);
    transition: transform var(--dur) var(--ease);
}

.hero-resume:hover .resume-go {
    transform: translateX(3px);
}

/* 三个数字。每个都带一行说明——只写「128」谁也不知道那是什么 */
.hero-stats {
    position: relative;
    z-index: 1;
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.stat {
    min-width: 108px;
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius);
    background: var(--white);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    text-align: center;
}

.stat-icon {
    font-size: var(--font-lg);
}

.stat-value {
    display: block;
    font-size: var(--font-4xl);
    font-weight: 600;
    line-height: 1.2;
}

.stat-value i {
    font-style: normal;
    font-size: var(--font-sm);
    font-weight: 400;
    color: var(--text-muted);
    margin-left: 2px;
}

.stat-label {
    display: block;
    font-size: var(--font-xs);
    color: var(--text-muted);
}

/* 三个数字各自的颜色：打卡用暖橙（激励）、已会用绿、待巩固用暖橙深一档 */
.stat-streak .stat-value {
    color: var(--accent);
}

.stat-known .stat-value {
    color: var(--success-dark);
}

.stat-practice .stat-value {
    color: var(--accent-dark);
}

/* ---------- 分段标题 ---------- */
.section-head {
    display: flex;
    align-items: baseline;
    gap: var(--space-4);
    flex-wrap: wrap;
    margin-bottom: var(--space-5);
}

/* 学科与交流区是同级的两段，段与段之间要有明显的一档间距 */
#subjectList + .section-head {
    margin-top: var(--space-10);
}

/* 段落标题右侧的入口，推到最右 */
.section-more {
    margin-left: auto;
    color: var(--primary);
    font-size: var(--font-base);
    white-space: nowrap;
}

.section-more:hover {
    text-decoration: underline;
}

.section-title {
    margin: 0;
    font-size: var(--font-2xl);
    font-weight: 600;
}

.section-note {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--font-sm);
}

/* ---------- 学科封面卡片 ---------- */
/*
 * 整卡是个 <a>，这里必须跟着 .subject-card 一起是纵向 flex：
 * 写成 display:block 会盖掉上面的 flex，于是 .cover-enter 的 margin-top:auto
 * 失效、卡片也不再撑满栅格行高——一行摆五张卡时高低不齐特别明显。
 */
.subject-card-link {
    display: flex;
    color: inherit;
    /* 列表逐张浮现：一次进来六张卡同时出现太生硬，错开 40ms 像是「排进来的」 */
    animation: card-rise var(--dur-slow) var(--ease) both;
    animation-delay: calc(var(--i, 0) * 40ms);
}

@keyframes card-rise {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
}

/* 学科色的光晕，只在右上角一小团，hover 时才显出来，不铺整卡 */
.cover-glow {
    position: absolute;
    top: -70px;
    right: -70px;
    width: 160px;
    height: 160px;
    border-radius: 50%;
    background: var(--subject, var(--primary));
    opacity: .06;
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
    pointer-events: none;
}

.subject-card:hover .cover-glow {
    opacity: .12;
    transform: scale(1.15);
}

.cover-head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.cover-name {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.35;
}

.cover-title {
    font-size: var(--font-2xl);
    font-weight: 600;
}

.cover-sub {
    font-size: var(--font-sm);
    color: var(--text-muted);
}

.cover-status {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding-top: var(--space-4);
    border-top: 1px dashed var(--border);
}

/* 封面上的进度：一条两段式细进度条 + 一行说明，比进度环更省高度 */
.cover-bar .progress-track {
    height: 6px;
    min-width: 0;
}

.cover-bar-text {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-2);
    font-size: var(--font-sm);
    color: var(--text-secondary);
}

.cover-pct {
    font-weight: 600;
    color: var(--success-dark);
}

.cover-hint {
    margin: 0;
    font-size: var(--font-sm);
    color: var(--text-muted);
}

.cover-hint b {
    color: var(--text-secondary);
}

/*
 * 进入学科：贴卡片底部，内容多少不同的卡片看起来一样齐。
 * 颜色是**靛蓝而不是学科色**——链接一律靛蓝是全站的约定，
 * 语文的红色写在这里会被当成报错。学科色只出现在图标、光晕与 hover 边框上。
 */
.cover-enter {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: auto;
    color: var(--primary);
    font-size: var(--font-base);
    font-weight: 500;
}

.cover-enter i {
    font-style: normal;
    transition: transform var(--dur) var(--ease);
}

.subject-card:hover .cover-enter i {
    transform: translateX(4px);
}

/* ---------- 骨架屏 ---------- */
/*
 * 接口没回来之前先摆出最终版式的灰影子，比一行「加载中…」稳——
 * 内容到位时不会整页跳动。
 */
.skeleton-card {
    pointer-events: none;
}

.sk {
    display: block;
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--bg-subtle) 25%, var(--bg) 37%, var(--bg-subtle) 63%);
    background-size: 400% 100%;
    animation: sk-shimmer 1.4s ease infinite;
}

.sk-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--radius);
}

.sk-line {
    height: 14px;
}

.sk-short {
    width: 50%;
}

.sk-chip {
    display: inline-block;
    width: 72px;
    height: 22px;
    border-radius: var(--radius-pill);
}

@keyframes sk-shimmer {
    from {
        background-position: 100% 50%;
    }
    to {
        background-position: 0 50%;
    }
}

/* 交流区入口的小图标，和学科卡片的图标一个语言 */
.forum-entry-icon {
    margin-right: var(--space-2);
}

/* ---------- 学科主页：左侧两级分类 + 右侧内容面板 ---------- */
.subject-layout {
    display: grid;
    grid-template-columns: 236px minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

/* 左侧分类栏整栏固定，切换内容时导航不动，学生始终知道自己在学科的哪一块 */
.subject-rail {
    position: sticky;
    top: 84px;
    padding: var(--space-3);
    /* 跟着视口高度走：矮屏上整栏自己滚动，不会把末尾几个分类顶到屏幕外面去。
       108px = 顶部导航 60 + sticky 偏移 24 + 一点余量 */
    max-height: calc(100vh - 108px);
    max-height: calc(100dvh - 108px);
    overflow-y: auto;
}

.rail-title {
    margin: 0 var(--space-2) var(--space-2);
    font-size: var(--font-sm);
    font-weight: 600;
    color: var(--text-muted);
}

.rail-group + .rail-group {
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--border);
}

/* 分类标题本身可点，点开是该分类的总览 */
.rail-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    font-family: inherit;
    font-size: var(--font-base);
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.rail-head:hover {
    background: var(--bg);
}

.rail-head.active {
    background: var(--primary-light);
    color: var(--primary);
}

.rail-num {
    margin-left: auto;
    color: var(--text-muted);
    font-size: var(--font-sm);
    font-weight: 400;
}

.rail-head.active .rail-num {
    color: var(--primary);
}

/* 二级分类：缩进一档并靠竖线归组，视觉上明确从属于上面的分类 */
.rail-items {
    margin: var(--space-1) 0 0 var(--space-3);
    padding-left: var(--space-2);
    border-left: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* 册次 / 年级小标题：只是把同一分类里的板块切成几段，不可点，
   所以做得比分类标题轻——小一档、灰色、不占按钮的样子 */
.rail-sub {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-2) 0 var(--space-1);
    padding: 0 var(--space-2);
    font-size: var(--font-xs);
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.05em;
}

.rail-sub:first-child {
    margin-top: 0;
}

.rail-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: var(--font-base);
    text-align: left;
    cursor: pointer;
}

.rail-item:hover {
    background: var(--bg);
    color: var(--text);
}

.rail-item.active {
    background: var(--primary-light);
    color: var(--primary);
    font-weight: 500;
}

.rail-item.muted {
    color: var(--text-muted);
}

.rail-item-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 勾选位（练习页左栏）：知识点可多选、模拟卷单选，勾上的就是这次要练的。
   固定宽度还让两组的名字对齐——没勾的那些也留着这一格。 */
.rail-check {
    flex-shrink: 0;
    width: 12px;
    color: var(--primary);
    font-size: var(--font-xs);
    line-height: 1;
}

/* 二级分类上的标签压到最小一档，主体是名字，标签只做点缀 */
.rail-item .tag {
    flex-shrink: 0;
    padding: 0 var(--space-2);
    font-size: var(--font-xs);
}

/* ---------- 右侧内容面板 ---------- */
.panel-head {
    margin-bottom: var(--space-4);
}

.panel-crumb {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: var(--font-sm);
}

/* 面板内的面包屑用 <button>（就地切换面板），独立页面顶部的用 <a>（跳回学科主页）；
   两者长相必须一致，所以样式写在一起 */
.panel-crumb button,
.panel-crumb a {
    padding: 0;
    border: 0;
    background: none;
    color: var(--primary);
    font-family: inherit;
    font-size: inherit;
    text-decoration: none;
    cursor: pointer;
}

.panel-crumb button:hover,
.panel-crumb a:hover {
    text-decoration: underline;
}

/* 页面级面包屑（.container 的第一个元素）与下面的页头之间留一档 */
.page-crumb {
    margin-bottom: var(--space-4);
}

.panel-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    font-size: var(--font-2xl);
    font-weight: 600;
}

.panel-desc {
    margin: var(--space-2) 0 0;
    color: var(--text-secondary);
    font-size: var(--font-base);
}

/* 面板内的小节标题，用于「按板块练」这类面板内分段 */
.panel-section {
    margin: var(--space-6) 0 var(--space-2);
    font-size: var(--font-lg);
    font-weight: 600;
}

.panel-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* 正文与工具面板都套一层卡片，面包屑留在卡片外，读起来有边界不飘 */
.panel-card {
    padding: var(--space-6);
}

.panel-card > .panel-title {
    margin-bottom: var(--space-3);
}

.panel-card > .panel-desc {
    margin-top: 0;
    margin-bottom: var(--space-4);
}

/* 板块导览：一级板块自己的正文，排在知识点列表上方 */
.board-guide {
    margin-bottom: var(--space-4);
}

/* 卡片里的小节标题不用再留那么大的上边距 */
.panel-card .panel-section:first-of-type {
    margin-top: var(--space-5);
}

/* ---------- 面板里的专项内容：筛选条 + 列表 + 分页 ---------- */
.tool-content {
    margin-top: var(--space-5);
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
}

.tool-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-bottom: var(--space-4);
}

.tool-filters label {
    color: var(--text-secondary);
    font-size: var(--font-sm);
}

/* 频次档 / 单元这类多选项的横排，放在面板里就不再额外留下边距 */
.tool-filters .band-strip {
    flex-basis: 100%;
    margin-bottom: 0;
}

.tool-status-summary {
    margin-left: auto;
    font-size: var(--font-sm);
}

.tool-progress {
    margin-bottom: var(--space-4);
}

/* 面板里的列表已经在卡片里了，卡片阴影去掉一档，避免层层叠影 */
.tool-list .word-card,
.tool-list .card {
    box-shadow: none;
}

.tool-pager {
    margin-top: var(--space-4);
}



/*
 * 词形表有 6 列，硬挤进面板宽度会把「释义」「变化规则」压成每行一两个字、
 * 行高涨到 200px。给一个可读的最小宽度，装不下就让它自己横向滚动。
 */
.table-wrap {
    overflow-x: auto;
}

.table-wrap .form-table {
    /*
     * 只需保住五列（三种形式 + 释义 + 规则）能读的宽度——例句已经另起一行、
     * 跨满整幅，不再和它们抢位置，所以这个值比原来的 1200px 小得多，
     * 外壳收在 1200px 之后也不会横向滚动。
     * 再窄下去（窄屏 / 面板里）仍然横向滚动，那是设计好的退路：
     * 硬挤会把「释义」压成每行一两个字、行高涨到 200px。
     */
    min-width: 720px;
}

/* 标记列压到最窄：两个按钮并排，不跟着正文列一起被拉宽 */
.form-table .mark-cell {
    /* 「后续巩固」四个字要在一行放得下，否则会折成「后续巩 / 固」 */
    width: 176px;
}

.form-table .mark-btn {
    white-space: nowrap;
}

.form-table .mark-cell .word-marks {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

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

/* 知识点正文上方那一行元信息里的按钮靠右，与标签拉开距离 */
.subject-panel .detail-meta .btn {
    margin-left: auto;
}

/* ---------- 模块卡片：比原来小一档，一屏能看全一个分类 ---------- */
/* 册次 / 年级分组的小标题，配合左栏的 .rail-sub */
.module-group {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    font-size: var(--font-md);
    font-weight: 600;
    color: var(--text);
}

.module-group-num {
    font-size: var(--font-sm);
    font-weight: 400;
    color: var(--text-muted);
}

.module-grid + .module-group {
    margin-top: var(--space-5);
}

.module-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
    gap: var(--space-3);
}

.module-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--white);
    box-shadow: var(--shadow-sm);
    color: inherit;
    font-family: inherit;
    font-size: var(--font-base);
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.module-card:hover {
    border-color: var(--primary);
    box-shadow: var(--shadow);
}

/* 无内容的模块整卡标灰，但保留同样的结构，不做删减 */
.module-card.disabled {
    background: var(--bg);
    box-shadow: none;
    cursor: default;
}

.module-card.disabled:hover {
    border-color: var(--border);
    box-shadow: none;
}

.module-name {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-md);
    font-weight: 600;
}

.module-icon {
    flex-shrink: 0;
    font-size: var(--font-lg);
    line-height: 1;
}

.module-desc {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.6;
}

.module-count {
    margin-top: auto;
    color: var(--text-muted);
    font-size: var(--font-sm);
}

/* ---------- 板块下的知识点列表 ---------- */
.kp-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.kp-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--white);
    color: inherit;
    font-family: inherit;
    font-size: var(--font-base);
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.kp-row:hover {
    border-color: var(--primary);
    background: var(--primary-light);
}

.kp-row.active {
    border-color: var(--primary);
    background: var(--primary-light);
}

.kp-row-main {
    flex: 1;
    min-width: 0;
}

.kp-row-name {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: 500;
}

.kp-row-summary {
    margin: var(--space-1) 0 0;
    color: var(--text-secondary);
    font-size: var(--font-sm);
    line-height: 1.6;
}

/* 正文上下的翻页条，让学生能在一个板块内连着看完 */
.kp-pager {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

.kp-pager .spacer {
    flex: 1;
}

.btn-sm {
    padding: var(--space-1) var(--space-3);
    font-size: var(--font-sm);
}

/* 屏幕不够宽时分类栏改为横排，不再占掉正文宽度 */
@media (max-width: 900px) {
    .subject-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    .subject-rail {
        position: static;
        max-height: none;
    }
}

.subject-hero {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
    margin-bottom: var(--space-5);
}

.subject-name {
    margin: 0;
    font-size: var(--font-4xl);
    font-weight: 600;
    letter-spacing: -.01em;
}

.subject-hero .subject-icon {
    width: 48px;
    height: 48px;
    font-size: var(--font-3xl);
}


/* ==========================================================
 * 元素周期表（科学专题）
 *
 * 18 列 × 7 行的标准排布，位置由数据决定（内联 grid-column / grid-row）。
 * **格子里唯一上色的是化合价**（暖橙 = 学习重点，这就是这个专题的主角）；
 * 类别只用极浅底色区分，中文名与原子序数保持中性。
 * 窄屏 / 面板里装不下 18 列就整张表横向滚动，不缩字号——
 * 缩到看不清的周期表没有意义。
 * ========================================================== */

.tool-intro {
    margin-bottom: var(--space-4);
}

.pt-legend {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-3);
    font-size: var(--font-xs);
    color: var(--text-secondary);
}

/* 图例的每一项就是一个迷你格子：14px 的浅色小方块根本分不出颜色，
   把底色直接铺在文字上才看得出「这一类的格子长这样」 */
.pt-legend-item {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--space-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.pt-legend-note {
    color: var(--text-muted);
}

/* 表格整体：装不下就横向滚动（和词形表一个办法） */
.pt-wrap {
    overflow-x: auto;
}

.ptable {
    display: grid;
    /* 第一列是周期号，其余 18 列是族 */
    grid-template-columns: 34px repeat(18, minmax(48px, 1fr));
    gap: var(--space-1);
    /* 34 + 18×48 + 19 个间隙 = 980px。装不下就滚动，**不缩字号**——
       缩到看不清的周期表没有意义，元素名本来就只有一个字 */
    min-width: 980px;
}

.pt-head,
.pt-side,
.pt-corner {
    display: grid;
    place-items: center;
    font-size: var(--font-xs);
    color: var(--text-muted);
}

.pt-corner {
    line-height: 1.2;
    text-align: center;
}

/* 镧系 / 锕系在主表里的入口格：虚线框，看得出它是「跳到下面那两行」而不是元素 */
.pt-band-link {
    display: grid;
    place-items: center;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-sm);
    font-size: var(--font-xs);
    line-height: 1.25;
    text-align: center;
    color: var(--text-muted);
}

.pt-cell {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    padding: var(--space-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--white);
    cursor: pointer;
    font-family: inherit;
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.pt-cell:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
    border-color: var(--primary-border);
}

/* 初中必会的元素：主色描边。必会是身份信息，走靛蓝一系，暖橙留给化合价 */
.pt-cell.is-core,
.pt-legend-item.is-core {
    border-color: var(--primary);
}

.pt-cell.active {
    border-color: var(--primary);
    box-shadow: var(--shadow);
}

.cat-1 {
    background: var(--element-metal);
}

.cat-2 {
    background: var(--element-nonmetal);
}

.cat-3 {
    background: var(--element-noble);
}

.pt-no {
    position: absolute;
    top: var(--space-1);
    left: var(--space-1);
    font-size: var(--font-xs);
    line-height: 1;
    color: var(--text-muted);
}

/* 化合价：标在元素符号上方，和教材上标价态的写法一致 */
.pt-valence {
    margin-top: var(--space-2);
    font-size: var(--font-xs);
    font-weight: 600;
    line-height: 1;
    color: var(--accent-dark);
    white-space: nowrap;
}

.pt-valence-none {
    color: var(--text-muted);
    font-weight: 400;
}

.pt-symbol {
    font-size: var(--font-lg);
    font-weight: 600;
    line-height: 1.1;
}

.pt-name {
    font-size: var(--font-xs);
    line-height: 1.1;
    color: var(--text-secondary);
}

/* 镧系 / 锕系：抽出来的两行，第一格是行名 */
/* 镧系 / 锕系行：模板与主表完全一致，15 个元素落在第 4~18 列，格子宽度才对得齐 */
.pt-band {
    display: grid;
    grid-template-columns: 34px repeat(18, minmax(48px, 1fr));
    gap: var(--space-1);
    margin-top: var(--space-1);
    min-width: 980px;
}

.pt-band-name {
    font-size: var(--font-xs);
}

/* ---------- 点一个元素弹出的详情（装在 Overlay 的 .modal-body 里） ---------- */
.pt-detail-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.pt-detail-symbol {
    font-size: var(--font-3xl);
    font-weight: 600;
    line-height: 1;
}

.pt-detail-title {
    font-size: var(--font-md);
    font-weight: 600;
    margin-right: var(--space-2);
}

.pt-row {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border-top: 1px solid var(--border);
    font-size: var(--font-sm);
}

.pt-row-label {
    flex: 0 0 96px;
    color: var(--text-muted);
}

.pt-row-value {
    flex: 1;
    min-width: 0;
}

.pt-memo {
    margin-top: var(--space-3);
}

/* 导语：从数据推出来的一句话（原子序数的含义 + 在表里的位置 + 类别） */
.pt-intro {
    margin: 0 0 var(--space-4);
    font-size: var(--font-sm);
    line-height: 1.8;
    color: var(--text-secondary);
}

/* 化合价块是弹层的主角：整幅宽、大字、暖橙底（复用词卡那一套） */
.pt-valence-box {
    margin-bottom: var(--space-3);
}

.pt-valence-note {
    margin: 0 0 var(--space-3);
    font-size: var(--font-xs);
    line-height: 1.7;
    color: var(--text-muted);
}

/* 结尾那两条推算规则：任何元素都用得上，所以固定放在最后 */
.pt-detail-foot {
    margin: var(--space-4) 0 0;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
    font-size: var(--font-xs);
    line-height: 1.8;
    color: var(--text-muted);
}

/* ---------- 常见元素化合价：一个元素一张卡（背诵面） ---------- */
.element-card-head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.element-symbol {
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    flex-shrink: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: var(--font-2xl);
    font-weight: 600;
}

.element-title {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.element-pinyin {
    font-size: var(--font-xs);
    color: var(--text-muted);
}

.element-meta {
    font-size: var(--font-xs);
    color: var(--text-secondary);
}

/* 化合价是这张卡的主角：整卡唯一的大字与唯一的暖橙 */
.element-valence {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding: var(--space-3);
    border-radius: var(--radius-sm);
    background: var(--accent-light);
}

.element-valence-label {
    font-size: var(--font-xs);
    color: var(--accent-dark);
    white-space: nowrap;
}

.element-valence-value {
    font-size: var(--font-xl);
    font-weight: 600;
    color: var(--accent-dark);
    letter-spacing: .02em;
}

.element-compounds {
    margin-top: var(--space-3);
    font-size: var(--font-sm);
    line-height: 1.8;
    color: var(--text-secondary);
}

.element-memo {
    margin-top: var(--space-3);
    font-size: var(--font-sm);
}


/* ==========================================================
 * 知识网络图（地理中考汇总）
 *
 * 不画力导向图：几十个连线在窄面板里是一团毛线，学生要的是
 * **答题时能顺着走下来的链**。所以用教材上那种框图——
 * 因果链横排（箭头串起来）、考点节点成网格、跨主题关联单独一行。
 *
 * 配色守全站分工：整张图只有「三条黄金分界线」那一块是暖橙成块的
 * （它就是「优先背这个」的意思），其余全走中性 + 主色。
 * ========================================================== */

.net-mainlines {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

.net-mainline {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-3) var(--space-4);
    border-left: 3px solid var(--primary);
    border-radius: var(--radius-sm);
    background: var(--primary-light);
}

.net-mainline b {
    font-size: var(--font-base);
}

.net-mainline span {
    font-size: var(--font-xs);
    line-height: 1.7;
    color: var(--text-secondary);
}

/* ---- 三条黄金分界线：整张图唯一成块的暖色 ---- */
.net-golden {
    margin-bottom: var(--space-6);
    padding: var(--space-4);
    border: 1px solid var(--accent-border);
    border-radius: var(--radius);
    background: var(--accent-light);
}

.net-golden-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    font-size: var(--font-md);
}

.net-golden-head span {
    font-size: var(--font-xs);
    font-weight: 400;
    color: var(--accent-dark);
}

.net-golden-item + .net-golden-item {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px dashed var(--accent-border);
}

.net-golden-name {
    margin-bottom: var(--space-2);
    font-size: var(--font-base);
    font-weight: 600;
}

.net-roles {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* 一条线的多重含义，每一条都是一枚小牌子——「一线多义」要看得出是并列的 */
.net-role {
    padding: 2px var(--space-2);
    border: 1px solid var(--accent-border);
    border-radius: var(--radius-pill);
    background: var(--white);
    font-size: var(--font-xs);
    color: var(--text-secondary);
}

/* ---- 主题块 ---- */
.net-theme {
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
}

.net-theme-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0 0 var(--space-1);
}

.net-theme-name {
    font-size: var(--font-lg);
    font-weight: 600;
}

.net-tagline {
    margin: 0 0 var(--space-4);
    font-size: var(--font-sm);
    line-height: 1.7;
    color: var(--text-secondary);
}

/* ---- 因果链：地理题的答题骨架 ---- */
.net-chains {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
}

.net-chain {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.net-step {
    padding: var(--space-1) var(--space-3);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-sm);
    background: var(--white);
    font-size: var(--font-sm);
}

.net-arrow {
    font-style: normal;
    color: var(--primary);
}

/* ---- 考点节点 ---- */
.net-nodes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
    gap: var(--space-3);
}

.net-node {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--white);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

.net-node:hover {
    transform: translateY(-2px);
    border-color: var(--primary-border);
    box-shadow: var(--shadow-sm);
}

.net-node-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.net-node-name {
    font-size: var(--font-base);
    font-weight: 600;
}

.net-node-board {
    font-size: var(--font-xs);
    color: var(--text-muted);
}

.net-facts {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* 必背结论：一条一行，前面一个小方块，扫读时数得清有几条 */
.net-fact {
    position: relative;
    padding-left: var(--space-4);
    font-size: var(--font-sm);
    line-height: 1.75;
    color: var(--text-secondary);
}

.net-fact::before {
    content: '';
    position: absolute;
    top: .6em;
    left: 0;
    width: 6px;
    height: 6px;
    border-radius: var(--radius-pill);
    background: var(--primary-border);
}

.net-fact strong {
    color: var(--text);
}

/* 底部压到底：结论条数不同的卡片，按钮仍在同一条线上 */
.net-node-go {
    margin-top: auto;
    font-size: var(--font-xs);
    color: var(--primary);
}

/* ---- 跨主题关联：这才是「网络」而不是「树」 ---- */
.net-links {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: var(--space-4) 0 var(--space-5);
}

.net-links-label {
    font-size: var(--font-xs);
    color: var(--text-muted);
}

.net-link {
    padding: var(--space-1) var(--space-3);
    border: 1px dashed var(--primary-border);
    border-radius: var(--radius-pill);
    background: var(--white);
    font-family: inherit;
    font-size: var(--font-xs);
    color: var(--text-secondary);
    cursor: pointer;
}

.net-link i {
    font-style: normal;
    color: var(--primary);
}

.net-link:hover {
    border-style: solid;
    background: var(--primary-light);
}


/* ==========================================================
 * 模拟卷：清单与整卷作答
 * ========================================================== */

.paper-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.paper-card {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--white);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}

.paper-card:hover {
    transform: translateY(-2px);
    border-color: var(--primary-border);
    box-shadow: var(--shadow-sm);
}

/* 卷号做大：一排卡片里最先要认出的是「第几套」 */
.paper-no {
    flex-shrink: 0;
    width: 36px;
    font-size: var(--font-3xl);
    font-weight: 600;
    line-height: 1;
    color: var(--border-strong);
}

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

.paper-name {
    font-size: var(--font-base);
    font-weight: 600;
}

.paper-focus {
    font-size: var(--font-xs);
    line-height: 1.6;
    color: var(--text-secondary);
}

.paper-stat {
    font-size: var(--font-xs);
    color: var(--text-muted);
}

.paper-go {
    flex-shrink: 0;
    font-size: var(--font-xs);
    color: var(--primary);
}

/* 整卷作答页：页头的卷信息 */
.paper-meta {
    font-size: var(--font-sm);
    color: var(--text-muted);
}

.paper-summary {
    display: block;
    margin-top: var(--space-3);
    font-size: var(--font-sm);
}

/* 交卷后的学习要点：与解析分开成块——解析说「为什么选它」，
   要点说「下次怎么想」，混在一段里学生只会看前半句 */
.key-point-box {
    margin-top: var(--space-3);
    font-size: var(--font-sm);
    line-height: 1.8;
}

.key-point-box b {
    margin-right: var(--space-2);
    color: var(--primary);
}


/* ==========================================================
 * 练习题页：与其它内容页保持同一套结构
 * （页头 → 一张操作卡 → 内容卡；视觉数值一律取令牌，不写内联样式）
 * ========================================================== */

/*
 * 右栏收窄提到整栏上，而不是只收题目卡。
 * 栏里是三个上下叠着的盒子（组卷条 / 卷说明 / 题目卡），只给题目卡套 .prose-card
 * 的话，宽屏上它比上面两个窄一截——一栏里三条左右边缘，就是「没对齐」。
 * 题干仍然是逐字读的内容，所以这一档收窄本身要保留，只是作用在栏上。
 */
.practice-panel {
    max-width: calc(var(--measure-max) + var(--space-6) * 2);
}

.setup-card {
    margin-bottom: var(--space-4);
}

/* 组卷条现在是操作卡里唯一一行，.filters 自带的下外边距会让卡片下面空一截 */
.setup-card .filters {
    margin-bottom: 0;
}

.count-input {
    width: 80px;
}

/* 「选没选知识点」跟在开始练习按钮后面；左栏里也用它显示加载 / 出错 */
.picker-hint {
    font-size: var(--font-sm);
    color: var(--text-muted);
}

.picker-hint-error {
    color: var(--danger);
}

/* 卷信息标签跟在说明后面，与详情页的 .detail-meta 同一种排法 */
.paper-tags {
    margin: var(--space-3) 0 0;
}

.paper-summary {
    margin-bottom: var(--space-4);
}

/* 试卷卡片的头：题量与满分先交代清楚 */
/*
 * 卡片头要和题目同一条左边缘。
 * .card 本身不带内边距（内边距在 .card-body 上，而题目卡没有套 .card-body），
 * .question-item 又自带一圈 --space-5，于是「本卷题目」贴在卡片边框上、
 * 题干却缩进 20px，宽屏上一眼就看出标题顶到了最左边。
 * 这里给卡片头补上与题目相同的左右内边距；分隔线仍然跨满整张卡（padding 不影响
 * 块级元素的边框宽度），所以看着还是一条卡片头的分隔线。
 * 下外边距归零：题目自己的上内边距已经把间距留出来了，两者相加会空出一大截。
 */
.paper-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: 0;
    padding: var(--space-5) var(--space-5) var(--space-3);
    border-bottom: 1px solid var(--border);
}

.paper-head-meta {
    font-size: var(--font-sm);
    font-weight: 400;
    color: var(--text-muted);
}

/* 题目的题型 / 难度 / 分值标签：跟在题干下面，与题号对齐 */
.question-meta {
    margin: 0 0 var(--space-3) var(--space-6);
}

.paper-actions {
    margin-top: var(--space-5);
    text-align: center;
}

.score-again {
    margin-left: auto;
}

.answer-blank {
    color: var(--text-muted);
}

/* ---------- 科学分科知识索引（js/science-branches.js） ---------- */
/* 分科标题：一科一块，图标 + 名字 + 节数，说明在下面一行 */
.branch-head {
    margin-bottom: var(--space-5);
}
.branch-head h4 {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--font-xl);
    color: var(--text);
}
.branch-head p {
    margin-top: var(--space-2);
    font-size: var(--font-sm);
    color: var(--text-secondary);
}
/* 册次是这份索引的第一层分组：课本一册一册地学，复习也是一册一册地过 */
.branch-volume + .branch-volume {
    margin-top: var(--space-5);
}
.branch-volume-head {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--border);
    font-weight: 600;
    color: var(--text);
}
.branch-volume-head i {
    font-style: normal;
    font-size: var(--font-sm);
    font-weight: 400;
    color: var(--text-muted);
}
/* 章内的节排成自适应多列：节名都很短，铺成一列会拖得很长 */
.branch-chapter {
    margin-top: var(--space-4);
}
.branch-chapter-name {
    font-size: var(--font-sm);
    color: var(--text-secondary);
}
.branch-sections {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-2) var(--space-5);
    margin-top: var(--space-2);
    list-style: none;
}
.branch-sections li {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    font-size: var(--font-base);
    color: var(--text);
}
/* 节号固定宽度，节名才对得齐（和练习页左栏的勾选位同一个办法） */
.branch-section-no {
    flex: 0 0 auto;
    min-width: 42px;
    font-size: var(--font-sm);
    color: var(--text-muted);
}

/* ---------- 公式手册（js/content-view.js 的 formulaCard） ---------- */
/* 排成一列：一条公式要连着符号表、条件、变形式、易错点、示例一起读，
   和古诗文正文同属「逐条读、逐条背」的内容，挤成两栏后符号表每行会断成两截 */
.formula-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}
.formula-card {
    padding: var(--space-5);
}
.formula-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
}
.formula-name {
    font-size: var(--font-xl);
    color: var(--text);
}
/* 表达式是这张卡的主体，单独一档字号、浅底衬出来。
   **不上彩色**：全站约定彩色只做小面积标记，一整条彩色公式反而更累眼 */
.formula-expression {
    margin-top: var(--space-3);
    padding: var(--space-4) var(--space-5);
    background: var(--bg-subtle);
    border-radius: var(--radius);
    font-size: var(--font-2xl);
    line-height: 1.6;
    color: var(--text);
    overflow-x: auto;
}
.formula-block {
    margin-top: var(--space-4);
}
.formula-label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-sm);
    font-weight: 600;
    color: var(--text-secondary);
}
.formula-block ul {
    list-style: none;
    /* 浏览器给 ul 的默认左内边距是 40px，去掉 list-style 也不会消失，
       不清零的话符号表整块会莫名缩进一截 */
    padding: 0;
    margin: 0;
    display: grid;
    gap: 6px;
}
.formula-block li {
    font-size: var(--font-base);
    line-height: 1.75;
    color: var(--text);
}
/* 符号表条数多、每条短，宽屏排两列；变形式同理 */
.formula-vars ul,
.formula-variants ul {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 6px var(--space-5);
}
/* 易错点前面加一个记号：这一栏是「详细讲解」里最该看的一块 */
.formula-pitfalls li {
    padding-left: var(--space-4);
    position: relative;
}
.formula-pitfalls li::before {
    content: '·';
    position: absolute;
    left: 0;
    color: var(--accent);
    font-weight: 700;
}
/* 示例一步一行、按顺序编号，与专项练习的分步解析同一个读法 */
.formula-example ul {
    counter-reset: formula-step;
}
.formula-example li {
    padding-left: var(--space-5);
    position: relative;
    counter-increment: formula-step;
}
.formula-example li::before {
    content: counter(formula-step);
    position: absolute;
    left: 0;
    width: 18px;
    text-align: center;
    font-size: var(--font-xs);
    color: var(--text-muted);
}
/* 推演：一步一行，编号由 ol 自己给。排在符号表之后、适用条件之前——
   先知道公式从哪儿来，再看它怎么用。它比别的块长，所以单栏排、不进两栏 */
.formula-derive ol {
    /* 浏览器给 ol 的默认左内边距是 40px，这里自己控制缩进 */
    padding-left: var(--space-6);
    margin: 0;
    display: grid;
    gap: var(--space-2);
}
.formula-derive li {
    font-size: var(--font-base);
    line-height: 1.8;
    color: var(--text);
    padding-left: var(--space-2);
}
/* 「定义式 / 推导式 / 实验归纳」是身份信息，走中性灰，不跟暖橙抢 */
.derive-kind {
    margin-left: var(--space-2);
    padding: 1px 8px;
    border-radius: var(--radius-pill);
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    font-size: var(--font-xs);
    font-style: normal;
    font-weight: 400;
    color: var(--text-secondary);
}

.formula-cond {
    margin-top: var(--space-4);
}
.formula-source {
    margin-top: var(--space-4);
    font-size: var(--font-sm);
    color: var(--text-muted);
}

/* ---------- 化学方程式（js/content-view.js 的 equationCard） ---------- */
/* 与公式卡同样排成一列：方程式要连着条件、现象、考点一起读，
   挤成两栏后长式子（如酒精燃烧）会断行，配平就看不出来了 */
.equation-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
}
/* 册次小标题：这一科按年级分开，段与段之间要一眼看得出换册了 */
.eq-volume {
    margin: var(--space-5) 0 0;
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--border);
    font-size: var(--font-lg);
    color: var(--text-secondary);
}
.eq-volume:first-child {
    margin-top: 0;
}
.equation-card {
    padding: var(--space-5);
}
.eq-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
}
.eq-name {
    font-size: var(--font-lg);
    color: var(--text);
}
/* 式子是这张卡的主体，与公式表达式同一档处理：大一号字 + 极浅底，**不上彩色** */
.eq-formula {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-3);
    padding: var(--space-4) var(--space-5);
    background: var(--bg-subtle);
    border-radius: var(--radius);
    font-size: var(--font-2xl);
    line-height: 1.6;
    color: var(--text);
    overflow-x: auto;
}
.eq-side {
    white-space: nowrap;
}
/* 反应条件写在等号上方，与课本一致；没有条件时这一栏只剩一个等号 */
.eq-sign {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.1;
}
.eq-cond {
    font-size: var(--font-xs);
    font-style: normal;
    color: var(--text-secondary);
    white-space: nowrap;
}
/* 符号说明：条数多而每条短，宽屏排两列（与公式卡的符号表同一个处理） */
.eq-symbols {
    display: flex;
    gap: var(--space-3);
    margin-top: var(--space-3);
}
.eq-symbols ul {
    list-style: none;
    /* 浏览器给 ul 的默认左内边距是 40px，去掉 list-style 也不会消失 */
    padding: 0;
    margin: 0;
    flex: 1 1 auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 4px var(--space-5);
}
.eq-symbols li {
    font-size: var(--font-sm);
    line-height: 1.7;
    color: var(--text-secondary);
}
/* 使用场景回答「这条式子用在哪儿」，与现象、考点并列成一行 */
.eq-scene .eq-label {
    color: var(--primary);
}

.eq-line {
    display: flex;
    gap: var(--space-3);
    margin-top: var(--space-3);
    font-size: var(--font-base);
    line-height: 1.75;
    color: var(--text);
}
.eq-label {
    flex: 0 0 auto;
    min-width: 30px;
    font-size: var(--font-sm);
    font-weight: 600;
    color: var(--text-secondary);
}
/* 考点前一个暖橙记号：一张卡里最该看的一行，与公式卡的易错点同一个做法 */
.eq-note .eq-label {
    color: var(--accent-dark);
}
.eq-foot {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-top: var(--space-4);
    font-size: var(--font-sm);
    color: var(--text-muted);
}
.eq-go {
    padding: 0;
    border: none;
    background: none;
    font-size: var(--font-sm);
    color: var(--primary);
    cursor: pointer;
}
.eq-go:hover {
    text-decoration: underline;
}

/* ---------- 历史「知识全境」时间线 ---------- */
/* 三层结构：时代 → 时间点 → 考点。默认只露前两层，点开才展开考点——
   一册 39 个时间点、91 条结论，全铺开就又是一份长讲义。 */
.tl-eras {
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
}

.tl-era-head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: 0 0 var(--space-2);
    font-size: var(--font-lg);
}

/* 时代序号：这一册分几段，一眼数得清 */
.tl-era-no {
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: var(--radius-pill);
    background: var(--primary-light);
    color: var(--primary);
    border: 1px solid var(--primary-border);
    font-size: var(--font-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.tl-era-theme {
    margin: 0 0 var(--space-4);
    color: var(--text-secondary);
    font-size: var(--font-sm);
}

/* 时间轴：靠左边一条竖线把同一个时代的时间点串起来 */
.tl-line {
    list-style: none;
    margin: 0;
    padding: 0 0 0 var(--space-5);
    border-left: 2px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.tl-node {
    position: relative;
}

/* 轴上的点。用 border 而不是实心块：展开时才填成主色，看得出「正在看哪一个」 */
.tl-node::before {
    content: '';
    position: absolute;
    left: calc(-1 * var(--space-5) - 6px);
    top: 14px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--white);
    border: 2px solid var(--border-strong);
}

.tl-node:has(.tl-node-head.open)::before {
    background: var(--primary);
    border-color: var(--primary);
}

.tl-node-head {
    width: 100%;
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: var(--font-md);
    text-align: left;
    cursor: pointer;
}

.tl-node-head:hover {
    border-color: var(--primary-border);
}

.tl-node-head.open {
    border-color: var(--primary-border);
    background: var(--bg-subtle);
}

/* 年代是这一科最要紧的东西，给它固定宽度让所有行左边对齐 */
.tl-year {
    flex-shrink: 0;
    min-width: 8.5em;
    color: var(--primary);
    font-size: var(--font-sm);
}

.tl-title {
    flex: 1;
    font-weight: 600;
}

.tl-lesson,
.tl-more {
    flex-shrink: 0;
    color: var(--text-muted);
    font-size: var(--font-xs);
}

.tl-facts {
    padding: var(--space-3) var(--space-4) var(--space-4);
    border: 1px solid var(--primary-border);
    border-top: none;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    background: var(--bg-subtle);
}

.tl-facts ul {
    margin: 0 0 var(--space-3);
    padding-left: var(--space-5);
    line-height: 1.8;
}

.tl-facts li + li {
    margin-top: var(--space-2);
}

.tl-go {
    font-family: inherit;
    font-size: var(--font-sm);
    color: var(--primary);
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
}

.tl-go:hover {
    text-decoration: underline;
}

@media (max-width: 700px) {
    /* 窄屏上年代与标题挤在一行会各剩几个字，改成上下两行 */
    .tl-node-head {
        flex-wrap: wrap;
    }

    .tl-year {
        min-width: 0;
    }
}

/* ---------- 必备题目（带答案的背题清单） ---------- */
.must-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.must-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--white);
    padding: var(--space-5);
}

.must-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.must-no {
    font-weight: 600;
    color: var(--text-secondary);
    font-size: var(--font-sm);
}

/* 题干与选项是逐字读的，行距按长正文给 */
.must-stem {
    font-size: var(--font-md);
    line-height: 1.8;
    white-space: pre-line;
}

.must-options {
    list-style: none;
    margin: var(--space-3) 0 0;
    padding: 0;
}

.must-option {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-1) 0;
    line-height: 1.8;
}

.must-opt-key {
    flex-shrink: 0;
    color: var(--text-secondary);
}

.must-answer,
.must-analysis,
.must-key {
    margin-top: var(--space-4);
}

/* 块标题自己带类名，**不要**写成 `.must-analysis b`——
   常考标记也是 <b>，那种后代选择器会把红字一起压成灰色并挤成独立一行（实测） */
.must-label {
    display: block;
    margin-bottom: var(--space-1);
    font-size: var(--font-sm);
    color: var(--text-secondary);
}

/* 常考内容：红色 + 加粗。全站只有它用红色正文——
   红是最强的一档标记（`.tag-must` 必考也是这个色系），
   一道题里只标一两处，标满了就等于没标。 */
.q-hot {
    color: var(--danger-dark);
    font-weight: 700;
}
