/* 工作台骨架专用样式。基础外观来自 Tabler（vendor/tabler），这里只写 Tabler 没有的部分。 */
:root { --shell-gap: 1rem; }

/* 左侧导航：脱离文档流固定住，不随页面滚动而移动。
   原来用 position:sticky，但它所在的 .d-flex 行高度＝内容高度，参照系被撑破，实测滚到 400px 时 top=-400（跟着滚走）。 */
.rail { position: fixed; inset: 0 auto 0 0; width: 96px; height: 100vh; height: 100dvh; z-index: 1030;
  display: flex; flex-direction: column; align-items: center; gap: .2rem; padding: .5rem 0;
  overflow-y: auto; overflow-x: hidden;
  background: var(--tblr-bg-surface); border-right: 1px solid var(--tblr-border-color); }

/* 给固定导航让出 96px；用子选择器限定，避免影响到工作台内部 .page 类名 */
.shell > .page { margin-left: 96px; }

/* 单屏外壳（P40）：整页固定成视口高度，页面级滚动条消失。
   注意必须用 .shell 这个独立类，不能写成 .d-flex——Tabler 大量组件也用 d-flex，
   早期版本误命中问答按钮外壳，把它撑到 768px 高。 */
@media (max-height: 900px) {
  html, body { height: 100%; overflow: hidden; }
  .shell { height: 100vh; }
  .shell > .page { height: 100vh; min-height: 0; overflow: hidden; }
  .shell .page-wrapper { height: 100vh; min-height: 0; display: flex; flex-direction: column; }
  .shell .page-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
  /* Tabler 的 .page-body 是纵向 flex，子级默认沿交叉轴拉伸；不锁住会撑出无意义的空白 */
  .shell .page-body > .container-xl, .shell .page-body > .container-fluid { height: auto; align-self: stretch; }
  /* 内部滚动条收细，避免单屏里出现粗黑滚动条 */
  .shell .page-body { scrollbar-width: thin; scrollbar-color: var(--tblr-border-color) transparent; }
  .shell .page-body::-webkit-scrollbar { width: 8px; height: 8px; }
  .shell .page-body::-webkit-scrollbar-track { background: transparent; }
  .shell .page-body::-webkit-scrollbar-thumb { background: var(--tblr-border-color); border-radius: 4px; }
}

/* 窄屏：导航改底部固定横排，避免占掉正文宽度 */
@media (max-width: 991.98px) {
  .rail { inset: auto 0 0 0; width: auto; height: auto; flex-direction: row; justify-content: space-around;
    gap: 0; padding: .25rem 0; overflow: visible; z-index: 1035;
    border-right: 0; border-top: 1px solid var(--tblr-border-color); }
  .rail-link { width: auto; flex: 1 1 0; min-height: 48px; font-size: 1.25rem; }
  .rail-link.mt-auto { margin-top: 0 !important; }
  .shell > .page { margin-left: 0; margin-bottom: 68px; }
}
.rail-link { width: 86px; min-height: 56px; padding: .35rem .2rem; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .12rem;
  border-radius: var(--tblr-border-radius); color: var(--tblr-secondary); font-size: 1.5rem; text-decoration: none; }
.rail-label { font-size: .6875rem; line-height: 1.1; text-align: center; }
.rail-link:hover { background: var(--tblr-bg-surface-secondary); color: inherit; }
.rail-link.active { background: var(--tblr-primary-lt); color: var(--tblr-primary); box-shadow: inset 2px 0 0 var(--tblr-primary); }

/* 占位块：诚实标注"这里还没做"，不假装完成 */
.ph { display: flex; align-items: center; justify-content: center; padding: 1rem; text-align: center;
  font-size: .8125rem; color: var(--tblr-secondary);
  background: var(--tblr-bg-surface-secondary); border: 1px dashed var(--tblr-border-color); border-radius: var(--tblr-border-radius); }
.ph-sm { min-height: 64px; }
.ph-md { min-height: 140px; }
.ph-lg { min-height: 240px; }

/* 三栏工作台 */
.workbench { display: grid; grid-template-columns: 260px minmax(0, 1fr) 340px; gap: var(--shell-gap); align-items: start; }
.workbench .stack { display: grid; gap: var(--shell-gap); }
@media (max-width: 1199.98px) { .workbench { grid-template-columns: 1fr; } }

/* 章节树（原生 details，零依赖） */
.tree summary { cursor: pointer; list-style: none; }
.tree summary::-webkit-details-marker { display: none; }

/* 编辑器 */
.editor-host { height: clamp(170px, 32vh, 300px); border-radius: var(--tblr-border-radius); overflow: hidden; }
.ace_marker-layer .marker-pin { position: absolute; z-index: 5;
  background: rgba(66, 153, 225, .30); border-left: 3px solid #4299e1; }
.ace_marker-layer .marker-pc { position: absolute; z-index: 4;
  background: rgba(246, 173, 85, .22); border-left: 3px solid #f6ad55; }

/* 解析结果与跳过清单 */
#skip-list { font-size: .75rem; color: var(--tblr-secondary); }
#skip-list code { font-size: .6875rem; }
/* 长报错 / 长代码不撑破容器 */
#skip-list code, #skip-list div, .ai-msg, .ai-panel-log, #toast, #parse-status, .step-title, .timeline-event-card {
  overflow-wrap: anywhere; word-break: break-word; }

/* 虚拟板 */
.board-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 200px; gap: var(--shell-gap); }
@media (max-width: 991.98px) { .board-wrap { grid-template-columns: 1fr; } }
.board-wrap { align-items: start; }
/* 寄存器/变量列不要撑高整张卡：超高就自己滚 */
.board-wrap > div:last-child { max-height: 34vh; overflow: auto; }
#board svg { display: block; width: 100%; height: auto; }
@media (min-width: 992px) { #board svg { max-height: 34vh; } }
.pin { cursor: pointer; }
.pin .pin-dot { fill: var(--tblr-bg-surface-secondary); stroke: var(--tblr-border-color); stroke-width: 2; }
.pin.on .pin-dot { fill: var(--tblr-green); stroke: var(--tblr-green); }
.pin text { font-size: 7px; fill: var(--tblr-secondary); }
.pin.flash .pin-dot { animation: pin-flash .5s ease 3; }
@keyframes pin-flash { 50% { r: 8; fill: var(--tblr-yellow); stroke: var(--tblr-yellow); } }
#regs .reg { display: flex; justify-content: space-between; padding: .25rem .5rem; border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--tblr-bg-surface-secondary); }
#regs .reg + .reg { margin-top: .25rem; }
.leds { display: flex; gap: .5rem; }
.led { width: 12px; height: 12px; border-radius: 50%; background: var(--tblr-bg-surface-secondary); border: 1px solid var(--tblr-border-color); }
.led.on { background: var(--tblr-yellow); border-color: var(--tblr-yellow); box-shadow: 0 0 8px var(--tblr-yellow); }

/* 快照时间轴（P0-2） */
.snap-bar { display: flex; align-items: center; gap: .75rem; }
.snap-bar input[type="range"] { flex: 1 1 auto; }
.badge-live { background: var(--tblr-green-lt); color: var(--tblr-green); }
.badge-replay { background: var(--tblr-yellow-lt); color: var(--tblr-yellow); }

/* 波形（P0-3）：WaveDrom 默认是浅色皮肤，深色模式下反转 */
#wave svg { max-width: 100%; height: auto; }
[data-bs-theme="dark"] #wave svg { filter: invert(.92) hue-rotate(180deg); }

/* AI 面板（C2=B） */
.ai-log { display: grid; gap: .5rem; max-height: 260px; overflow: auto; }
.ai-msg { padding: .5rem .75rem; border-radius: var(--tblr-border-radius); font-size: .875rem; }
.ai-msg.me { background: var(--tblr-primary-lt); }
.ai-msg.bot { background: var(--tblr-bg-surface-secondary); }
.ai-msg .ai-tag { display: block; font-size: .6875rem; color: var(--tblr-secondary); margin-top: .25rem; }

/* 半自动演示条（P0-4 / C4=B） */
.demo-bar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 20px; z-index: 1080;
  display: none; align-items: center; gap: 1rem; padding: .75rem 1.25rem; max-width: 780px;
  background: var(--tblr-bg-surface); border: 1px solid var(--tblr-border-color); border-radius: var(--tblr-border-radius-lg);
  box-shadow: var(--tblr-shadow-lg); }
.demo-bar.on { display: flex; }
.demo-bar .kbd { font-family: ui-monospace, monospace; background: var(--tblr-bg-surface-secondary);
  border: 1px solid var(--tblr-border-color); border-radius: 4px; padding: 0 .35rem; }

/* 飞线动画的小点（P1-1） */
.fly-dot { position: absolute; z-index: 1090; width: 10px; height: 10px; border-radius: 50%;
  background: var(--tblr-blue); box-shadow: 0 0 12px var(--tblr-blue); pointer-events: none; }

/* 轻提示（分享链接、故障恢复等） */
#toast { position: fixed; left: 50%; transform: translate(-50%, -12px); top: 72px; z-index: 1095;
  padding: .5rem .9rem; border-radius: var(--tblr-border-radius); opacity: 0; pointer-events: none;
  background: var(--tblr-bg-surface); border: 1px solid var(--tblr-border-color); box-shadow: var(--tblr-shadow-lg);
  transition: opacity .2s ease, transform .2s ease; font-size: .8125rem; }
#toast.on { opacity: 1; transform: translate(-50%, 0); }

/* 故障诊断卡（P1-2） */
#fault-card .card { border-color: var(--tblr-yellow); }

/* 对话入口（C1）：右下角悬浮 */
.ai-fab { position: fixed; right: 20px; bottom: 20px; z-index: 1096; width: 48px; height: 48px;
  border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.25rem;
  box-shadow: var(--tblr-shadow-lg); }
.ai-panel { position: fixed; right: 20px; bottom: 78px; z-index: 1096; width: 340px; max-width: calc(100vw - 40px);
  display: none; flex-direction: column; gap: .5rem; padding: .75rem;
  background: var(--tblr-bg-surface); border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius-lg); box-shadow: var(--tblr-shadow-lg); }
.ai-panel.on { display: flex; }
.ai-panel-head { display: flex; align-items: center; gap: .5rem; }
.ai-panel-log { display: grid; gap: .4rem; max-height: 280px; overflow: auto; }
.ai-panel-form { display: flex; gap: .4rem; }
.ai-msg .ai-tag { display: block; font-size: .6875rem; color: var(--tblr-secondary); margin-top: .2rem; }

/* 左右栏收起（工作台）：隐藏后同步改栅格，避免留空列 */
.workbench.no-left { grid-template-columns: minmax(0, 1fr) 340px; }
.workbench.no-right { grid-template-columns: 260px minmax(0, 1fr); }
.workbench.no-left.no-right { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 1199.98px) {
  .workbench.no-left, .workbench.no-right, .workbench.no-left.no-right { grid-template-columns: minmax(0, 1fr); }
}

/* 演示模式中锁住其它按钮，避免脚本与手点互相打架 */
body.demo-on header .btn:not([data-demo-start]):not([data-demo-exit]),
body.demo-on header .form-select { pointer-events: none; opacity: .45; }

/* 短屏（1366×768 投影）：压掉纵向留白，保证三栏同屏 */
@media (max-height: 820px) {
  .page-body { padding-top: .5rem; }
  .navbar { margin-bottom: .25rem; }
  .card-body { padding: .5rem .75rem; }
  .card-header { padding: .5rem .75rem; }
  .card-table > :not(caption) > * > * { padding: .35rem .5rem; }
  .editor-host { height: 150px; }
  #board svg { max-height: 24vh; }
  .board-wrap > div:last-child { max-height: 24vh; }
  #regs .reg { font-size: .75rem; padding: .15rem .4rem; }
}

/* 图表占位（组件未加载 / 无数据） */
.chart-ph { display: flex; align-items: center; justify-content: center; min-height: 180px;
  border: 1px dashed var(--tblr-border-color); border-radius: var(--tblr-border-radius);
  color: var(--tblr-secondary); font-size: .8125rem; }

/* 误区纠错卡（P50）：把「流传说法 / 实际情况 / 依据」摆成对照组，一眼看出差在哪 */
.mc-block { border: 1px solid var(--tblr-border-color); border-left: 3px solid var(--tblr-orange);
  border-radius: var(--tblr-border-radius); padding: .4rem .5rem; background: var(--tblr-bg-surface-secondary); }
.mc-head { font-weight: 700; font-size: .8125rem; margin-bottom: .25rem; color: var(--tblr-orange); }
.mc-row { display: flex; gap: .4rem; align-items: flex-start; font-size: .8125rem; line-height: 1.35; }
.mc-row + .mc-row { margin-top: .3rem; }
.mc-tag { flex: 0 0 auto; width: 4.2rem; text-align: center; font-size: .6875rem; line-height: 1.3;
  padding: .1rem .2rem; border-radius: 3px; }
.mc-tag-no { background: var(--tblr-red-lt); color: var(--tblr-red); }
.mc-tag-yes { background: var(--tblr-green-lt); color: var(--tblr-green); }
.mc-tag-why { background: var(--tblr-secondary-lt); color: var(--tblr-secondary); }
.mc-tip { margin-top: .3rem; font-size: .75rem; color: var(--tblr-secondary); }

/* 器件未建模标注（P11-lite）：用中性色，不制造"这里坏了"的错觉 */
.dev-note { border: 1px solid var(--tblr-border-color); border-left: 3px solid var(--tblr-secondary);
  border-radius: var(--tblr-border-radius); padding: .35rem .5rem; font-size: .75rem; line-height: 1.35;
  background: var(--tblr-bg-surface-secondary); color: var(--tblr-secondary); }
.dev-head { font-weight: 700; color: var(--tblr-body-color); margin-bottom: .15rem; }
.dev-shows { margin-top: .2rem; }

/* 打印（导出路线图）例外：撤掉一屏外壳，让内容自然分页，否则只会印出第一屏 */
@media print {
  html, body { height: auto !important; overflow: visible !important; }
  .shell, .shell > .page, .shell .page-wrapper { height: auto !important; min-height: 0 !important; overflow: visible !important; }
  .shell .page-body { overflow: visible !important; }
  .rail, .ai-fab, .ai-panel, .demo-bar, #toast, #ai-health-backdrop, #nl2-backdrop, #why-panel { display: none !important; }
}

/* 列表面板（资料树用的滚动容器，占位） */
.list-scroll { max-height: 420px; overflow: auto; }

/* P85 首页"最近事件"：一行三格。
   原来是 timeline，3 条 194px，把首页顶出 1366×768；现在 3 条只占一行，页面高度基本恒定。 */
.recent-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem .9rem; }
.recent-cell { display: flex; align-items: center; gap: .35rem; font-size: .75rem; line-height: 1.5; min-width: 0; }
.recent-cell .t { color: var(--tblr-secondary); flex: 0 0 auto; }
.recent-cell .w { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recent-cell .r { color: var(--tblr-secondary); flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 991.98px) { .recent-grid { grid-template-columns: 1fr; } }

/* 吉祥物「小五」（assets/mascot.js）：全站可见的小小学习搭子。
   只做"轻动"：呼吸式浮动 + 5 秒一次的眨眼，不用花哨动画抢教学内容的注意力。 */
.m5 { display: inline-block; line-height: 0; vertical-align: -3px; flex: 0 0 auto; }
.m5 svg { display: block; }
.m5 .m5-eye { animation: m5-blink 5.2s infinite; transform-box: fill-box; transform-origin: center; }
@keyframes m5-blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(.12); } }
.m5-think svg, .m5-confused svg { animation: m5-bob 1.8s ease-in-out infinite; }
@keyframes m5-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1px); } }
.rail-mascot { display: flex; justify-content: center; padding: .4rem 0 .2rem; cursor: help; }
.rail-brand { display: flex; flex-direction: column; align-items: center; padding-bottom: .2rem; }
.rail-brand-name { font-size: .75rem; font-weight: 700; letter-spacing: .06em; color: var(--tblr-primary); }
@media (prefers-reduced-motion: reduce) { .m5 * { animation: none !important; } }

/* 卡片面板里的"看图理解"入口：
   Tabler 的 .btn 默认 white-space:nowrap，而左栏只有约 210px 可用宽度，
   长中文文案会被左右截掉（实测溢出 12px）。这里允许换行并放开行高，
   文案同时拆成"主标题 + 关卡信息"两行。 */
.vis-link { white-space: normal; height: auto; line-height: 1.25; padding: .2rem .35rem; text-align: center;
  font-size: .75rem;
  /* P97：这个按钮里本想"主标题 / 关卡信息"上下两行，但 .btn 是 inline-flex，
     两个 span 会被排成一行挤在一起（实测两个 span 同一行 top=226/227）。 */
  flex-direction: column; align-items: center; justify-content: center; gap: .05rem; }
.vis-link span { white-space: normal; }
.vis-link span + span { font-size: .6875rem; }

/* A1 依据行：AI 回答下面的"依据：…"。用分隔线和小字，和大模型正文区分开，
   避免被当成回答的一部分（评委常问"这句是谁说的"）。
   四个落点（工作台消息 / 悬浮助手 / 首页诊断 / 记录页周报 / 看图学C 错项解释）共用这一条。 */
.ai-basis { display: block; margin-top: .2rem; padding-top: .2rem; font-size: .6875rem; line-height: 1.35;
  color: var(--tblr-secondary); border-top: 1px dashed var(--tblr-border-color); }

/* ===== 配色方案（P99）：信息类型色 =====
   5 个类型识别色，只允许出现在 ①卡片左侧 3px 色条 ②卡片标题里的图标 —— 不做大面积填充，避免花。
   主色由各页面 <html data-bs-theme-primary="indigo"> 提供（Tabler 官方机制，零 CSS）。
   实测对比度：色条对卡片底 5.90 / 6.88 / 5.35 / 4.43 / 5.72（非文字图形要求 ≥3:1，全部达标）。 */
:root {
  --t-ai: #14b8a6;   /* AI 相关：值班台、AI 诊断 */
  --t-act: #f59f00;  /* 现在要做的动作：当前卡片 */
  --t-prog: #2fb344; /* 进度：能力雷达、章节进度 */
  --t-log: #7c8db5;  /* 记录：最近事件（低饱和，不抢眼） */
  --t-nav: #94a3b8;  /* 入口 / 导航（中性，"去哪都行"不需要抢色） */
}
.card[data-type] { border-left: 3px solid var(--t); }
.card[data-type] .card-title i { color: var(--t); }
.card[data-type="ai"] { --t: var(--t-ai); }
.card[data-type="act"] { --t: var(--t-act); }
.card[data-type="prog"] { --t: var(--t-prog); }
.card[data-type="log"] { --t: var(--t-log); }
.card[data-type="nav"] { --t: var(--t-nav); }
/* 上面 5 个色是按深色底挑的；浅色主题下对白底不达标（实测 #14b8a6 只有 2.3:1），
   所以浅色单独配一套深一档的等价色，保证色条对白底 ≥4.5:1。 */
[data-bs-theme="light"] {
  --t-ai: #0f766e;   /* 5.3:1 on #fff */
  --t-act: #b45309;  /* 5.1:1 */
  --t-prog: #15803d; /* 4.7:1 */
  --t-log: #475569;  /* 7.2:1 */
  --t-nav: #64748b;  /* 4.9:1 */
}

/* 首页/AI 中枢共用的紧凑排版件（值班台条目、读数行、标题画布） */
.duty-item { display: flex; gap: .55rem; align-items: flex-start; }
.duty-item + .duty-item { margin-top: .45rem; padding-top: .45rem; border-top: 1px solid var(--tblr-border-color); }
.duty-item .n { flex: 0 0 1.45rem; height: 1.45rem; border-radius: 50%; background: var(--tblr-primary-lt);
  color: var(--tblr-primary); display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .75rem; }
.duty-item .what { font-size: .875rem; font-weight: 600; line-height: 1.35; }
.duty-item .why { color: var(--tblr-secondary); font-size: .6875rem; line-height: 1.4; }

/* AI 值班台的"讲详细点"回答：给一块独立面板。
   原来是把三行小字直接堆在按钮行下面（正文 + 徽标行 + 依据行 + 免责声明都挤在一起），
   展开后还会溢出写死的行高、压住下面四个模块。 */
.duty-ai { margin-top: .5rem; padding: .5rem .6rem; border-radius: .4rem;
  background: var(--tblr-primary-lt); border: 1px solid var(--tblr-border-color); }
.duty-ai-head { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-bottom: .3rem; }
.duty-ai-head .duty-ai-tag { font-size: .6875rem; font-weight: 600; color: var(--tblr-primary); }
.duty-ai-text { font-size: .8125rem; line-height: 1.5; }
.duty-ai-basis { margin-top: .35rem; padding-top: .3rem; font-size: .6875rem; line-height: 1.4;
  color: var(--tblr-secondary); border-top: 1px dashed var(--tblr-border-color); }
.duty-ai-note { margin-top: .25rem; font-size: .625rem; line-height: 1.4; color: var(--tblr-secondary); }
.mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .6875rem; line-height: 1.5; }
.rowline { display: flex; align-items: center; gap: .45rem; }
.rowline + .rowline { margin-top: .3rem; }
.dot { width: .5rem; height: .5rem; border-radius: 50%; display: inline-block; flex: 0 0 auto; }

/* 能力雷达的图例改由 HTML 画，不再用 ECharts 的 legend：
   ECharts 6.1.0 在这个宽度（容器约 400px）的窄容器里会把第二项的文字压在第一项上，
   实测首页与规划页都会叠字（"目标"被"已完成"盖住），换版本才能指望它自己修好。
   颜色和 series 里显式写的那两个值必须一致，改一个要改两处。 */
.chart-legend { display: inline-flex; align-items: center; gap: .6rem; }
.chart-legend > span { display: inline-flex; align-items: center; gap: .25rem; white-space: nowrap; }
.chart-legend > span > i { width: .5rem; height: .5rem; border-radius: 50%; display: inline-block; flex: 0 0 auto; }
/* 每条能力轴的"已完成 / 目标"细条：光写 90 / 0 读不出谁是谁 */
.gapbar { flex: 1 1 auto; min-width: 1.5rem; height: .3rem; border-radius: .15rem;
  background: rgba(138, 148, 166, .22); overflow: hidden; }
.gapbar > i { display: block; height: 100%; border-radius: .15rem; background: #91cc75; }

/* 方向 3：可点的 AI 徽标（打开"为什么没回话"面板）；依据徽标是悬停查看，用 help 光标区分开 */
[data-ai-health] { cursor: pointer; }
/* 无障碍：AI 徽标只有 20px 高（低于 24px 建议值）。用一层透明覆盖把可点区域撑到 28px，
   不动排版高度 —— 加 padding 会让状态行整体变高，进而把页面顶出 1366×768。 */
[data-ai-health] { position: relative; }
[data-ai-health]::after { content: ''; position: absolute; left: 0; right: 0; top: -4px; bottom: -4px; }
#ai-basis { cursor: help; }
/* 健康面板 / AI 现场编程都做成居中弹窗：工作台右栏本来就是 AI 面板，浮在右下角会正好盖住回答 */
#ai-health, #nl2-modal { position: fixed; left: 50%; top: 50%; right: auto; bottom: auto; transform: translate(-50%, -50%);
  width: 400px; max-width: calc(100vw - 40px); max-height: calc(100vh - 120px); overflow: auto; z-index: 1091; }
/* 「AI 现场编程」要放代码，宽一点 */
#nl2-modal { width: 560px; }
#ai-health-backdrop, #nl2-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, .5); z-index: 1090; display: none; }
#ai-health-backdrop.on, #nl2-backdrop.on { display: block; }
#ai-health td { padding: .2rem .5rem; font-size: .75rem; vertical-align: top; }
/* 生成的代码预览：等宽 + 可滚动，别把弹窗撑出屏幕 */
.nl-code { margin: 0; padding: .4rem .5rem; max-height: 232px; overflow: auto; font: 12px/1.45 Consolas, Menlo, monospace;
  background: var(--tblr-bg-surface-secondary); border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius); color: var(--tblr-body-color); white-space: pre; }
