2071 lines
39 KiB
CSS
2071 lines
39 KiB
CSS
:root {
|
||
--brand: #5b5ce2;
|
||
--sider-top: #20224a;
|
||
--sider-bottom: #15162e;
|
||
--content-bg: #f5f6fb;
|
||
--text-secondary: #6f7080;
|
||
--border-soft: #ececf5;
|
||
/* 中性面:与 theme.ts 的 palette 一一对应 */
|
||
--surface: #ffffff;
|
||
--surface-2: #fafaff;
|
||
--surface-hover: #f6f6fd;
|
||
--tab-rail: #f2f3fa;
|
||
--text-strong: #1f2033;
|
||
--text-muted: #b9bacb;
|
||
--header-bg: rgba(255, 255, 255, 0.88);
|
||
--scrollbar: #c9cae6;
|
||
--track: #f1f2f6;
|
||
--track-raised: #ffffff;
|
||
--brand-soft: rgba(91, 92, 226, 0.08);
|
||
--success-soft: #f0fdf4;
|
||
--success-soft-border: #bbf7d0;
|
||
--danger-soft: #fef2f2;
|
||
--danger-soft-border: #fecaca;
|
||
--warning-soft: #fffbeb;
|
||
/* 内容页布局尺度:顶栏高度、内容列左右留白、内容列最大宽度 */
|
||
--layout-header-h: 56px;
|
||
--content-pad: 14px;
|
||
/* 底部留白单独一个变量:.app-content 的下边距比四周略大一点,
|
||
阅读器高度等「满屏高度」计算时统一引用它,避免出现几像素的竖直滚动条。 */
|
||
--content-pad-end: calc(var(--content-pad) + 4px);
|
||
--content-max: 1680px;
|
||
}
|
||
|
||
/* 深色模式:只换中性色,品牌色与语义色保持不变 */
|
||
:root[data-theme="dark"] {
|
||
--content-bg: #12141f;
|
||
--text-secondary: #9b9db4;
|
||
--border-soft: #2a2c40;
|
||
--surface: #1a1c2a;
|
||
--surface-2: #1f2132;
|
||
--surface-hover: #22243a;
|
||
--tab-rail: #16182a;
|
||
--text-strong: #e9eaf3;
|
||
--text-muted: #5d5f78;
|
||
--header-bg: rgba(26, 28, 42, 0.88);
|
||
--scrollbar: #3a3c55;
|
||
--track: #24263c;
|
||
--track-raised: #3a3e5c;
|
||
--brand-soft: rgba(91, 92, 226, 0.22);
|
||
--success-soft: rgba(22, 163, 74, 0.14);
|
||
--success-soft-border: rgba(22, 163, 74, 0.4);
|
||
--danger-soft: rgba(220, 38, 38, 0.14);
|
||
--danger-soft-border: rgba(220, 38, 38, 0.4);
|
||
--warning-soft: rgba(212, 136, 6, 0.14);
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
background: var(--content-bg);
|
||
font-family:
|
||
-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
|
||
"Microsoft YaHei", sans-serif;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
|
||
#root {
|
||
min-height: 100vh;
|
||
}
|
||
|
||
::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
|
||
::-webkit-scrollbar-thumb {
|
||
background: var(--scrollbar);
|
||
border-radius: 8px;
|
||
}
|
||
|
||
::-webkit-scrollbar-track {
|
||
background: transparent;
|
||
}
|
||
|
||
/* ---------------- 侧边栏外壳 ---------------- */
|
||
|
||
.app-sider {
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.sider {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
background: linear-gradient(180deg, var(--sider-top) 0%, var(--sider-bottom) 100%);
|
||
}
|
||
|
||
.sider-brand {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
height: 56px;
|
||
padding: 0 10px 0 12px;
|
||
flex-shrink: 0;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
color: #fff;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||
transition: padding 0.2s ease;
|
||
}
|
||
|
||
/* 收拢时只留 logo,并且要保证 logo 居中 */
|
||
.sider--collapsed .sider-brand {
|
||
justify-content: center;
|
||
padding: 0;
|
||
}
|
||
|
||
.sider-brand-mark {
|
||
display: grid;
|
||
place-items: center;
|
||
width: 30px;
|
||
height: 30px;
|
||
flex-shrink: 0;
|
||
border-radius: 9px;
|
||
background: var(--brand);
|
||
color: #fff;
|
||
font-size: 17px;
|
||
font-weight: 800;
|
||
box-shadow: 0 4px 12px rgba(91, 92, 226, 0.45);
|
||
transition:
|
||
transform 0.18s ease,
|
||
opacity 0.16s ease;
|
||
}
|
||
|
||
.sider-brand-text {
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
font-size: 14.5px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* 菜单头部的收拢按钮:与平台名同一行,靠右 */
|
||
.sider-brand-collapse {
|
||
margin-inline-start: auto;
|
||
flex-shrink: 0;
|
||
width: 30px;
|
||
height: 30px;
|
||
padding: 0;
|
||
color: rgba(255, 255, 255, 0.66);
|
||
}
|
||
|
||
/* 收拢态:logo 与展开按钮叠在同一位置,hover / 聚焦时原地换人 */
|
||
.sider-brand-logo {
|
||
position: relative;
|
||
display: grid;
|
||
place-items: center;
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
.sider-brand-toggle {
|
||
display: grid;
|
||
place-items: center;
|
||
width: 30px;
|
||
height: 30px;
|
||
padding: 0;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.sider-brand-logo .sider-brand-toggle {
|
||
position: absolute;
|
||
inset: 0;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
}
|
||
|
||
.sider-brand-logo:hover .sider-brand-mark,
|
||
.sider-brand-logo:focus-within .sider-brand-mark {
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
}
|
||
|
||
.sider-brand-logo:hover .sider-brand-toggle,
|
||
.sider-brand-logo:focus-within .sider-brand-toggle {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
}
|
||
|
||
.sider-brand .sider-brand-toggle:not(:disabled):hover {
|
||
color: #fff;
|
||
background: rgba(255, 255, 255, 0.14);
|
||
}
|
||
|
||
.sider-scroll {
|
||
flex: 1;
|
||
min-height: 0;
|
||
overflow-x: hidden;
|
||
overflow-y: auto;
|
||
padding: 10px 0 12px;
|
||
}
|
||
|
||
.sider-scroll::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
|
||
.sider-scroll::-webkit-scrollbar-thumb {
|
||
background: rgba(255, 255, 255, 0.16);
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.sider-menu.ant-menu-dark .ant-menu-item-group-title,
|
||
.sider-scroll .ant-menu-dark .ant-menu-item-group-title {
|
||
padding-inline: 22px;
|
||
letter-spacing: 0.6px;
|
||
}
|
||
|
||
/* 收拢态下的分组分隔线与弹出子菜单 */
|
||
.sider-scroll .ant-menu-dark .ant-menu-item-divider {
|
||
margin-inline: 16px;
|
||
border-color: rgba(255, 255, 255, 0.12);
|
||
}
|
||
|
||
.sider-footer {
|
||
flex-shrink: 0;
|
||
padding: 10px;
|
||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||
}
|
||
|
||
.sider-user {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
padding: 7px 8px;
|
||
border-radius: 10px;
|
||
cursor: pointer;
|
||
background: rgba(255, 255, 255, 0.07);
|
||
transition: background 0.2s;
|
||
}
|
||
|
||
.sider-user:hover {
|
||
background: rgba(255, 255, 255, 0.14);
|
||
}
|
||
|
||
.sider-user--collapsed {
|
||
justify-content: center;
|
||
padding: 6px 0;
|
||
}
|
||
|
||
.sider-user-name {
|
||
color: #fff;
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.sider-user-role {
|
||
color: rgba(255, 255, 255, 0.5);
|
||
font-size: 11px;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/* 移动端抽屉中的侧栏:去掉 antd 默认留白 */
|
||
.app-sider-drawer .ant-drawer-body {
|
||
background: linear-gradient(180deg, var(--sider-top) 0%, var(--sider-bottom) 100%);
|
||
}
|
||
|
||
/* ---------------- 顶栏(移动端在此唤出菜单抽屉) ---------------- */
|
||
|
||
.app-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 20;
|
||
/* 与 .app-content-inner 同一条基线:内容列被 max-width 收窄时,
|
||
顶栏控件同步内收(推导:内容列左偏移 = pad + (100% - 2*pad - 上限)/2
|
||
= (100% - 上限)/2,未被夹住时就是 pad,故取两者较大值)。 */
|
||
padding-inline: max(
|
||
var(--content-pad),
|
||
calc((100% - var(--content-max)) / 2)
|
||
) !important;
|
||
background: var(--header-bg);
|
||
border-bottom: 1px solid var(--border-soft);
|
||
backdrop-filter: saturate(180%) blur(8px);
|
||
}
|
||
|
||
/* 移动端的菜单入口:带描边的小方块,避免被当成正文里的返回按钮 */
|
||
.header-toggle {
|
||
flex-shrink: 0;
|
||
display: grid;
|
||
place-items: center;
|
||
width: 38px;
|
||
height: 32px;
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 10px;
|
||
background: var(--surface-2);
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.header-toggle:hover {
|
||
color: var(--brand);
|
||
border-color: rgba(91, 92, 226, 0.35);
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
/* 状态切换时图标轻微横向位移,强化「推走 / 拉回」的方向感 */
|
||
.header-toggle-icon {
|
||
display: inline-grid;
|
||
place-items: center;
|
||
animation: header-toggle-in 0.2s ease;
|
||
}
|
||
|
||
.header-toggle-glyph {
|
||
display: block;
|
||
}
|
||
|
||
@keyframes header-toggle-in {
|
||
from {
|
||
transform: translateX(-3px);
|
||
opacity: 0.35;
|
||
}
|
||
to {
|
||
transform: none;
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.header-toggle-icon {
|
||
animation: none;
|
||
}
|
||
}
|
||
|
||
/* 平台名只在侧栏文字被收拢掉时出现,避免与侧栏品牌行重复 */
|
||
.app-header-brand {
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
color: var(--text-strong);
|
||
}
|
||
|
||
.header-divider {
|
||
flex-shrink: 0;
|
||
width: 1px;
|
||
height: 22px;
|
||
margin-inline: -3px;
|
||
background: var(--border-soft);
|
||
}
|
||
|
||
/* 功能页面 header:与下方模块面板同款面板(同底色、同描边、同圆角),
|
||
标题 + 描述在左,该功能的主操作按钮在右 */
|
||
.page-header {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 8px 16px;
|
||
min-height: 54px;
|
||
margin-bottom: 16px;
|
||
padding: 10px 20px;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.page-header-heading {
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.page-header .page-header-title {
|
||
margin: 0;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.page-header .page-header-desc {
|
||
display: block;
|
||
margin-top: 1px;
|
||
font-size: 12px;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.page-header-dot {
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* 功能页头右侧的主操作:由 HeaderActions portal 进来,空的时候不占位 */
|
||
.page-header-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.page-header-actions:empty {
|
||
display: none;
|
||
}
|
||
|
||
.header-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
margin-inline-start: auto;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.header-control {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
min-width: 38px;
|
||
height: 38px;
|
||
padding-inline: 8px;
|
||
border-radius: 12px;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* 明暗模式:圆角方块 + 轨道底色,图标本身表示当前可执行的动作 */
|
||
.mode-toggle {
|
||
width: 38px;
|
||
font-size: 18px;
|
||
color: var(--text-strong);
|
||
background: var(--track);
|
||
}
|
||
|
||
.mode-toggle:hover {
|
||
color: var(--brand);
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
/* 语言切换:分段控件,选中项抬起成同圆角的小方块(与明暗按钮同高) */
|
||
.header-actions .lang-switch.ant-segmented {
|
||
padding: 3px;
|
||
border-radius: 12px;
|
||
background: var(--track);
|
||
}
|
||
|
||
.header-actions .lang-switch .ant-segmented-item {
|
||
border-radius: 9px;
|
||
color: var(--text-secondary);
|
||
transition: color 0.18s ease;
|
||
}
|
||
|
||
.header-actions .lang-switch .ant-segmented-item-label {
|
||
min-width: 36px;
|
||
height: 32px;
|
||
padding-inline: 10px;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
line-height: 32px;
|
||
}
|
||
|
||
.header-actions .lang-switch .ant-segmented-item:hover:not(.ant-segmented-item-selected) {
|
||
color: var(--text-strong);
|
||
}
|
||
|
||
.header-actions .lang-switch .ant-segmented-item-selected,
|
||
.header-actions .lang-switch .ant-segmented-thumb {
|
||
background: var(--track-raised);
|
||
box-shadow: 0 1px 2px rgba(15, 17, 45, 0.14);
|
||
}
|
||
|
||
.header-actions .lang-switch .ant-segmented-item-selected {
|
||
color: var(--text-strong);
|
||
}
|
||
|
||
/* 内容页边距:留白随视口变宽略微加大,但宽度优先给内容,
|
||
避免高分辨屏上「中间一条窄柱、两侧大片空白」。 */
|
||
@media (min-width: 900px) {
|
||
:root {
|
||
--content-pad: 20px;
|
||
}
|
||
}
|
||
|
||
@media (min-width: 1600px) {
|
||
:root {
|
||
--content-pad: 24px;
|
||
}
|
||
}
|
||
|
||
@media (min-width: 2200px) {
|
||
:root {
|
||
--content-pad: 28px;
|
||
}
|
||
}
|
||
|
||
.app-content {
|
||
padding: var(--content-pad);
|
||
padding-block-end: var(--content-pad-end);
|
||
}
|
||
|
||
.app-content-inner {
|
||
max-width: min(100%, var(--content-max));
|
||
margin: 0 auto;
|
||
}
|
||
|
||
/* 页面切换淡入 */
|
||
.view-fade {
|
||
animation: view-fade 0.24s ease both;
|
||
}
|
||
|
||
@keyframes view-fade {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(6px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: none;
|
||
}
|
||
}
|
||
|
||
/* ---------------- 登录页 ---------------- */
|
||
|
||
.login-bg {
|
||
min-height: 100vh;
|
||
display: grid;
|
||
place-items: center;
|
||
padding: 16px;
|
||
background: linear-gradient(135deg, #5b5ce2 0%, #312e81 60%, #1e1b4b 100%);
|
||
}
|
||
|
||
/* 登录页右上角的语言 / 明暗切换:渐变背景上用浅色控件 */
|
||
.login-bg > .header-actions {
|
||
position: fixed;
|
||
inset-block-start: 18px;
|
||
inset-inline-end: 20px;
|
||
z-index: 2;
|
||
}
|
||
|
||
.login-bg .mode-toggle,
|
||
.login-bg .lang-switch.ant-segmented {
|
||
--track: rgba(255, 255, 255, 0.18);
|
||
--track-raised: #ffffff;
|
||
color: rgba(255, 255, 255, 0.9);
|
||
}
|
||
|
||
.login-bg .mode-toggle {
|
||
color: #ffffff;
|
||
}
|
||
|
||
.login-bg .mode-toggle:hover {
|
||
--track: rgba(255, 255, 255, 0.3);
|
||
color: #ffffff;
|
||
}
|
||
|
||
.login-bg .lang-switch .ant-segmented-item {
|
||
color: rgba(255, 255, 255, 0.72);
|
||
}
|
||
|
||
.login-bg .lang-switch .ant-segmented-item:hover:not(.ant-segmented-item-selected) {
|
||
color: #ffffff;
|
||
}
|
||
|
||
.login-bg .lang-switch .ant-segmented-item-selected,
|
||
.login-bg .lang-switch .ant-segmented-thumb {
|
||
background: #ffffff;
|
||
color: #312e81;
|
||
}
|
||
|
||
.login-card {
|
||
width: 400px;
|
||
max-width: 100%;
|
||
border-radius: 16px;
|
||
box-shadow: 0 24px 64px rgba(15, 16, 46, 0.35);
|
||
}
|
||
|
||
.login-brand-mark {
|
||
display: inline-grid;
|
||
width: 52px;
|
||
height: 52px;
|
||
border-radius: 15px;
|
||
font-size: 27px;
|
||
}
|
||
|
||
/* ---------------- 通用页面块 ---------------- */
|
||
|
||
.page-stack {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
}
|
||
|
||
.panel-toolbar {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
|
||
.section-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
margin: 0 0 8px;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: var(--text-strong);
|
||
}
|
||
|
||
/* 指标卡:可选图标 + 数值 */
|
||
.metric-card .ant-statistic-title {
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.metric-icon {
|
||
display: grid;
|
||
place-items: center;
|
||
width: 42px;
|
||
height: 42px;
|
||
flex-shrink: 0;
|
||
border-radius: 12px;
|
||
background: rgba(91, 92, 226, 0.1);
|
||
color: var(--brand);
|
||
font-size: 19px;
|
||
}
|
||
|
||
.metric-icon--success {
|
||
background: rgba(22, 163, 74, 0.1);
|
||
color: #16a34a;
|
||
}
|
||
|
||
.metric-icon--warning {
|
||
background: rgba(212, 136, 6, 0.12);
|
||
color: #d48806;
|
||
}
|
||
|
||
/* 掌握度概览:一条分布条看完四档,段宽按知识点数量占比;图例可点进知识地图 */
|
||
.mastery-distribution {
|
||
flex: 1;
|
||
min-width: 240px;
|
||
}
|
||
|
||
.mastery-band {
|
||
display: flex;
|
||
height: 10px;
|
||
overflow: hidden;
|
||
border-radius: 999px;
|
||
background: var(--surface-2);
|
||
}
|
||
|
||
/* 轻量列表:抽屉章节 / 结果回看 / 推荐步骤统一节奏 */
|
||
.data-rows {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.data-row {
|
||
padding: 12px 2px;
|
||
border-bottom: 1px solid var(--border-soft);
|
||
}
|
||
|
||
.data-row:last-child {
|
||
border-bottom: none;
|
||
padding-bottom: 2px;
|
||
}
|
||
|
||
.data-row--clickable {
|
||
cursor: pointer;
|
||
transition: background 0.2s;
|
||
}
|
||
|
||
.data-row--clickable:hover {
|
||
background: var(--surface-2);
|
||
}
|
||
|
||
/* 加载态:整页 / 局部两种高度 */
|
||
.async-state {
|
||
padding: 48px 0;
|
||
text-align: center;
|
||
}
|
||
|
||
.async-state--compact {
|
||
padding: 24px 0;
|
||
}
|
||
|
||
.async-skeleton {
|
||
padding: 8px 2px 12px;
|
||
}
|
||
|
||
/* 表格里的纯文本次要信息 */
|
||
.cell-sub {
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* 次要说明常是整句话,限制一行,否则整列会被撑得比屏幕还宽 */
|
||
.ant-table-cell .cell-sub {
|
||
max-width: 360px;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
/* 选项字母前缀,错题本 / 练习记录 / 答题共用 */
|
||
.option-letter {
|
||
display: inline-block;
|
||
width: 26px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* 答题选项行 */
|
||
.option-row {
|
||
height: auto !important;
|
||
min-height: 44px;
|
||
padding: 10px 16px !important;
|
||
text-align: left !important;
|
||
justify-content: flex-start !important;
|
||
white-space: normal !important;
|
||
}
|
||
|
||
.option-row-letter {
|
||
display: inline-block;
|
||
width: 24px;
|
||
color: inherit;
|
||
opacity: 0.7;
|
||
}
|
||
|
||
/* 答题题干:练习流程统一排版 */
|
||
.question-stem {
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
line-height: 1.7;
|
||
margin: 20px 0 14px;
|
||
}
|
||
|
||
/* 回看选项行(错题本 / 练习记录 / 题库预览),与答题行同一套排版语义 */
|
||
.option-review {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 6px;
|
||
padding: 8px 12px;
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 8px;
|
||
background: var(--surface);
|
||
line-height: 1.7;
|
||
transition: background 0.2s, border-color 0.2s;
|
||
}
|
||
|
||
.option-review--correct {
|
||
background: var(--success-soft);
|
||
border-color: var(--success-soft-border);
|
||
}
|
||
|
||
.option-review--wrong {
|
||
background: var(--danger-soft);
|
||
border-color: var(--danger-soft-border);
|
||
}
|
||
|
||
.option-review-icon {
|
||
margin-left: auto;
|
||
flex-shrink: 0;
|
||
font-size: 15px;
|
||
line-height: 1.7;
|
||
}
|
||
|
||
/* 知识图谱管理:左侧结构树 + 右侧详情 */
|
||
.graph-main {
|
||
flex: 1 1 620px;
|
||
min-width: min(520px, 100%);
|
||
}
|
||
|
||
.graph-detail {
|
||
width: 380px;
|
||
max-width: 100%;
|
||
position: sticky;
|
||
top: 76px;
|
||
}
|
||
|
||
.tree-box {
|
||
max-height: 620px;
|
||
overflow: auto;
|
||
padding: 12px;
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 10px;
|
||
background: var(--surface);
|
||
}
|
||
|
||
/* ---------------- 教材 / 课程:竖向 Tab + 等高卡片 + 分页 ---------------- */
|
||
|
||
/*
|
||
* Tab 与内容必须读起来是一块东西:外壳是一张卡,导航条是嵌在卡内的分段面板,
|
||
* 选中项抬成与内容区同底色的白色小块 —— 看到高亮就知道右边显示的是它的内容。
|
||
*/
|
||
.resource-tabs.ant-tabs-left,
|
||
.resource-tabs.ant-tabs-top {
|
||
overflow: hidden;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 16px;
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-content {
|
||
padding: 0;
|
||
}
|
||
|
||
/* 竖向:只有 2 个标签,不需要 antd 的滚动裁剪 */
|
||
.resource-tabs.ant-tabs-left > .ant-tabs-nav,
|
||
.resource-tabs.ant-tabs-left .ant-tabs-nav-wrap {
|
||
overflow: visible;
|
||
}
|
||
|
||
/* 导航条浮在卡片内侧:四边留白,不再和内容区抢那条分隔线 */
|
||
.resource-tabs.ant-tabs-left > .ant-tabs-nav {
|
||
flex: 0 0 186px;
|
||
width: 186px;
|
||
align-self: stretch;
|
||
position: static;
|
||
margin: 10px 0 10px 10px;
|
||
padding: 8px;
|
||
border-radius: 12px;
|
||
background: var(--tab-rail);
|
||
}
|
||
|
||
.resource-tabs.ant-tabs-left > .ant-tabs-body-holder {
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding: 18px 20px 20px 22px;
|
||
}
|
||
|
||
/* antd 给左侧形态的内容区留了 24px,改由 body-holder 统一控制 */
|
||
.resource-tabs.ant-tabs-left > .ant-tabs-body-holder > .ant-tabs-content {
|
||
padding: 0;
|
||
}
|
||
|
||
/* 窄屏:同一条分段面板改卧在卡片顶部 */
|
||
.resource-tabs.ant-tabs-top > .ant-tabs-nav {
|
||
margin: 10px 10px 0;
|
||
padding: 6px;
|
||
border-radius: 12px;
|
||
background: var(--tab-rail);
|
||
}
|
||
|
||
.resource-tabs.ant-tabs-top > .ant-tabs-body-holder {
|
||
padding: 16px 18px 18px;
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-nav-list {
|
||
width: 100%;
|
||
}
|
||
|
||
/* antd 自带的导航分隔线由卡片描边代替,留着会再多切一刀 */
|
||
.resource-tabs .ant-tabs-nav::before {
|
||
display: none;
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-tab {
|
||
justify-content: flex-start;
|
||
align-self: stretch;
|
||
height: 40px;
|
||
margin: 0 0 2px !important;
|
||
padding: 0 12px !important;
|
||
border-radius: 9px;
|
||
/* 标签只有名称,禁止折行 */
|
||
white-space: nowrap;
|
||
color: var(--text-secondary);
|
||
transition:
|
||
background 0.18s ease,
|
||
box-shadow 0.18s ease,
|
||
color 0.18s ease;
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-tab:last-child {
|
||
margin-bottom: 0 !important;
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-tab:hover {
|
||
color: var(--text-strong);
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-tab .ant-tabs-tab-btn {
|
||
width: 100%;
|
||
color: inherit;
|
||
}
|
||
|
||
/* 选中项:白底小块浮在面板上,底色与右侧内容一致 */
|
||
.resource-tabs .ant-tabs-tab-active,
|
||
.resource-tabs .ant-tabs-tab-active:hover {
|
||
background: var(--surface);
|
||
box-shadow: 0 1px 3px rgba(15, 17, 45, 0.14);
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-tab-active .ant-tabs-tab-btn,
|
||
.resource-tabs .ant-tabs-tab-active .ant-tabs-tab-btn .anticon {
|
||
color: var(--brand);
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* 顶部形态:两项均分宽度 */
|
||
.resource-tabs.ant-tabs-top .ant-tabs-tab {
|
||
flex: 1 1 0;
|
||
margin-inline-end: 0 !important;
|
||
}
|
||
|
||
.resource-tabs .ant-tabs-ink-bar {
|
||
display: none;
|
||
}
|
||
|
||
.resource-tab-label {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* 内容区是实底卡片,内层卡片靠描边和淡投影保持层次 */
|
||
.resource-tabs .equal-card {
|
||
box-shadow: 0 1px 3px rgba(15, 17, 45, 0.05);
|
||
}
|
||
|
||
/* 卡片等高:栅格列与卡片一起撑满,内容多少不再影响高度 */
|
||
.card-grid {
|
||
--card-h: 352px;
|
||
align-items: stretch;
|
||
}
|
||
|
||
.card-grid > .ant-col {
|
||
display: flex;
|
||
}
|
||
|
||
.card-grid .equal-card {
|
||
width: 100%;
|
||
height: var(--card-h);
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.card-grid .equal-card .ant-card-body {
|
||
flex: 1;
|
||
min-height: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* 断点与 Col 的 xl 对齐:单列时没有对齐压力,固定高度只会撑出一片空白 */
|
||
@media (max-width: 1199px) {
|
||
.card-grid .equal-card {
|
||
height: auto;
|
||
min-height: 260px;
|
||
}
|
||
}
|
||
|
||
/* 弹性留白:把页脚和操作区顶到卡片底部,不同内容量的卡片同一条基线 */
|
||
.card-fill {
|
||
flex: 1;
|
||
min-height: 0;
|
||
}
|
||
|
||
/* 页脚不参与拉伸,章节目录单行显示,剩下的并入 +N */
|
||
.card-foot {
|
||
flex: none;
|
||
}
|
||
|
||
.card-tags {
|
||
display: flex;
|
||
gap: 6px;
|
||
}
|
||
|
||
.card-tags .ant-tag {
|
||
max-width: 150px;
|
||
margin-inline-end: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.card-pin {
|
||
padding-top: 12px;
|
||
}
|
||
|
||
.card-clamp {
|
||
display: -webkit-box;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 2;
|
||
overflow: hidden;
|
||
/* flex-basis 取的是未裁剪的整段文字高度,允许压缩时会把第二行切半,这里锁定两行高 */
|
||
flex: none;
|
||
}
|
||
|
||
.card-pager {
|
||
margin-top: 16px;
|
||
}
|
||
|
||
/* 数学公式 */
|
||
.math-inline {
|
||
font-size: 1em;
|
||
}
|
||
|
||
.math-block {
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
padding: 4px 2px;
|
||
}
|
||
|
||
.katex-display {
|
||
margin: 0.25em 0;
|
||
}
|
||
|
||
/* ---------------- 电子书阅读器 ---------------- */
|
||
|
||
.ebook-reader {
|
||
display: flex;
|
||
flex-direction: column;
|
||
/* 顶栏 + 内容区上下留白之外的全部空间,保证页面本身不产生竖直滚动 */
|
||
height: calc(
|
||
100vh - var(--layout-header-h) - var(--content-pad) - var(--content-pad-end)
|
||
);
|
||
min-height: 480px;
|
||
overflow: hidden;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.ebook-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
flex-shrink: 0;
|
||
min-height: 52px;
|
||
padding: 8px 16px;
|
||
border-bottom: 1px solid var(--border-soft);
|
||
}
|
||
|
||
.ebook-bar-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.ebook-name {
|
||
flex: 1;
|
||
min-width: 0;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.ebook-bar-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.ebook-body {
|
||
position: relative;
|
||
display: flex;
|
||
flex: 1;
|
||
min-height: 0;
|
||
}
|
||
|
||
/* PDF:虚拟滚动容器,页面绝对定位在占位轨道上 */
|
||
.ebook-pdf {
|
||
flex: 1;
|
||
overflow: auto;
|
||
padding: 24px 0;
|
||
}
|
||
|
||
.ebook-pdf-strip {
|
||
position: relative;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.ebook-pdf-page {
|
||
position: absolute;
|
||
background: #ffffff;
|
||
border-radius: 2px;
|
||
box-shadow: 0 1px 6px rgba(15, 17, 45, 0.12);
|
||
}
|
||
|
||
.ebook-pdf-canvas {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
/* EPUB:epub.js 往这里塞 iframe,尺寸交给它自己算 */
|
||
.ebook-epub {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.ebook-epub iframe {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
border: 0;
|
||
}
|
||
|
||
.ebook-overlay {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: color-mix(in srgb, var(--surface) 82%, transparent);
|
||
}
|
||
|
||
.ebook-overlay-inner {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
|
||
.ebook-overlay-text {
|
||
color: var(--text-secondary);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.ebook-foot {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
flex-shrink: 0;
|
||
padding: 8px 16px;
|
||
border-top: 1px solid var(--border-soft);
|
||
}
|
||
|
||
.ebook-caption {
|
||
color: var(--text-secondary);
|
||
font-size: 12px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.ebook-progress {
|
||
flex: 1;
|
||
margin: 0;
|
||
}
|
||
|
||
.ebook-keys-hint {
|
||
opacity: 0.7;
|
||
}
|
||
|
||
.ebook-counter {
|
||
min-width: 92px;
|
||
text-align: center;
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.ebook-font-btn {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.ebook-toc-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.ebook-toc-item {
|
||
width: 100%;
|
||
text-align: start;
|
||
overflow: hidden;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
:root {
|
||
--content-pad-end: calc(var(--content-pad) + 2px);
|
||
}
|
||
|
||
.app-content {
|
||
padding: var(--content-pad);
|
||
padding-block-end: var(--content-pad-end);
|
||
}
|
||
|
||
.ebook-reader {
|
||
min-height: 420px;
|
||
}
|
||
|
||
.ebook-counter {
|
||
min-width: 0;
|
||
}
|
||
|
||
.ebook-keys-hint {
|
||
display: none;
|
||
}
|
||
|
||
.app-header {
|
||
gap: 8px;
|
||
padding-inline: 12px !important;
|
||
}
|
||
|
||
/* 窄屏放不下按钮文字:主操作只留图标,文案保留给读屏与无障碍名称 */
|
||
.page-header {
|
||
margin-bottom: 12px;
|
||
padding: 10px 14px;
|
||
}
|
||
|
||
.page-header-actions .ant-btn > span:not(.anticon):not(.ant-btn-icon) {
|
||
position: absolute;
|
||
width: 1px;
|
||
height: 1px;
|
||
overflow: hidden;
|
||
clip-path: inset(50%);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.page-header-actions .ant-btn {
|
||
min-width: 34px;
|
||
padding-inline: 0;
|
||
}
|
||
}
|
||
|
||
/* ---------------- 今日任务:自评卡片与结算区 ---------------- */
|
||
|
||
/* 掌握度自评三档:图标 + 标签 + 说明,选中态给品牌色描边与浅底 */
|
||
.daily-rates {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
|
||
gap: 10px;
|
||
}
|
||
|
||
.daily-rate {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 10px;
|
||
padding: 12px 14px;
|
||
text-align: start;
|
||
background: var(--surface-2);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 12px;
|
||
cursor: pointer;
|
||
transition:
|
||
background 0.2s,
|
||
border-color 0.2s;
|
||
}
|
||
|
||
.daily-rate:hover:not(:disabled) {
|
||
background: var(--surface-hover);
|
||
border-color: var(--brand);
|
||
}
|
||
|
||
.daily-rate:disabled {
|
||
opacity: 0.65;
|
||
cursor: default;
|
||
}
|
||
|
||
.daily-rate--active {
|
||
background: var(--brand-soft);
|
||
border-color: var(--brand);
|
||
box-shadow: inset 0 0 0 1px var(--brand);
|
||
}
|
||
|
||
.daily-rate-icon {
|
||
color: var(--brand);
|
||
font-size: 18px;
|
||
}
|
||
|
||
.daily-rate-text {
|
||
display: flex;
|
||
flex: 1;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
}
|
||
|
||
.daily-rate-label {
|
||
color: var(--text-strong);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.daily-rate-desc {
|
||
color: var(--text-secondary);
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.daily-rate-check {
|
||
color: var(--brand);
|
||
font-size: 15px;
|
||
}
|
||
|
||
/* 完成态结算块:章节、自评、完成时刻、连续天数一次看完 */
|
||
.daily-done {
|
||
display: flex;
|
||
gap: 14px;
|
||
padding: 14px 16px;
|
||
background: var(--success-soft);
|
||
border: 1px solid var(--success-soft-border);
|
||
border-radius: 14px;
|
||
}
|
||
|
||
.daily-done-icon {
|
||
color: #16a34a;
|
||
font-size: 26px;
|
||
}
|
||
|
||
/* 结算区:主按钮独占一行,提示语跟在按钮下面 */
|
||
.daily-foot {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
|
||
/* 确认框里的章节名可能很长:限宽换行,避免气泡顶出内容区 */
|
||
.daily-confirm-desc {
|
||
max-width: 260px;
|
||
}
|
||
|
||
/* 重点按钮:今日任务的唯一主操作,尺寸要压过页面其余按钮 */
|
||
.daily-submit.ant-btn {
|
||
min-height: 52px;
|
||
border-radius: 12px;
|
||
box-shadow: 0 10px 22px rgba(91, 92, 226, 0.26);
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.daily-submit.ant-btn:disabled {
|
||
box-shadow: none;
|
||
}
|
||
|
||
/* ---------------- 分屏工作台(题库 / 记录 / 错题 / 答题) ---------------- */
|
||
|
||
.split-view {
|
||
display: flex;
|
||
align-items: stretch;
|
||
overflow: hidden;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 14px;
|
||
box-shadow: 0 1px 2px rgba(31, 32, 51, 0.04);
|
||
}
|
||
|
||
.split-aside {
|
||
flex: 0 0 auto;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
background: var(--surface-2);
|
||
}
|
||
|
||
.split-view--left .split-aside {
|
||
border-inline-end: 1px solid var(--border-soft);
|
||
}
|
||
|
||
.split-view--right .split-aside {
|
||
border-inline-start: 1px solid var(--border-soft);
|
||
}
|
||
|
||
.split-main {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 窄屏:左右分屏退回上下堆叠,清单只占一小段高度 */
|
||
.split-view--stack {
|
||
flex-direction: column;
|
||
height: auto !important;
|
||
}
|
||
|
||
.split-view--stack .split-aside {
|
||
border-inline-end: 0;
|
||
border-inline-start: 0;
|
||
border-bottom: 1px solid var(--border-soft);
|
||
width: 100% !important;
|
||
max-height: 40vh;
|
||
}
|
||
|
||
.split-view--stack .split-main {
|
||
min-height: 60vh;
|
||
}
|
||
|
||
.split-resizer {
|
||
flex: 0 0 7px;
|
||
cursor: col-resize;
|
||
position: relative;
|
||
background: transparent;
|
||
touch-action: none;
|
||
}
|
||
|
||
.split-resizer::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0 3px;
|
||
border-radius: 3px;
|
||
background: var(--border-soft);
|
||
transition: background 0.16s ease;
|
||
}
|
||
|
||
.split-resizer:hover::after,
|
||
.split-resizer--active::after {
|
||
background: var(--brand);
|
||
}
|
||
|
||
body.split-dragging {
|
||
cursor: col-resize;
|
||
user-select: none;
|
||
}
|
||
|
||
/* 分屏里的一栏 */
|
||
.pane {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
min-height: 0;
|
||
}
|
||
|
||
.pane-head {
|
||
flex: 0 0 auto;
|
||
padding: 12px 14px;
|
||
border-bottom: 1px solid var(--border-soft);
|
||
background: var(--surface);
|
||
}
|
||
|
||
.split-aside > .pane > .pane-head {
|
||
background: var(--surface-2);
|
||
}
|
||
|
||
.pane-head-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 10px;
|
||
}
|
||
|
||
.pane-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: var(--text-strong);
|
||
min-width: 0;
|
||
}
|
||
|
||
.pane-extra {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.pane-toolbar {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.pane-toolbar:empty {
|
||
display: none;
|
||
}
|
||
|
||
/* 题库侧栏的三个筛选下拉尽量等分一行;栏太窄时整体换行,
|
||
而不是把「难度不限」压成「难度…」;
|
||
菜单宽度靠 popupMatchSelectWidth={false} 单独放开,长选项不会被裁。 */
|
||
.bank-filter-select {
|
||
flex: 1 1 92px;
|
||
min-width: 92px;
|
||
}
|
||
|
||
.pane-body {
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
overflow: auto;
|
||
padding: 10px 12px 18px;
|
||
}
|
||
|
||
.pane--flat .pane-body {
|
||
padding: 0;
|
||
overflow: hidden;
|
||
display: flex;
|
||
}
|
||
|
||
.pane-foot {
|
||
flex: 0 0 auto;
|
||
padding: 10px 14px;
|
||
border-top: 1px solid var(--border-soft);
|
||
background: var(--surface);
|
||
}
|
||
|
||
/* 清单条目 */
|
||
.master-item {
|
||
display: block;
|
||
width: 100%;
|
||
text-align: start;
|
||
padding: 10px 12px;
|
||
margin-bottom: 6px;
|
||
border: 1px solid transparent;
|
||
border-radius: 10px;
|
||
background: transparent;
|
||
color: inherit;
|
||
cursor: pointer;
|
||
transition: background 0.16s ease, border-color 0.16s ease;
|
||
}
|
||
|
||
.master-item:hover {
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
.master-item--active {
|
||
background: var(--brand-soft);
|
||
border-color: rgba(91, 92, 226, 0.35);
|
||
}
|
||
|
||
.master-item-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-weight: 600;
|
||
color: var(--text-strong);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.master-item-sub {
|
||
margin-top: 3px;
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.master-group {
|
||
margin: 6px 0 4px;
|
||
padding: 0 4px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* 得分环 / 计数的数字都用等宽数字,纵向对比才整齐 */
|
||
.tabular {
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* ---------------- 试卷排版 ---------------- */
|
||
|
||
.paper {
|
||
display: flex;
|
||
flex-direction: column;
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
min-width: 0;
|
||
}
|
||
|
||
.paper-head {
|
||
flex: 0 0 auto;
|
||
padding: 14px 20px 10px;
|
||
border-bottom: 1px solid var(--border-soft);
|
||
background: var(--surface);
|
||
}
|
||
|
||
.paper-head-main {
|
||
min-width: 0;
|
||
}
|
||
|
||
.paper-title {
|
||
font-size: 16px;
|
||
font-weight: 650;
|
||
color: var(--text-strong);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.paper-meta {
|
||
margin-top: 2px;
|
||
font-size: 12.5px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.7;
|
||
}
|
||
|
||
.paper-head-side {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.paper-score {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
padding: 0 12px;
|
||
border-inline-start: 1px solid var(--border-soft);
|
||
}
|
||
|
||
.paper-score-value {
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--brand);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.paper-score-total {
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.paper-score-label {
|
||
font-size: 11.5px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.paper-head-tools {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.paper-body {
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
overflow: auto;
|
||
padding: 14px 18px 24px;
|
||
}
|
||
|
||
/* 一道题 */
|
||
.paper-question {
|
||
display: flex;
|
||
gap: 12px;
|
||
padding: 14px 10px 16px;
|
||
border-radius: 12px;
|
||
transition: background 0.16s ease, box-shadow 0.16s ease;
|
||
}
|
||
|
||
.paper-question + .paper-question {
|
||
border-top: 1px dashed var(--border-soft);
|
||
border-radius: 12px 12px 0 0;
|
||
}
|
||
|
||
.paper-question--active {
|
||
background: var(--surface-2);
|
||
box-shadow: inset 3px 0 0 var(--brand);
|
||
}
|
||
|
||
.paper-question-rail {
|
||
flex: 0 0 auto;
|
||
padding-top: 1px;
|
||
}
|
||
|
||
.paper-question-no {
|
||
display: inline-grid;
|
||
place-items: center;
|
||
min-width: 28px;
|
||
height: 28px;
|
||
padding: 0 6px;
|
||
border-radius: 50%;
|
||
background: var(--track);
|
||
color: var(--text-strong);
|
||
font-size: 13px;
|
||
font-weight: 700;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.paper-question--correct .paper-question-no {
|
||
background: var(--success-soft);
|
||
color: var(--success-soft-border);
|
||
color: #16a34a;
|
||
}
|
||
|
||
.paper-question--wrong .paper-question-no {
|
||
background: var(--danger-soft);
|
||
color: #dc2626;
|
||
}
|
||
|
||
.paper-question-main {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
|
||
.paper-question-head {
|
||
min-height: 24px;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.paper-question-actions {
|
||
margin-inline-start: auto;
|
||
}
|
||
|
||
.paper-stem {
|
||
font-size: 15.5px;
|
||
font-weight: 600;
|
||
line-height: 1.85;
|
||
color: var(--text-strong);
|
||
margin: 6px 0 12px;
|
||
}
|
||
|
||
.paper-options {
|
||
max-width: 760px;
|
||
}
|
||
|
||
.paper-answer {
|
||
margin-top: 12px;
|
||
padding: 10px 12px;
|
||
border-radius: 10px;
|
||
background: var(--surface-2);
|
||
border: 1px solid var(--border-soft);
|
||
max-width: 760px;
|
||
}
|
||
|
||
.paper-explain-body {
|
||
margin-top: 10px;
|
||
padding-top: 10px;
|
||
border-top: 1px dashed var(--border-soft);
|
||
line-height: 1.85;
|
||
color: var(--text-strong);
|
||
}
|
||
|
||
.paper-explain-toggle {
|
||
border: 0;
|
||
background: transparent;
|
||
padding: 0;
|
||
cursor: pointer;
|
||
color: var(--brand);
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* 答题卡 */
|
||
.answer-sheet {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.answer-sheet-chips {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.answer-chip {
|
||
position: relative;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
min-width: 32px;
|
||
height: 30px;
|
||
padding: 0 8px;
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 9px;
|
||
background: var(--surface);
|
||
color: var(--text-strong);
|
||
font-size: 13px;
|
||
font-variant-numeric: tabular-nums;
|
||
cursor: pointer;
|
||
transition: border-color 0.16s ease, background 0.16s ease, transform 0.16s ease;
|
||
}
|
||
|
||
.answer-chip:hover {
|
||
transform: translateY(-1px);
|
||
border-color: var(--brand);
|
||
}
|
||
|
||
.answer-chip--active {
|
||
border-color: var(--brand);
|
||
box-shadow: 0 0 0 2px var(--brand-soft);
|
||
}
|
||
|
||
.answer-chip-icon {
|
||
font-size: 11px;
|
||
}
|
||
|
||
.answer-chip--correct {
|
||
background: var(--success-soft);
|
||
border-color: var(--success-soft-border);
|
||
color: #16a34a;
|
||
}
|
||
|
||
.answer-chip--wrong {
|
||
background: var(--danger-soft);
|
||
border-color: var(--danger-soft-border);
|
||
color: #dc2626;
|
||
}
|
||
|
||
.answer-chip--done {
|
||
border-color: rgba(91, 92, 226, 0.45);
|
||
color: var(--brand);
|
||
}
|
||
|
||
.answer-chip--pending {
|
||
border-style: dashed;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.answer-sheet-legend {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.answer-sheet-legend-toggle {
|
||
border: 0;
|
||
background: transparent;
|
||
padding: 0;
|
||
cursor: pointer;
|
||
color: var(--text-secondary);
|
||
font-size: 12px;
|
||
text-decoration: underline dotted;
|
||
}
|
||
|
||
.answer-sheet-legend-items {
|
||
display: flex;
|
||
}
|
||
|
||
.answer-sheet-legend-items span {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.answer-dot {
|
||
width: 9px;
|
||
height: 9px;
|
||
border-radius: 3px;
|
||
display: inline-block;
|
||
}
|
||
|
||
.answer-dot--correct {
|
||
background: var(--success-soft);
|
||
border: 1px solid #16a34a;
|
||
}
|
||
|
||
.answer-dot--wrong {
|
||
background: var(--danger-soft);
|
||
border: 1px solid #dc2626;
|
||
}
|
||
|
||
.answer-dot--done {
|
||
background: var(--brand-soft);
|
||
border: 1px solid var(--brand);
|
||
}
|
||
|
||
.answer-dot--pending {
|
||
background: transparent;
|
||
border: 1px dashed var(--text-muted);
|
||
}
|
||
|
||
.answer-sheet-summary {
|
||
margin-inline-start: auto;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
font-size: 12.5px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* 答题中的提交条 */
|
||
.paper-submit {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
/* 题库卡片里的章节导航 */
|
||
.chapter-nav-count {
|
||
font-variant-numeric: tabular-nums;
|
||
color: var(--text-secondary);
|
||
font-size: 12px;
|
||
}
|
||
|
||
|
||
/* 试卷头部:标题与视图切换并排 */
|
||
.paper-head-row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
/* 题干下方的主体(选项 / 作答控件) */
|
||
.paper-body-slot {
|
||
min-width: 0;
|
||
}
|
||
|
||
/* 可折叠解析 */
|
||
.paper-explain {
|
||
margin-top: 12px;
|
||
max-width: 760px;
|
||
}
|
||
|
||
.paper-explain-caret {
|
||
margin-inline-start: 6px;
|
||
font-size: 10px;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
/* 我的作答 / 正确答案 对照 */
|
||
.answer-compare {
|
||
align-items: center;
|
||
row-gap: 4px;
|
||
}
|
||
|
||
.answer-chip-no {
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* 清单里的可点分组(教材名)与更紧凑的子项(章节) */
|
||
.master-group-button {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
width: 100%;
|
||
padding: 5px 8px;
|
||
border: 0;
|
||
border-radius: 8px;
|
||
background: transparent;
|
||
color: var(--text-strong);
|
||
font: inherit;
|
||
text-align: start;
|
||
cursor: pointer;
|
||
transition: background 0.16s ease, color 0.16s ease;
|
||
}
|
||
|
||
.master-group-button:hover {
|
||
background: var(--surface-hover);
|
||
}
|
||
|
||
.master-group-button--active {
|
||
color: var(--brand);
|
||
}
|
||
|
||
.master-item--tight {
|
||
padding: 7px 10px;
|
||
margin-bottom: 2px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.master-item--tight .master-item-title {
|
||
font-weight: 500;
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* 侧栏底部的小字提示 */
|
||
.aside-hint {
|
||
margin-top: 14px;
|
||
padding: 10px 4px 0;
|
||
border-top: 1px dashed var(--border-soft);
|
||
line-height: 1.7;
|
||
}
|
||
|
||
/* 生成任务进度条(挂在分屏上方,高度变化由 ResizeObserver 收敛) */
|
||
.bank-task {
|
||
margin-bottom: 12px;
|
||
padding: 12px 16px 4px;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 12px;
|
||
}
|
||
|
||
/* 成绩单摘要 */
|
||
.result-score {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 8px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.result-score-value {
|
||
font-size: 30px;
|
||
font-weight: 700;
|
||
line-height: 1.1;
|
||
color: var(--brand);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.result-score-total {
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.result-score-label {
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.result-knowledge {
|
||
margin-top: 14px;
|
||
padding-top: 4px;
|
||
border-top: 1px dashed var(--border-soft);
|
||
}
|
||
|
||
.result-knowledge-row {
|
||
gap: 8px;
|
||
padding: 4px 0;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.result-knowledge-name {
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
color: var(--text-strong);
|
||
}
|
||
|
||
|
||
/* 章节测试:组卷条件收成上方一条窄栏,高度留给答题工作台 */
|
||
.test-launcher {
|
||
padding: 12px 14px;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border-soft);
|
||
border-radius: 14px;
|
||
box-shadow: 0 1px 2px rgba(31, 32, 51, 0.04);
|
||
}
|
||
|
||
.test-launcher-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.test-launcher-select {
|
||
width: 260px;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.test-launcher-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
margin-top: 10px;
|
||
padding-top: 10px;
|
||
border-top: 1px dashed var(--border-soft);
|
||
}
|
||
|
||
.test-launcher-tags {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 4px;
|
||
}
|
||
|
||
.test-launcher-note {
|
||
flex: 1 1 240px;
|
||
min-width: 0;
|
||
font-size: 12.5px;
|
||
}
|
||
|
||
@media (max-width: 1200px) {
|
||
.paper-head {
|
||
padding: 12px 14px 8px;
|
||
}
|
||
|
||
.paper-body {
|
||
padding: 14px 12px 26px;
|
||
}
|
||
|
||
.paper-question {
|
||
padding: 16px 6px 18px;
|
||
}
|
||
}
|