/* 标博士 · 组件样式 v0.2 · 2026-11-03 * 依赖 tokens.css。规范见 docs/design/design-system.md §7;组件预览 components.html 和原型 docs/prototype/ 共用本文件。 * 原型阶段的参考实现:前端不用带样式的 UI 框架(AR10),正式实现按这里的视觉写组件样式,不必照搬选择器。 * v0.2(决策 U5,定稿样张 ui-demo/explore/workbench-d5.html): * - 只有一种容器:白卡片,1px 发丝线,圆角 12,无阴影;卡片里不再套面板; * - 表头无底色、无粗线,12px 辅助灰列名;行间发丝线;行悬停 --c-n50; * - 圆角三档:标签 6、控件 8、卡片 / 对话框 12;按钮高 36 / 32 / 40; * - 中性标签只有一种:--c-n100 实底、无描边;问题级别标签形状不变(致命实心、重要描边、提示无框); * - Q1–Q12(2026-11-03 已确认):流水「+」用墨色(Q1);AI 正文始终墨色(Q2);选中 = --c-n50 底 + 左侧 3px 墨色竖条(Q3); * 不写裸色值(Q6);数字字号三档(Q7)。 * - 收尾(2026-11-03):.fig 默认字号进共用层;致命问题行不再加红竖线(级别只靠实心「致命」标签); * 原文纸面用 --font-doc / --fs-doc / --lh-doc,原句高亮改为「蓝铅笔浅底 + 蓝色底边」。 */ /* ---- 基础 ---- */ *{box-sizing:border-box} body{margin:0;background:var(--bg-page);color:var(--text-primary);font:var(--fs-body)/var(--lh-body) var(--font-sans);-webkit-font-smoothing:antialiased} :focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px} [hidden]{display:none!important} .row{display:flex;flex-wrap:wrap;gap:var(--sp-3);align-items:center} .grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6)} .fig{font-family:var(--font-figures);font-variant-numeric:tabular-nums;font-weight:var(--fw-bold);font-size:var(--fs-figure-sm)} /* 数字字号(Q7):正文里独立出现的数字默认 15(--fs-figure-sm);12px 小字里 13(--fs-figure-xs);统计大数字用 .big(--fs-figure 28) */ :is(small,.cap,.note,.cost,.flag,.sev,.tag,.chip,.msg,.cite-src,.proj-sub,.psub) .fig,table.data th .fig,table.data a .fig{font-size:var(--fs-figure-xs)} .note{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary);margin:var(--sp-3) 0 0} /* ---- 卡片:全页唯一的容器 ---- * 整块卡片:.card(自带内边距)。 * 分区卡片:.card.flush 不带内边距,里面用 .card-h(标题行)/ .card-b(正文)/ .card-f(底栏,带发丝线),左右边距统一 --card-x。 */ .card{background:var(--bg-surface);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card);padding:var(--card-y) var(--card-x)} .card.flush{padding:0} .card.flush > .card-h{display:flex;align-items:center;gap:var(--sp-3);min-height:var(--card-h-min);margin:0;padding:var(--sp-3) var(--card-x)} .card-h h2,.card-h h3{margin:0;font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans)} .card-b{padding:var(--sp-1) var(--card-x) var(--sp-4)} .card-f{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-3) var(--card-x);border-top:var(--line) solid var(--border-subtle)} /* ---- 级别标签与中性标签 ---- */ .sev{display:inline-flex;align-items:center;gap:var(--sp-1);height:var(--tag-h);padding:0 var(--sp-2);border-radius:var(--radius-tag);font:var(--fw-bold) var(--fs-caption)/1 var(--font-sans);white-space:nowrap} .sev .fig{font-size:var(--fs-figure-xs)} .sev.fatal{background:var(--sev-fatal);color:var(--text-on-dark)} .sev.major{border:var(--line-sev) solid var(--sev-major);color:var(--sev-major-text)} .sev.hint{background:var(--sev-hint-soft);color:var(--sev-hint)} /* 中性标签(状态、类别、包):只有这一种,--c-n100 实底、无描边、墨色字 */ .tag{display:inline-flex;align-items:center;gap:var(--sp-1);height:var(--tag-h);padding:0 var(--sp-2);border-radius:var(--radius-tag);background:var(--c-n100);font-size:var(--fs-caption);line-height:1;color:var(--text-primary);white-space:nowrap} .tag.status{background:var(--c-n100)} /* AI 标识(Q2):蓝铅笔 1px 描边 + 蓝铅笔字;AI 产出的正文本身仍是墨色 */ .tag.ai{background:none;box-shadow:inset 0 0 0 1px var(--ai);color:var(--ai)} .flag{font-size:var(--fs-caption);color:var(--text-secondary)} /* ---- 链接 ---- */ a.plain,.lnk{color:var(--text-primary);text-decoration:underline;text-decoration-color:var(--link-underline);text-underline-offset:3px;transition:text-decoration-color var(--dur-fast) var(--ease)} a.plain:hover,.lnk:hover{text-decoration-color:var(--c-ink)} /* 有悬停说明的文字(如「就绪」):虚线下划线 */ .hint-u{text-decoration:underline dashed;text-decoration-color:var(--hint-underline);text-underline-offset:4px;cursor:help} /* ---- 按钮 ---- * 主按钮墨底白字(页面级一屏一个,对话框里可以有自己的主按钮,Q12);次按钮白底 + 控件边框;文字按钮悬停出 --c-n100。 */ .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:var(--control-h);padding:0 var(--btn-px);border-radius:var(--radius-ctl);border:var(--line) solid var(--border-control);background:var(--bg-surface);color:var(--text-primary);font:var(--fs-body)/1 var(--font-sans);white-space:nowrap;cursor:pointer;transition:background-color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)} a.btn{text-decoration:none} .btn:hover{background:var(--c-n50);border-color:var(--c-ink)} .btn:active{background:var(--c-n100)} .btn.primary{background:var(--c-ink);border-color:var(--c-ink);color:var(--text-on-dark);font-weight:var(--fw-bold)} .btn.primary:hover{background:var(--primary-hover);border-color:var(--primary-hover)} .btn.primary:active{background:var(--primary-active);border-color:var(--primary-active)} .btn.text{border-color:transparent;background:none;padding:0 var(--sp-3)} .btn.text:hover{background:var(--c-n100);border-color:transparent} .btn.sm{height:var(--control-h-sm);padding:0 var(--btn-px-sm)} .btn.text.sm{padding:0 10px} .btn.lg{height:var(--control-h-lg);padding:0 var(--btn-px-lg)} .btn[disabled],.btn[disabled]:hover{color:var(--text-disabled);background:var(--c-n100);border-color:var(--c-n100);cursor:not-allowed;font-weight:var(--fw-regular)} .btn.text[disabled]{background:none;border-color:transparent} .cost{font-size:var(--fs-caption);color:var(--text-secondary);white-space:nowrap} .cost .fig{font-size:var(--fs-figure-xs);color:var(--text-primary)} /* ---- 问题行 + 页边批注 ---- */ .results{background:var(--bg-surface);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card);overflow:hidden} .results-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-3);padding:var(--sp-5) var(--card-x);border-bottom:var(--line) solid var(--border-subtle)} .results-head h3{font:var(--fw-bold) var(--fs-h2)/var(--lh-h2) var(--font-serif);margin:0} .results-head .proj{color:var(--text-secondary)} .results-head .counts{margin-left:auto;display:flex;gap:var(--sp-2)} .finding{position:relative;display:grid;grid-template-columns:minmax(0,1fr) var(--margin-note-w);gap:var(--sp-8);padding:var(--sp-5) var(--card-x);border-top:var(--line) solid var(--border-subtle)} .finding:first-of-type{border-top:0} /* v0.2 收尾:「致命」行不再加左侧红竖线,级别只靠实心「致命」标签(与工作台一致);左侧 3px 竖条只表示「当前条」(墨色,§7.18) */ .f-head{display:flex;align-items:center;gap:var(--sp-2)} .f-title{font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans)} .f-head .flag{margin-left:var(--sp-1);border-radius:var(--radius-tag);background:var(--c-n100);padding:0 6px;line-height:var(--tag-h)} .f-text{margin:var(--sp-2) 0 0;color:var(--text-primary)} .f-text + .f-text{margin-top:0} .f-actions{display:flex;flex-wrap:wrap;gap:var(--sp-2);align-items:center;margin-top:var(--sp-3)} .f-actions .feedback{margin-left:auto;font-size:var(--fs-caption)} /* 人工确认署名(§3.3、Q2):绿 ✓ + 姓名 + 时间 + 动作 */ .sign{margin-top:var(--sp-3);font-size:var(--fs-body);color:var(--confirmed);display:flex;gap:var(--sp-2);align-items:baseline;flex-wrap:wrap} .sign b{font-weight:var(--fw-bold)} .sign .fig{font-weight:var(--fw-medium)} .sign .undo{color:var(--text-secondary);font-size:var(--fs-caption);margin-left:var(--sp-2)} /* 出处(§7.3):左侧 2px 蓝铅笔竖线 + 原句 */ .cite{position:relative;border-left:2px solid var(--ai);padding:2px 0 2px var(--sp-3)} .cite + .cite{margin-top:var(--sp-3)} .finding .cite:first-child::before{content:"";position:absolute;left:calc(-1 * var(--sp-8) - 2px);top:11px;width:calc(var(--sp-8) - 4px);border-top:1.5px dashed var(--ai)} .cite-src{display:block;color:var(--ai);font-size:var(--fs-caption);line-height:var(--lh-caption);text-decoration:none} a.cite-src:hover{color:var(--ai-strong);text-decoration:underline;text-underline-offset:3px} .cite-src .fig{font-size:var(--fs-figure-xs)} .cite q{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden;quotes:none;margin-top:2px;line-height:var(--lh-read);color:var(--text-primary)} .cite.on{border-left-width:4px;padding-left:calc(var(--sp-3) - 2px)} .cite q mark{background:var(--ai-soft);color:inherit;padding:0 1px} .cite.missing{border-left-style:dashed} .cite.missing p{margin:2px 0 0;color:var(--text-secondary);font-size:var(--fs-caption);line-height:var(--lh-caption)} /* 行内出处链接(d5):蓝铅笔字,悬停出蓝铅笔浅底;用在列表行右侧 */ .cite-link{display:inline-flex;align-items:center;gap:var(--sp-1);margin:-2px -6px;padding:2px 6px;border-radius:var(--radius-ctl);color:var(--ai);font-size:var(--fs-body);text-decoration:none;white-space:nowrap;transition:background-color var(--dur-fast) var(--ease)} .cite-link:hover{background:var(--ai-soft);color:var(--ai-strong)} .cite-link .fig{font-size:var(--fs-figure-sm)} .ocr{font:var(--fw-bold) 11px/1 var(--font-figures);color:var(--text-secondary);background:var(--c-n100);padding:2px 4px;border-radius:var(--radius-xs);margin-left:4px;vertical-align:1px} .folded{padding:var(--sp-3) var(--card-x);border-top:var(--line) solid var(--border-subtle);color:var(--text-secondary);font-size:var(--fs-body)} /* ---- 清单与待确认 ---- * .pending(虚线蓝框)是 v0.1 的待确认区,只剩原型在用;v0.2 起待确认是清单顶部的分组(ui-demo/demo.css 的 .grp-h.ai,§7.6),原型重刷时替换 */ .pending{border:1.5px dashed var(--ai);border-radius:var(--radius-card);background:var(--bg-surface);padding:var(--card-y) var(--card-x)} .pending h4{margin:0;font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans);color:var(--ai)} .pending > p{margin:var(--sp-1) 0 var(--sp-3);color:var(--text-secondary)} .item{display:grid;grid-template-columns:24px minmax(0,1fr) auto;gap:var(--sp-3);padding:var(--sp-3) 0;border-top:var(--line) solid var(--border-subtle);align-items:start} .item:first-of-type{border-top:0} .imp{font-size:var(--fs-title);line-height:var(--lh-body);text-align:center} .item .t{font-weight:var(--fw-bold)} .item .meta{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:4px} .item .side{text-align:right;font-size:var(--fs-caption);line-height:var(--lh-caption)} /* 选中(Q3):--c-n50 底 + 左侧 3px 墨色竖条;蓝色只留给原文高亮和出处 */ .item.sel{background:var(--c-n50);box-shadow:inset 3px 0 0 var(--c-ink)} .src-ai{color:var(--ai)} .old{text-decoration:line-through;color:var(--text-secondary)} .list-head{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)} .list-head h4{margin:0;font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans)} /* ---- 表格(参数对照表、流水、项目列表)---- * v0.2:表头无底色、无粗线,12px 辅助灰列名;行间发丝线;首尾列与卡片左右边距对齐。 * 单独摆放时自带卡片外框;放进 .card.flush 时去掉外框。 */ table.data{width:100%;border-collapse:separate;border-spacing:0;background:var(--bg-surface);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card)} .card table.data,.results table.data{border:0;border-radius:0;background:none} table.data th{text-align:left;font-weight:var(--fw-regular);font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary);padding:var(--sp-3) var(--sp-3) var(--sp-2);white-space:nowrap;background:none} table.data td{padding:10px var(--sp-3);border-top:var(--line) solid var(--border-subtle);vertical-align:top;height:44px} table.data th:first-child,table.data td:first-child{padding-left:var(--card-x)} table.data th:last-child,table.data td:last-child{padding-right:var(--card-x)} .card:not(.flush) table.data th:first-child,.card:not(.flush) table.data td:first-child{padding-left:0} .card:not(.flush) table.data th:last-child,.card:not(.flush) table.data td:last-child{padding-right:0} table.data td:first-child{white-space:nowrap} table.data tbody tr:last-child td:first-child{border-bottom-left-radius:var(--radius-card)} table.data tbody tr:last-child td:last-child{border-bottom-right-radius:var(--radius-card)} table.data .num{font-family:var(--font-figures);font-variant-numeric:tabular-nums;font-weight:var(--fw-medium);font-size:var(--fs-figure-sm);white-space:nowrap} table.data .r{text-align:right} table.data a:not(.btn):not(.plain):not(.lnk){color:var(--ai);text-decoration:none;font-size:var(--fs-caption);white-space:nowrap} table.data a:not(.btn):not(.plain):not(.lnk):hover{color:var(--ai-strong);text-decoration:underline;text-underline-offset:3px} table.data a .fig{font-size:var(--fs-figure-xs)} table.data.hover tbody tr{cursor:pointer} table.data.hover tbody tr td{transition:background-color var(--dur-fast) var(--ease)} table.data.hover tbody tr:hover td{background:var(--bg-hover)} /* 选中行(Q3):与读标清单一致 */ table.data tbody tr.sel td{background:var(--c-n50)} table.data tbody tr.sel td:first-child{box-shadow:inset 3px 0 0 var(--c-ink)} /* 参数对照表「判断」列(§7.7):只用四个词;同一行另有「级别」列(Q5) */ .verdict{font-weight:var(--fw-bold);white-space:nowrap} .verdict.fatal{color:var(--sev-fatal)} .verdict.major{color:var(--sev-major-text)} .verdict.manual{color:var(--text-secondary);font-weight:var(--fw-regular)} /* ---- 原文查看器 ---- */ .viewer{background:var(--c-n100);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card);display:flex;flex-direction:column;overflow:hidden} .viewer-bar{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-4);background:var(--bg-surface);border-bottom:var(--line) solid var(--border-subtle);font-size:var(--fs-caption)} .viewer-bar b{font-size:var(--fs-body);white-space:nowrap} .viewer-bar > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .viewer-bar .pager{margin-left:auto;display:flex;flex:none;gap:var(--sp-2);align-items:center;white-space:nowrap} .sheet{margin:var(--sp-4) auto;width:86%;background:var(--c-white);box-shadow:var(--shadow-sheet);padding:28px 32px;font:var(--fs-doc)/var(--lh-doc) var(--font-doc);color:var(--text-primary)} .sheet p{margin:0 0 6px} /* 原句高亮(§7.8):蓝铅笔浅底 + 蓝色底边;跨行时每一行都带底边,换行处不断开(box-decoration-break)。当前出处底边加粗为 2px */ .sheet .hl{background:var(--ai-soft);box-shadow:inset 0 -1px 0 var(--ai);padding:1px 0;-webkit-box-decoration-break:clone;box-decoration-break:clone} .sheet .hl.on{box-shadow:inset 0 -2px 0 var(--ai)} .sheet .faint{color:var(--text-secondary)} /* ---- 工作台 ---- */ .proj-name{font-weight:var(--fw-bold);font-size:var(--fs-title);line-height:var(--lh-title)} .proj-sub{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)} .due-soon{color:var(--warn-text)} .due-today{color:var(--warn-text);font-weight:var(--fw-bold)} .due-past{color:var(--text-secondary)} .ready{display:flex;gap:6px;align-items:center;flex-wrap:wrap} /* ---- 额度 ---- */ .quota .big{font:var(--fw-bold) var(--fs-figure)/var(--lh-figure) var(--font-figures);font-variant-numeric:tabular-nums} .quota .unit{color:var(--text-secondary);margin-left:4px;font-family:var(--font-figures);font-variant-numeric:tabular-nums} .bar{height:6px;background:var(--c-n100);border-radius:3px;overflow:hidden;margin:var(--sp-2) 0} .bar i{display:block;height:100%;background:var(--c-ink);border-radius:3px} .bar.warn i{background:var(--warn)} /* 流水「+ / −」(Q1):都用墨色,靠符号区分;绿色只表示人工确认 */ .flow td.plus,.flow td.minus{color:var(--text-primary)} /* ---- 提醒(§7.12)---- * v0.2:和卡片同规格的白条(圆角 12、发丝线),不用彩色浅底和左边线;颜色只在图标和关键字上。 */ .alert{display:flex;gap:var(--sp-3);align-items:flex-start;padding:14px var(--card-x);background:var(--bg-surface);border:var(--line) solid var(--border-subtle);border-radius:var(--radius-card)} .alert + .alert{margin-top:var(--sp-3)} .alert.warn b,.alert .when{color:var(--warn-text);font-weight:var(--fw-bold)} .alert p{margin:0} .alert > .ic{flex:none;margin-top:2px} .alert.warn > .ic{color:var(--warn)} .alert.done > .ic{color:var(--confirmed)} .ico{flex:none;width:18px;height:18px;border-radius:50%;display:inline-grid;place-items:center;font:var(--fw-bold) var(--fs-caption)/1 var(--font-sans);margin-top:2px} .ico.i{border:1.5px solid var(--c-ink)} .ico.w{border:1.5px solid var(--warn);color:var(--warn-text)} .ico.ok{background:var(--confirmed);color:var(--c-white)} /* ---- 表单 ---- */ .field{display:flex;flex-direction:column;gap:6px;max-width:360px} .field + .field{margin-top:var(--sp-4)} .field label{font-weight:var(--fw-bold)} .field label small{font-weight:var(--fw-regular);color:var(--text-secondary)} .input{height:var(--control-h);border:var(--line) solid var(--border-control);border-radius:var(--radius-ctl);padding:0 var(--sp-3);font:var(--fs-body) var(--font-sans);color:var(--text-primary);background:var(--bg-surface)} .input::placeholder{color:var(--text-secondary)} .field.err .input{border-color:var(--warn);box-shadow:inset 0 0 0 1px var(--warn)} .field .msg{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)} .field.err .msg{color:var(--warn-text);display:flex;gap:6px;align-items:center} .field.err .msg .ico{width:14px;height:14px;font-size:10px;margin:0} .chips{display:flex;gap:6px;flex-wrap:wrap} .chips .btn{height:26px;padding:0 var(--sp-2);font-size:var(--fs-caption);border-radius:var(--radius-tag)} /* ---- 进度 ---- */ .steps{list-style:none;margin:0;padding:0} .steps li{display:flex;gap:var(--sp-3);align-items:center;padding:6px 0} .steps .dot{width:18px;height:18px;border-radius:50%;border:1.5px solid var(--border-control);flex:none;display:grid;place-items:center;font-size:11px} .steps .done .dot{background:var(--c-ink);border-color:var(--c-ink);color:var(--c-white)} .steps .now .dot{border-color:var(--c-ink);border-width:2px} .steps .now{font-weight:var(--fw-bold)} .steps .todo{color:var(--text-secondary)} /* ---- 报告页眉(模拟 PDF,字号按纸面,不跟界面字阶) ---- */ .report{background:var(--c-white);border:var(--line) solid var(--border-subtle);max-width:620px;padding:28px 36px;font-size:13px;line-height:1.6} .report-head{display:flex;justify-content:space-between;align-items:center;border-bottom:var(--line) solid var(--c-ink);padding-bottom:10px} .report-head img{height:26px} .report-head span{font-size:11px;color:var(--text-secondary)} .report h3{font:var(--fw-bold) 22px/1.4 var(--font-serif);margin:22px 0 4px} .report dl{display:grid;grid-template-columns:96px 1fr;gap:4px 12px;margin:14px 0} .report dt{color:var(--text-secondary)} .report dd{margin:0} .report-scope{border:var(--line) solid var(--border-subtle);padding:10px 14px;margin-top:10px} .report-scope b{display:block;margin-bottom:2px} .report-foot{margin-top:18px;padding-top:8px;border-top:var(--line) solid var(--border-subtle);display:flex;justify-content:space-between;font-size:11px;color:var(--text-secondary)} @media (max-width:1100px){ .finding{grid-template-columns:1fr;gap:var(--sp-3)} .finding .cite:first-child::before{display:none} }