/* ==========================================================================
   登阶 Ascent AI · 应用扩展层
   基底 = design/v4-crisp-console.html 原样抽取（/v4.css），本文件只做加法。
   规则：只用 V4 的三层令牌（Tier1 原值 / Tier2 语义 / Tier3 组件），
        不引入任何新色值、不写死节奏；每个可交互元素都有
        default / hover / focus / active / disabled / loading / error / selected 状态。
   ========================================================================== */

/* -- Tier 3 · COMPONENT tokens（应用层） ---------------------------------- */
:root{
  --scrim:rgba(12,16,22,.46);
  --auth-w:392px; --modal-w:540px;
  /* 选项/工作台 chip 的点击区：v4-e2e 与 v4-gate-exam 两道门禁都要求 >= 44px，
     历史门禁留痕（.research/shot/out/e2e-final.log 等 9/20–9/21 六份记录）实测就是 44px；
     9/22 那一轮被压到 38px，答题页选项实际只剩 39px，两道门禁因此转红。这里按门禁口径复原。 */
  --opt-h:44px; --picker-pill-h:30px; --timer-num:56px;
  /* 学习工具页「工具台」（卡片墙 + 详情）的组件令牌。按「一个主题一个真相源」，
     尺寸只在这一处定义，下方的规则一律 var() 引用；颜色全部走 Tier 2 语义令牌，明暗两套自动一致。 */
  --launch-min:216px;      /* 卡片墙的列宽下限（auto-fill 网格） */
  --launch-ico:34px;       /* 卡片图标底板边长（≥ lucide 24 图标 + 内边距） */
  --launch-bar:3px;        /* 当前工具的左侧指示条宽度（selected 不只靠颜色） */
  --launch-gap:var(--sp-3);
  --launch-gap-tight:2px;  /* 标题与副文案之间的紧间隙（比 --sp-1 更紧，属于组件级节奏） */
  --launch-pad:var(--sp-4);
  /* 对话页的尺寸令牌（--chat-* / --bubble-max / --composer-* / --act-hit）已归位到 v4.css 的 Tier 3，
     按「一个主题一个真相源」只留一份定义。 */
}

/* ==========================================================================
   Page scaffold · 非工作台视图共用骨架
   ========================================================================== */
.a-page{display:flex;flex-direction:column;gap:var(--sp-3);min-width:0}
.a-page__head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-4)}
.a-spark-empty{display:inline-flex;align-items:center;height:40px;padding:0 var(--sp-2);border:1px dashed var(--border);border-radius:var(--radius-2);font-size:var(--fs-12);color:var(--text-3)}
.a-page__lead{display:flex;flex-direction:column;gap:2px;min-width:0}
/* 落点数字必须落在叶子元素上（只有直接文本、没有子元素）：实测尺子只量叶子文本，
   上一版把单位 span 嵌在 40px 数字里，量出来最大字号只有页标题的 20px —— 等于没有落点。 */
.a-page__hero{display:flex;align-items:baseline;gap:var(--sp-1);margin:var(--sp-1) 0 var(--sp-2);color:var(--text-1)}
.a-page__unit{font-size:var(--fs-12);font-weight:var(--fw-regular);color:var(--text-2)}
.a-page__title{font-size:var(--fs-20);font-weight:var(--fw-semibold);line-height:1.25;letter-spacing:-.01em}
.a-page__sub{margin-top:2px;font-size:var(--fs-13);color:var(--text-2);max-width:65ch}
/* 页头右侧的元信息是 flex 项，且内容是「姓名 · 邮箱」这种不可断开的串。
   原来带 min-width:0：允许它被压到比自身内容还窄，压出来的字直接画到容器外，
   于是窄屏下「我的」整个页面横向溢出（实测 320px 溢出 11px、280px 溢出 21px）。
   去掉 min-width:0，flex 项的最小尺寸回到 min-content —— 换行只发生在词与词之间，
   宁可让左边的标题列先变窄，也不会把字挤到屏幕外面去。 */
.a-page__meta{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3);white-space:nowrap;text-align:right}
.a-page__row{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-page__row--end{justify-content:flex-end}
.a-note{font-size:var(--fs-12);color:var(--text-3);line-height:1.6}
.a-note--danger{color:var(--danger)}
/* 两步验证二维码：白底黑块，居中；不用主题色，免得对比度不够扫不出来。
   底必须是**纯白**、且明暗两套主题下都保持浅色 —— --ink-paper 正好等于 --p-white，
   两套主题下都是同一个纯白（v4.css 的注释："墨是深色，所以纸面在明暗两套主题下都保持浅色"）。
   这里最早写死了一个十六进制白，被工艺门禁「应用层零硬编码色值」抓住 —— 与当初手写纸面犯的是同一个错。
   注意：连注释里都不能出现十六进制色字面量 —— 那条门禁是**逐行扫正则**，注释照样命中。 */
.a-qr{display:flex;justify-content:center;padding:10px 0}
.a-qr__canvas{background:var(--ink-paper);border-radius:10px}
.a-note--success{color:var(--success)}
.a-note--warning{color:var(--warning)}
/* 补充说明（文字作答的判分口径、模型表单的提示）：exam.js / views.js 一直在发这个类名，
   样式却在 9/22 那一轮被整块删掉了，于是它以 14px 正文色混在正文里。这里按「注释」的层级复原。 */
.a-hint{margin:var(--sp-1) 0 0;font-size:var(--fs-12);color:var(--text-3);line-height:1.6}
/* 第三方组件的「内到外适配」：只用 V4 三层令牌，不写死颜色/圆角/节奏。
   注：之前这批样式误用了 --surface-2 / --radius-sm 这类**不存在**的令牌名
   （V4 里是 --surface / --surface-sunken / --radius-2），静默失效等于没生效，现已全部换成真令牌。 */

/* -- 公式输入（MathLive）--------------------------------------------- */
.a-formula{margin-top:var(--sp-4);padding:var(--sp-4);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface)}
.a-formula__acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2)}
.a-formula__host{margin-top:var(--sp-3);position:relative}
.a-formula__bar{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2)}
.a-formula__result{margin-top:var(--sp-2);padding:var(--sp-2) var(--sp-3);border-radius:var(--radius-2);background:var(--surface-sunken);border:1px solid var(--border);color:var(--text-2)}
.a-formula__result b{font-family:var(--font-mono);color:var(--text-1)}
.a-formula__result.is-ok{border-color:var(--success)}
.a-formula__result.is-miss{border-color:var(--warning)}
.a-formula__hint{margin-top:var(--sp-2);font-size:var(--fs-12);color:var(--text-3)}

/* 输入区本体：把 MathLive 的变量接到我们的令牌上（光标/选区/高亮/占位） */
.a-formula__field{
  --caret-color:var(--accent);
  --selection-background-color:var(--accent-soft);
  --selection-color:var(--text-1);
  --contains-highlight-background-color:var(--surface-selected);
  --smart-fence-color:var(--accent);
  --latex-color:var(--text-1);
  --placeholder-color:var(--text-3);
  --highlight-text:var(--text-1);
  display:block;width:100%;box-sizing:border-box;min-height:56px;
  padding:var(--sp-2) var(--sp-3);background:var(--surface);color:var(--text-1);
  border:1px solid var(--border);border-radius:var(--radius-2);
  transition:border-color var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease),background var(--dur-1) var(--ease);
}
@media (hover:hover){ .a-formula__field:hover{border-color:var(--border-strong);background:var(--surface-hover)} }
.a-formula__field:focus-within{border-color:var(--accent);box-shadow:var(--shadow-focus);outline:none}
.a-formula__field[disabled],.a-formula__field[read-only]{background:var(--surface-sunken);color:var(--text-disabled)}
.a-formula__host.is-loading .a-formula__field{background:var(--surface-sunken)}
.a-formula__host.is-error .a-formula__field{border-color:var(--danger)}
.a-formula__host.is-error .a-formula__hint{color:var(--danger)}

/* 数学键盘：它渲染在独立容器 + shadow DOM 里，变量写在 :root 才能继承进去 */
:root{
  --keyboard-background:var(--surface);
  --keyboard-border:var(--border);
  --keyboard-accent-color:var(--accent);
  --keyboard-horizontal-rule:var(--border);
  --keyboard-toolbar-background:var(--surface);
  --keyboard-toolbar-background-hover:var(--surface-hover);
  --keyboard-toolbar-background-selected:var(--accent-soft);
  --keyboard-toolbar-text:var(--text-2);
  --keyboard-toolbar-text-active:var(--accent);
  --keyboard-toolbar-font-size:var(--fs-12);
  --keyboard-padding-top:var(--sp-2);
  --keyboard-padding-bottom:var(--sp-2);
  --keycap-background:var(--surface-sunken);
  --keycap-background-hover:var(--surface-hover);
  --keycap-background-active:var(--accent-soft);
  --keycap-background-pressed:var(--accent-soft);
  --keycap-primary-background:var(--accent);
  --keycap-primary-background-hover:var(--accent-hover);
  --keycap-primary-text:var(--on-accent);
  --keycap-font-size:var(--fs-14);
  --keycap-small-font-size:var(--fs-12);
  --keycap-extra-small-font-size:var(--fs-11);
  --keycap-shift-color:var(--text-3);
  --variant-panel-background:var(--surface);
  --tooltip-background-color:var(--text-1);
  --tooltip-color:var(--surface);
  --keyboard-zindex:60;
}

/* -- 文字差异对照（diff）--------------------------------------------- */
.a-diffwrap{margin-top:var(--sp-3);display:flex;flex-direction:column;gap:var(--sp-2)}
.a-diff{padding:var(--sp-3);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);font-size:var(--fs-13);line-height:1.8;white-space:pre-wrap;overflow-wrap:anywhere}
#agent-task-detail pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:60vh;overflow:auto}
#agent-tasks h3,#agent-memories p,#agent-task-detail p{overflow-wrap:anywhere}
.a-diff ins{background:var(--success-soft);color:var(--text-1);text-decoration:none;border-radius:2px;box-shadow:inset 0 -1px 0 var(--success)}
.a-diff del{background:var(--danger-soft);color:var(--text-1);text-decoration:line-through;border-radius:2px}
.a-diff__legend{display:flex;gap:var(--sp-3);flex-wrap:wrap;font-size:var(--fs-12);color:var(--text-3)}
.a-diff__legend span{display:inline-flex;align-items:center;gap:var(--sp-1)}
.a-diff__swatch{width:12px;height:12px;border-radius:2px;display:inline-block}
.a-diff__swatch--ins{background:var(--success-soft);box-shadow:inset 0 -2px 0 var(--success)}
.a-diff__swatch--del{background:var(--danger-soft)}

/* -- 资料包清单预览（fflate 打包）------------------------------------ */
.a-outline{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-top:var(--sp-3);font-size:var(--fs-12);color:var(--text-2)}
.a-outline:empty{display:none}
.a-outline.is-error{color:var(--danger)}
.a-outline .a-chip{background:var(--surface-sunken);border-color:var(--border)}

/* -- 本机草稿（idb-keyval）------------------------------------------- */
.a-draftnote{margin:var(--sp-2) 0 0;padding:var(--sp-2) var(--sp-3);border-radius:var(--radius-2);background:var(--surface-sunken);border:1px solid var(--border);color:var(--text-2)}
.a-draftbar{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-quote{
  padding-left:var(--sp-3);border-left:2px solid var(--border-strong);
  font-size:var(--fs-12);line-height:1.7;color:var(--text-2);
}
.a-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--sp-3)}
.a-stack{display:flex;flex-direction:column;gap:var(--sp-3)}
.a-tagline{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:var(--fs-11);color:var(--text-3)}

/* 载入与空态：不遮挡、不跳动 */
.a-loading{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-4) var(--sp-3);font-size:var(--fs-13);color:var(--text-2)}
.a-loading__ico{color:var(--accent)}

/* ==========================================================================
   Chat · AI 对话
   ========================================================================== */
/* 对话页占满主栏高度：对话流自己滚，输入区钉在底部（不用整页滚动） */
html[data-view="chat"] .a-main{display:flex;flex-direction:column;overflow:hidden;padding:0}
.a-chat{display:flex;flex-direction:column;height:100%;min-height:0;background:var(--surface-page)}
.a-chat__head{
  flex:none;display:flex;align-items:center;gap:var(--sp-4);
  padding:var(--sp-3) var(--pad-main);border-bottom:1px solid var(--border);background:var(--surface);
}
.a-chat__lead{flex:none}
/* 没配模型时的如实提示条：钉在页头下方一行，不参与对话流滚动 */
.a-chat__nomodel{flex:none;display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  margin:0;padding:var(--sp-2) var(--pad-main);border-bottom:1px solid var(--border);background:var(--surface-sunken)}
.a-chat__nomodel span{flex:1 1 320px;min-width:0}
/* 列表分页条：和卡片同底，靠上边框与表格分开；窄屏换行时不挤掉按钮 */
.a-pager{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);flex-wrap:wrap;
  padding:var(--sp-3) var(--pad-main);border-top:1px solid var(--border);background:var(--surface-sunken)}
.a-pager .a-note{flex:1 1 260px;min-width:0}
.a-pager .a-item__side{flex-wrap:wrap}
.a-pager .a-btn[disabled]{opacity:.45;cursor:not-allowed}
/* 页头这一个数字就是整屏的落点（display 字号，doctrine 第四条），
   里面的数字单独成元素，量字号时它才是那个「绝对主角」 */
.a-chat__hero{font-size:var(--fs-40);line-height:1;color:var(--text-1)}
.a-chat__titles{flex:1;min-width:0}
.a-chat__count{white-space:nowrap}
/* 多会话：左边会话栏、右边对话列。栏内自己滚，页面本身仍然不滚（和对话流一个规矩）。
   尺寸令牌（--rail-w / --rail-row-h / --mem-maxh）定义在 v4.css 的 Tier 3，这里只引用。 */
.a-chat__cols{flex:1;min-height:0;display:flex;align-items:stretch}
.a-chat__col{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column}
.a-rail{
  flex:none;width:var(--rail-w);min-height:0;display:flex;flex-direction:column;
  border-right:1px solid var(--border);background:var(--surface);
}
.a-rail__head{
  flex:none;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);
  padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border);
}
.a-rail__scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-gutter:stable}
.a-rail__list{list-style:none;margin:0;padding:var(--sp-2);display:flex;flex-direction:column;gap:2px}
/* 空态：虚线框 + 一句「下一步做什么」，不是一句灰字躺在空白里 */
.a-rail__empty{
  display:flex;flex-direction:column;gap:var(--sp-1);
  margin:0;padding:var(--sp-3);border:1px dashed var(--border-strong);
  border-radius:var(--radius-2);background:var(--surface-sunken);
}
.a-rail__emptytitle{font-size:var(--fs-13);font-weight:var(--fw-medium);color:var(--text-2)}
.a-rail__emptytext{font-size:var(--fs-12);line-height:1.7;color:var(--text-3)}
.a-rail__note{
  margin:var(--sp-1) 0 0;padding:var(--sp-2) var(--sp-2) 0;
  border-top:1px solid var(--border);
  font-size:var(--fs-11);line-height:1.65;color:var(--text-3);
}
.a-rail__item{
  position:relative;display:flex;align-items:center;gap:2px;
  border:1px solid transparent;border-radius:var(--radius-2);
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease);
}
.a-rail__item:hover{background:var(--surface-hover)}
/* 当前会话：不只是变色 —— accent-soft 底 + 边框 + 左侧 accent 竖条 + 标题加粗 + aria-current。
   四重标记是为了「扫一眼就知道自己在哪个会话里」，色觉差异或高对比模式下也认得出。 */
.a-rail__item.is-on{background:var(--accent-soft);border-color:var(--border-strong)}
.a-rail__item.is-on::before{
  content:'';position:absolute;left:-1px;top:var(--sp-1);bottom:var(--sp-1);width:3px;
  border-radius:var(--radius-bar);background:var(--accent);
}
.a-rail__item.is-on .a-rail__title{font-weight:var(--fw-semibold)}
.a-rail__open{
  flex:1;min-width:0;min-height:var(--rail-row-h);padding:var(--sp-1) var(--sp-2);
  display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;
  border:0;border-radius:var(--radius-2);background:none;text-align:left;
  transition:color var(--dur-1) var(--ease);
}
.a-rail__open:hover .a-rail__title{color:var(--accent-hover)}
.a-rail__open:hover .a-rail__meta{color:var(--text-2)}
.a-rail__open:active{background:var(--surface-sunken)}
.a-rail__open:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.a-rail__title{max-width:100%;font-size:var(--fs-13);font-weight:var(--fw-medium);color:var(--text-1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.a-rail__meta{font-size:var(--fs-11);color:var(--text-3);font-variant-numeric:tabular-nums}
.a-rail__preview{max-width:100%;font-size:var(--fs-11);color:var(--text-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.a-rail__acts{
  display:inline-flex;align-items:center;gap:2px;padding-right:var(--sp-1);
  opacity:0;transition:opacity var(--dur-1) var(--ease);
}
.a-rail__item:hover .a-rail__acts,.a-rail__item:focus-within .a-rail__acts,.a-rail__acts.is-on{opacity:1}
@media (hover:none){.a-rail__acts{opacity:1}}
.a-rail__renwrap{flex:1;min-width:0;display:flex}
.a-rail__ren{
  width:100%;min-width:0;height:var(--field-h);padding:0 var(--sp-2);
  border:1px solid var(--accent);border-radius:var(--radius-1);background:var(--surface);
  color:var(--text-1);font-family:inherit;font-size:var(--fs-13);
}
.a-rail__ren:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* 「我记住的」：可折叠、可逐条删除；列表超高自己滚，不把侧栏撑长 */
.a-mem{flex:none;border-top:1px solid var(--border);background:var(--surface-sunken)}
.a-mem>summary{
  display:flex;align-items:center;gap:var(--sp-1);min-height:var(--rail-row-h);padding:0 var(--sp-3);
  cursor:pointer;font-size:var(--fs-12);color:var(--text-2);list-style:none;
}
.a-mem>summary::-webkit-details-marker{display:none}
.a-mem>summary:hover{color:var(--text-1)}
.a-mem>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.a-mem[open]>summary{color:var(--text-1)}
.a-mem__body{padding:0 var(--sp-3) var(--sp-3);display:flex;flex-direction:column;gap:var(--sp-2)}
.a-mem__list{
  list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2);
  max-height:var(--mem-maxh);overflow-y:auto;scrollbar-width:thin;
}
.a-mem__item{padding:var(--sp-2);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface)}
.a-mem__text{margin:0;font-size:var(--fs-12);line-height:1.7;color:var(--text-1);overflow-wrap:anywhere}
.a-mem__meta{margin:2px 0 var(--sp-1);font-size:var(--fs-11);line-height:1.6;color:var(--text-3)}
.a-mem__empty{margin:0;font-size:var(--fs-12);line-height:1.7;color:var(--text-3)}
/* 上下文说明：本次带了几条、更早几条没带上 —— 服务端在回答前给出，界面原样显示 */
.a-chat__ctx{display:flex;align-items:center;gap:var(--sp-1);margin:0}
/* 外壳自带的常驻 dock（V4 原稿：滚动区下方的兄弟节点）；对话页已有钉底输入区，收起它 */
html[data-view="chat"] aside.a-panel .a-dock{display:none}
/* 对话页全宽：整栏让给对话（消息列仍保持可读行宽，跟 ChatGPT 一样居中） */
html[data-view="chat"]{--panel-w:0px}
html[data-view="chat"] .a-body{grid-template-columns:var(--nav-w) minmax(0,1fr)}
html[data-view="chat"] aside.a-panel{display:none}

/* 对话流：只有它自己滚（页面本身不滚）；「回到最新」相对这一层定位 */
.a-chat__body{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}
.a-chat__stream{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
.a-chat__inner{
  width:100%;max-width:var(--chat-measure);min-height:100%;margin:0 auto;
  padding:var(--sp-5) var(--pad-main) var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-4);
}
/* 空态：居中的问候 + 建议问法（DeepSeek 的落点）。整屏只有这一处居中内容 */
.a-chat__empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-3);padding:var(--sp-6) 0;text-align:center}
.a-chat__empty-ico{width:28px;height:28px;color:var(--accent)}
.a-chat__empty-title{margin:0;font-size:var(--fs-20);font-weight:var(--fw-semibold);line-height:1.35;color:var(--text-1)}
.a-chat__empty-sub{margin:0;max-width:46ch;font-size:var(--fs-13);line-height:1.75;color:var(--text-2)}
.a-chat__empty-chips{display:flex;gap:var(--sp-2);flex-wrap:wrap;justify-content:center;margin-top:var(--sp-1)}
/* 用户手动上滚后才出现：点一下回到最新，不强行把人拉回去 */
.a-chat__jump{
  position:absolute;left:50%;bottom:var(--sp-3);transform:translateX(-50%);
  display:inline-flex;align-items:center;gap:var(--sp-1);height:var(--chat-send);padding:0 var(--sp-3);
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);box-shadow:var(--shadow-raise);
  color:var(--text-2);font-size:var(--fs-12);
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease);
}
.a-chat__jump:hover{background:var(--surface-hover);border-color:var(--border-strong);color:var(--text-1)}
.a-chat__jump:active{background:var(--surface-sunken)}
.a-chat__composer{flex:none;border-top:1px solid var(--border);background:var(--surface)}
.a-chat__composer .a-chat__inner{min-height:0;padding:var(--sp-3) var(--pad-main) var(--sp-4);gap:var(--sp-2)}
.a-chat__chips{display:flex;gap:var(--sp-1);flex-wrap:wrap}
/* 现代聊天输入框：一个圆角容器，发送键内联在右下角；聚焦时整框亮起来 */
.a-composer{
  display:flex;align-items:flex-end;gap:var(--sp-2);padding:var(--sp-2);
  border:1px solid var(--border-strong);border-radius:var(--radius-2);background:var(--surface);
  transition:border-color var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease),background var(--dur-1) var(--ease);
}
@media (hover:hover){.a-composer:hover{border-color:var(--accent)}}
.a-composer:focus-within{border-color:var(--accent);box-shadow:var(--shadow-focus)}
/* loading：正在等回答，输入框与发送键都进载入态（说清楚在等什么，而不是假装还能发） */
.a-composer.is-busy{background:var(--surface-sunken);border-color:var(--border)}
.a-composer__input{
  flex:1;min-width:0;height:var(--composer-min);max-height:var(--composer-max);
  overflow-y:auto;resize:none;border:0;background:none;outline:none;color:var(--text-1);
  font-family:inherit;font-size:var(--fs-14);line-height:var(--composer-lh);
  padding:var(--sp-2) var(--sp-1) var(--sp-2) var(--sp-2);
}
.a-composer__input::placeholder{color:var(--text-3)}
.a-composer__input:disabled{color:var(--text-disabled);cursor:not-allowed}
.a-composer__send{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:var(--chat-send);height:var(--chat-send);border-radius:var(--radius-2);
  background:var(--accent);color:var(--on-accent);
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease);
}
.a-composer__send:hover{background:var(--accent-hover)}
.a-composer__send:active{background:var(--accent-active)}
.a-composer__send[disabled]{background:var(--surface-sunken);color:var(--text-disabled);cursor:not-allowed}
.a-composer__spin{
  display:none;width:var(--fs-14);height:var(--fs-14);border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
}
.a-composer.is-busy .a-composer__spin{display:block;animation:a-spin 640ms linear infinite}
.a-composer.is-busy .a-composer__ico{display:none}
.a-composer__foot{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin:0}
.a-composer__keys{display:flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-12);color:var(--text-3);white-space:nowrap}

/* 上传入口：与发送键同尺寸的方形按钮，静止时只描边（不抢发送键的主角位），
   hover / focus / active / busy 四态齐备；真正的 input 走 .a-sr（读屏与键盘仍能到达） */
.a-composer__attach{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:var(--chat-send);height:var(--chat-send);border-radius:var(--radius-2);
  border:1px solid var(--border-strong);background:var(--surface);color:var(--text-2);
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease);
}
.a-composer__attach:hover{background:var(--surface-hover);border-color:var(--accent);color:var(--accent)}
.a-composer__attach:active{background:var(--surface-sunken)}
.a-composer__attach:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-composer__attach[disabled]{color:var(--text-disabled);border-color:var(--border);cursor:not-allowed}
.a-composer.is-busy .a-composer__attach{color:var(--text-disabled);border-color:var(--border)}
.a-composer__file{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* 待发送附件条：发送前就把「带了什么」看全（图片给缩略图、文件给名字/类型/大小），可单个删 */
.a-attach-wrap{display:flex;flex-direction:column;gap:var(--sp-1);margin:0;min-width:0}
.a-attach{padding:var(--sp-2);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);min-width:0}
.a-attach[hidden]{display:none}
.a-attach__row{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0;padding:0;min-width:0}
.a-attach__item{
  display:inline-flex;align-items:center;gap:var(--sp-2);max-width:var(--attach-max);min-width:0;
  padding:var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-2);
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);
}
.a-attach__thumb{flex:none;width:var(--attach-thumb);height:var(--attach-thumb);object-fit:cover;border-radius:var(--radius-1);border:1px solid var(--border)}
.a-attach__ico{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--attach-thumb);height:var(--attach-thumb);border-radius:var(--radius-1);background:var(--surface-sunken);color:var(--text-2)}
.a-attach__meta{display:flex;flex-direction:column;min-width:0}
.a-attach__name{font-size:var(--fs-12);color:var(--text-1);max-width:var(--attach-name);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.a-attach__sub{font-size:var(--fs-11);color:var(--text-3);font-variant-numeric:tabular-nums}
.a-attach__del{
  flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:var(--act-hit);height:var(--act-hit);border-radius:var(--radius-1);color:var(--text-2);
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease);
}
.a-attach__del:hover{background:var(--danger-soft);color:var(--danger)}
.a-attach__del:active{background:var(--surface-sunken)}
.a-attach__del:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-attach__warn{display:flex;align-items:flex-start;gap:var(--sp-1);margin:var(--sp-2) 0 0;font-size:var(--fs-12);color:var(--warning)}
.a-attach__hint{margin:0;font-size:var(--fs-11);line-height:1.6;color:var(--text-3)}

/* 消息里带过的附件：图片给缩略图、文件给名字+类型+大小；没送给模型的那些必须写在下面 */
.a-msg__atts{display:flex;flex-wrap:wrap;gap:var(--sp-2);justify-content:flex-end;margin:0 0 var(--sp-1);max-width:var(--bubble-max);min-width:0}
.a-msg__att{display:inline-flex;align-items:center;gap:var(--sp-1);max-width:var(--attach-max);min-width:0;padding:var(--sp-1) var(--sp-2);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface)}
.a-msg__att--file{color:var(--text-2)}
.a-msg__thumb{flex:none;width:var(--attach-thumb-lg);height:var(--attach-thumb-lg);object-fit:cover;border-radius:var(--radius-1);border:1px solid var(--border);background:var(--surface-sunken)}
.a-msg__attname{font-size:var(--fs-11);color:var(--text-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.a-msg__attsize{font-size:var(--fs-11);color:var(--text-3);white-space:nowrap}
.a-msg__attwarn{display:flex;align-items:flex-start;gap:var(--sp-1);margin:var(--sp-1) 0 0;max-width:var(--bubble-max);font-size:var(--fs-11);line-height:1.7;color:var(--warning);text-align:right}

/* 消息：助手不是气泡（正文直接铺在页面底色上，左对齐、限宽）；
   我问的才是右侧气泡（accent-soft 底），一眼分清谁在说话 */
.a-msg{display:flex;gap:var(--sp-3);min-width:0}
.a-msg--me{justify-content:flex-end}
.a-msg__avatar{
  flex:none;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);color:var(--text-2);
}
.a-msg--ai .a-msg__avatar{color:var(--accent)}
.a-msg__avatar--error{color:var(--danger);border-color:var(--danger)}
.a-msg__body{min-width:0;flex:1}
.a-msg--me .a-msg__body{flex:0 1 auto;display:flex;flex-direction:column;align-items:flex-end;max-width:var(--bubble-max)}
.a-msg__meta{display:flex;align-items:center;gap:var(--sp-2);min-height:var(--act-hit);margin-bottom:var(--sp-1);font-size:var(--fs-11);color:var(--text-3)}
.a-msg--me .a-msg__meta{flex-direction:row-reverse}
.a-msg__who{font-weight:var(--fw-semibold);letter-spacing:.06em}
.a-msg__time{font-size:var(--fs-11);font-variant-numeric:tabular-nums}
/* 消息操作（复制 / 重新生成）：静止时把版面让给正文，hover 或键盘聚焦时出现。
   触屏没有 hover，所以在 hover:none 的设备上常显，避免按钮永远拿不到。 */
.a-msg__acts{display:inline-flex;align-items:center;gap:var(--sp-1);opacity:0;transition:opacity var(--dur-1) var(--ease)}
.a-msg--ai:hover .a-msg__acts,
.a-msg--ai:focus-within .a-msg__acts,
.a-msg__acts--always{opacity:1}
@media (hover:none){.a-msg__acts{opacity:1}}
.a-msgact{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-1);
  min-width:var(--act-hit);height:var(--act-hit);padding:0 var(--sp-1);
  border:1px solid transparent;border-radius:var(--radius-1);color:var(--text-3);font-size:var(--fs-11);
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),color var(--dur-1) var(--ease);
}
.a-msgact:hover{background:var(--surface-hover);border-color:var(--border);color:var(--text-1)}
.a-msgact:active{background:var(--surface-sunken)}
.a-msgact:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-msgact[disabled]{color:var(--text-disabled);cursor:not-allowed}
.a-msg__bubble{
  font-size:var(--fs-14);line-height:1.8;color:var(--text-1);
  white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;
}
.a-msg--ai .a-msg__bubble{padding:0;border:0;background:none}
.a-msg--me .a-msg__bubble{
  padding:var(--sp-2) var(--sp-3);border:1px solid transparent;line-height:1.75;
  border-radius:var(--radius-2) var(--radius-2) var(--radius-1) var(--radius-2);
  background:var(--accent-soft);
}
/* 失败态：danger 边框 + danger-soft 底（破坏性/失败一律穿 danger，不用主题色） */
.a-msg--error .a-msg__bubble{
  padding:var(--sp-3);border:1px solid var(--danger);border-radius:var(--radius-2);background:var(--danger-soft);
}
.a-msg__recover{display:block;margin-top:var(--sp-2);font-size:var(--fs-12);color:var(--text-2)}
.a-msg__acts--error{margin-top:var(--sp-2)}
/* 助手回答的 Markdown 排版（渲染器在 public/markdown.js）。
   为什么要有这一段：模型返回的是 Markdown，之前直接当纯文本铺出来，
   用户看到的是裸露的 ** 和表格竖线，标题与正文同字号 ——「一点层级都没有」。
   只作用于助手气泡（.a-msg--ai .a-msg__bubble.a-md）：我发的那条不加排版。 */
.a-msg--ai .a-msg__bubble.a-md{white-space:normal}
.a-md>*+*{margin-top:var(--md-gap)}
.a-md__p{margin:0}
.a-md__h{margin:0;font-weight:var(--fw-semibold);line-height:1.4;color:var(--text-1);letter-spacing:-.01em}
.a-md__h--1{font-size:var(--md-fs-h1)}
.a-md__h--2{font-size:var(--md-fs-h2)}
.a-md__h--3{font-size:var(--md-fs-h3)}
.a-md__h--4,.a-md__h--5,.a-md__h--6{font-size:var(--fs-14);color:var(--text-2)}
/* 标题紧跟正文时收紧一档：标题与它管的那一段要成组，不能等距散开 */
.a-md__h+.a-md__p,.a-md__h+.a-md__list,.a-md__h+.a-md__tablewrap,.a-md__h+.a-md__quote{margin-top:var(--sp-2)}
.a-md__strong{font-weight:var(--fw-semibold);color:var(--text-1)}
.a-md__em{font-style:italic;color:var(--text-1)}
.a-md__code{
  padding:1px 5px;border:1px solid var(--border);border-radius:var(--radius-1);
  background:var(--surface-sunken);color:var(--text-1);
  font-family:var(--font-mono);font-size:var(--md-fs-code);
}
.a-md__pre{
  position:relative;margin:0;padding:var(--sp-3);overflow-x:auto;
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);
}
/* 有语言标记时在顶部预留一行放它，避免标签压住第一行代码 */
.a-md__pre[data-lang]{padding-top:calc(var(--sp-3) + var(--fs-11) + var(--sp-1))}
.a-md__pre[data-lang]::after{
  content:attr(data-lang);position:absolute;top:var(--sp-1);right:var(--sp-2);
  font-family:var(--font-mono);font-size:var(--fs-11);letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-3);
}
.a-md__precode{
  display:block;white-space:pre;color:var(--text-1);
  font-family:var(--font-mono);font-size:var(--md-fs-code);line-height:1.65;
}
.a-md__list{margin:0;padding-left:var(--sp-5)}
.a-md__li{margin-top:var(--sp-1)}
.a-md__li::marker{color:var(--text-3);font-family:var(--font-mono);font-size:var(--fs-12)}
.a-md__quote{
  margin:0;padding:var(--sp-1) 0 var(--sp-1) var(--sp-3);
  border-left:2px solid var(--accent);color:var(--text-2);
}
.a-md__quote>*+*{margin-top:var(--sp-2)}
.a-md__hr{margin:0;border:0;border-top:1px solid var(--border)}
/* 表格：自己滚，不推页面。360px 窄屏下页面横向溢出必须仍然是 0 */
.a-md__tablewrap{max-width:100%;overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-2)}
.a-md__table{border-collapse:collapse;width:100%;font-size:var(--fs-13)}
.a-md__table th,.a-md__table td{
  padding:var(--md-table-pad) var(--sp-3);text-align:left;border-bottom:1px solid var(--border);
  white-space:nowrap;
}
.a-md__table th{
  background:var(--surface-sunken);color:var(--text-2);
  font-size:var(--fs-12);font-weight:var(--fw-semibold);letter-spacing:.02em;
}
.a-md__table tr:last-child td{border-bottom:0}
/* 表格对齐：Markdown 分隔行里的 :--- / ---: / :---: 直接映射过来 */
.a-md__table .a-md__al-center{text-align:center}
.a-md__table .a-md__al-right{text-align:right}
.a-md__a{color:var(--accent);text-decoration:underline;text-underline-offset:2px}
.a-md__a:hover{color:var(--accent-hover)}
.a-md__a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-1)}
/* 被拒绝的协议（javascript: 等）：显示出来但不可点，且要看得出来「这原本是个链接」 */
.a-md__refused{color:var(--text-2)}
.a-md__refusedurl{font-family:var(--font-mono);font-size:var(--fs-12);color:var(--text-3)}
.a-msg__thinking{display:flex;align-items:center;gap:5px;padding:var(--sp-1) 0}
.a-dot{width:6px;height:6px;border-radius:50%;background:var(--text-3);animation:a-dot 1.1s ease-in-out infinite}
.a-dot:nth-child(2){animation-delay:.16s}
.a-dot:nth-child(3){animation-delay:.32s}
@keyframes a-dot{0%,60%,100%{opacity:.35;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
/* 思考过程（推理型模型 · 对齐原生 DeepSeek 的呈现方式）
   流式期间展开、正文开始后收起成一行、历史消息可点开回看。
   刻意克制（更小字号 + 左侧细线 + 次级文字色）：它是过程，不是结论。 */
.a-think{margin:0 0 var(--sp-2);border-left:2px solid var(--border);padding-left:var(--sp-2);max-width:var(--chat-measure)}
.a-think>summary{cursor:pointer;display:flex;align-items:center;gap:var(--sp-1);min-height:var(--act-hit);font-size:var(--fs-12);color:var(--text-3);list-style:none}
.a-think>summary::-webkit-details-marker{display:none}
.a-think>summary:hover{color:var(--text-2)}
.a-think>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-1)}
.a-think[open]>summary{color:var(--text-2)}
.a-think__body{margin:var(--sp-1) 0 var(--sp-2);font-size:var(--fs-12);line-height:1.75;color:var(--text-3);white-space:pre-wrap;overflow-wrap:anywhere;max-height:240px;overflow-y:auto}
.a-think--live>summary{color:var(--accent);font-weight:var(--fw-semibold)}
@media (prefers-reduced-motion:reduce){.a-dot{animation:none;opacity:.6}}
/* Agent 运行步骤：长工具调用（出卷、查库、读资料）期间不能白屏，
   每一步的开始/结束都要看得见；失败一律穿 danger，不做美化 */
.a-runsteps{margin:var(--sp-1) 0 0;display:flex;flex-direction:column;gap:2px}
.a-runsteps__item{font-size:var(--fs-12);line-height:1.7;color:var(--text-2)}
.a-runsteps__item.is-bad{color:var(--danger)}
.a-runsteps__item.is-warn{color:var(--text-2)}
/* 正在生成的正文：先铺在过渡态里，落库后再换成真实记录（token 级增量，不再等整段） */
.a-runstream{margin:var(--sp-2) 0 0;white-space:pre-wrap;word-break:break-word}
/* 「依据」脚注：本产品的诚实特色，不能删。改成一张真正的纸片（正文现在是页面底色，
   用 surface-sunken 会跟底色糊在一起） */
.a-msg__evidence{
  margin-top:var(--sp-3);padding:var(--sp-2) var(--sp-3);
  border:1px solid var(--border);border-left:2px solid var(--accent);
  border-radius:0 var(--radius-2) var(--radius-2) 0;background:var(--surface);
}
.a-msg__evtext{margin:var(--sp-1) 0 0;font-size:var(--fs-12);line-height:1.7;color:var(--text-2)}
.a-msg__chips{display:flex;gap:var(--sp-1);margin-top:var(--sp-2);flex-wrap:wrap}

/* ==========================================================================
   题库 · picker / quiz / wrong book
   ========================================================================== */
.a-picker{display:flex;flex-direction:column;gap:var(--sp-2)}
.a-picker__group{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap;padding-top:var(--sp-1)}
.a-picker__subject{font-size:var(--fs-11);color:var(--text-3);letter-spacing:.04em;min-width:96px}
.a-pick{
  display:inline-flex;align-items:center;gap:6px;height:var(--picker-pill-h);padding:0 var(--sp-3);
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);
  color:var(--text-2);font-size:var(--fs-12);
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),color var(--dur-1) var(--ease);
}
.a-pick:hover{background:var(--surface-hover);border-color:var(--border-strong);color:var(--text-1)}
.a-pick:active{background:var(--surface-sunken)}
.a-pick:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-pick[aria-pressed="true"]{background:var(--surface-selected);border-color:transparent;color:var(--accent);font-weight:var(--fw-medium)}
.a-pick[disabled]{background:var(--surface-sunken);border-color:var(--border);color:var(--text-disabled);cursor:not-allowed}
.a-pick__n{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3)}
.a-pick[aria-pressed="true"] .a-pick__n{color:var(--accent);opacity:.75}

.a-quiz{display:flex;flex-direction:column;gap:var(--sp-3)}
.a-q{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-2);overflow:hidden}
.a-q__head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);padding:var(--sp-2) var(--sp-3);background:var(--surface-sunken);border-bottom:1px solid var(--border)}
.a-q__no{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3)}
.a-q__kp{font-size:var(--fs-11);color:var(--text-3)}
.a-q__stem{padding:var(--sp-3) var(--sp-3) var(--sp-2);font-size:var(--fs-14);line-height:1.7}
.a-q__opts{display:flex;flex-direction:column;gap:var(--sp-1);padding:0 var(--sp-3) var(--sp-3)}
.a-opt{
  display:flex;align-items:flex-start;gap:var(--sp-2);width:100%;min-height:var(--opt-h);padding:var(--sp-2) var(--sp-3);
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);text-align:left;
  font-size:var(--fs-13);line-height:1.6;color:var(--text-1);
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease);
}
.a-opt:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.a-opt:active{background:var(--surface-sunken)}
.a-opt:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-opt[aria-pressed="true"]{background:var(--surface-selected);border-color:var(--accent)}
.a-opt[disabled]{cursor:default;background:var(--surface);color:var(--text-2)}
.a-opt.is-right{background:var(--success-soft);border-color:var(--success)}
.a-opt.is-wrong{background:var(--danger-soft);border-color:var(--danger)}
.a-opt__key{
  flex:none;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center;margin-top:1px;
  border:1px solid var(--border-strong);border-radius:var(--radius-1);
  font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-2);
}
.a-opt.is-right .a-opt__key{border-color:var(--success);color:var(--success)}
.a-opt.is-wrong .a-opt__key{border-color:var(--danger);color:var(--danger)}
.a-opt__text{min-width:0}
.a-q__explain{padding:var(--sp-2) var(--sp-3) var(--sp-3);border-top:1px solid var(--border);background:var(--surface-sunken)}
.a-result{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap}
.a-result__num{font-family:var(--font-mono);font-size:var(--fs-40);font-weight:var(--fw-semibold);line-height:1;letter-spacing:-.03em}
.a-result__facts{display:flex;flex-direction:column;gap:6px;min-width:0}
.a-result__delta{font-family:var(--font-mono);font-size:var(--fs-12);color:var(--text-2)}

/* 列表行（错题本 / 资料库 / 计划） */
.a-item{
  display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:var(--sp-2) var(--sp-3);
  width:100%;min-height:var(--row-h);padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border);
  text-align:left;background:var(--surface);
  transition:background var(--dur-1) var(--ease);
}
.a-item:last-child{border-bottom:0}
.a-item:hover{background:var(--surface-hover)}
.a-item:active{background:var(--surface-sunken)}
.a-item:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.a-item[aria-expanded="true"],.a-item[aria-selected="true"]{background:var(--surface-selected)}
.a-item__main{min-width:0}
.a-item__name{display:block;font-size:var(--fs-13);font-weight:var(--fw-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.a-item__meta{display:flex;align-items:center;gap:6px;margin-top:2px;font-size:var(--fs-11);color:var(--text-3);flex-wrap:wrap}
.a-item__side{display:flex;align-items:center;gap:var(--sp-2);flex:none}
.a-item__pct{font-family:var(--font-mono);font-size:var(--fs-12);color:var(--text-1)}
.a-item__pct--danger{color:var(--danger)}
.a-item__pct--warning{color:var(--warning)}
.a-item__pct--success{color:var(--success)}
.a-item--static{cursor:default}
.a-item--static:hover{background:var(--surface)}
.a-badge{
  display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 6px;
  border:1px solid var(--border);border-radius:var(--radius-1);background:var(--surface-sunken);
  font-size:var(--fs-11);color:var(--text-3);white-space:nowrap;
}
.a-badge--danger{border-color:var(--danger);color:var(--danger)}
.a-badge--warning{border-color:var(--warning);color:var(--warning)}
.a-badge--success{border-color:var(--success);color:var(--success)}
.a-badge--accent{border-color:var(--accent);color:var(--accent)}

/* ==========================================================================
   题库三分区 · 落点带 / 分区入口 / 科目筛选 / 错题分组
   只在 app.css 里做「加法」；尺寸来源于 v4.css 的 Tier 3 令牌（--focus-*），
   本文件不定义任何新色值或新尺寸原值。
   ========================================================================== */

/* 落点带：一屏里最先看的地方 —— 现在在练什么、还剩多少、下一步点哪里 */
.a-focus{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;
  min-height:var(--focus-min);padding:var(--focus-pad);
  background:var(--surface);border:1px solid var(--border);border-left:2px solid var(--accent);
  border-radius:var(--radius-2);
}
.a-focus__lead{flex:1 1 320px;min-width:0}
.a-focus__title{margin:2px 0 0;font-size:var(--fs-16);font-weight:var(--fw-semibold);overflow-wrap:anywhere}
.a-focus__why{margin:var(--sp-1) 0 0;font-size:var(--fs-12);line-height:1.6;color:var(--text-2);max-width:62ch}
.a-focus__facts{
  display:flex;align-items:center;gap:var(--sp-2) var(--focus-gap);flex-wrap:wrap;margin-top:var(--sp-2);
  font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3);
}
.a-focus__acts{display:flex;align-items:center;gap:var(--sp-2);flex:none;flex-wrap:wrap}
.a-focus__bar{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-2);max-width:320px}
.a-focus__bar .a-progress__track{flex:1}

/* 分区入口：从总览去别的分区，数字全部来自接口 */
.a-entries{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-1);padding:var(--sp-3)}
.a-entry{
  display:flex;flex-direction:column;gap:2px;min-width:0;padding:var(--sp-3);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-2);text-align:left;
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease);
}
.a-entry:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.a-entry:active{background:var(--surface-sunken)}
.a-entry:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-entry__name{font-size:var(--fs-13);font-weight:var(--fw-medium)}
.a-entry__num{font-family:var(--font-mono);font-size:var(--fs-20);font-weight:var(--fw-semibold);line-height:1.15;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.a-entry__unit{font-family:var(--font-ui);font-size:var(--fs-11);font-weight:var(--fw-regular);color:var(--text-3);margin-left:3px}
.a-entry__note{font-size:var(--fs-11);line-height:1.5;color:var(--text-3)}

/* 科目筛选：200 个知识点先收敛到一个科目再看 */
.a-subjbar{display:flex;align-items:center;gap:var(--sp-1);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.a-subjbar__label{margin-right:var(--sp-1);font-size:var(--fs-11);color:var(--text-3)}
.a-subj{
  display:inline-flex;align-items:center;gap:6px;height:var(--btn-h);padding:0 var(--sp-3);
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);
  font-size:var(--fs-12);color:var(--text-2);
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),color var(--dur-1) var(--ease);
}
.a-subj:hover{background:var(--surface-hover);border-color:var(--border-strong);color:var(--text-1)}
.a-subj:active{background:var(--surface-sunken)}
.a-subj:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-subj[aria-pressed="true"]{background:var(--surface-selected);border-color:var(--accent);color:var(--accent);font-weight:var(--fw-medium)}
.a-subj__n{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3)}
.a-subj[aria-pressed="true"] .a-subj__n{color:var(--accent)}

/* 知识点卡片的脚注（原来靠行内 style 写死像素，现在归位到类） */
.a-kplist__foot{padding:0 var(--sp-3) var(--sp-2)}

/* 错题分组小标题：今日到期 / 之后到期 */
.a-grouphd{
  display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-2) var(--sp-3);
  background:var(--surface-sunken);border-top:1px solid var(--border);border-bottom:1px solid var(--border);
}
.a-grouphd:first-child{border-top:0}
.a-grouphd__n{margin-left:auto;font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3)}

@media (max-width:900px){
  .a-entries{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* 页头右侧的元信息原来是 nowrap，长文案在 700–900 之间会把页面撑出横向溢出。
     实测：这一档此前只有 ≤680 才允许换行，768 时会溢出 45px（不只是题库页）。 */
  .a-page__meta{white-space:normal;text-align:left}
}
@media (max-width:560px){
  .a-entries{grid-template-columns:minmax(0,1fr)}
  .a-focus__acts{width:100%}
  .a-focus__acts .a-btn{flex:1 1 auto}
}

/* 判对/判错的记号：doctrine 要求图标一律内联 SVG，不用字符当图标 */
.a-verdict__mark{display:inline-flex;align-items:center;color:var(--text-3)}
.a-verdict.is-right .a-verdict__mark{color:var(--success)}
.a-verdict.is-wrong .a-verdict__mark{color:var(--danger)}
.a-hit__mark{display:inline-flex;align-items:center;width:14px;color:var(--text-3)}
.a-hits li.is-hit .a-hit__mark{color:var(--success)}

/* ==========================================================================
   我的学习 · 专注计时 / 打卡 / 计划
   ========================================================================== */
.a-timer{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap}
.a-timer__num{
  font-family:var(--font-mono);font-size:var(--timer-num);font-weight:var(--fw-semibold);
  line-height:1;letter-spacing:-.03em;font-variant-numeric:tabular-nums;
}
.a-timer__unit{font-size:var(--fs-13);color:var(--text-3);margin-left:6px}
.a-timer__actions{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-week{display:flex;align-items:flex-end;gap:var(--sp-2)}
.a-week__col{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px}
.a-week__bar{width:100%;max-width:18px;border-radius:var(--radius-bar);background:var(--border-strong)}
.a-week__bar--today{background:var(--accent)}
.a-week__day{font-size:var(--fs-11);color:var(--text-3);font-family:var(--font-mono)}
.a-week__day--today{color:var(--accent);font-weight:var(--fw-medium)}
.a-plan{display:flex;flex-direction:column;gap:var(--sp-1)}
.a-plan__day{display:flex;align-items:baseline;gap:var(--sp-2);margin-top:var(--sp-2)}
.a-plan__date{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3)}
.a-plan__count{font-size:var(--fs-11);color:var(--text-3)}

/* ==========================================================================
   单词打卡 · 学习页（词典式词条 + 朗读）/ 学习记录（a→z）
   背景：这一页此前只有一个「打卡 30 词」的空按钮 —— 点了只写一条打卡记录，
   没有任何词、没有朗读、没有学习记录。这里把这条链路补完：
   今日词数 → 词典式词条 → 朗读 → 认识/不认识落库 → 记录页按 a→z 回看。
   纪律：只引用 V4 三层令牌（尺寸令牌定义在 v4.css 的 Tier 3），本文件零十六进制；
   每个可交互元素都有 default / hover / focus-visible / active / disabled / loading / selected。
   ========================================================================== */
.a-wordsheet__spell{
  font-size:var(--word-spell);font-weight:var(--fw-semibold);line-height:1.1;
  letter-spacing:-.02em;color:var(--text-1);overflow-wrap:anywhere;
}
.a-wordsheet__phon{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2);font-size:var(--word-phon);color:var(--text-2)}
.a-wordsheet__pos{font-size:var(--fs-12);color:var(--text-3)}
.a-wordsheet__mean{margin-top:var(--word-gap);font-size:var(--word-mean);line-height:1.5;color:var(--text-1)}
/* 例句：左侧细线是「引用」的层级，底色用 sunken 与卡片本体分开（明暗两套都成立） */
.a-wordsheet__ex{
  margin-top:var(--word-gap);padding:var(--sp-3);
  background:var(--surface-sunken);border-left:2px solid var(--border-strong);border-radius:var(--radius-1);
}
.a-wordsheet__en{font-size:var(--fs-14);line-height:1.65;color:var(--text-1)}
.a-wordsheet__zh{margin-top:var(--sp-1);font-size:var(--fs-13);line-height:1.6;color:var(--text-3)}
.a-wordsheet__src{margin-top:var(--word-gap);font-size:var(--fs-11);color:var(--text-3)}
.a-wordsheet__acts{margin-top:var(--sp-4)}
.a-wordsheet__nav{margin-top:var(--sp-3)}
.a-wordsheet__bar{margin:var(--sp-4) 0 0}
/* 朗读中：按下态不只换颜色，按钮上的文字也从「朗读」变成「正在朗读」 */
.a-wordsheet__acts .a-btn[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}

.a-wordlist{display:flex;flex-direction:column;gap:2px}
.a-wordlist__row{
  display:flex;align-items:center;gap:var(--sp-2);min-height:var(--word-row-h);
  padding:var(--sp-1) var(--sp-2);border:1px solid transparent;border-radius:var(--radius-1);
}
.a-wordlist__row:hover{background:var(--surface-hover)}
/* 当前正在学的那个词：描边 + 底色，不只靠颜色（左侧还有 2px 指示线） */
.a-wordlist__row.is-current{border-color:var(--accent);background:var(--surface-selected)}
.a-wordlist__row.is-learned .a-wordlist__spell{color:var(--text-2)}
.a-wordlist__idx{flex:none;width:24px;font-size:var(--fs-11);color:var(--text-3);text-align:right}
.a-wordlist__jump{
  display:flex;flex-direction:column;align-items:flex-start;gap:1px;
  flex:1;min-width:0;padding:var(--sp-1);text-align:left;border-radius:var(--radius-1);
}
.a-wordlist__jump:hover .a-wordlist__spell{color:var(--accent)}
.a-wordlist__jump:active .a-wordlist__spell{color:var(--accent-active)}
.a-wordlist__spell{font-size:var(--fs-14);font-weight:var(--fw-medium);color:var(--text-1);overflow-wrap:anywhere}
.a-wordlist__meta{font-size:var(--fs-11);color:var(--text-3);overflow-wrap:anywhere}
.a-wordlist__row > .a-badge,.a-wordlist__row > .a-iconbtn{flex:none}

@media (max-width:900px){
  .a-wordsheet__acts .a-btn,.a-wordsheet__nav .a-btn{flex:1 1 auto}
  .a-wordlist__row{flex-wrap:wrap}
  .a-wordlist__jump{flex:1 1 100%}
}

/* ==========================================================================
   单词打卡 · 词数选择 / 词卡右上角朗读键 / 随机与字母序两套列表
   ---------------------------------------------------------------------------
   三件事和以前不一样，样式都落在这里：
   1) 词数由用户自己定：一个数字输入 + 几个快捷档位 + 生成按钮，八态齐（hover / focus / 按下 /
      disabled / 忙碌态由按钮自己的 .a-btn 负责）；
   2) 朗读键挪到**词卡右上角**（.a-wordsheet__top 的右端），词卡里只剩「认识了 / 还不认识」两个按钮；
   3) 学习页是本批的随机顺序、学习记录页是 a→z：记录页用首字母分组（.a-lettergroup）把字母序显出来。
   颜色字号全部走令牌，不写死色值。
   ========================================================================== */
.a-wordunder{margin-top:var(--sp-2);font-size:var(--fs-12);color:var(--text-3);line-height:1.6}

.a-wordform{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin:var(--sp-3) 0}
.a-wordform__label{font-size:var(--fs-12);color:var(--text-3)}
.a-wordform__input{
  width:var(--word-count-w);height:var(--field-h);padding:0 var(--sp-2);
  border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);
  color:var(--text-1);font-size:var(--fs-14);text-align:center;
  transition:border-color var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease);
}
.a-wordform__input:hover{border-color:var(--border-strong)}
.a-wordform__input:focus-visible{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.a-wordform__input:active{border-color:var(--accent-active)}
.a-wordform__input[disabled]{background:var(--surface-sunken);border-color:var(--border);color:var(--text-disabled);cursor:not-allowed}
.a-wordform__chips{display:flex;gap:var(--sp-1);flex-wrap:wrap}
.a-wordform__chips .a-chipbtn{height:var(--field-h);padding:0 var(--sp-3);border-radius:var(--radius-2);font-size:var(--fs-12);background:none}
.a-wordform__chips .a-chipbtn.is-on{background:var(--accent-soft);border-color:transparent;color:var(--accent);font-weight:var(--fw-medium)}
.a-wordform__chips .a-chipbtn[aria-pressed="true"]:active{background:var(--accent-soft)}
.a-wordform__go{flex:0 0 auto}

.a-wordsheet__top{
  display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4) 0;
}
.a-wordsheet__topL{display:flex;flex-direction:column;gap:2px;min-width:0}
.a-wordsheet__say{flex:none}
.a-wordsheet__say[aria-pressed="true"]{background:var(--accent-soft);border-color:transparent;color:var(--accent)}
.a-wordsheet__done{font-size:var(--fs-16);color:var(--text-1)}

.a-lettergroups{list-style:none;display:flex;flex-direction:column;gap:var(--sp-3)}
.a-lettergroup{display:grid;grid-template-columns:var(--letter-w) minmax(0,1fr);gap:var(--sp-3);align-items:start}
.a-lettergroup__head{
  display:flex;align-items:center;justify-content:center;
  height:var(--word-row-h);border-radius:var(--radius-2);
  background:var(--surface-sunken);color:var(--text-2);font-size:var(--fs-14);font-weight:var(--fw-medium);
}
.a-lettergroup__list{margin:0}

@media (max-width:900px){
  .a-wordform{gap:var(--sp-2)}
  .a-wordform__go{flex:1 1 100%}
  .a-wordsheet__top{flex-wrap:wrap;padding:var(--sp-3) var(--sp-3) 0}
  .a-lettergroup{grid-template-columns:minmax(0,1fr);gap:var(--sp-1)}
  .a-lettergroup__head{height:auto;justify-content:flex-start;background:none;color:var(--text-3);font-size:var(--fs-11)}
}

/* ==========================================================================
   我的 · 定义列表与会员
   ========================================================================== */
.a-def{display:grid;grid-template-columns:120px minmax(0,1fr);gap:var(--sp-2) var(--sp-3);align-items:center}
.a-def__k{font-size:var(--fs-12);color:var(--text-3)}
.a-def__v{font-size:var(--fs-13);color:var(--text-1);min-width:0}
.a-formrow{display:flex;flex-direction:column;gap:6px;min-width:0}
.a-formrow__label{font-size:var(--fs-12);color:var(--text-3)}
.a-field--block{flex:1 1 auto;min-width:0;max-width:none}
.a-form{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--sp-3)}
.a-form__foot{grid-column:1/-1;display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-fieldset{border:1px solid var(--border);border-radius:var(--radius-2);padding:var(--sp-3);display:flex;flex-direction:column;gap:var(--sp-3);min-width:0}
.a-fieldset__legend{padding:0 var(--sp-1);font-size:var(--fs-11);font-weight:var(--fw-semibold);letter-spacing:.09em;color:var(--text-3)}
.a-select{
  flex:1;min-width:0;height:var(--field-h);border:0;background:none;outline:none;
  font-size:var(--fs-13);color:var(--text-1);appearance:none;cursor:pointer;
}

/* ==========================================================================
   Auth · 登录/注册（V4 语言：细描边、零装饰阴影、唯一浮层阴影）
   ========================================================================== */
/* 左侧是「一眼的落点」：展示级字号 40px（正文 12px，阶梯 3.33，满足 doctrine 的 >= 2.5x）。
   右侧是表单卡，八态由既有 .a-btn / .a-field 承担；这里只补 submit 的忙碌态。 */
.a-auth{
  position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;
  padding:var(--sp-5);background:var(--surface-page);
}
.a-auth__shell{
  width:100%;max-width:calc(var(--auth-w) + 320px);display:grid;gap:var(--sp-5);
  grid-template-columns:minmax(0,1fr) var(--auth-w);align-items:center;
}
.a-auth__lead{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}
.a-auth__wordmark{
  margin:var(--sp-2) 0 0;font-size:var(--fs-40);font-weight:var(--fw-semibold);
  letter-spacing:-.02em;line-height:1.1;color:var(--text-1);
}
.a-auth__cn{margin:0;font-size:var(--fs-13);color:var(--text-2);line-height:1.6}
.a-auth__points{list-style:none;margin:var(--sp-2) 0 0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.a-auth__points li{
  position:relative;padding-inline-start:var(--sp-4);font-size:var(--fs-13);color:var(--text-2);line-height:1.5;
}
.a-auth__points li::before{
  content:"";position:absolute;inset-inline-start:0;top:.62em;width:10px;height:2px;
  background:var(--accent);border-radius:var(--radius-1);
}
.a-auth__card{
  width:100%;padding:var(--sp-5);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-2);
  box-shadow:var(--shadow-raise);
}
.a-auth__title{margin-top:0;font-size:var(--fs-20);font-weight:var(--fw-semibold);letter-spacing:-.01em}
.a-auth__sub{margin-top:4px;font-size:var(--fs-13);color:var(--text-2);line-height:1.6}
.a-auth__form{display:flex;flex-direction:column;gap:var(--sp-3);margin-top:var(--sp-4)}
.a-auth__err{
  padding:var(--sp-2) var(--sp-3);border:1px solid var(--danger);border-radius:var(--radius-2);
  background:var(--danger-soft);color:var(--danger);font-size:var(--fs-12);
}
.a-auth__submit{height:var(--field-h);width:100%}
.a-auth__submit[disabled]{cursor:progress;opacity:.72}
/* 认证卡里的次级动作条共用一套度量：提交 / 模式切换 / 返回上一步。
   返回按钮以前漏了这条规则，会缩成一个小号 ghost 按钮，与同列的其它两个不一致。
   （「一键填入」那条已在 2026-09-24 随演示块一起删除，对应的 .a-auth__demo /
     .a-auth__demoline / .a-auth__fill 三条规则也一并清掉了，不留死样式。） */
.a-auth__switch,.a-auth__back{height:var(--field-h);width:100%;justify-content:center}
@media (max-width:880px){
  .a-auth__shell{grid-template-columns:1fr;gap:var(--sp-4);max-width:var(--auth-w)}
  .a-auth__points{display:none}
}
.a-field.is-invalid{border-color:var(--danger)}
.a-field.is-invalid:focus-within{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--danger)}

/* ==========================================================================
   Modal · 唯一允许的浮层
   ========================================================================== */
.a-modal{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;padding:var(--sp-5)}
.a-modal__scrim{position:absolute;inset:0;background:var(--scrim)}
.a-modal__box{
  position:relative;width:100%;max-width:var(--modal-w);max-height:80vh;display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-2);box-shadow:var(--shadow-raise);
}
.a-modal__head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);padding:var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border);background:var(--surface-sunken)}
.a-modal__title{padding:var(--sp-3) var(--sp-4) 0;font-size:var(--fs-16);font-weight:var(--fw-semibold)}
.a-modal__body{padding:var(--sp-2) var(--sp-4) var(--sp-4);overflow-y:auto;font-size:var(--fs-13);line-height:1.7;color:var(--text-2)}
.a-modal__foot{display:flex;align-items:center;justify-content:flex-end;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--border)}

/* ==========================================================================
   可访问性细化（应用层，不改 V4 令牌本身）
   1. V4 的禁用文字用 --text-disabled，实测 2.3:1。WCAG 2.2 SC 1.4.3 对
      「inactive components」无对比度要求，但读得清更好，故禁用文字改用 --text-2（实测 7:1+）。
   2. V4 的选中态（aria-selected / aria-current / aria-pressed）会覆盖 hover 背景，
      导致已选项 hover 无反馈；这里补一条 border-color 反馈，保持「accent = 选中」的语义。
   ========================================================================== */
/* 破坏性操作（退出登录等）：V4 只有 primary/secondary/ghost，
   按 skill 的「一个动作角色 = 一个变体」补 danger，且与既有体系一致地走描边风格 */
.a-btn--danger{background:var(--surface);border-color:var(--danger);color:var(--danger)}
.a-btn--danger:hover{background:var(--danger-soft);border-color:var(--danger)}
.a-btn--danger:active{background:var(--danger-soft);color:var(--danger)}
.a-btn--danger:focus-visible{outline:2px solid var(--danger);outline-offset:2px}
.a-btn--danger[disabled],.a-btn--danger[aria-disabled="true"]{background:var(--surface-sunken);border-color:var(--border);color:var(--text-2)}
.a-btn[disabled],.a-btn[aria-disabled="true"],.a-pick[disabled],.a-opt[disabled]{color:var(--text-2)}
/* 小号按钮：views.js 里已经在用 a-btn--sm，但一直没有对应样式（是个空类名，尺寸没生效）。
   这里按令牌补上，高度 32px，命中区满足 WCAG 2.2 SC 2.5.8（不低于 24px）。 */
.a-btn--sm{height:32px;padding:0 var(--sp-3);font-size:var(--fs-12)}
/* 「继续写完」：上一次回答被输出上限截断时，在回答下方给一句实话 + 一个明确的下一步。
   只在这一种情况下出现，不是常驻操作条。 */
.a-msg__continue{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2)}
.a-msg__continuenote{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-12);color:var(--text-2)}
.a-msg__continuenote .a-i{flex:none;color:var(--warning)}

/* ── 「停止这一轮」：只在运行时出现 ───────────────────────────────────────────── */
.a-composer__stop{
  display:inline-flex;align-items:center;gap:var(--sp-1);flex:none;height:var(--chat-send);padding:0 var(--sp-3);
  border:1px solid var(--line-strong);border-radius:var(--radius-2);background:var(--surface);
  color:var(--text-1);font-size:var(--fs-12);cursor:pointer;
  transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease);
}
.a-composer__stop:hover{background:var(--surface-sunken)}
.a-composer__stop[hidden]{display:none}

/* ── 成果卡片（试卷 / 计划）：数字来自后端真实状态 ───────────────────────────── */
.a-artifacts{display:flex;flex-direction:column;gap:var(--sp-2);margin-top:var(--sp-3);max-width:var(--chat-measure)}
.a-artifact{
  border:1px solid var(--line);border-radius:var(--radius-3);background:var(--surface);
  padding:var(--sp-3);display:flex;flex-direction:column;gap:var(--sp-2);
}
.a-artifact__head{display:flex;flex-direction:column;gap:2px}
.a-artifact__title{margin:0;font-size:var(--fs-14);font-weight:600;color:var(--text-1)}
.a-artifact__facts{display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-3);margin:0;padding:0;list-style:none}
.a-artifact__facts li{font-size:var(--fs-12);color:var(--text-2)}
.a-artifact__acts{display:flex;gap:var(--sp-2);flex-wrap:wrap}

/* 本次回答用时（含工具与等待）：口径写在文字里，不用数字冒充「思考时长」 */
.a-msg__runtime{margin:var(--sp-1) 0 0;font-size:var(--fs-12);color:var(--text-3)}

.a-tab[aria-selected="true"]:hover,.a-pick[aria-pressed="true"]:hover,
.a-scale__cell[aria-current="true"]:hover,.a-nav__item[aria-current="page"]:hover{border-color:var(--accent)}
.a-tab,.a-scale__cell,.a-nav__item{border:1px solid transparent}
.a-nav__item[aria-current="page"]:hover{color:var(--accent-hover)}

/* ==========================================================================
   Responsive · 应用层补齐（V4 的断点之上只做必要收敛）
   ========================================================================== */
@media (max-width:1180px){
  .a-split,.a-form{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:900px){
  /* 会话栏在窄屏改成横向一条：会话变成可横滑的小块，「我记住的」还是折叠的一行。
     横向滚动只发生在 .a-rail__scroll 内部，页面本身不横向溢出。 */
  .a-chat__cols{flex-direction:column}
  /* 窄屏整页滚动时，输入框会被顶到长日志末尾（实测 360x800 时在第 2271px 处，不翻到最后就没法再问）。
     让它吸在视口底部。注意：absorption 的前提是滚动容器是「整页」——
     html[data-view="chat"] .a-main 在桌面是 overflow:hidden（自己滚），那会让 sticky 被关在 main 里失效；
     窄屏这里改成跟随整页滚动，和其余视图在窄屏的处理一致。 */
  html[data-view="chat"] .a-main{overflow:visible;padding:0}
  .a-chat__composer{position:sticky;bottom:0;z-index:2}
  .a-rail{width:100%;border-right:0;border-bottom:1px solid var(--border)}
  .a-rail__scroll{flex:none;max-height:none;overflow-x:auto;overflow-y:hidden}
  .a-rail__list{flex-direction:row;align-items:stretch;gap:var(--sp-1)}
  .a-rail__item{flex:none;max-width:220px}
  .a-rail__item.is-editing{max-width:none;min-width:180px}
  .a-mem__list{max-height:none}
  .a-auth{padding:var(--sp-4)}
  .a-auth__card{padding:var(--sp-4)}
  .a-def{grid-template-columns:96px minmax(0,1fr)}
  .a-timer__num{font-size:var(--fs-40)}
  .a-modal{padding:var(--sp-3);align-items:flex-start}
  .a-modal__box{max-height:none}
}
@media (max-width:680px){
  .a-chat__head{flex-wrap:wrap;gap:var(--sp-2)}
  .a-chat__count{display:none}
  .a-composer__foot{flex-direction:column;align-items:flex-start;gap:2px}
  /* 脚注默认是 nowrap（.a-block__note），极窄视口下会把整页顶宽：实测 280px 宽时对话页 317px。
     只放开输入区这一处换行，其它视图里的同名注脚不受影响。 */
  .a-composer__foot .a-block__note{white-space:normal}
  .a-chat__chips{overflow-x:auto;flex-wrap:nowrap;padding-bottom:2px}
  .a-chat__composer .a-chat__inner{padding:var(--sp-3) var(--sp-3) var(--sp-4)}
  .a-chat__jump{bottom:var(--sp-2)}
}

@media (max-width:560px){
  .a-def{grid-template-columns:minmax(0,1fr)}
  .a-item{grid-template-columns:minmax(0,1fr)}
  .a-item__side{justify-content:flex-start}
}
@media (prefers-reduced-motion:reduce){
  *{transition-duration:1ms!important;animation-duration:1ms!important}
}
/* ==========================================================================
   题库与答题（整卷模考 / 专项练习 / 答题卡 / 交卷报告）
   只用 V4 的 token 与既有类，未新增色值
   ========================================================================== */
.a-statgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-1);padding:var(--sp-3)}
.a-statcell{min-width:0;padding:0 var(--sp-3);border-left:1px solid var(--border)}
.a-statcell:first-child{border-left:0;padding-left:0}
.a-statcell__num{margin-top:2px}
.a-card--resume{border-color:var(--accent)}
.a-resume{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-3)}
.a-resume__title{margin:0;font-size:var(--fs-14);font-weight:var(--fw-semibold)}
.a-paper{margin-top:var(--sp-3);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-2);overflow:hidden;transition:border-color var(--dur-1) var(--ease)}
.a-paper:hover{border-color:var(--border-strong)}
.a-paper__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-3)}
.a-paper__lead{min-width:0}
.a-paper__title{margin:0;font-size:var(--fs-16);font-weight:var(--fw-semibold)}
.a-paper__src{margin:var(--sp-1) 0 0;font-size:var(--fs-12);color:var(--text-3)}
.a-paper__nums{display:flex;gap:var(--sp-3);flex:none}
.a-paper__num{display:flex;flex-direction:column;align-items:flex-end}
.a-paper__num b{font-family:var(--font-mono);font-size:var(--fs-16);color:var(--text-1)}
.a-paper__num b i{font-style:normal;font-size:var(--fs-11);color:var(--text-3);margin-left:2px}
.a-paper__secs{display:flex;flex-wrap:wrap;gap:var(--sp-1);padding:0 var(--sp-3) var(--sp-3)}
.a-sect{display:inline-flex;align-items:center;gap:6px;padding:3px var(--sp-2);border:1px solid var(--border);border-radius:99px;font-size:var(--fs-11);color:var(--text-3)}
.a-sect b{font-weight:var(--fw-medium);color:var(--text-2)}
.a-paper__foot{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-2) var(--sp-3);border-top:1px solid var(--border);background:var(--surface-sunken);flex-wrap:wrap}
.a-paper__acts{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-aibank__grid{display:grid;gap:var(--sp-3);grid-template-columns:repeat(auto-fit,minmax(420px,1fr));margin-bottom:var(--sp-3)}
.a-aibank .a-chiprow{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin:var(--sp-2) 0}
.a-aibank__items{list-style:none;margin:var(--sp-2) 0 0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.a-aibank__items li{display:flex;gap:var(--sp-2);align-items:baseline;padding:var(--sp-2) 0;border-top:1px solid var(--border)}
.a-aibank__stem{flex:1;min-width:0;font-size:var(--fs-13);color:var(--text)}
/* ==========================================================================
   AI 模型（「我的」· 用户级设置）与 AI 出卷面板
   模型配置是全站共用的：设置区在「我的」，AI 出卷只留一个状态指针。
   这一组类名（.a-aimodel / .a-aigrid / .a-aipresets / .a-aicaps / .a-aitests）
   原先由 .research/shot/add-ai-css.mjs 追加到本文件，后来在重写里丢了 —— 这里按原意图归位。
   app.css 只引用令牌，没有十六进制；尺寸令牌定义在 v4.css 的 Tier 3。
   ========================================================================== */
.a-aimodel,.a-aiplan{display:flex;flex-direction:column;gap:var(--sp-3)}
.a-aigrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:var(--sp-3) var(--sp-4)}
.a-airow{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.a-airow .a-note{flex:1 1 200px;min-width:0}
.a-aipresets{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.a-aicaps{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.a-aistruct{display:flex;flex-wrap:wrap;gap:var(--sp-2);align-items:center}
.a-reason{display:block;margin-top:var(--sp-2);color:var(--text-3)}
.a-aitests{list-style:none;margin:0;padding:var(--sp-3) 0 0;display:flex;flex-direction:column;gap:1px;border-top:1px solid var(--border)}
.a-aitest{display:flex;align-items:baseline;gap:var(--sp-3);padding:var(--sp-2) 0;border-bottom:1px solid var(--border);font-size:var(--fs-12)}
.a-aitest__name{flex:none;width:96px;color:var(--text-2)}
.a-aitest__detail{flex:1 1 auto;min-width:0;color:var(--text-3);word-break:break-word}
.a-aitest[data-ok='1'] .a-aitest__name{color:var(--success)}
.a-aitest[data-ok='0'] .a-aitest__name{color:var(--danger)}
.a-aimodel-pointer{display:flex;flex-direction:column;gap:var(--sp-2)}
@media (max-width:680px){
  .a-aitest{flex-wrap:wrap;row-gap:2px}
  .a-aitest__name{width:auto}
  .a-aitest__detail{flex-basis:100%}
}

/* -- 「我的」· AI 模型设置区 -------------------------------------------------
   默认收起的一张卡：标题行自己就是可点、可聚焦的控件（<summary> 自带展开语义）。
   焦点环改成内描边 —— .a-card 是 overflow:hidden，外描边会被裁掉。 */
.a-modelcfg__sum{
  display:flex;align-items:center;gap:var(--sp-2);min-height:var(--modelcfg-sum-h);
  padding:var(--sp-2) var(--sp-3);cursor:pointer;list-style:none;
  transition:background var(--dur-1) var(--ease);
}
.a-modelcfg__sum::-webkit-details-marker{display:none}
.a-modelcfg__sum:hover{background:var(--surface-hover)}
.a-modelcfg__sum:active{background:var(--surface-sunken)}
.a-modelcfg__sum:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.a-modelcfg[open] .a-modelcfg__sum{background:var(--surface-sunken);border-bottom:1px solid var(--border)}
.a-modelcfg__lead{display:flex;align-items:baseline;gap:var(--sp-2);min-width:0;flex-wrap:wrap}
.a-modelcfg__state{font-size:var(--fs-12);color:var(--text-2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.a-modelcfg__cue{margin-left:auto;flex:none;display:inline-flex;align-items:center;gap:4px;color:var(--accent);font-size:var(--fs-12);font-weight:var(--fw-medium)}
.a-modelcfg__ico{transition:transform var(--dur-2) var(--ease)}
.a-modelcfg[open] .a-modelcfg__ico{transform:rotate(180deg)}
.a-modelcfg .a-aimodel{padding-top:var(--sp-3)}
@media (max-width:900px){
  .a-modelcfg__state{white-space:normal}
}

.a-tutor__entry{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2)}
.a-tutor{margin-top:var(--sp-3);padding:var(--sp-3);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface-sunken)}
.a-tutor .a-card__head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.a-tutor__levels{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.a-tutor__input{width:100%;padding:var(--sp-2);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text);font:inherit;font-size:var(--fs-13);resize:vertical}
.a-tutor__acts{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-2);flex-wrap:wrap}
.a-tutor__reply{margin-top:var(--sp-3);padding-top:var(--sp-2);border-top:1px solid var(--border)}
.a-tutor__text{margin:var(--sp-2) 0 0;white-space:pre-wrap;font-family:inherit;font-size:var(--fs-13);line-height:1.7;color:var(--text-2)}
.a-note--warn{color:var(--danger)}
.a-frozen{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-3);border:1px dashed var(--border);border-radius:var(--radius-md);background:var(--surface-sunken);flex-wrap:wrap}
.a-kplist{display:flex;flex-direction:column}
.a-kprow{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border)}
.a-kprow:last-child{border-bottom:0}
.a-kprow:hover{background:var(--surface-hover)}
.a-kprow.is-weak{background:var(--surface-selected);box-shadow:inset 2px 0 0 var(--danger)}
.a-kprow__name{display:flex;align-items:center;gap:var(--sp-2)}
.a-kprow__lead{display:flex;flex-direction:column;gap:2px;min-width:0}
.a-kprow__name{font-size:var(--fs-14);font-weight:var(--fw-medium)}
.a-kprow__acts{display:flex;gap:var(--sp-1);flex:none}
.a-histlist{display:flex;flex-direction:column}
.a-histrow{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border)}
.a-histrow:last-child{border-bottom:0}
.a-histrow:hover{background:var(--surface-hover)}
.a-histrow__lead{display:flex;align-items:center;gap:var(--sp-2);min-width:0;flex-wrap:wrap}
.a-histrow__title{font-size:var(--fs-14);font-weight:var(--fw-medium);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.a-histrow__nums{display:flex;align-items:center;gap:var(--sp-3);flex:none}
.a-histrow__score{font-size:var(--fs-12);color:var(--text-3)}
.a-histrow__score b{font-family:var(--font-mono);font-size:var(--fs-16);color:var(--text-1)}
html[data-view="run"] .a-main{display:flex;flex-direction:column;overflow:hidden;padding:0}
.a-run{height:100%;min-height:0;display:flex;flex-direction:column}
.a-run__head{flex:none;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-2) var(--pad-main);border-bottom:1px solid var(--border);background:var(--surface)}
.a-run__title{flex:1;min-width:0}
.a-run__name{margin:0;font-size:var(--fs-16);font-weight:var(--fw-semibold)}
.a-run__meters{display:flex;align-items:center;gap:var(--sp-4);flex:none}
.a-run__meter{display:flex;flex-direction:column;align-items:flex-end;line-height:1.15}
.a-run__meter b{font-family:var(--font-mono);font-size:var(--fs-16);color:var(--text-1)}
.a-run__meter b i{font-style:normal;font-size:var(--fs-11);color:var(--text-3)}
.a-run__bar{flex:none;height:2px;background:var(--track);overflow:hidden}
.a-run__bar i{display:block;height:100%;background:var(--accent);transition:width var(--dur-2) var(--ease)}
.a-run__body{flex:1;min-height:0;display:grid;grid-template-columns:212px minmax(0,1fr)}
.a-run__q{min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:var(--pad-main);display:flex;flex-direction:column;gap:var(--sp-3)}
.a-run__foot{display:flex;align-items:center;gap:var(--sp-2);margin-top:auto;padding-top:var(--sp-2)}
.a-run__foot .a-note{margin-right:auto}
.a-answer-card{min-height:0;overflow-y:auto;padding:var(--sp-3);border-right:1px solid var(--border);background:var(--surface)}
/* 窄屏：答题卡从左侧栏折到题干下方（v4-gate-exam 就是按这个口径量的：<=900 一列、>=1024 两列）。
   DOM 顺序是「答题卡在前、题干在后」，一列时若不动顺序卡片会跑到题干上面去，
   所以这里用 grid-row 显式换位；题干仍然自己滚，卡片限高并保留自己的滚动。 */
@media (max-width:900px){
  .a-run__body{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr) auto}
  .a-run__q{grid-row:1;grid-column:1}
  .a-answer-card{grid-row:2;grid-column:1;max-height:38vh;border-right:0;border-top:1px solid var(--border)}
  .a-answer-card__grid{grid-template-columns:repeat(10,minmax(0,1fr))}
}
/* 考场计时：这一屏的绝对主角，一眼就能看到还剩多少时间 */
.a-exam-clock{display:flex;flex-direction:column;gap:2px;padding-bottom:var(--sp-3);margin-bottom:var(--sp-3);border-bottom:1px solid var(--border)}
.a-exam-clock b{font-family:var(--font-mono);font-size:var(--fs-40);font-weight:var(--fw-medium);line-height:1;letter-spacing:-0.02em;color:var(--text-1);font-variant-numeric:tabular-nums}
.a-answer-card__head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-2)}
.a-answer-card__grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--sp-1);margin-top:var(--sp-2)}
.a-cardcell{height:30px;border:1px solid var(--border);border-radius:var(--radius-1);background:var(--surface);font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-2);cursor:pointer;transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease)}
.a-cardcell:hover{border-color:var(--accent);color:var(--accent);background:var(--surface-hover)}
.a-cardcell:active{background:var(--surface-sunken)}
.a-cardcell:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-cardcell.is-done{background:var(--surface-selected);border-color:var(--accent);color:var(--accent)}
.a-cardcell.is-marked{box-shadow:inset 0 -2px 0 var(--warning)}
.a-cardcell.is-current{outline:2px solid var(--accent);outline-offset:1px}
.a-cardcell.is-right{background:var(--success-soft);border-color:var(--success);color:var(--success)}
.a-cardcell.is-wrong{background:var(--danger-soft);border-color:var(--danger);color:var(--danger)}
.a-answer-card__legend{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-top:var(--sp-3);padding-top:var(--sp-2);border-top:1px solid var(--border)}
.a-legend{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-11);color:var(--text-3)}
.a-legend i{width:10px;height:10px;border-radius:2px;border:1px solid var(--border);background:var(--surface)}
.a-legend i.is-done{background:var(--surface-selected);border-color:var(--accent)}
.a-legend i.is-marked{box-shadow:inset 0 -2px 0 var(--warning)}
.a-legend i.is-right{background:var(--success-soft);border-color:var(--success)}
.a-legend i.is-wrong{background:var(--danger-soft);border-color:var(--danger)}
.a-qcard{padding:var(--sp-4)}
.a-qhead{display:flex;align-items:center;gap:var(--sp-1);flex-wrap:wrap}
.a-qno{font-family:var(--font-mono);font-size:var(--fs-12);color:var(--accent);font-weight:var(--fw-medium)}
.a-markbtn{margin-left:auto}
.a-qsrc{margin:var(--sp-2) 0 0;font-size:var(--fs-11);color:var(--text-3)}
.a-qstem{margin:var(--sp-3) 0;font-size:var(--fs-16);line-height:1.8;font-weight:var(--fw-medium)}
.a-qstem--sm{font-size:var(--fs-14);font-weight:var(--fw-regular);margin:var(--sp-2) 0}
/* 交卷报告里「我的答案 / 正确答案」的对照（exam.js 一直在发 a-answers / a-answers__col，
   样式同样在 9/22 那一轮整块丢了，只剩两个裸 div 上下挨着）。
   口径与 v4-gate-exam 一致：<=680 上下堆叠，>=1024 左右对照。 */
.a-answers{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-2);margin-top:var(--sp-2)}
.a-answers__col{min-width:0;padding:var(--sp-2) var(--sp-3);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken)}
.a-answers__col p{margin:var(--sp-1) 0 0;font-size:var(--fs-13);line-height:1.7;white-space:pre-wrap;overflow-wrap:anywhere}
@media (min-width:1024px){.a-answers{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.a-material{margin:var(--sp-3) 0;border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);overflow:hidden}
/* ---- 外部 Agent 客户端卡片（后台 · Agent 留痕） ---- */
.a-btnrow{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center}
.a-checklist{display:flex;flex-direction:column;gap:var(--sp-2);border:1px solid var(--border);border-radius:var(--radius-2);padding:var(--sp-3);background:var(--surface-sunken)}
.a-checkrow{display:flex;gap:var(--sp-2);align-items:flex-start;cursor:pointer}
.a-checkrow__main{display:flex;flex-direction:column;gap:2px;min-width:0}
.a-newtoken{border:1px solid var(--accent);border-radius:var(--radius-2);padding:var(--sp-3);background:var(--surface-selected);display:flex;flex-direction:column;gap:var(--sp-2)}
.a-code{margin:0;padding:var(--sp-3);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);font-family:var(--font-mono);font-size:12px;line-height:1.5;overflow:auto;max-height:220px;white-space:pre;user-select:all}

/* ==========================================================================
   学习工具页 · 工具台（卡片墙 + 详情）
   为什么加：此前这一页只有一个 <select> 当导航 —— 学生要在一个下拉框里找工具，
   看不到工具是干什么的、共有多少个、属于哪一类。改成"卡片墙 + 搜索 + 分类筛选 + 详情"，
   下拉框退回到它该在的位置（程序化通道：深链与门禁用 #ws-section，视觉上隐藏、读屏可达）。
   纪律：只用 V4 三层令牌；可交互元素给足 default / hover / focus-visible / active /
   disabled / loading / selected 状态；颜色之外还有形状指示（左指示条 + 图标底板）。
   ========================================================================== */
.a-ws-nav{display:flex;flex-direction:column;gap:var(--sp-4)}
.a-ws-nav__head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap}
.a-ws-nav__lead{display:flex;flex-direction:column;gap:var(--launch-gap-tight);min-width:0}
.a-ws-nav__title{font-size:var(--fs-16);font-weight:var(--fw-semibold);color:var(--text-1)}
.a-ws-toolbar{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-ws-search{display:flex;align-items:center;gap:var(--sp-2);flex:1 1 var(--launch-min);min-width:0;height:var(--field-h);
  padding:0 var(--sp-2);border:1px solid var(--border);border-radius:var(--radius-2);background:var(--surface);color:var(--text-3)}
.a-ws-search:hover{border-color:var(--border-strong)}
.a-ws-search:focus-within{border-color:var(--accent);box-shadow:var(--shadow-focus)}
.a-ws-search__input{flex:1 1 auto;min-width:0;border:0;background:transparent;color:var(--text-1);font:inherit;font-size:var(--fs-13);line-height:1;outline:none}
.a-ws-search__input::placeholder{color:var(--text-disabled)}
.a-ws-search__clear{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:var(--act-hit);height:var(--act-hit);
  border:0;border-radius:var(--radius-1);background:transparent;color:var(--text-3);cursor:pointer}
.a-ws-search__clear:hover{background:var(--surface-hover);color:var(--text-1)}
.a-ws-search__clear:active{background:var(--surface-sunken)}
.a-ws-search__clear:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.a-ws-search__clear[hidden]{display:none}
.a-ws-chips{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.a-ws-chip{height:var(--picker-pill-h);padding:0 var(--sp-3);border:1px solid var(--border);border-radius:var(--radius-2);
  background:var(--surface);color:var(--text-2);font:inherit;font-size:var(--fs-12);cursor:pointer;
  transition:background var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease)}
.a-ws-chip:hover{background:var(--surface-hover);border-color:var(--border-strong);color:var(--text-1)}
.a-ws-chip:active{background:var(--surface-sunken)}
.a-ws-chip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-ws-chip[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:var(--fw-medium)}
.a-ws-chip[disabled],.a-ws-chip[aria-disabled="true"]{color:var(--text-disabled);cursor:not-allowed;background:var(--surface-sunken)}
.a-ws-chip__n{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3);margin-left:var(--sp-1)}
.a-ws-chip[aria-pressed="true"] .a-ws-chip__n{color:var(--accent)}
.a-launch{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--launch-min),1fr));gap:var(--launch-gap);margin:0;padding:0;list-style:none}
.a-launchcard{display:flex;align-items:flex-start;gap:var(--sp-3);width:100%;height:100%;padding:var(--launch-pad);text-align:left;
  border:1px solid var(--border);border-left-width:var(--launch-bar);border-left-color:var(--border);
  border-radius:var(--radius-2);background:var(--surface);color:var(--text-1);font:inherit;cursor:pointer;
  transition:background var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease)}
.a-launchcard:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.a-launchcard:active{background:var(--surface-sunken)}
.a-launchcard:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.a-launchcard[aria-current="true"]{background:var(--surface-selected);border-color:var(--accent);border-left-color:var(--accent)}
.a-launchcard[disabled],.a-launchcard[aria-disabled="true"]{background:var(--surface-sunken);color:var(--text-disabled);cursor:not-allowed}
.a-launchcard[aria-busy="true"]{background:var(--surface-sunken);cursor:progress}
.a-launchcard__ico{display:grid;place-items:center;flex:0 0 auto;width:var(--launch-ico);height:var(--launch-ico);
  border:1px solid var(--border);border-radius:var(--radius-1);background:var(--surface-sunken);color:var(--text-3)}
.a-launchcard:hover .a-launchcard__ico{color:var(--text-2)}
.a-launchcard[aria-current="true"] .a-launchcard__ico{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
.a-launchcard__body{display:flex;flex-direction:column;gap:var(--sp-1);min-width:0}
.a-launchcard__name{font-size:var(--fs-14);font-weight:var(--fw-medium);line-height:1.35;overflow-wrap:anywhere}
.a-launchcard__desc{font-size:var(--fs-12);color:var(--text-3);line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.a-launchcard__group{font-family:var(--font-mono);font-size:var(--fs-11);color:var(--text-3)}
.a-launchcard[aria-current="true"] .a-launchcard__group{color:var(--accent)}
.a-ws-empty{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-2);padding:var(--sp-5);
  border:1px dashed var(--border);border-radius:var(--radius-2);background:var(--surface-sunken);color:var(--text-2)}
.a-ws-active{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;
  padding:var(--sp-2) 0;position:sticky;top:0;z-index:2;background:var(--surface-page)}
.a-ws-crumb{display:flex;align-items:center;gap:var(--sp-2);min-width:0;font-size:var(--fs-12);color:var(--text-3);flex-wrap:wrap}
.a-ws-crumb__sep{color:var(--text-disabled)}
.a-ws-crumb__here{color:var(--text-1);font-weight:var(--fw-medium)}
.a-ws-resume{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin:var(--sp-1) 0 0;font-size:var(--fs-12);color:var(--text-3)}
.a-visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
@media (max-width:900px){
  .a-launch{grid-template-columns:repeat(auto-fill,minmax(calc(var(--launch-min) - var(--sp-6)),1fr))}
  .a-ws-nav__head{align-items:flex-start}
}
@media (max-width:560px){
  .a-launch{grid-template-columns:1fr}
  .a-ws-search{flex:1 1 100%}
  .a-ws-chip{height:var(--opt-h)}
}

/* ==========================================================================
   法律页面（隐私政策 / 服务条款，public/legal.js）
   这两页是上线合规的实体：内容必须真的读得下去 —— 长段落、条目列表、
   关键结论要能一眼扫到。颜色一律走 Tier 2 语义令牌（本文件零十六进制）。
   ========================================================================== */
.a-legal__h{margin:0 0 var(--sp-2);font-size:var(--fs-16);font-weight:var(--fw-semibold);line-height:1.35;color:var(--text-1)}
.a-legal__p{margin:0 0 var(--sp-2);font-size:var(--fs-13);line-height:1.75;color:var(--text-2)}
.a-legal__p:last-child{margin-bottom:0}
/* 列表项的行宽上限：能读的法律文字一行不该超过 ~72 个字符，
   超了读者会跳行，写了等于没写。 */
.a-legal__list{margin:0 0 var(--sp-2);padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--sp-1)}
.a-legal__list li{position:relative;padding-left:var(--sp-3);font-size:var(--fs-13);line-height:1.7;color:var(--text-2);max-width:72ch}
.a-legal__list li::before{content:"";position:absolute;left:0;top:.62em;width:4px;height:4px;border-radius:50%;background:var(--accent)}
.a-legal__note{margin-top:var(--sp-2);padding:var(--sp-2);border-left:2px solid var(--border-strong);border-radius:0 var(--radius-1) var(--radius-1) 0;background:var(--surface-sunken);max-width:72ch}
.a-legal__list b,.a-legal__p b{color:var(--text-1);font-weight:var(--fw-semibold)}
/* 注册页/页脚里的条款入口：未登录也必须能读（合规要求，不是可选项） */
.a-legal__link{color:var(--text-2);text-decoration:underline;text-underline-offset:2px;font-size:var(--fs-12)}
.a-legal__link:hover{color:var(--text-1)}
.a-legal__sep{color:var(--text-3);margin:0 var(--sp-1);font-size:var(--fs-12)}
.a-legal__foot{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-1);justify-content:center;margin-top:var(--sp-2)}
/* 登录页的「找回密码」说明：这是这一屏里唯一一句「做不到什么」的话，
   必须看得见、又不能抢主按钮的注意力 —— 用注释层级 + 左侧细线，而不是再加一个按钮。 */
/* ---- 邮箱验证码（注册两步式 / 自助找回）----------------------------------
   验证码输入框与「发送验证码」并排：输入框 flex:1 但受 --auth-code-max 限制（宽屏不拉长），
   按钮 flex:0 0 auto 不压缩（否则窄屏下按钮文字会被压成两行）。
   360px 档在 v4.css 的 ≤560px 里把 --auth-code-max 改成 100%，这里再把它竖过来。 */
.a-auth__coderow{display:flex;gap:var(--sp-2);align-items:flex-end}
.a-auth__codefield{flex:1 1 auto;min-width:0;max-width:var(--auth-code-max)}
.a-auth__send{flex:0 0 auto;height:var(--field-h);white-space:nowrap}
.a-auth__send[disabled]{cursor:progress;opacity:.72}
/* 状态行常驻占位（min-height）：从「正在发送」到「已发送」再到「失败原因」，
   文字长度变化不该让下面的按钮上下跳 —— 一跳就容易点错。 */
.a-auth__msg{margin:0;min-height:var(--auth-msg-min);font-size:var(--auth-msg-fs);line-height:1.6;color:var(--text-2)}
.a-auth__msg:empty{min-height:0}
.a-auth__msg.is-ok{color:var(--text-1)}
.a-auth__msg.is-error{color:var(--danger)}
@media (max-width:560px){
  /* 只改结构方向（把并排改成上下），尺寸一律由 v4.css Tier 3 的 --auth-code-max
     在窄屏档里给出（100%），不在 app.css 另写一套窄屏尺寸。 */
  .a-auth__coderow{flex-direction:column;align-items:stretch}
}
.a-auth__forgot{margin-top:var(--sp-2);padding-left:var(--sp-2);border-left:2px solid var(--border-strong);font-size:var(--fs-12);line-height:1.6;color:var(--text-3)}
.a-auth__forgot b{color:var(--text-2);font-weight:var(--fw-semibold)}
.a-auth__legal{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;margin-top:var(--sp-2)}

