/* 背包与资料（t-20261026-wybz pack）：右栏「背包」一栏、物品栏、资料一页一页、上传窗口、
   左上角「上传资料」、左栏背包气泡、错题本、背包 / 地图 / 计划窗口的同一副外框与顶上的三个标签。
   只引用 kaopy.css 的 token；动效按分级：按下 T0（120–200ms），新资料出现、读好、外圈走满 T1（300–600ms）。 */

/* ---------- 左上角「上传资料」：一页纸加向上的箭头 ----------
   还没有资料：整颗是蓝的，外面一圈蓝光扩两次，名字最后淡出来挂在右边；资料在解析：外圈一道进度，读完走满、换成完成色再淡掉 */
.sidebar-item .pack-upload {
  --read: 0;
  --from: 0;
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
  border-radius: 50%;
  background: var(--surface);
  color: var(--accent);
  box-shadow: var(--shadow-pop);
  cursor: pointer;
  transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.sidebar-item .pack-upload > .icon { width: 20px; height: 20px; }
.sidebar-item .pack-upload:hover { border-color: var(--accent); background: var(--accent-soft); transform: scale(1.04); }
.sidebar-item .pack-upload:active { transform: scale(.92); transition-duration: 120ms; }
.sidebar-item .pack-upload:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sidebar-item .pack-upload.is-empty { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
/* 光圈只在小人跑到上传钮旁、手臂指过来的那一刻扩一次（t-20261027-i1dr，workspace-guide.js 给钮写 data-call="visiting"）；载入时不播 */
.sidebar-item .pack-upload.is-empty[data-call="visiting"] { animation: pack-upload-call 1s ease-out 1 both; }
.sidebar-item .pack-upload.is-empty:hover { border-color: var(--accent-strong); background: var(--accent-strong); }
@keyframes pack-upload-call {
  0% { box-shadow: var(--shadow-pop), 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
  60% { box-shadow: var(--shadow-pop), 0 0 0 10px color-mix(in srgb, var(--accent) 20%, transparent); }
  100% { box-shadow: var(--shadow-pop), 0 0 0 14px color-mix(in srgb, var(--accent) 0%, transparent); }
}
.pack-upload__ring { position: absolute; inset: -5px; width: calc(100% + 10px); height: calc(100% + 10px); fill: none; pointer-events: none; transform: rotate(-90deg); opacity: 0; transition: opacity 240ms ease; }
.pack-upload__ring circle { stroke: var(--border); stroke-width: 2.5; }
.pack-upload__ring .pack-upload__fill { stroke: var(--accent); stroke-linecap: round; stroke-dasharray: calc(var(--read, 0) * 100) 100; transition: stroke-dasharray 400ms ease; }
.pack-upload.is-reading .pack-upload__ring, .pack-upload.is-done .pack-upload__ring { opacity: 1; }
/* 最后一份读好：外圈从读到的位置走满、换成完成色（0–240ms），满圈停一下（到 360ms），再放大一点淡掉（到 600ms），共 600ms（T1）。
   减少动态时没有这几段：满圈完成色停一会儿就收 */
.pack-upload.is-done .pack-upload__fill { stroke: var(--success); stroke-dasharray: 100 100; transition: none; animation: pack-ring-fill 600ms ease-out both; }
.pack-upload.is-done .pack-upload__ring { animation: pack-ring-done 600ms ease forwards; }
@keyframes pack-ring-fill { 0% { stroke: var(--accent); stroke-dasharray: calc(var(--from, 0) * 100) 100; } 40%, 100% { stroke: var(--success); stroke-dasharray: 100 100; } }
@keyframes pack-ring-done { 0%, 60% { opacity: 1; transform: rotate(-90deg) scale(1); } 100% { opacity: 0; transform: rotate(-90deg) scale(1.12); } }
.sidebar-item .pack-upload .abar-tip { position: absolute; z-index: 4; left: calc(100% + 10px); top: 50%; display: inline-flex; align-items: center; min-width: max-content; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-pop); font-size: var(--fs-caption); font-weight: 600; line-height: 1.5; white-space: nowrap; opacity: 0; visibility: hidden; pointer-events: none; transform: translate(-4px, -50%); transition: opacity 120ms ease, transform 140ms ease, visibility 120ms; }
.sidebar-item .pack-upload:is(:hover, :focus-visible) .abar-tip { opacity: 1; visibility: visible; transform: translate(0, -50%); transition-delay: 380ms; }
/* 还没有资料：导师第一轮说完、小人指过以后（data-call="called"），名字一直挂着，是一枚淡蓝小签，尖角指向按钮（字最后出现）；气泡打开时让开 */
.sidebar-item .pack-upload.is-empty[data-call="called"] .abar-tip { visibility: visible; border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: var(--accent-soft); color: var(--accent-strong); transition: none; animation: pack-tip-in 200ms ease-out both; }
@keyframes pack-tip-in { from { opacity: 0; transform: translate(-4px, -50%); } to { opacity: 1; transform: translate(0, -50%); } }
.sidebar-item .pack-upload.is-empty[data-call="called"] .abar-tip::before { content: ''; position: absolute; left: -5px; top: 50%; width: 8px; height: 8px; margin-top: -4px; border-bottom: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); border-left: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); background: var(--accent-soft); transform: rotate(45deg); }
.left-side:has(> .lp:not([hidden])) .pack-upload.is-empty .abar-tip { visibility: hidden; animation: none; opacity: 0; }
/* 小人正指着它（光圈那一刻起）：名字签先让开，指的和说的只留一处，不叠在小人和气泡上（焦点回到钮上时它也会弹出来） */
.sidebar-item .pack-upload[data-call="visiting"] .abar-tip { visibility: hidden; opacity: 0; animation: none; }
/* 有窗口（背包、旁问、地图、计划、上传）盖过来时名字签收起，不在左栏和窗口之间的缝里露出一截 */
/* 只收起、不关掉动画：窗口关上时名字签直接是该有的样子，不再从头播一遍 1 秒延时的淡入（那一下正好撞上刚出现的计划 / 旁问的动效） */
body:is(.board-focus-mode, :has(dialog[open])) .pack-upload.is-empty .abar-tip { visibility: hidden; }

/* 窄屏抽屉收着、还没有资料：顶栏左上角的抽屉按钮和桌面那颗上传钮一样整颗变蓝、蓝光扩两次（点它开抽屉），
   右下角挂一枚上传小签；点开抽屉，最上面那颗蓝色的「上传资料」就是它指的地方。抽屉开着时按钮回到平常的样子、小签收起，
   屏幕上只有一颗蓝色的上传钮 */
@media (max-width: 1023px) {
  /* 抽屉按钮和蓝色的「考呗」标志之间拉开一点，按钮上的光圈和小签自成一处，不和标志读成一块 */
  #leftDrawerBtn { margin-right: 8px; }
  #leftDrawerBtn.has-upload-call { position: relative; overflow: visible; background: var(--accent); color: var(--on-accent); }
  #leftDrawerBtn.has-upload-call[data-call="visiting"] { animation: pack-drawer-call 1s ease-out 1 both; }
  #leftDrawerBtn.has-upload-call:hover { background: var(--accent-strong); color: var(--on-accent); }
  body.left-open #leftDrawerBtn.has-upload-call { background: var(--faint-bub); color: var(--muted); animation: none; }
  /* 光圈只扩到按钮外 4px：按钮离视口上沿、左沿各留着这么多，整圈都在屏幕里 */
  @keyframes pack-drawer-call {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
    55% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 32%, transparent); }
    100% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 0%, transparent); }
  }
  #leftDrawerBtn.has-upload-call::after { content: ''; position: absolute; right: -6px; bottom: -6px; width: 19px; height: 19px; box-sizing: border-box; border: 2px solid var(--canvas); border-radius: 50%; background: var(--accent); pointer-events: none; }
  #leftDrawerBtn.has-upload-call::before { content: ''; position: absolute; z-index: 1; right: -2px; bottom: -2px; width: 11px; height: 11px; background: var(--on-accent); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20V5M5.5 11.5 12 5l6.5 6.5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20V5M5.5 11.5 12 5l6.5 6.5'/%3E%3C/svg%3E") center / contain no-repeat; pointer-events: none; }
  body.left-open #leftDrawerBtn.has-upload-call::before, body.left-open #leftDrawerBtn.has-upload-call::after { display: none; }
  /* 抽屉打开时左下角的头像和计分不和正文的浮动按钮叠在一起：浮动按钮让开 */
  body.left-open .composer-launcher { visibility: hidden; }
}

/* ---------- 右栏两个功能：背包、旁问（t-20261026-haf5：点开过的才有一级标签，一次只放一个、占满右栏）；
   背包窗口开着时，窗口里点的链接落在右栏的「旁边一栏」，它站在背包那个一级标签下 ---------- */
/* 一级标签和背包窗口顶上的页签同一种样子（小一号）：一道浅灰的底，当前那只是白纸、顶上一道蓝边，和下面这一栏连成一块 */
.rp-primary-tabs { gap: 2px; padding: 6px 8px 0; }
@media (min-width: 1024px) { .rp-primary-tabs { border-radius: var(--win-radius, var(--r-md)) var(--win-radius, var(--r-md)) 0 0; } }
.rp-primary-tab { flex: 0 1 128px; height: 36px; padding: 0 14px; border: 0; border-radius: 10px 10px 0 0; color: var(--muted); font-size: var(--fs-ui); transition: color 140ms ease, background-color 140ms ease; }
.rp-primary-tab .icon { width: 17px; height: 17px; }
.rp-primary-tab:active:not(.is-on) .icon { transform: scale(.86); }
.rp-primary-tab.is-on { margin-bottom: -1px; border: 0; background: var(--surface); color: var(--ink); box-shadow: inset 0 2px 0 var(--accent), inset 1px 0 0 var(--border), inset -1px 0 0 var(--border); }
.rp-primary-tab.is-on .icon { color: var(--accent); }
/* 一级标签已经写着这个功能的名字：下面这一栏不再挂名字签（旁问窗口里没有一级标签，那里照旧挂着） */
.rp-body > .rp-section > .rp-tabbar > .rp-section-title { display: none !important; }
.rp-body > .rp-section[data-view="aside"] > .rp-tabbar > .board-focus-toggle { margin-left: auto; }
/* 这个功能里还没有标签（旁问的空白页）：它的放大和关闭挪上去，和一级标签同一行（右端），不留一道空着的标签条 */
.rp-body > .rp-primary-tabs:not([hidden]) ~ .rp-section > .rp-tabbar:not(:has(.wtab-strip > .wtab:not([hidden]))) { position: relative; z-index: 2; align-self: flex-end; box-sizing: border-box; height: 42px; margin-top: -43px; padding: 6px 6px 0; border-bottom: 0; background: transparent; }
.wtab.pack-tab { --pack-tab-bg: var(--surface-subtle); position: sticky; left: 0; z-index: 1; padding: 0 9px; background: var(--pack-tab-bg); }
@media (min-width: 1024px) { .wtab.pack-tab { --pack-tab-bg: var(--surface); } }
/* 背包标签钉在标签条最左：后面的标签多了横着滚，它不跟着滚走；滚动按整只标签对齐，钉住的标签后面不会露出半个字 */
.wtab.pack-tab::after { content: ''; position: absolute; top: 0; right: -10px; bottom: 0; left: auto; width: 10px; height: auto; background: linear-gradient(to right, var(--pack-tab-bg), transparent); pointer-events: none; }
.wtab.pack-tab:hover { background: color-mix(in srgb, var(--ink) 5%, var(--pack-tab-bg)); }
.wtab.pack-tab.is-on { background: color-mix(in srgb, var(--ink) 8%, var(--pack-tab-bg)); color: var(--accent-strong); }
.wtab.pack-tab .icon { width: 18px; height: 18px; flex: none; }
/* 物品栏那只标签只剩图标：一级标签已经写着「背包」 */
.wtab.pack-tab .wtab-label { display: none; }
/* 标签两种样子：放得下时每只都是图标 + 名字；放不下时（is-tight）没开着的只剩图标，开着的那只留名字（太长才省略），
   还放不下才横着滚——背包图标后面不会压着半只标签。没开着的标签平时不挂叉，指到它（或键盘停在它上）时叉浮在右端，宽度不跳 */
:is(.rp-section[data-view="pack"], .rp-beside, .sp-primary .rp-section) > .rp-tabbar .wtab:not(.pack-tab) { flex: none; }
:is(.rp-section[data-view="pack"], .rp-beside, .sp-primary .rp-section) > .rp-tabbar .wtab:not(.pack-tab):not(.is-on) > .wtab-label { max-width: 7em; }
:is(.rp-section[data-view="pack"], .rp-beside, .sp-primary .rp-section) > .rp-tabbar .wtab:not(.pack-tab).is-on { flex: 0 1 auto; min-width: 112px; max-width: 176px; }
:is(.rp-section[data-view="pack"], .rp-beside, .sp-primary .rp-section) > .rp-tabbar .wtab:not(.pack-tab).is-on > .wtab-label { min-width: 0; }
:is(.rp-section[data-view="pack"], .rp-beside, .rp-section[data-view="aside"]) > .rp-tabbar .wtab:not(.pack-tab):not(.is-on) > .wtab-close { position: absolute; top: 50%; right: 5px; margin: 0; background: var(--surface-subtle); opacity: 0; transform: translateY(-50%); transition: opacity 120ms ease; }
:is(.rp-section[data-view="pack"], .rp-beside, .rp-section[data-view="aside"]) > .rp-tabbar .wtab:not(.pack-tab):not(.is-on):is(:hover, :focus-visible) > .wtab-close { opacity: 1; }
/* 每只标签前面一颗图标：笔记本、错题本、速查表、资料的格式图标（旁问是那只手） */
.wtab > .wtab-icon { width: 15px; height: 15px; flex: none; }
.wtab > .material-format-icon.wtab-icon { width: 14px; height: 16px; stroke-width: 1.6; }
.wtab > .material-format-icon.wtab-icon text { display: none; }
/* 和物品栏里那几格同一套颜色：笔记蓝、错题本红、速查表黄（只剩图标时也分得清） */
.wtab > .wtab-icon:not(.material-format-icon) { color: var(--accent-strong); }
.wtab.mistakes-tab > .wtab-icon { color: var(--danger); }
.wtab.cheat-tab > .wtab-icon { color: var(--marker-ink); }
/* 标签放不下（side-panel.js 量出来加 is-tight）：没开着的只剩图标、不挂叉，开着的那只留名字 */
:is(.rp-section, .rp-beside) > .rp-tabbar > .wtab-strip.is-tight > .wtab:not(.is-on):not(.pack-tab) { flex: none; min-width: 0; padding: 0 7px; }
:is(.rp-section, .rp-beside) > .rp-tabbar > .wtab-strip.is-tight > .wtab:not(.is-on):not(.pack-tab) > :is(.wtab-label, .wtab-no, .wtab-close) { display: none; }
.wtab > .wtab-no { flex: none; color: var(--faint); font-weight: 500; font-variant-numeric: tabular-nums; }
.wtab.is-on > .wtab-no { color: var(--muted); }
.rp-section[data-view="pack"] > .rp-tabbar .wtab-strip, .rp-beside > .rp-tabbar .wtab-strip { scroll-snap-type: x mandatory; scroll-padding-left: 44px; }
.rp-beside > .rp-tabbar .wtab-strip { scroll-padding-left: 0; }
:is(.rp-section[data-view="pack"], .rp-beside) > .rp-tabbar .wtab:not(.pack-tab) { scroll-snap-align: start; }
/* 笔记助手只跟着笔记页 */
.rp-section[data-view="pack"]:not(:has(#pane-board.is-on)) > .rp-tabbar > .note-agent-launcher { display: none; }
.rp-section[data-view="pack"]:not(:has(#pane-board.is-on)) > .rp-tabbar > .board-focus-toggle { margin-left: auto; }
.rp-beside > .rp-tabbar > .rp-collapse { margin-left: auto; }
#pane-pack.is-on { display: block; padding: 14px 14px 28px; }
/* 旁问一栏还没有标签时，顶上是一枚和背包标签同样的签（图标 + 名字），两栏的标签条一个样子 */
.rp-section .rp-section-title:not([hidden]) { display: inline-flex; flex: none; align-items: center; gap: 6px; height: 30px; margin-right: auto; padding: 0 10px; box-sizing: border-box; border-radius: var(--r-sm); background: color-mix(in srgb, var(--ink) 8%, var(--surface)); color: var(--accent-strong); font-size: var(--fs-ui); font-weight: 600; line-height: 1; }
.rp-section .rp-section-title .icon { width: 17px; height: 17px; flex: none; }
/* 旁问的空白页：一张纸上一段字被划选，从它冒出一个问号气泡（不写字；那句提示只给读屏）。出现时划选先铺开，气泡再弹出来（T1，共 460ms） */
.rp-empty.is-on { flex-direction: column; gap: 0; }
.rp-empty__hint { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.aside-empty-art { width: min(168px, 56%); height: auto; overflow: visible; }
.sp-primary .aside-empty-art { width: 220px; }
.aside-empty-art__paper { fill: var(--surface); stroke: var(--border); stroke-width: 1.5; }
.aside-empty-art__line { fill: none; stroke: var(--border-strong); stroke-width: 4; stroke-linecap: round; }
.aside-empty-art__sel { fill: var(--accent-soft); transform-box: fill-box; transform-origin: left center; }
.aside-empty-art__picked { fill: none; stroke: var(--accent); stroke-width: 4; stroke-linecap: round; }
.aside-empty-art__bubble { transform-box: fill-box; transform-origin: 18% 100%; }
.aside-empty-art__bubble-fill { fill: var(--accent); }
.aside-empty-art__mark { fill: none; stroke: var(--on-accent); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.rp-empty.is-on .aside-empty-art__sel { animation: pack-sel-sweep 260ms cubic-bezier(.3,.8,.4,1) both; }
.rp-empty.is-on .aside-empty-art__picked { animation: pack-fade-in 160ms ease-out 120ms both; }
.rp-empty.is-on .aside-empty-art__bubble { animation: pack-bubble-pop 220ms cubic-bezier(.3,1.5,.5,1) 240ms both; }
@keyframes pack-sel-sweep { from { transform: scaleX(0); } to { transform: none; } }
@keyframes pack-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pack-bubble-pop { 0% { opacity: 0; transform: scale(.5); } 70% { opacity: 1; transform: scale(1.08); } 100% { opacity: 1; transform: none; } }
#pane-pack[hidden], #pane-board[hidden] { display: none; }

/* ---------- 窗口：背包、旁问、地图、计划四个窗口同一副外框 ----------
   左边缘始终在左栏右边 12px（左栏的圆按钮整颗露在遮罩下面），右边离屏幕 16px；右栏开在旁边时只缩宽度、让出右栏。
   最宽 1400px，从顶栏下 16px 到底边 16px */
@media (min-width: 1024px) {
  :root { --pw-left: 68px; --pw-right: 16px; --pw-beside: calc(var(--right-panel-w) + 12px); --pw-top: calc(var(--topbar-h) + 16px); --pw-h: min(940px, calc(100dvh - var(--topbar-h) - 32px)); }
  body.board-focus-mode .sp-primary {
    --pw-w: min(1400px, calc(100vw - var(--pw-left) - var(--pw-right)));
    top: var(--pw-top);
    bottom: auto;
    left: calc(var(--pw-left) + (100vw - var(--pw-left) - var(--pw-right) - var(--pw-w)) / 2);
    width: var(--pw-w);
    height: var(--pw-h);
  }
  body.board-focus-mode:not(.rp-collapsed) .sp-primary { --pw-right: var(--pw-beside); }
  dialog.knowledge-map-page-overlay:not(.route-overlay) { left: var(--pw-left); right: var(--pw-right); width: min(1400px, calc(100vw - var(--pw-left) - var(--pw-right))); height: var(--pw-h); margin: var(--pw-top) auto 16px; }
  dialog.knowledge-map-page-overlay.is-beside-panel:not(.route-overlay) { right: var(--pw-beside); width: min(1400px, calc(100vw - var(--pw-left) - var(--pw-beside))); }
  /* 关窗的叉：四个窗口都是右上角同一处、同一颗白底圆钮（压在浅灰的页签行上） */
  .sp-primary > .rp-section > .rp-tabbar > .rp-collapse,
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close { position: absolute; top: 15px; right: 15px; z-index: 2; display: grid; place-items: center; width: 34px; height: 34px; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: 50%; background: var(--surface); color: var(--ink); box-sizing: border-box; transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease; }
  .sp-primary > .rp-section > .rp-tabbar > .rp-collapse .icon { width: 16px; height: 16px; }
  .sp-primary > .rp-section > .rp-tabbar > .rp-collapse:hover,
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close:hover,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close:hover { border-color: var(--ink); background: var(--ink); color: var(--surface); }
  .sp-primary > .rp-section > .rp-tabbar > .rp-collapse svg,
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close svg,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close svg { transition: transform 160ms ease; }
  .sp-primary > .rp-section > .rp-tabbar > .rp-collapse:hover svg,
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close:hover svg,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close:hover svg { transform: rotate(90deg); }
  .sp-primary > .rp-section > .rp-tabbar > .rp-collapse:active,
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close:active,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close:active { transform: scale(.92); }
  /* 地图、计划窗口的叉原来是一个「×」字：换成和背包、旁问窗口同一个圆叉（同一条路径、同样粗），字只留给读屏 */
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close { font-size: 0; line-height: 0; }
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close::before,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close::before { content: ''; position: absolute; inset: 0; width: 16px; height: 16px; margin: auto; background: currentColor; transition: transform 160ms ease; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center / contain no-repeat; }
  .knowledge-map-page-overlay__panel.has-panel-nav .knowledge-map-page-overlay__close:hover::before,
  .plan-overlay__panel.has-panel-nav .plan-overlay__close:hover::before { transform: rotate(90deg); }
  /* 窗口只有一行页头，和地图、计划窗口的页签行一样高：背包窗口是三个页签在正中，左边是打开的笔记、资料等标签（物品栏就是亮着的「背包」页签，
     不再另挂一只钉住的背包标签），右边收起和关闭；旁问窗口是它的标签行 */
  .sp-primary > .rp-section > .rp-tabbar { position: relative; min-height: 64px; padding: 0 62px 0 18px; box-sizing: border-box; border-bottom: 1px solid var(--border); border-radius: var(--win-radius, var(--r-md)) var(--win-radius, var(--r-md)) 0 0; background: var(--surface-subtle); }
  .sp-primary .rp-section-title:not([hidden]) { height: 36px; padding: 0 14px; font-size: var(--fs-body); }
  .sp-primary.has-panel-nav > .rp-section > .rp-tabbar { --nav-half: 170px; padding-left: 14px; }
  .sp-primary.has-panel-nav > .rp-section > .rp-tabbar > .panel-nav-row { position: absolute; left: 50%; bottom: 0; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; transform: translateX(-50%); }
  .sp-primary.has-panel-nav > .rp-section > .rp-tabbar > .wtab-strip { flex: 0 1 auto; max-width: calc(50% - var(--nav-half) - 30px); }
  .sp-primary.has-panel-nav .wtab.pack-tab { display: none; }
  .sp-primary.has-panel-nav > .rp-section > .rp-tabbar > :is(.note-agent-launcher, .board-focus-toggle) { margin-left: auto; }
  .sp-primary.has-panel-nav > .rp-section > .rp-tabbar > .note-agent-launcher + .board-focus-toggle { margin-left: 0; }
  /* 物品栏之外开着别的标签时，亮着的「背包」页签点了回到物品栏 */
  .sp-primary:has(.wtab-strip > .wtab.is-on:not(.pack-tab)) .panel-nav__tab[aria-current="page"][data-panel="materials"] { cursor: pointer; }
  /* 窗口里地方宽：开着的那只标签写得下全名 */
  .sp-primary :is(.rp-section[data-view="pack"], .rp-section) > .rp-tabbar .wtab:not(.pack-tab).is-on { max-width: 300px; }
}
.sp-primary { background: var(--surface); }
.sp-primary:not([hidden]) { animation: pack-window-in 220ms cubic-bezier(.2,.8,.2,1); }
@keyframes pack-window-in { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
.sp-primary #pane-pack.is-on { width: 100%; max-width: 1080px; margin-inline: auto; padding: 26px 32px 44px; box-sizing: border-box; }
.sp-primary .pack-slots { grid-template-columns: repeat(3, 120px); gap: 22px; margin-bottom: 30px; }
.sp-primary .pack-slot__art { max-width: none; }
/* 笔记窗口的目录：一行一个标题，不把「名义 GDP 与实际 GDP」拆成两行；目录先拿正文两侧的空白（正文那张纸本来就居中、两边有余），
   窗口再窄才省略，全名在悬停提示里 */
.sp-primary .sn-toc { width: min(260px, 30%); }
.sp-primary .sn-toc__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 窗口开着时正文左边页边那一列对话速览收起，左栏和窗口之间那道缝里只有遮罩 */
body.board-focus-mode .chat-rail, body:has(dialog.knowledge-map-page-overlay[open]) .chat-rail { visibility: hidden; }
/* 左栏气泡标题行不挂快捷键键帽：快捷键在左栏圆按钮的悬停提示里（和读屏的 aria-keyshortcuts） */
.sidebar-heading__key { display: none; }
/* 计划窗口和另外几个一样是不透明的白纸（不再透出后面的模糊影子），标签已经写着「计划」，标题不再重复一遍 */
.plan-overlay__panel.has-panel-nav, [data-theme="dark"] .plan-overlay__panel.has-panel-nav { background: var(--surface); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: var(--win-shadow, var(--shadow-modal)); }
.plan-overlay__panel.has-panel-nav .plan-overlay__title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- 窗口顶上的三个标签：背包 / 地图 / 计划，像游戏面板顶上的页签 ----------
   标签行是一道浅灰的底，当前那一页签是白纸、顶上一道蓝边，和下面的面板连成一块；
   换窗口时白页签从上一个滑过来（T0 180ms），新窗口原地淡入，滑到以后那一格的图标轻轻弹一下 */
.panel-nav-row { position: relative; display: flex; flex: none; align-items: flex-end; justify-content: center; min-height: 64px; padding: 0 64px; box-sizing: border-box; border-bottom: 1px solid var(--border); border-radius: var(--win-radius, var(--r-md)) var(--win-radius, var(--r-md)) 0 0; background: var(--surface-subtle); }
.panel-nav { position: relative; display: flex; flex: none; align-items: flex-end; max-width: 100%; gap: 4px; margin-bottom: -1px; }
.panel-nav__thumb { position: absolute; top: 0; bottom: 0; left: 0; width: 0; border: 1px solid var(--border); border-bottom: 0; border-radius: 12px 12px 0 0; background: var(--surface); box-shadow: inset 0 3px 0 var(--accent); pointer-events: none; }
.panel-nav__thumb.is-moving { transition: transform 180ms cubic-bezier(.3,.9,.3,1), width 180ms cubic-bezier(.3,.9,.3,1); }
.panel-nav__tab { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 9px; height: 50px; padding: 2px 22px 0 18px; border: 0; border-radius: 12px 12px 0 0; background: transparent; color: var(--muted); font: 600 var(--fs-body)/1 var(--font-sans); white-space: nowrap; cursor: pointer; transition: color 160ms ease, background-color 160ms ease; }
.panel-nav__tab .icon { width: 22px; height: 22px; flex: none; transition: transform 120ms ease; }
.panel-nav__tab:hover:not(:disabled):not([aria-current]) { color: var(--ink); background: color-mix(in srgb, var(--surface) 55%, transparent); }
.panel-nav__tab:active:not(:disabled):not([aria-current]) .icon { transform: scale(.86); }
.panel-nav__tab[aria-current="page"] { color: var(--ink); cursor: default; transition: none; }
.panel-nav:not(.has-thumb) .panel-nav__tab[aria-current="page"] { background: var(--surface); box-shadow: inset 0 3px 0 var(--accent), inset 1px 0 0 var(--border), inset -1px 0 0 var(--border); }
.panel-nav__tab[aria-current="page"] .icon { color: var(--accent); }
/* 白纸滑过去的 180ms 里，新页签的字和图标还是平常的颜色、旧页签还像选中的；白纸到位时两边一起换色 */
.panel-nav__tab.is-arrived { animation: panel-nav-ink-on 180ms linear both; }
.panel-nav__tab.is-arrived .icon { animation: panel-nav-icon-on 180ms linear both, panel-nav-arrive 200ms cubic-bezier(.3,1.6,.5,1) 180ms both; }
.panel-nav__tab.is-left { animation: panel-nav-ink-off 180ms linear both; }
.panel-nav__tab.is-left .icon { animation: panel-nav-icon-off 180ms linear both; }
@keyframes panel-nav-ink-on { 0%, 72% { color: var(--muted); } 100% { color: var(--ink); } }
@keyframes panel-nav-icon-on { 0%, 72% { color: var(--muted); } 100% { color: var(--accent); } }
@keyframes panel-nav-ink-off { 0%, 72% { color: var(--ink); } 100% { color: var(--muted); } }
@keyframes panel-nav-icon-off { 0%, 72% { color: var(--accent); } 100% { color: var(--muted); } }
@keyframes panel-nav-arrive { 0% { transform: scale(.82); } 60% { transform: scale(1.16); } 100% { transform: none; } }
.panel-nav__tab:disabled { color: var(--faint); opacity: .55; cursor: default; }
.panel-nav__tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
/* 地图窗口：标题就是亮着的「地图」，导出与关闭放到标签那一行的右边 */
.knowledge-map-page-overlay__panel.has-panel-nav { position: relative; }
.knowledge-map-page-overlay__panel.has-panel-nav:not(.plan-overlay__panel) > .knowledge-map-page-overlay__header { position: absolute; top: 15px; right: 15px; z-index: 2; height: 34px; padding: 0; border: 0; background: none; }
.knowledge-map-page-overlay__panel.has-panel-nav:not(.plan-overlay__panel) > .knowledge-map-page-overlay__header .knowledge-map-page-overlay__close { position: relative; top: auto; right: auto; }
.knowledge-map-page-overlay__panel.has-panel-nav:not(.plan-overlay__panel) #knowledgeMapPageTitle { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.plan-overlay__panel.has-panel-nav { grid-template-rows: auto auto minmax(0, 1fr) auto auto; }
/* 从标签切过来的窗口：外框和标签行原地不动，里面的内容淡入（不再从下往上浮） */
.has-panel-nav.is-switched, .sp-primary.has-panel-nav.is-switched:not([hidden]) { animation: none; }
.has-panel-nav.is-switched:not(.sp-primary) > :not(.panel-nav-row), .sp-primary.has-panel-nav.is-switched > .rp-section > .rp-section__body { animation: panel-switch-in 160ms ease-out both; }
@keyframes panel-switch-in { from { opacity: 0; } to { opacity: 1; } }

/* ---------- 物品栏：上面三格（笔记、错题本、速查表），下面资料一页一页 ---------- */
.pack-slots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-bottom: 22px; }
.pack-slot { display: grid; justify-items: center; gap: 7px; min-width: 0; padding: 0; border: 0; background: none; color: var(--ink); font: inherit; cursor: pointer; }
/* 一格：游戏物品栏的方格，底边一道内阴影像嵌在格子里 */
.pack-slot__art { position: relative; display: grid; place-items: center; width: 100%; aspect-ratio: 1; max-width: 96px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface-subtle); box-shadow: inset 0 -3px 0 color-mix(in srgb, var(--ink) 6%, transparent); transition: transform 160ms cubic-bezier(.2,.8,.2,1), border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease; }
.pack-slot__art > svg:first-child { width: 58%; height: 58%; overflow: visible; }
.pack-slot__name { max-width: 100%; overflow: hidden; color: var(--muted); font-size: var(--fs-caption); font-weight: 600; line-height: 1.3; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
/* 悬停只给有指针的设备（触屏点过以后不留着悬停的样子） */
@media (hover: hover) {
  .pack-slot:not(:disabled):hover .pack-slot__art { border-color: var(--border-strong); background: var(--surface); transform: translateY(-2px); box-shadow: inset 0 -3px 0 color-mix(in srgb, var(--ink) 6%, transparent), var(--shadow-pop); }
  .pack-slot:not(:disabled):hover .pack-slot__name { color: var(--ink); }
  .pack-shelf .file-row.is-openable:hover .material-sheet { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: 2px 2px 0 -1px var(--surface), 2px 2px 0 0 var(--border-strong), var(--shadow-pop); }
  .pack-sheet-add:hover { border-color: var(--accent); background: var(--accent-soft); transform: translateY(-2px); }
  .pack-quick__sheet:hover .material-sheet { border-color: var(--border-strong); transform: translateY(-2px); }
}
/* 按下：格子往里一沉（T0） */
.pack-slot:not(:disabled):active .pack-slot__art { transform: scale(.94); box-shadow: inset 0 2px 0 color-mix(in srgb, var(--ink) 8%, transparent); transition-duration: 120ms; }
.pack-slot:focus-visible { outline: none; }
.pack-slot:focus-visible .pack-slot__art { outline: 2px solid var(--accent); outline-offset: 2px; }
.pack-slot:disabled { cursor: default; }
/* 空格子：虚线、画淡一半；上锁的格子右下角一把锁 */
.pack-slot.is-empty .pack-slot__art { border-style: dashed; border-color: var(--border-strong); background: transparent; box-shadow: none; }
.pack-slot.is-empty .pack-slot__art > svg:first-child { opacity: .42; }
.pack-slot.is-empty .pack-slot__name { color: var(--faint); }
/* 速查表格右上角的小点：生成中是蓝点，资料更新过是黄点（和笔记目录行尾的同一个记号） */
.pack-slot__dot { position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.pack-slot__dot.is-stale { background: var(--marker); }
/* 画：笔记是暖纸本子，错题本有一条红丝带和叉，速查表是一页纸上一道闪电 */
.pack-slot .art-cover { fill: var(--surface); stroke: var(--ink); stroke-width: 2; stroke-linejoin: round; }
.pack-slot[data-item="notes"] .art-cover { fill: var(--board-paper); stroke: var(--board-border); }
.pack-slot .art-spine { stroke: var(--accent); stroke-width: 3; stroke-linecap: round; fill: none; }
.pack-slot .art-line { fill: none; stroke: var(--faint); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pack-slot .art-ribbon { fill: var(--danger); stroke: none; }
.pack-slot[data-item="mistakes"] .art-spine { stroke: var(--danger); }
.pack-slot .art-cross { fill: none; stroke: var(--danger); stroke-width: 2.6; stroke-linecap: round; }
.pack-slot .art-bolt { fill: var(--marker); stroke: var(--marker-ink); stroke-width: 1.2; stroke-linejoin: round; }
/* 笔记写了多少：格子底边一道细条（完成色），不写数 */
.pack-slot__meter { position: absolute; left: 14%; right: 14%; bottom: 10%; height: 3px; overflow: hidden; border-radius: 2px; background: var(--border); }
.pack-slot__meter i { --fill: 0; display: block; width: calc(var(--fill, 0) * 100%); height: 100%; border-radius: inherit; background: var(--success); transition: width 400ms ease; }

/* 资料：一页一页（同一个 #materialShelf：平时在物品栏，点「上传资料」搬进上传窗口） */
.pack-shelf { --sheet-w: 92px; }
.sp-primary .pack-shelf { --sheet-w: 132px; }
.pack-shelf__head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }
.pack-group-title { display: inline-flex; flex: none; align-items: center; gap: 7px; color: var(--muted); font-size: var(--fs-caption); font-weight: 600; }
.pack-group-title .icon { width: 16px; height: 16px; color: var(--accent-strong); }
.pack-shelf__head .material-search { flex: 1 1 140px; min-width: 0; max-width: 320px; height: 32px; margin: 0 0 0 auto; padding: 0 12px; box-sizing: border-box; }
.pack-shelf #materialSearchEmpty { margin: 0 0 10px; }
.pack-shelf__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--sheet-w), 1fr)); align-items: start; gap: 18px 12px; }
.pack-shelf__grid > .file-list { display: contents; }
.pack-shelf .material-list-item, .pack-shelf .file-list > li { position: relative; display: flex; flex-direction: column; min-width: 0; margin: 0; padding: 0; border: 0; }
.pack-shelf .material-list-item[hidden], .pack-shelf .file-list > li[hidden] { display: none; }
/* 还没有资料：只有加号那一页，不再配一句话 */
.pack-shelf .file-list > li.empty-materials { display: none; }
.pack-shelf .file-row { position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 8px; width: 100%; padding: 0; border-radius: var(--r-sm); background: none; container-type: inline-size; }
.pack-shelf .file-row.is-openable:hover { background: none; }
.pack-shelf .file-row > .file-state { display: none; }
.pack-shelf .file-open::after { border-radius: var(--r-sm); }
.pack-shelf .file-main { gap: 4px; }
.pack-shelf .file-name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; color: var(--ink); font-size: var(--fs-caption); font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.pack-shelf .file-meta { flex-wrap: wrap; font-size: var(--fs-caption); }
.pack-shelf .file-meta-text:empty { display: none; }
/* 进度画在纸上：解析那一道条和过程说明不再写字（读屏照旧读得到）；本地上传时纸下面一道细条 */
.pack-shelf .material-progress { margin-top: 2px; }
.pack-shelf .material-progress__label, .pack-shelf .material-wait, .pack-shelf .file-upload-hint { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* 状态那句话不上屏（悬停整页纸看得到，读屏照旧读得到），只留下面的「重新识别」钮 */
.pack-shelf .material-status { display: block; height: 0; margin: 0; overflow: visible; color: transparent; font-size: 0; line-height: 0; }
.pack-shelf .material-progress[data-bar="parse"] { display: none; }
.pack-shelf .material-progress[data-bar="upload"]:has(+ .material-progress[data-bar="parse"]:not([data-step="waiting"])) { display: none; }
.pack-shelf .material-progress__track { height: 4px; border-radius: 2px; background: var(--border); }
.pack-shelf .material-progress__track > * { border-radius: inherit; background: var(--accent); }
/* 没读完整的资料：「重新识别」是纸右下角一颗圆钮（一支转圈的箭头），字在悬停提示里 */
.pack-shelf .material-status .material-reparse { position: absolute; top: calc(133.333cqw - 36px); right: 6px; z-index: 3; display: grid; place-items: center; width: 28px; height: 28px; margin: 0; padding: 0; overflow: hidden; border: 1px solid var(--border); border-radius: 50%; background: var(--surface); color: var(--accent-strong); box-shadow: var(--shadow-pop); font-size: 0; text-decoration: none; cursor: pointer; transition: transform 140ms ease, background-color 140ms ease, border-color 140ms ease; }
.pack-shelf .material-status .material-reparse::before { content: ''; width: 15px; height: 15px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19.5 12a7.5 7.5 0 1 1-2.2-5.3'/%3E%3Cpath d='M19.5 4.5v4h-4'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19.5 12a7.5 7.5 0 1 1-2.2-5.3'/%3E%3Cpath d='M19.5 4.5v4h-4'/%3E%3C/svg%3E") center / contain no-repeat; }
.pack-shelf .material-status .material-reparse:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); transform: rotate(-30deg); }
.pack-shelf .material-status .material-reparse:active:not(:disabled) { transform: scale(.9); }
.pack-shelf .material-status .material-reparse:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pack-shelf .material-status .material-reparse:disabled { color: var(--faint); cursor: wait; }
/* 一页纸 */
.material-sheet { --read: 0; position: relative; display: grid; place-items: center; width: 100%; aspect-ratio: 3 / 4; overflow: hidden; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface); box-shadow: 2px 2px 0 -1px var(--surface), 2px 2px 0 0 var(--border); transition: transform 160ms cubic-bezier(.2,.8,.2,1), border-color 160ms ease, box-shadow 160ms ease; }
.material-sheet > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; opacity: 0; transition: opacity 200ms ease; }
.material-sheet.has-thumb > img { opacity: 1; }
/* 深色：资料的页图是一张白纸。整张反过来（白纸变黑、黑字变亮，色相转回原来的颜色），再用 screen 叠在这页纸自己的底色上：
   纸就是周围那层深色面（--surface 等 token），字接近 --ink，彩色的图表保持原来的色相。缩略图、速查表的页图、资料标签里的整页同一种画法；
   照片（图片资料）不反，只压暗一档 */
[data-theme="dark"] :is(.material-sheet, .cs-mark__page, .material-viewer .mv-page) { isolation: isolate; }
[data-theme="dark"] :is(.material-sheet.has-thumb > img, .cs-mark__page > img, .material-viewer:not([data-photo="true"]) .mv-page-image) { filter: invert(1) hue-rotate(180deg) brightness(.9); mix-blend-mode: screen; }
[data-theme="dark"] .material-viewer[data-photo="true"] .mv-page-image { filter: brightness(.82); }
/* 课件页是横的：上下留白用纸自己的底色（不画在图上，深色压暗时留白不会变成黑条） */
.material-sheet.is-slide { background: var(--surface-subtle); }
.material-sheet.is-slide > img { object-fit: contain; object-position: center; }
/* 格式图标：PDF 红、Word 蓝、PPT 黄、表格绿（同 workspace.css 的配色），没认出格式的才是灰的 */
.material-sheet > .material-format-icon, .material-sheet > .icon { position: relative; z-index: 1; width: 36%; height: auto; }
.material-sheet > .icon:not([data-kind]) { color: var(--muted); }
.material-sheet > .material-format-icon[data-kind="image"] { color: var(--muted); }
.material-sheet.has-thumb > .material-format-icon { position: absolute; left: 6px; bottom: 6px; width: 22px; height: 25px; filter: drop-shadow(0 0 2px var(--surface)); }
.pack-shelf .file-row.is-openable:active .material-sheet { transform: scale(.96); transition-duration: 120ms; }
.pack-shelf .file-open:focus-visible::after { outline: none; }
.pack-shelf .file-row:has(.file-open:focus-visible) .material-sheet { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 还在解析：纸上一层淡蓝从下往上涨，顶上一道蓝线是读到的位置 */
.material-sheet.is-reading::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--read, 0) * 100%); border-top: 2px solid var(--accent); background: color-mix(in srgb, var(--accent-soft) 85%, transparent); transition: height 400ms ease; }
.material-sheet.is-reading > img { opacity: .35; }
/* 刚读好（这一页里看着它读完）：纸轻轻跳一下，右上角落一个完成色的钩，停一会儿淡掉（T1） */
.material-sheet__done { position: absolute; top: 6px; right: 6px; z-index: 5; width: 24px; height: 24px; opacity: 0; }
.material-sheet__done circle { fill: var(--success); }
.material-sheet__done path { fill: none; stroke: var(--on-accent); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* 水位一直留到第一页图到了（workspace-pack.js settleReady）：图淡入时水位从原来的高度淡出，不闪一张空白页 */
.material-sheet.is-just-ready { animation: pack-sheet-ready 480ms cubic-bezier(.3,1.2,.4,1); }
.material-sheet.is-just-ready::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--read, 0) * 100%); border-top: 2px solid var(--accent); background: color-mix(in srgb, var(--accent-soft) 85%, transparent); pointer-events: none; animation: pack-level-out 240ms ease-out both; }
.material-sheet.is-just-ready > .material-sheet__done { animation: pack-done-pop 2200ms cubic-bezier(.2,1.3,.4,1) both; }
@keyframes pack-sheet-ready { 0% { transform: none; } 32% { transform: translateY(-12px) scale(1.06); } 64% { transform: translateY(2px) scale(.99); } 100% { transform: none; } }
@keyframes pack-level-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes pack-done-pop { 0% { opacity: 0; transform: scale(.3); } 18% { opacity: 1; transform: scale(1.15); } 26%, 80% { opacity: 1; transform: none; } 100% { opacity: 0; transform: none; } }
/* 解析没读完整 / 失败：纸角一个提醒色 / 错误色的折角（背包、上传窗口、左栏气泡三处一样） */
:is(.file-row, .pack-quick__sheet)[data-material-status="partial"] .material-sheet::before,
:is(.file-row, .pack-quick__sheet)[data-material-status="failed"] .material-sheet::before { content: ''; position: absolute; top: 0; right: 0; z-index: 2; width: 18px; height: 18px; background: linear-gradient(225deg, var(--marker) 50%, transparent 50%); }
:is(.file-row, .pack-quick__sheet)[data-material-status="failed"] .material-sheet::before { background: linear-gradient(225deg, var(--danger) 50%, transparent 50%); }
/* 本地还在上传（还没有服务端记录）或格式不对的行：图标本身就是一页虚线纸 */
.pack-shelf .file-row:not(:has(> .material-sheet)) > .icon { width: 100%; height: auto; aspect-ratio: 3 / 4; padding: 30% 30%; box-sizing: border-box; border: 1px dashed var(--border-strong); border-radius: var(--r-sm); background: var(--surface); color: var(--muted); }
.pack-shelf .file-row.is-failed:not(:has(> .material-sheet)) > .icon { border-color: var(--danger); color: var(--danger); }
.pack-shelf .file-row .caption.err { font-size: var(--fs-caption); line-height: 1.45; }
/* 删除：只在上传窗口里管资料时有（背包里只找、只用）。有指针：指到那一页，左上角出一颗小圆钮（右上角留给折角和读好的钩）；
   触屏：点标题行的垃圾桶进「整理」状态，每页左上角才出删除钮，平时不常驻 */
.pack-shelf:not(.is-in-window) .material-delete.btn { display: none; }
.pack-shelf .material-delete.btn { position: absolute; top: 6px; left: 6px; z-index: 4; width: 26px; height: 26px; margin: 0; border: 1px solid var(--border); border-radius: 50%; background: var(--surface); color: var(--muted); box-shadow: var(--shadow-pop); opacity: 0; visibility: hidden; transform: scale(.85); transition: opacity 140ms ease, transform 140ms ease, color 140ms ease, visibility 140ms; }
@media (hover: hover) { .pack-shelf .material-list-item:is(:hover, :focus-within) .material-delete.btn { opacity: 1; visibility: visible; transform: none; } }
.pack-shelf.is-managing .material-delete.btn { opacity: 1; visibility: visible; transform: none; }
.pack-shelf .material-delete.btn:hover:not([disabled]) { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.pack-manage { display: none; flex: none; place-items: center; width: 32px; height: 32px; padding: 0; border: 1px solid var(--border); border-radius: 50%; background: var(--surface); color: var(--muted); cursor: pointer; transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease, transform 120ms ease; }
.pack-manage .icon { width: 16px; height: 16px; }
.pack-manage:active { transform: scale(.9); }
.pack-manage:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pack-manage[aria-pressed="true"] { border-color: var(--danger); background: var(--danger-soft); color: var(--danger); }
@media (hover: none) { .pack-shelf.is-in-window .pack-manage { display: grid; } }
/* 新来的那一页：从下面弹一下落位（T1），名字在纸落稳后再淡出来（字最后出现） */
.pack-shelf .file-row.is-fresh .material-sheet, .pack-shelf .file-row.is-busy > .icon { animation: pack-sheet-in 420ms cubic-bezier(.34,1.36,.64,1) both; }
.pack-shelf .file-row.is-fresh > .file-main, .pack-shelf .file-row.is-busy > .file-main { animation: pack-text-in 180ms ease-out 260ms both; }
@keyframes pack-sheet-in { from { opacity: 0; transform: translateY(22px) scale(.84); } to { opacity: 1; transform: none; } }
/* 删掉的那一页：缩小、往下沉一点淡出（T1 300ms），删完不再另弹一句话 */
.pack-shelf .material-list-item.is-leaving { pointer-events: none; animation: pack-sheet-out 300ms cubic-bezier(.35,0,.65,1) forwards; }
@keyframes pack-sheet-out { to { opacity: 0; transform: translateY(10px) scale(.78); } }
@keyframes pack-text-in { from { opacity: 0; } to { opacity: 1; } }
/* 加一页：第一格是一张虚线空白页，中间一个加号 */
.pack-sheet-add { display: grid; place-items: center; width: 100%; aspect-ratio: 3 / 4; padding: 0; border: 1.5px dashed var(--border-strong); border-radius: var(--r-sm); background: transparent; color: var(--accent); cursor: pointer; transition: border-color 150ms ease, background-color 150ms ease, transform 150ms ease; }
.pack-sheet-add .icon { width: 26px; height: 26px; stroke-width: 2; }
.pack-sheet-add:active { transform: scale(.95); transition-duration: 120ms; }
.pack-sheet-add:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pack-shelf.is-in-window .pack-sheet-add { display: none; }

/* ---------- 上传窗口：上面是上传方式（紧凑两行），下面是这门课的资料，一页一页 ----------
   窗口顶边固定在顶栏下面，内容变多变少只往下长，不再上下跳；手机上是从底下升起的满宽抽屉 */
/* 删资料的确认窗口盖在上传窗口上面 */
.material-delete-dialog { z-index: calc(var(--z-dialog) + 20); }
.video-link-dialog.upload-dialog { place-items: start center; padding: calc(var(--topbar-h) + 24px) 18px 18px; }
.upload-dialog .upload-window { display: flex; flex-direction: column; width: min(960px, 100%); max-height: calc(100dvh - var(--topbar-h) - 42px); overflow: hidden; border: 1px solid var(--win-border, var(--border)); border-radius: var(--win-radius, var(--r-md)); background: var(--surface); box-shadow: var(--shadow-modal); animation: pack-window-in 200ms cubic-bezier(.2,.8,.2,1); }
.upload-dialog .upload-window > .video-link-dialog__panel { flex: none; display: grid; grid-template-columns: minmax(0, 1fr) 132px; grid-template-areas: "head head" "drop folder" "paste add" "feedback feedback"; align-items: stretch; gap: 14px 12px; width: auto; max-height: none; overflow: visible; padding: 20px 24px 22px; border: 0; border-radius: 0; box-shadow: none; }
.upload-window .upload-dialog__heading { grid-area: head; }
.upload-window .upload-dialog__drop { grid-area: drop; display: grid; grid-template-columns: auto auto; grid-template-areas: "icon text" "formats formats"; align-content: center; justify-content: center; gap: 12px 12px; min-height: 108px; padding: 18px 20px; text-align: left; transition: border-color 150ms ease, background-color 150ms ease; }
.upload-window .upload-dialog__drop > .icon { grid-area: icon; width: 28px; height: 28px; align-self: center; }
.upload-window .upload-dialog__drop strong { grid-area: text; align-self: center; font-size: var(--fs-body); }
.upload-window .upload-dialog__drop > span { grid-area: formats; justify-self: center; }
.upload-window .upload-dialog__drop:active { background: var(--accent-soft); }
/* 触屏点过以后不留着悬停的蓝底 */
@media (hover: none) { .upload-window .upload-dialog__drop:hover:not(:focus-visible):not(:active) { border-color: var(--border-strong); background: var(--canvas); } }
/* 能传什么：一排格式小图标（读屏读那句说明） */
.upload-formats__icons { display: flex; align-items: center; justify-content: center; gap: 8px; }
.upload-formats__icons .material-format-icon { width: 24px; height: 27px; flex: none; stroke-width: 1.4; }
/* 拖放区里的图标默认是蓝的；格式小图标照资料页上的配色：PDF 红、Word 蓝、PPT 黄、图片灰、音频绿 */
.upload-formats__icons .material-format-icon[data-kind="pdf"] { color: var(--danger); }
.upload-formats__icons .material-format-icon[data-kind="doc"] { color: var(--accent-strong); }
.upload-formats__icons .material-format-icon[data-kind="ppt"] { color: var(--marker-ink); }
.upload-formats__icons .material-format-icon[data-kind="image"] { color: var(--muted); }
.upload-formats__icons .material-format-icon[data-kind="audio"] { color: var(--success); }
.upload-formats__icons .material-format-icon__wave { fill: none; stroke: var(--surface); stroke-width: 1.8; stroke-linecap: round; }
.upload-formats__said { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* 选择文件夹：拖放区旁边一张同高的虚线卡，上面一个文件夹 */
.upload-window .upload-dialog__folder { grid-area: folder; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; height: auto; min-height: 108px; padding: 12px 10px; border: 1px dashed var(--border-strong); border-radius: var(--r-md); background: var(--canvas); color: var(--ink); font-size: var(--fs-caption); font-weight: 600; line-height: 1.35; white-space: normal; text-align: center; transition: border-color 150ms ease, background-color 150ms ease, transform 120ms ease; }
.upload-window .upload-dialog__folder::before { content: ''; width: 28px; height: 28px; background: var(--accent-strong); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linejoin='round'%3E%3Cpath d='M3.5 7.5a2 2 0 0 1 2-2h4l2 2.2h7a2 2 0 0 1 2 2v7.8a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linejoin='round'%3E%3Cpath d='M3.5 7.5a2 2 0 0 1 2-2h4l2 2.2h7a2 2 0 0 1 2 2v7.8a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z'/%3E%3C/svg%3E") center / contain no-repeat; }
.upload-window .upload-dialog__folder:hover, .upload-window .upload-dialog__folder:focus-visible { border-color: var(--accent); background: var(--accent-soft); }
.upload-window .upload-dialog__folder:active { transform: scale(.97); }
/* 粘贴框和「添加」同一行、同高、顶边对齐；框上那行小标题只留给读屏（框里的提示已经说了能贴什么） */
.upload-window .upload-dialog__paste { grid-area: paste; gap: 0; }
.upload-window .upload-dialog__paste > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* 一行字正好装下：1 + 11 + 20 + 11 + 1 = 44，不多出来，系统设成「始终显示滚动条」时也不冒滑块 */
.upload-window .upload-dialog__paste textarea { box-sizing: border-box; min-height: 44px; height: 44px; padding-block: 11px; line-height: 20px; resize: none; }
.upload-window .video-link-dialog__actions { grid-area: add; align-self: start; justify-content: stretch; }
.upload-window .video-link-dialog__actions .btn { width: 100%; height: 44px; }
.upload-window .video-link-dialog__feedback { grid-area: feedback; margin: 0 !important; }
/* 上面的上传方式不动，下面的资料自己滚（标题行一直在窗口顶上）；资料这一块的底色铺到窗口底边 */
.upload-window__shelf { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 18px 24px 26px; border-top: 1px solid var(--border); background: color-mix(in srgb, var(--canvas) 55%, var(--surface)); }
.upload-window__shelf .pack-shelf { --sheet-w: 118px; }
/* 资料往下翻时，「资料」与搜索框那一行停在这一块的顶上（底色跟着这一块） */
.upload-window__shelf .pack-shelf__head { position: sticky; top: -18px; z-index: 6; margin: -18px -24px 14px; padding: 18px 24px 10px; background: color-mix(in srgb, var(--canvas) 55%, var(--surface)); }
/* 还没有资料：资料一栏只有加号那一页，不挂搜索框和整理钮 */
.pack-shelf:not(:has(.file-list > li:not(.empty-materials))) .pack-shelf__head :is(.material-search, .pack-manage) { display: none; }
/* 第一次（还没有资料）：只有上传方式 */
.upload-window__shelf:not(:has(.pack-shelf)), .upload-window__shelf:has(.file-list > li.empty-materials:only-child) { display: none; }

/* 还没分类的资料：类别签不写「选类别」，是一枚虚线的空签，里面一个小标签图形（点开选类别；字留给读屏和悬停） */
.pack-shelf .material-use-tag.is-empty { display: inline-grid; place-items: center; width: 30px; padding: 0; font-size: 0; color: var(--muted); }
.pack-shelf .material-use-tag.is-empty::before { content: ''; width: 13px; height: 13px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 12.3V4.8A1.3 1.3 0 0 1 4.8 3.5h7.5l8.4 8.4a1.3 1.3 0 0 1 0 1.8l-7 7a1.3 1.3 0 0 1-1.8 0z'/%3E%3Ccircle cx='8.3' cy='8.3' r='1.4'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 12.3V4.8A1.3 1.3 0 0 1 4.8 3.5h7.5l8.4 8.4a1.3 1.3 0 0 1 0 1.8l-7 7a1.3 1.3 0 0 1-1.8 0z'/%3E%3Ccircle cx='8.3' cy='8.3' r='1.4'/%3E%3C/svg%3E") center / contain no-repeat; }
.pack-shelf .material-use-tag.is-empty:hover { border-color: var(--accent); color: var(--accent-strong); }
.pack-shelf .material-use-tag.is-empty:active { transform: scale(.92); }

/* ---------- 左栏背包气泡：三格 + 最近的几份资料；气泡只有内容那么高，不压住一整列正文 ---------- */
#leftPanel .lp-pane[data-mode="materials"] { padding: 6px 14px 16px; }
.left-side > #leftPanel:has(> .lp-pane.is-on[data-mode="materials"]) { bottom: auto; max-height: calc(100dvh - var(--topbar-h) - 20px); }
.pack-quick .pack-slots { gap: 10px; margin-bottom: 18px; }
.pack-quick .pack-slot__art { max-width: 80px; }
.pack-quick__sheets { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 10px; }
.pack-quick__sheet { display: grid; align-content: start; gap: 5px; min-width: 0; padding: 0; border: 0; background: none; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.pack-quick__sheet .material-sheet { transition: transform 150ms ease, border-color 150ms ease; }
.pack-quick__sheet:active .material-sheet { transform: scale(.95); transition-duration: 120ms; }
.pack-quick__sheet:focus-visible { outline: none; }
.pack-quick__sheet:focus-visible .material-sheet { outline: 2px solid var(--accent); outline-offset: 2px; }
.pack-quick__name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; color: var(--muted); font-size: var(--fs-caption); line-height: 1.35; overflow-wrap: anywhere; }

/* ---------- 资料标签（背包里打开的一份资料）：工具栏只剩图标钮，页码挂在每页左上角的外面 ---------- */
.material-viewer .mv-tool:is([data-act="zoom-out"], [data-act="fit"], [data-act="zoom-in"]) { position: relative; width: 30px; min-width: 30px; height: 30px; padding: 0; border-radius: 50%; font-size: 0; }
.material-viewer .mv-tool:is([data-act="zoom-out"], [data-act="fit"], [data-act="zoom-in"])::before { content: ''; position: absolute; inset: 0; width: 16px; height: 16px; margin: auto; background: currentColor; }
.material-viewer .mv-tool[data-act="zoom-out"]::before { -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E") center / contain no-repeat; }
.material-viewer .mv-tool[data-act="zoom-in"]::before { -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 12h12M12 6v12'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 12h12M12 6v12'/%3E%3C/svg%3E") center / contain no-repeat; }
/* 适宽：两道竖边中间一支左右箭头 */
.material-viewer .mv-tool[data-act="fit"]::before { -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 5v14M20.5 5v14M7 12h10M10 9l-3 3 3 3M14 9l3 3-3 3'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 5v14M20.5 5v14M7 12h10M10 9l-3 3 3 3M14 9l3 3-3 3'/%3E%3C/svg%3E") center / contain no-repeat; }
/* 缩小、适宽、放大：同一排三颗圆钮（平时就有浅底细边的圆），和页码框同高、同一条中线；适宽开着时是淡蓝底蓝色图标。下载也是同样大的一颗，不带底 */
.material-viewer .mv-bar { align-items: center; gap: 4px; }
.material-viewer .mv-page-input { height: 30px; border-radius: 15px; }
.material-viewer .mv-tool:is([data-act="zoom-out"], [data-act="fit"], [data-act="zoom-in"]) { border: 1px solid var(--border); background: var(--surface-subtle); color: var(--muted); transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease, transform 120ms ease; }
.material-viewer .mv-tool:is([data-act="zoom-out"], [data-act="fit"], [data-act="zoom-in"]):hover { border-color: var(--border-strong); background: var(--surface); color: var(--ink); }
.material-viewer .mv-tool[data-act="fit"][aria-pressed="true"] { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: var(--accent-soft); color: var(--accent-strong); }
.material-viewer .mv-download { display: inline-grid; place-items: center; width: 30px; min-width: 30px; height: 30px; padding: 0; border-radius: 50%; }
.material-viewer .mv-tool:active { transform: scale(.9); }
/* 页码小标签挂在每页左上角的外面（页与页之间留出它的高度），不压页面里的字 */
.material-viewer .mv-pages { padding-top: 32px; }
.material-viewer .mv-page + .mv-page { margin-top: 34px; }
.material-viewer .mv-tag { top: auto; bottom: calc(100% + 6px); left: 0; }
/* 深色：整页的纸是 --surface（页图的画法见上面「一页纸」），翻页的那一片底是 --canvas，一页一页分得出来 */
[data-theme="dark"] .material-viewer .mv-page { background: var(--surface); }
/* 整页是图的那一页（没有文字层）：不在页上写「可以整页引用、记重点」，指到它时整页一圈虚线框，说明这一页整页可点 */
.material-viewer .mv-page-hint { display: none !important; }
@media (hover: hover) { .material-viewer .mv-page.is-page-only:not(.is-framed):hover { outline: 1.5px dashed color-mix(in srgb, var(--accent) 70%, transparent); outline-offset: 3px; cursor: pointer; } }

/* ---------- 错题本标签（t-20261027-i1dr B15）：按小节合订，卡片只露题干和两行答案，解析折叠在卡底 ---------- */
/* 右栏里：顶上一条跳转，下面一屏一屏的卡；窗口里：左边是目录（同笔记窗口，类名也是 sn-toc），顶上只剩打印钮 */
.mistakes-pane.rp-pane.is-on { display: flex; height: 100%; min-height: 0; padding: 0; }
.mb { display: flex; flex: 1; min-width: 0; min-height: 0; }
.mb-main { display: flex; flex: 1; flex-direction: column; min-width: 0; min-height: 0; }
.mb-bar { position: relative; display: flex; flex: none; align-items: center; gap: 4px; padding: 5px 8px; border-bottom: 1px solid var(--border); }
.mb-bar[hidden] { display: none; }
.mb-pick { flex: 1; min-width: 0; }
.mb-print { display: grid; flex: none; place-items: center; width: 32px; height: 32px; margin-left: auto; padding: 0; border: 1px solid transparent; border-radius: 50%; background: transparent; color: var(--muted); cursor: pointer; transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease, transform 120ms ease; }
.mb-print:active:not(:disabled) { transform: scale(.9); }
.mb-print:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mb-print:disabled { opacity: .45; cursor: default; }
.mb-scroll { position: relative; flex: 1 1 auto; min-height: 0; padding: 12px 12px 28px; overflow-y: auto; overscroll-behavior: contain; }
.mb-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.mb-empty { margin: 24px 4px; color: var(--muted); font-size: var(--fs-ui); line-height: 1.6; }
.mb-groups { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }
.mb-group__title { display: flex; align-items: baseline; gap: 6px; margin: 0 0 6px; padding: 0 2px; color: var(--ink); font-size: var(--fs-ui); font-weight: 600; line-height: 1.3; }
.mb-group__no { flex: none; color: var(--faint); font-variant-numeric: tabular-nums; font-weight: 400; }
.mb-group__text { min-width: 0; overflow-wrap: anywhere; }
.mb-group__title.is-done, .mb-group__title.is-done .mb-group__no { color: var(--faint); }
/* 两组以内没有跳转，顶上只剩一枚打印钮：不画分隔线，贴着第一组 */
.mb:not(.has-pick) .mb-bar { padding-bottom: 0; border-bottom: 0; }
.mb:not(.has-pick) .mb-scroll { padding-top: 2px; }
.mb:not(.has-pick) .mb-bar[hidden] + .mb-scroll { padding-top: 12px; }
.mb.has-pick .mb-group:first-child > .mb-group__title { display: none; }
.sp-primary .mb.has-pick .mb-group:first-child > .mb-group__title { display: flex; }
/* 窗口里没有顶上那个下拉（有目录）；列居中，不拉满整个窗口 */
.sp-primary .mistakes-pane.is-on { padding: 14px 14px 0; }
.sp-primary .mb-pick { display: none; }
.sp-primary .mb-bar { box-sizing: border-box; width: 100%; max-width: 768px; margin-inline: auto; justify-content: flex-end; padding: 0 24px 6px; border-bottom: 0; }
.sp-primary .mb-scroll { padding: 6px 24px 44px; }
.sp-primary .mb-groups { max-width: 720px; margin-inline: auto; }
.sp-primary .mb-toc { padding-bottom: 44px; }
.rp-beside .mb-groups { max-width: 760px; margin-inline: auto; }

.mistake-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; margin: 0; padding: 0; list-style: none; }
.mistake-card { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; min-width: 0; padding: 9px 12px 7px 14px; border: 1px solid var(--border); border-left: 3px solid var(--danger); border-radius: var(--r-sm); background: var(--surface); }
/* 订正过了（之后答对过）和已掌握：左边那道红边换成绿 */
.mistake-card:is([data-status="reviewed"], [data-status="mastered"]) { border-left-color: var(--success); }
.mistake-card__head { display: flex; align-items: center; gap: 8px; }
.mistake-card.is-fixed:not(.is-mastered) > .mistake-card__q, .mistake-card.is-fixed:not(.is-mastered) > .mistake-card__head { margin-right: 24px; }
.mistake-card__fixed { position: absolute; top: 9px; right: 10px; display: inline-grid; place-items: center; width: 20px; height: 20px; }
.mistake-card__fixed .k-medal { width: 20px; height: 20px; }
.mistake-card__point { min-width: 0; color: var(--faint); font-size: var(--fs-caption); line-height: 1.4; overflow-wrap: anywhere; }
.mistake-card__q { margin: 0; color: var(--ink); font-size: var(--fs-ui); line-height: 1.5; overflow-wrap: anywhere; }
.mistake-card__body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; min-width: 0; }
.mistake-card__answers { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1px; }
.mistake-card__answers p { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 7px; margin: 0; font-size: var(--fs-ui); line-height: 1.5; }
.mistake-card__mark { flex: none; width: 14px; height: 14px; align-self: flex-start; margin-top: calc((1.5em - 14px) / 2); stroke-width: 2.4; }
.mistake-card__text { min-width: 0; max-width: calc(100% - 21px); overflow-wrap: anywhere; }
/* 你写的、参考答案太长时先收到三行，点开解析再看全文 */
.mistake-card:not(.is-open) .mistake-card__text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.mistake-card:not(.is-open) .mistake-card__chosen > .mistake-card__text { -webkit-line-clamp: 2; }
/* 多选的几个选项一个都不收起来：选错的那个正是要看的 */
.mistake-card:not(.is-open) :is(.mistake-card__chosen, .mistake-card__correct).is-multi > .mistake-card__text { display: block; overflow: visible; -webkit-line-clamp: unset; }
.mistake-card__chosen { color: var(--danger); }
/* 选错的划掉；多选里选对的那几个不划（哪个对由后端给，.is-right） */
.mistake-card__chosen > .mistake-card__text > .mistake-card__pick:not(.is-right) { text-decoration: line-through; text-decoration-thickness: 1px; }
/* 试卷小题：题干前一枚小小的试卷记号，不写字 */
.mistake-card__source { display: inline-block; margin-right: 6px; color: var(--faint); vertical-align: -2px; line-height: 1; }
.mistake-card__source > svg { display: block; width: 14px; height: 14px; }
.mistake-card__correct { color: var(--success); }
.mistake-card__correct.is-none { justify-content: flex-end; }
.mistake-card__acts { display: inline-flex; flex: none; align-items: center; align-self: flex-end; gap: 2px; margin: -4px -6px -4px auto; }
.mistake-card__go { position: absolute; top: 9px; right: 9px; display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 1px solid transparent; border-radius: 50%; background: transparent; color: var(--muted); cursor: pointer; transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease, transform 120ms ease; }
.mistake-card__go:active { transform: scale(.9); }
.mistake-card__go:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 错题卡上的箭头挂在答案行末尾（速查表的条目仍是右上角那一颗，上面的基础样式） */
.mistake-card__acts > .mistake-card__go { position: static; width: 28px; height: 28px; }

/* 没有作答：红叉后面一道空着的答题横线；用图片作答：一枚图片记号 */
.mistake-card__chosen.is-blank { align-items: center; }
.mistake-card__chosen.is-blank > .mistake-card__mark { margin-top: 0; align-self: center; }
.mistake-card__blank { display: block; width: min(160px, 60%); height: 14px; border-bottom: 1.5px solid color-mix(in srgb, var(--danger) 55%, var(--border)); }
.mistake-card__photo { display: inline-grid; place-items: center; color: var(--danger); }

/* 「解析」钮挂在正确答案那一行的末尾，不另占一行；展开后，解析、错因、批语都在卡底 */
.mistake-card__more { display: inline-flex; flex: none; align-items: center; gap: 1px; height: 24px; padding: 0 4px 0 8px; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--muted); font: inherit; font-size: var(--fs-caption); line-height: 1; cursor: pointer; transition: background-color 140ms ease, color 140ms ease; }
.mistake-card__more:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mistake-card__chevron { width: 16px; height: 16px; transition: transform 180ms ease; }
.mistake-card.is-open .mistake-card__chevron { transform: rotate(180deg); }
.mistake-card__fold { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: 0fr; transition: grid-template-rows 180ms ease; }
.mistake-card.is-open > .mistake-card__body > .mistake-card__fold, .mistake-card.is-open > .mistake-card__body .mistake-card__fold { grid-template-rows: 1fr; }
.mistake-card__why { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; min-height: 0; overflow: hidden; visibility: hidden; transition: visibility 0s 180ms; }
.mistake-card.is-open .mistake-card__why { visibility: visible; transition-delay: 0s; }
.mistake-card__why > :first-child { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.mistake-card__why p { margin: 0; color: var(--muted); font-size: var(--fs-ui); line-height: 1.65; overflow-wrap: anywhere; }
.mistake-card__why .mistake-card__explain { color: var(--ink); }
.mistake-card__why .mistake-card__personal { padding-left: 10px; border-left: 2px solid var(--danger); }
.mistake-card__why .mistake-card__feedback { padding-left: 10px; border-left: 2px solid var(--marker); }
.mistake-card__why > .mistake-card__personal:first-child, .mistake-card__why > .mistake-card__feedback:first-child { padding-top: 0; border-top: 0; }
.mistake-card__why > .mistake-card__kind:first-child { padding-top: 8px; }
.mistake-card__tag { display: inline-block; margin-right: 6px; padding: 0 7px; border-radius: var(--r-pill); background: var(--danger-soft); color: var(--danger); font-size: 11.5px; font-weight: 600; line-height: 20px; vertical-align: 1px; }

/* 已掌握（连续答对两次）：一行灰字，点开才是整张卡 */
.mistake-card.is-mastered:not(.is-open) { padding: 0 36px 0 0; border-color: transparent; background: transparent; }
.mistake-card.is-mastered:not(.is-open) > .mistake-card__body { display: none; }
.mistake-card__lead { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 34px; margin: 0; padding: 5px 6px 5px 4px; border: 0; border-radius: var(--r-xs); background: transparent; color: var(--muted); font: inherit; text-align: left; cursor: pointer; }
.mistake-card__lead:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.mistake-card.is-mastered.is-open > .mistake-card__lead { padding: 0 28px 0 0; min-height: 30px; align-items: flex-start; }
.mistake-card.is-mastered.is-open > .mistake-card__lead > .mistake-card__mastered { margin-top: 2px; }
.mistake-card__mastered { flex: none; width: 18px; height: 18px; color: var(--success); stroke-width: 2.2; }
.mistake-card.is-mastered .mistake-card__q { min-width: 0; color: var(--muted); }
.mistake-card.is-mastered:not(.is-open) .mistake-card__q { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mistake-card.is-mastered > .mistake-card__go { position: absolute; top: 3px; right: 4px; }
.mistake-card.is-mastered.is-open > .mistake-card__go { top: 6px; right: 6px; }
.mistake-card.is-mastered .mistake-card__more { display: none; }
@media (pointer: coarse) {
  .mistake-card__more { height: 30px; padding: 0 6px 0 10px; }
}
/* 悬停只在真有鼠标的设备上：手机上点一下收起「解析」后，不留着灰底像还按着 */
@media (hover: hover) {
  .mb-print:hover:not(:disabled) { border-color: var(--border); background: var(--surface-subtle); color: var(--accent-strong); }
  .mistake-card__go:hover { border-color: var(--border); background: var(--surface-subtle); color: var(--accent-strong); }
  .mistake-card__more:hover { background: var(--surface-subtle); color: var(--ink); }
  .mistake-card__lead:hover { background: var(--surface-subtle); }
  .mistake-card.is-mastered.is-open > .mistake-card__lead:hover { background: transparent; }
}
/* 窄屏的抽屉里，桌宠站在右下角：册子滚到底，最后一张卡要整张滚到小人和它的提示气泡上面 */
@media (max-width: 1023px) {
  .mb-scroll, .sp-primary .mb-scroll { padding-bottom: 112px; }
}
@media (prefers-reduced-motion: reduce) {
  .mistake-card__fold, .mistake-card__why, .mistake-card__chevron, .mb-print, .mistake-card__more { transition: none; }
}

/* ---------- 删资料的确认：要删的那一页纸在标题左边，删除钮是危险色 ---------- */
.unit-time-panel.pack-delete-panel { display: grid; grid-template-columns: 52px minmax(0, 1fr); grid-template-areas: "sheet title" "actions actions"; align-items: center; gap: 16px 16px; }
.pack-delete-panel__sheet { grid-area: sheet; }
/* 标题里的文件名不在词中间断（「10月18日」不会拆到两行），一个词太长才在任意处换行 */
.pack-delete-panel > h3 { grid-area: title; margin: 0; word-break: keep-all; overflow-wrap: anywhere; }
.pack-delete-panel > .unit-time-actions { grid-area: actions; }
.pack-delete-panel__sheet[data-material-status="partial"]::before, .pack-delete-panel__sheet[data-material-status="failed"]::before { content: ''; position: absolute; top: 0; right: 0; z-index: 2; width: 14px; height: 14px; background: linear-gradient(225deg, var(--marker) 50%, transparent 50%); }
.pack-delete-panel__sheet[data-material-status="failed"]::before { background: linear-gradient(225deg, var(--danger) 50%, transparent 50%); }
.pack-said { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.btn.btn-primary.pack-danger { border-color: var(--danger); background: var(--danger); color: var(--on-accent); }
.btn.btn-primary.pack-danger:hover { border-color: color-mix(in srgb, var(--danger) 82%, var(--ink)); background: color-mix(in srgb, var(--danger) 82%, var(--ink)); }
.btn.btn-primary.pack-danger:active { transform: scale(.96); }
.btn.btn-primary.pack-danger:focus-visible { outline: 2px solid var(--danger); outline-offset: 2px; }

@media (max-width: 1023px) {
  .upload-dialog .upload-window > .video-link-dialog__panel { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "head head" "drop drop" "folder folder" "paste add" "feedback feedback"; padding: 16px 16px 18px; }
  .upload-window .upload-dialog__drop { min-height: 96px; }
  .upload-window .upload-dialog__folder { flex-direction: row; min-height: 44px; padding: 8px 14px; }
  .upload-window .upload-dialog__folder::before { width: 20px; height: 20px; }
  .upload-window .video-link-dialog__actions .btn { width: auto; min-width: 76px; }
  .upload-window__shelf { padding: 16px 16px 22px; }
  .upload-window__shelf .pack-shelf__head { top: -16px; margin: -16px -16px 12px; padding: 16px 16px 10px; }
  .upload-window__shelf .pack-shelf { --sheet-w: 92px; }
}
/* 手机：上传窗口是从底下升起的满宽抽屉，左右不留缝，不会偏出屏幕 */
@media (max-width: 767px) {
  .video-link-dialog.upload-dialog { place-items: end stretch; padding: 0; }
  /* 有资料时抽屉占满到顶栏下面、高度固定（搜索时不跟着矮下去）；第一次只有上传方式，就只有那么高 */
  .upload-dialog .upload-window:has(> .upload-window__shelf .file-list > .material-list-item) { height: calc(100dvh - var(--topbar-h)); }
  .upload-dialog .upload-window { width: 100%; max-height: calc(100dvh - var(--topbar-h)); box-sizing: border-box; border-width: 1px 0 0; border-radius: var(--win-radius, var(--r-md)) var(--win-radius, var(--r-md)) 0 0; padding-bottom: env(safe-area-inset-bottom); animation: pack-sheet-up 260ms cubic-bezier(.2,.8,.2,1); }
  @keyframes pack-sheet-up { from { transform: translateY(32px); opacity: 0; } to { transform: none; opacity: 1; } }
}

/* 手机上地图、计划窗口顶上的页签行（t-20261026-wybz 整合）：三个页签靠左排、收窄，右边让出导出和关闭两颗键的位子，不叠在一起；
   没亮着的页签只留图标（字留给读屏），亮着的那一个写字 */
@media (max-width: 559px) {
  .panel-nav-row { min-height: 54px; padding: 0 96px 0 10px; justify-content: flex-start; }
  .panel-nav__tab { height: 44px; gap: 6px; padding: 2px 13px 0; font-size: var(--fs-ui); }
  .panel-nav__tab:not([aria-current="page"]) > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .knowledge-map-page-overlay__panel.has-panel-nav:not(.plan-overlay__panel) > .knowledge-map-page-overlay__header { top: 10px; right: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar-item .pack-upload, .sidebar-item .pack-upload.is-empty, .pack-upload.is-done .pack-upload__ring, .pack-upload.is-done .pack-upload__fill, .sidebar-item .pack-upload.is-empty .abar-tip, #leftDrawerBtn.has-upload-call, .sidebar-item .pack-upload.is-empty[data-call="visiting"], #leftDrawerBtn.has-upload-call[data-call="visiting"] { animation: none; transition: none; }
  .sidebar-item .pack-upload.is-empty .abar-tip { opacity: 1; transform: translate(0, -50%); }
  .pack-upload__ring, .pack-upload__ring .pack-upload__fill, .pack-slot__meter i, .material-sheet.is-reading::after, .panel-nav__thumb.is-moving { transition: none; }
  .rp-empty.is-on :is(.aside-empty-art__sel, .aside-empty-art__picked, .aside-empty-art__bubble), .pack-shelf .material-list-item.is-leaving { animation: none; }
  .pack-shelf .file-row.is-fresh .material-sheet, .pack-shelf .file-row.is-busy > .icon, .pack-shelf .file-row.is-fresh > .file-main, .pack-shelf .file-row.is-busy > .file-main, .sp-primary:not([hidden]), .upload-dialog .upload-window, .has-panel-nav.is-switched:not(.sp-primary) > :not(.panel-nav-row), .sp-primary.has-panel-nav.is-switched > .rp-section > .rp-section__body, .material-sheet.is-just-ready, .panel-nav__tab.is-arrived, .panel-nav__tab.is-arrived .icon, .panel-nav__tab.is-left, .panel-nav__tab.is-left .icon { animation: none; }
  .material-sheet.is-just-ready > .material-sheet__done { animation: none; opacity: 1; }
  .material-sheet.is-just-ready::after { animation: none; opacity: 0; }
  .pack-slot__art, .material-sheet, .pack-sheet-add, .panel-nav__tab, .panel-nav__tab .icon, .upload-window .upload-dialog__folder, .mistake-card__go, .pack-shelf .material-status .material-reparse, .pack-shelf .material-delete.btn, .pack-manage { transition: none; }
  .pack-slot:not(:disabled):hover .pack-slot__art, .pack-shelf .file-row.is-openable:hover .material-sheet, .pack-sheet-add:hover, .pack-quick__sheet:hover .material-sheet, .pack-shelf .material-status .material-reparse:hover:not(:disabled) { transform: none; }
}

/* t-20261026-wybz fixA：资料页缩略图上的页码签不压在页面上（课件的标题常常就在左上角）。
   回答里的课件页卡片：页码签挪到页底那一行、文件名前面，还是那一枚签（记了整页重点变黄、框起来变蓝，workspace.css）；
   知识点浮窗里的一手页卡：页码挪到卡面左下角（像印在页脚的页码），不压页顶的标题 */
.material-page-card.has-actions { display: grid; grid-template-columns: minmax(0, 1fr); }
.material-page-card.has-actions > .material-page-face { grid-row: 1; grid-column: 1; }
.material-page-card.has-actions > figcaption { grid-row: 2; grid-column: 1; padding-left: 52px; }
.material-page-card.has-actions > .material-page-tag { position: relative; top: auto; left: auto; grid-row: 2; grid-column: 1; align-self: start; justify-self: start; margin: 8px 0 0 14px; }
.km-card .km-card__no { top: auto; bottom: 5px; }

/* t-20261027-i1dr b7 左栏知识地图钮的外圈：后台建图中一圈细线，存好几批走到几分之几；不缓动，建好就撤掉 */
.abar-ring { position: absolute; inset: -5px; width: calc(100% + 10px); height: calc(100% + 10px); fill: none; pointer-events: none; transform: rotate(-90deg); opacity: 0; }
.abar-ring circle { stroke: var(--border); stroke-width: 2.5; }
.abar-ring .abar-ring__fill { stroke: var(--accent); stroke-linecap: round; stroke-dasharray: calc(var(--read, 0) * 100) 100; opacity: calc(var(--read, 0) * 100); }  /* 一批都没存下时不画：圆头线帽加零长度的线段会留一个蓝点 */
.abar-btn.is-building .abar-ring { opacity: 1; }
