/** * ACT-WORK-05 三张工单件的设计系统(2026-08-31 视图层整体重设计。用户定: * 「中间这一块不要搞的像后台管理端,要像给客户使用的 C 端界面;可以按主题加 SVG 图形, * 可以有动画,加强交互 —— 只保留功能,视图层可以推翻重新设计」)。 * * 设计语言:「精密检测报告」—— * · 题头是一块深色电路板夜景(hero):芯片封装、铜引脚、流动的走线信号, * 三张件各有一幕对应自己职能的场景(建档台 / 对决量尺 / 落账席); * · 正文回到瓷白纸面,报告化排版:丝印体小标(silkscreen)、mono 料号、 * 引脚号式的序号列 —— 用电子行业自己的版面语汇,不借后台管理端的灰表格; * · 动画只做 transform / opacity(信号点流动、晶粒呼吸、印章环慢转、入场浮起), * prefers-reduced-motion 下全部静止 —— 与工作台动画同一条纪律。 * * 旧的 target-style.ts(逐字节抽自目标件的三段样式)随本次重设计退役:目标件是 * 「照着做」时代的锚,这一版是活动自己的设计,样式只此一处真源。 * * **这一整段活在 TS 模板字符串里 —— 不许出现反引号**(一个反引号就把串截断, * esbuild 报在几行之外;本仓踩过)。注释里也别写星号斜杠连排。 * * 几条被包内测试钉死的**机制规则逐字保留**,别「顺手整理」: * · 序号计数器五连(.jc-tbl-wrap table, .tbl-wrap table 成对出现); * · table:not(.on) tr.jc-row-static { display: none; }(种子行只在编辑态露面); * · .jc-gate-bar:has(.jc-gate-text:empty) 显隐(gate_reason 是中文自由文本, * data-class-of 在它上面永远算不出 v-token,显隐只认 data-blank 出的空文本节点); * · .jc-tbl-wrap 不许 overflow:hidden(表宽超出要能横着滑)。 */ /** 件① 数据工单的强调色 —— 数据蓝(与治理台「数据」语义同族) */ export const ACCENT_DATA = ` :root{ --acc:#2e6bff; --acc-deep:#1f52d6; --acc-soft:#e3ecff; --acc-line:#c2d5ff; --acc-wash:#f3f7ff; --glow:#6fa1ff; --glow-line:rgba(111,161,255,.36); --hero-tint:rgba(46,107,255,.34); } `; /** 件②③ 验收工单的强调色 —— 验收绿 #0aa294(2026-08-27 用户定:与对话区验收卡同色) */ export const ACCENT_LEDGER = ` :root{ --acc:#0aa294; --acc-deep:#07857a; --acc-soft:#dcf5f1; --acc-line:#aee5dd; --acc-wash:#f0fbf9; --glow:#2fd4c2; --glow-line:rgba(47,212,194,.34); --hero-tint:rgba(10,162,148,.32); --ledger:#0aa294; } `; export const SHELL_CSS = ` /* ================= 令牌与底 ================= */ :root{ --ink:#182430; --ink-2:#3d4c5c; --ink-3:#67788a; --ink-4:#97a5b3; --line:#dbe3ea; --line-soft:#e8edf3; --soft:#f5f8fa; --paper:#edf1f5; --board:#0e1b27; --board-2:#15263a; --cu:#d99a5b; --cu-deep:#b57632; --ok:#1e9e56; --ok-soft:#e4f7ec; --danger:#dd4a3a; --danger-soft:#feecea; --amber:#b07a10; --amber-soft:#fdf3d8; --cond:#5661f0; --cond-soft:#e9ebfe; --hero-ink:#f4f8fc; --hero-dim:rgba(226,238,248,.62); --mono:"SF Mono",Menlo,Consolas,monospace; } *{box-sizing:border-box} html,body{margin:0;padding:0} body{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:var(--paper);color:var(--ink);font-size:14px;line-height:1.7;-webkit-font-smoothing:antialiased} .page{margin:0;padding:0} .card{background:#fff;overflow:hidden;border:0;border-radius:0} .mono{font-family:var(--mono)} i{font-style:normal} /* ================= 题头:电路板夜景 hero ================= */ .card-head{ position:relative;display:flex;flex-direction:column;gap:12px;padding:20px 22px 22px;color:var(--hero-ink); background: repeating-linear-gradient(0deg, rgba(255,255,255,.03) 0 1px, transparent 1px 28px), repeating-linear-gradient(90deg, rgba(255,255,255,.03) 0 1px, transparent 1px 28px), radial-gradient(900px 340px at 18% -40%, var(--hero-tint), transparent 62%), linear-gradient(158deg, #13212f 0%, var(--board) 56%, #0f1d2b 100%); } .hero-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap} .hero-sys{flex:1 1 auto;min-width:0;font-size:10.5px;font-weight:800;letter-spacing:.17em;color:var(--hero-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .hero-chips{flex:none;display:flex;gap:6px} .hero-tag{font-size:11px;font-weight:800;padding:2px 11px;border-radius:999px;color:#fff;background:var(--acc);box-shadow:0 4px 14px var(--glow-line);white-space:nowrap} .hero-step{font-size:11px;font-weight:700;padding:2px 11px;border-radius:999px;color:var(--hero-dim);border:1px solid rgba(255,255,255,.22);white-space:nowrap} .hero-title{margin:0;font-size:23px;font-weight:800;line-height:1.25;letter-spacing:.01em;color:#fff} .hero-meta{font-size:11.5px;color:var(--hero-dim)} .hero-meta b{font-weight:700;color:#fff} /* ── hero 舞台:芯片铭牌 + 信号走线 ── */ .stage{position:relative;display:flex;align-items:stretch;justify-content:center;gap:clamp(20px,7vw,72px);padding:14px 6px 6px} .stage::before{content:"";position:absolute;left:5%;right:5%;top:52%;border-top:2px dashed var(--glow-line)} .stage::after{content:"";position:absolute;top:52%;left:5%;width:9px;height:9px;margin-top:-4px;border-radius:999px;background:var(--glow);box-shadow:0 0 14px 3px var(--glow-line),0 0 4px 1px var(--glow);animation:sig 3.4s linear infinite} .stage-lab{padding-bottom:8px} .stage-duel{padding-top:28px} .hchip{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:6px;flex:0 1 176px;min-width:128px;padding:13px 12px 11px;border-radius:14px;background:rgba(255,255,255,.97);color:var(--ink);box-shadow:0 14px 30px rgba(3,10,18,.5),inset 0 1px 0 rgba(255,255,255,.7)} .hchip.v-absent{background:rgba(255,252,246,.97);outline:2px dashed var(--cu);outline-offset:-6px} .hchip-role{font-size:10.5px;font-weight:800;letter-spacing:.08em;color:var(--ink-4)} .hchip-pn{font-size:14.5px;font-weight:800;color:var(--ink);overflow-wrap:anywhere;text-align:center;line-height:1.3} .hchip-badges{display:flex;gap:6px;flex-wrap:wrap;justify-content:center} .csvg{width:86px;height:auto;display:block} .c-body{fill:var(--board-2);stroke:rgba(217,154,91,.55);stroke-width:1.4} .c-pin{fill:var(--cu)} .c-die{fill:var(--acc);opacity:.9;animation:breathe 2.8s ease-in-out infinite} .c-dot{fill:rgba(255,255,255,.85)} .duel-type{position:absolute;z-index:1;left:50%;top:-4px;transform:translateX(-50%);font-size:10.5px;font-weight:800;letter-spacing:.06em;color:var(--hero-dim);border:1px solid rgba(255,255,255,.2);border-radius:999px;padding:2px 12px;background:rgba(10,20,30,.55);white-space:nowrap} .duel-type i{font-style:normal;color:#fff} .hero-verdict{display:flex;justify-content:center;padding:2px 0 0} /* ── hero 落账席(件③):印章 + 一句话结论 ── */ .stage-seal{position:relative;display:flex;align-items:center;justify-content:center;gap:22px;padding:12px 4px 4px;flex-wrap:wrap} .seal{position:relative;flex:none;width:112px;height:112px;border-radius:999px;display:grid;place-items:center} .seal::before{content:"";position:absolute;inset:0;border:1.6px dashed rgba(255,255,255,.34);border-radius:999px;animation:sealspin 16s linear infinite} .seal-core{display:grid;place-items:center;padding:7px 11px;border-radius:999px;background:rgba(255,255,255,.97);box-shadow:0 12px 26px rgba(3,10,18,.5)} .seal-sum{flex:1 1 240px;min-width:200px;max-width:420px;margin:0;font-size:13px;line-height:1.85;color:var(--hero-dim)} .seal-sum:empty::after{content:"—"} /* ── 浅色题头变体(件① 2026-08-31 用户:「标题背景还是改成之前的那种蓝色渐变」—— 渐变取自原目标件 card-head 那一条,深色电路夜景只留给验收两件)── */ .hd-light .card-head{background:linear-gradient(120deg,#f0f5ff 0%,#fff 55%,#eef4ff 100%);color:var(--ink);border-bottom:2px solid var(--ink)} .hd-light .hero-sys{color:var(--ink-4)} .hd-light .hero-title{color:var(--ink)} .hd-light .hero-step{color:var(--ink-3);border-color:var(--line)} .hd-light .hero-meta{color:var(--ink-3)} .hd-light .hero-meta b{color:var(--ink)} /* ================= 正文分区 ================= */ .card-bd{padding:20px 22px 8px} .sec{display:flex;align-items:baseline;gap:9px;margin:26px 0 10px;flex-wrap:wrap} .sec:first-child{margin-top:4px} .sec-pin{flex:none;align-self:center;width:24px;height:24px;border-radius:8px;display:grid;place-items:center;background:var(--acc-soft);color:var(--acc-deep)} .zic{width:13px;height:13px;display:block} .sec-t{font-size:13.5px;font-weight:800;color:var(--ink);letter-spacing:.02em} .sec-d{flex:1 1 200px;min-width:0;font-size:11.5px;color:var(--ink-3)} /* 简报卡(做什么 / 纪律…) */ .brief{border:1px solid var(--line-soft);border-left:3px solid var(--acc);border-radius:10px;background:var(--acc-wash);padding:13px 16px;margin:0 0 4px} .brief p{margin:0 0 7px;font-size:12.5px;line-height:1.75;color:var(--ink-2)} .brief p:last-child{margin-bottom:0} .brief b{color:var(--ink)} .done,.need{display:inline-block;font-size:10.5px;font-weight:800;padding:0 8px;border-radius:999px;vertical-align:1px;margin-right:2px} .done{color:var(--ok);background:var(--ok-soft)} .need{color:var(--acc-deep);background:var(--acc-soft)} /* 收尾指引 */ .flow{margin:24px 0 14px;padding:12px 16px;border-radius:10px;border:1px dashed var(--acc-line);background:var(--acc-wash);font-size:12.5px;color:var(--ink-2);line-height:1.8} .flow b{color:var(--acc-deep)} /* 页脚:丝印条 */ .card-foot{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:12px 22px;border-top:1px solid var(--line-soft);background:var(--soft);font-size:11px;color:var(--ink-4);flex-wrap:wrap} .foot-r{letter-spacing:.04em} /* ================= 顶部「还差什么」红带(机制:显隐认 data-blank 的空文本节点) ================= */ .jc-gate-bar{display:flex;flex-direction:column;gap:5px;margin:0 0 16px;padding:11px 14px;border-radius:10px;background:var(--danger-soft);border:1px solid #f5c0ba;color:var(--danger);font-size:12.5px;line-height:1.7} .jc-gate-bar b{font-weight:800} .jc-gate-bar:has(.jc-gate-text:empty){display:none} /* 逐块的缺项点名并进这一条(2026-08-31 用户:「页面上所有的问题都合并到最上面的还差什么」)—— 与提交闸同源的基座读数,数值为 0 的那一行自己消失,只在待处理态出现 */ .jc-gate-sub{display:none;font-size:12px;color:#a03d34;padding-left:2px} html.editable .jc-gate-sub{display:block} html.editable .jc-gate-sub.v-0{display:none} /* 缺项红带 —— 与提交闸同源的必填提示,只在待处理态出现 */ .jc-gapbar{display:none} html.editable .jc-gapbar{display:flex;align-items:flex-start;gap:8px;margin:0 0 10px;padding:9px 13px;border-radius:9px;background:var(--danger-soft);border:1px solid #f5c0ba;color:var(--danger);font-size:12px;line-height:1.7} .jc-gapbar b{font-weight:800} .jc-gapbar span{color:#a03d34} html.editable .jc-gapbar.v-0{display:none} /* ================= 编辑闸与加行(只在待处理态露面) ================= */ html:not(.editable) .jc-editgate, html:not(.editable) .jc-addrow { display: none !important; } .jc-editgate{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 10px;padding:8px 12px;border-radius:10px;background:var(--soft);border:1px solid var(--line-soft);font-size:12px;color:var(--ink-3)} .jc-editgate-t{flex:1 1 auto;min-width:0} .jc-editgate-t b{color:var(--ink-2);font-weight:700} .jc-egbtn{flex:none;display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:1px solid var(--line);border-radius:999px;padding:6px 15px;font:inherit;font-size:12px;font-weight:700;color:var(--ink-2);background:#fff;transition:border-color .16s,color .16s,background .16s,box-shadow .16s} .jc-egbtn:hover{border-color:var(--acc);color:var(--acc-deep);box-shadow:0 0 0 3px var(--acc-soft)} .jc-egbtn:active{transform:scale(.96)} .jc-egbtn.save{color:#fff;background:var(--acc);border-color:var(--acc)} .jc-egbtn.save:hover{filter:brightness(1.06);color:#fff} .jc-editgate .eg-cancel,.jc-editgate .eg-save{display:none} .jc-editgate.on{background:var(--acc-wash);border-color:var(--acc-line);color:var(--acc-deep)} .jc-editgate.on .eg-open{display:none} .jc-editgate.on .eg-cancel,.jc-editgate.on .eg-save{display:inline-flex} .jc-addrow{display:none;margin:8px 0 0} .jc-tbl-wrap:has(table.on) + .jc-addrow { display: flex; align-items: center; gap: 8px; } .jc-addrow button{cursor:pointer;border:1px dashed var(--acc-line);border-radius:999px;background:var(--acc-wash);color:var(--acc-deep);font:inherit;font-size:12px;font-weight:700;padding:6px 15px;transition:border-color .16s,box-shadow .16s} .jc-addrow button:hover{border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-soft)} .jc-addrow button:active{transform:scale(.96)} .jc-addrow em{font-style:normal;font-size:11px;color:var(--ink-4)} /* ================= 报告表格 ================= */ .jc-tbl-wrap{border:1px solid var(--line-soft);border-radius:12px;background:#fff;overflow-x:auto;overflow-y:hidden} .jc-tbl-wrap, .tbl-wrap { overflow-x: auto; overflow-y: hidden; } table{width:100%;border-collapse:collapse;font-size:12.5px} thead th{position:static;text-align:left;font-size:10.5px;font-weight:800;letter-spacing:.07em;color:var(--ink-4);background:var(--soft);padding:9px 12px;border-bottom:1px solid var(--line);white-space:nowrap} th.req::after{content:" *";color:var(--danger);font-size:10px} tbody td{padding:10px 12px;border-bottom:1px solid var(--line-soft);vertical-align:top;color:var(--ink-2)} tbody tr:last-child td{border-bottom:0} tbody tr:hover td{background:var(--acc-wash)} td.rn,td.num{font-family:var(--mono);font-size:11px;color:var(--ink-4);white-space:nowrap} td.mono{font-family:var(--mono);font-size:12px;color:var(--ink-2)} td.cust{font-weight:700;color:var(--ink)} td.desc,.desc{color:var(--ink-3);font-size:12px;line-height:1.6} /* 序号列交给 CSS 计数器(沙箱零脚本,增删行后自己数对;两种列名、两种包装类都接) */ .jc-tbl-wrap table, .tbl-wrap table { counter-reset: rn; } .jc-tbl-wrap table td.rn, .tbl-wrap table td.rn { counter-increment: rn; } .jc-tbl-wrap table td.rn .jc-rn-num::before, .tbl-wrap table td.rn .jc-rn-num::before { content: counter(rn); } .jc-tbl-wrap table td.num, .tbl-wrap table td.num { counter-increment: rn; } .jc-tbl-wrap table td.num::before, .tbl-wrap table td.num::before { content: counter(rn); } /* ── 看与改是两件事:只读份 / 输入孪生件由 .on 二选一 ── */ .jc-vcell{display:block;font-size:12.5px;color:var(--ink);line-height:1.55;overflow-wrap:anywhere} .jc-vcell.mono{font-family:var(--mono);font-size:12px;color:var(--ink-2)} .jc-vcell:empty::after{content:"—";color:var(--ink-4)} .jc-cell{display:none;width:100%;min-width:72px;border:1px solid var(--line);border-radius:8px;padding:6px 9px;font:inherit;font-size:12.5px;color:var(--ink);background:#fff} .jc-cell:focus{border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-soft);outline:none} .jc-cell.mono{font-family:var(--mono);font-size:12px} input.jc-cell, select.jc-cell { height: 32px; box-sizing: border-box; padding-top: 0; padding-bottom: 0; vertical-align: middle; } table.on td>.jc-vcell{display:none} table.on td>.jc-vcell.ro{display:block} table.on td>.jc-cell{display:block} table.on td>.jc-vcell:empty::after{content:none} /* 增删行的痕(取消还原三件套的可视面) */ table.on tr.jc-row-new td { background: #f0fbf5; } table.on tr.jc-row-gone td { background: #fff6f5; opacity: .55; } table.on tr.jc-row-gone .jc-cell { text-decoration: line-through; color: var(--ink-3); } .jc-rowdel{display:none;cursor:pointer;border:1px solid var(--line);border-radius:999px;background:#fff;color:var(--ink-3);width:20px;height:20px;line-height:1;font-size:12px;padding:0;margin-left:5px;vertical-align:middle} table.on .jc-rowdel{display:inline-grid;place-items:center} .jc-rowdel:hover{border-color:var(--danger);color:var(--danger)} table.on tr.jc-row-gone .jc-rowdel { border-color: var(--danger); color: var(--danger); background: #fff; } /* 静态种子行:零行也加得出第一行 —— 只在编辑态露面(读态看见空壳子是界面撒谎) */ table:not(.on) tr.jc-row-static { display: none; } table.on tr.jc-row-static td{background:var(--acc-wash);border-top:1px dashed var(--acc-line)} /* 主键钥匙格:不给人看,但真挂 data-col(漏了钥匙,这一行凑不出主键) */ .rowkey{display:none} /* ================= 徽标基座(取值上色一律 data-class-of 投影,选择器从值算) ================= */ .stx,.ct,.rl,.st,.risk-badge{display:inline-block;font-size:11px;font-weight:700;padding:1px 9px;border-radius:999px;border:1px solid transparent;white-space:nowrap} .rl{background:var(--soft);border-color:var(--line-soft);color:var(--ink-3);font-size:10.5px;letter-spacing:.03em} .rec{display:inline-block;font-size:11.5px;font-weight:800;padding:2px 13px;border-radius:999px;border:1px solid transparent;white-space:nowrap} .rec.rec-lg{font-size:14.5px;padding:7px 20px;letter-spacing:.03em} /* kv 行(收口结论 / 待验项共用的键值版式) */ .kv{display:flex;gap:12px;padding:10px 0;border-bottom:1px solid var(--line-soft);font-size:12.5px} .kv:last-child{border-bottom:0} .kv i{flex:0 0 84px;font-style:normal;color:var(--ink-4);font-size:11px;font-weight:700;letter-spacing:.05em;padding-top:2px} .kv > span{flex:1 1 auto;color:var(--ink-2);line-height:1.7;overflow-wrap:anywhere} .kv > span:empty::after{content:"—";color:var(--ink-4)} .kv-box{border:1px solid var(--line-soft);border-radius:12px;background:var(--soft);padding:4px 16px;margin-bottom:4px} /* ================= 动画(全部 transform / opacity;reduced-motion 全静) ================= */ @keyframes sig{0%{transform:translateX(0);opacity:0}7%{opacity:1}93%{opacity:1}100%{transform:translateX(min(86vw,760px));opacity:0}} @keyframes breathe{0%,100%{opacity:.55}50%{opacity:1}} @keyframes sealspin{to{transform:rotate(360deg)}} @keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}} .hero-top{animation:rise .5s cubic-bezier(.2,.7,.3,1) both} .hero-title{animation:rise .5s .06s cubic-bezier(.2,.7,.3,1) both} .stage,.stage-seal{animation:rise .55s .14s cubic-bezier(.2,.7,.3,1) both} .hero-verdict,.hero-meta{animation:rise .55s .22s cubic-bezier(.2,.7,.3,1) both} @media (prefers-reduced-motion: reduce){ *{animation:none !important;transition:none !important} } /* ================= 电路蓝图工作台(件① 的两张档案卡)================= 2026-08-31 用户:「卡片下面那个容器黑色和页面背景不搭」—— 深色板底退场,换**浅色蓝图**: 底是强调色的极浅晕染 + 淡格线,走线与信号点用强调色 —— 电路语汇留着,纸面色阶不断裂。 */ .board{position:relative;margin:0 0 6px;padding:18px 14px 16px;border-radius:16px;border:1px solid var(--acc-line); background: repeating-linear-gradient(0deg, rgba(46,107,255,.045) 0 1px, transparent 1px 26px), repeating-linear-gradient(90deg, rgba(46,107,255,.045) 0 1px, transparent 1px 26px), linear-gradient(158deg, var(--acc-wash) 0%, #fff 62%, var(--acc-wash) 100%)} .board::before{content:"";position:absolute;left:4%;right:4%;top:50%;border-top:2px dashed var(--acc-line)} /* 「可替换」动画(2026-08-31 用户第二稿:「不要做到背景板上,背景板会被卡片覆盖; 和卡片做到一级,可以压缩一点卡片的大小」)—— .dossiers 改三列网格,中间留一条 **实体动画道**(卡片各占左右列、相应收窄,谁也盖不住它):中央 ⇄ 徽轻呼吸, 两枚信号点绕徽**轨道对转**(此上彼下地绕圈 = 两颗料换位),底下横穿的虚线总线 在道里露出来把两张卡接起来。 */ .swapfx{position:absolute;left:50%;top:50%;width:76px;height:76px;transform:translate(-50%,-50%);z-index:1;pointer-events:none} .sw-ic{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:36px;height:36px;padding:8px;box-sizing:border-box;color:var(--acc);background:#fff;border:1px solid var(--acc-line);border-radius:999px;box-shadow:0 4px 12px rgba(18,38,63,.16);animation:swbreathe 2.8s ease-in-out infinite} .sw-orbit{position:absolute;left:50%;top:50%;width:64px;height:64px;margin:-32px 0 0 -32px;animation:sworbit 4.5s linear infinite} .sw-dot{position:absolute;left:50%;width:8px;height:8px;margin-left:-4px;border-radius:999px;background:var(--acc);box-shadow:0 0 8px 2px var(--acc-soft)} .sw-d1{top:-4px} .sw-d2{bottom:-4px} @keyframes sworbit{to{transform:rotate(360deg)}} @keyframes swbreathe{0%,100%{transform:translate(-50%,-50%) scale(1)}50%{transform:translate(-50%,-50%) scale(1.1)}} /* 三列网格:左右两列给卡,中间 76px 是动画道 —— 与卡同级的真实空间,不被覆盖 */ .dossiers{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr) 76px minmax(0,1fr);row-gap:16px} .dossiers > .dossier:nth-of-type(odd){grid-column:1} .dossiers > .dossier:nth-of-type(even){grid-column:3} .dossier{display:flex;flex-direction:column;gap:11px;background:#fff;border:1px solid var(--line-soft);border-radius:16px;padding:15px 16px 14px;box-shadow:0 8px 22px rgba(18,38,63,.09);transition:box-shadow .18s,transform .18s} .dossier:hover{transform:translateY(-2px);box-shadow:0 12px 28px rgba(18,38,63,.13)} .dz-top{display:flex;align-items:center;gap:12px} .dz-top .csvg{width:64px;flex:none} .dz-id{display:flex;flex-direction:column;gap:4px;min-width:0} .dz-role{display:flex;gap:6px;flex-wrap:wrap} .dz-pn{font-size:15px;font-weight:800;overflow-wrap:anywhere;line-height:1.3} .dz-pn .jc-vcell{font-size:15px;font-weight:800;color:var(--ink)} .dz-type{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:8px 10px;border-radius:10px;background:var(--acc-wash);border:1px solid var(--acc-line)} .dz-lb{flex:none;font-style:normal;font-size:10.5px;font-weight:800;letter-spacing:.05em;color:var(--ink-4)} .dz-type .jc-cell{flex:1 1 140px;width:auto} /* 类型名守卫:这一行的下拉真有选中项(selectCurrent 按行作用域写的 option[selected])才摆名 —— 行里没选,data-by 落回外层的名一个字都不摆,换「待选择」胶囊。 守卫挂在共同祖先 .dz-type 上、单层 :has —— :has() 里再嵌 :has() 是非法选择器,整条会被浏览器 静默丢弃(第一版就栽在这:守卫写了等于没写,XL 那张卡照样摆出它没有的类型)。 */ .tsel{flex:1 1 auto;min-width:0} .tsel > span > i{display:inline-block;font-size:11.5px;font-weight:800;color:var(--acc-deep);background:var(--acc-soft);border-radius:999px;padding:1px 11px} .dz-type:not(:has(option[selected])) .tsel > span{display:none} .dz-type:not(:has(option[selected])) .tsel::after{content:"待选择 · 点「编辑」挑一个";display:inline-block;font-size:11px;font-weight:700;color:var(--amber);background:var(--amber-soft);border:1px dashed #eeda9e;border-radius:999px;padding:1px 10px} .dz-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px 12px} .fcell{display:flex;flex-direction:column;gap:3px;min-width:0} .fcell.wide{grid-column:1 / -1} .fcell > i{font-style:normal;font-size:10.5px;font-weight:800;letter-spacing:.05em;color:var(--ink-4)} .fcell.req > i::after{content:" *";color:var(--danger)} .fcell .jc-vcell{font-size:12.5px} /* 三级占位:必填红 / 建议橘(空格子直说要不要填,不摆一枚含糊的破折号) */ .fcell.req .jc-vcell:empty::after{content:"必填";font-size:10.5px;font-weight:800;color:var(--danger);background:var(--danger-soft);border-radius:999px;padding:0 9px} /* 徽标包装的必填格(如生命周期):没值时徽标 class 恰为裸 "stx"(class-of 没投出 v-*), wrapper 不为 :empty,上一条够不着 —— 认裸 class 补同一枚胶囊(单层 :has) */ .fcell.req .jc-vcell:has(> [class="stx"])::after{content:"必填";font-size:10.5px;font-weight:800;color:var(--danger);background:var(--danger-soft);border-radius:999px;padding:0 9px} .fcell.sug .jc-vcell:empty::after{content:"建议";font-size:10.5px;font-weight:800;color:var(--amber);background:var(--amber-soft);border-radius:999px;padding:0 9px} /* 档案卡的编辑态 —— **按卡开,只点亮这张卡的正面**(2026-08-31 用户:「各自编辑各自的部分, 不要做联动」:.on 由 scopedTargets 落在被点那张卡的行 section 上,不再落整个宿主); 只圈 .front 是因为卡背住着另一地址的宿主,不圈的话参数输入会被主数据的编辑顺手点亮 */ .dossier.on .front .jc-vcell{display:none} .dossier.on .front .jc-vcell.ro{display:block} .dossier.on .front .jc-cell{display:block} .dossier.on .front .jc-vcell:empty::after{content:none} .dossier.on .dz-role{display:flex} /* ── 翻面(纯 CSS:checkbox + :has,零脚本;reduced-motion 下瞬时切换)── */ .dossier{position:relative;perspective:1200px;padding:0;background:none;border:0;box-shadow:none} .dossier:hover{transform:none;box-shadow:none} .flip-in{display:grid;transform-style:preserve-3d;transition:transform .55s cubic-bezier(.3,.7,.3,1)} .face{grid-area:1 / 1;display:flex;flex-direction:column;gap:11px;background:#fff;border:1px solid var(--line-soft);border-radius:16px;padding:15px 16px 14px;box-shadow:0 8px 22px rgba(18,38,63,.09);backface-visibility:hidden;min-width:0} .face.back{transform:rotateY(180deg)} .flip-tg{position:absolute;opacity:0;pointer-events:none} .flip-hit{position:absolute;inset:0;z-index:3;cursor:pointer} .flip-cue{position:absolute;z-index:4;bottom:10px;right:10px;pointer-events:none;opacity:.6;transition:opacity .16s,transform .16s} .flip-cue i{font-style:normal;display:inline-block;font-size:10.5px;font-weight:800;color:var(--acc-deep);background:var(--acc-soft);border:1px solid var(--acc-line);border-radius:999px;padding:2px 10px} .dossier:hover .flip-cue{opacity:1;transform:translateY(-2px)} /* 两句提示按面切换 —— 选择器都写到 .flip-cue i 之下的同层级,别被基座那条特异度压回来(踩过) */ .flip-cue .cue-back{display:none} /* 翻转三态,后写的赢:人点的 < 主数据编辑锁正面 < 参数编辑翻背面 */ .dossier:has(.flip-tg:checked) .flip-in{transform:rotateY(180deg)} .dossier:has(.flip-tg:checked) .flip-cue .cue-front{display:none} .dossier:has(.flip-tg:checked) .flip-cue .cue-back{display:inline-block} .dossier.on .flip-in{transform:rotateY(0deg)} .dossier:has(.pback.on) .flip-in{transform:rotateY(180deg)} /* 编辑中的**这张卡**不许翻(哪面在编辑锁哪面),点击层与提示丸一起收;另一张卡不受影响 */ .dossier.on .flip-hit,.dossier:has(.pback.on) .flip-hit{display:none} .dossier.on .flip-cue,.dossier:has(.pback.on) .flip-cue{display:none} /* 悬浮侧倾:预告「这张卡点了会翻」—— 只在读态、只在真有悬浮的设备、且不嫌动画的人那里 */ @media (hover:hover) and (prefers-reduced-motion: no-preference){ .dossier:hover:not(.on):not(:has(.flip-tg:checked)):not(:has(.pback.on)) .flip-in{transform:rotateY(-12deg)} .dossier:hover:not(.on):has(.flip-tg:checked):not(:has(.pback.on)) .flip-in{transform:rotateY(168deg)} } /* ── 卡角编辑钮:笔=编辑当前这一面,软盘=保存,叉=放弃(2026-08-31 用户定,顶掉两行编辑闸)── 笔只在待处理态露面(html.editable,与从前的闸同一条纪律);软盘/叉只在对应面的编辑态露面。 */ .fabs{position:absolute;top:10px;right:10px;z-index:5;display:flex;gap:6px} .fab{display:none;width:32px;height:32px;border-radius:999px;border:1px solid var(--acc-line);background:#fff;color:var(--acc-deep);cursor:pointer;place-items:center;padding:0;box-shadow:0 4px 12px rgba(18,38,63,.14);transition:border-color .16s,color .16s,box-shadow .16s} .fab:hover{border-color:var(--acc);box-shadow:0 6px 16px rgba(18,38,63,.22)} .fab:active{transform:scale(.94)} .fic{width:15px;height:15px;display:block;margin:auto} .fab.pen{color:var(--acc-deep)} .fab.disk{background:var(--acc);border-color:var(--acc);color:#fff} .fab.xbtn{color:var(--ink-3)} /* 笔:这张卡当下这一面、且这张卡没在编辑 —— 各卡各开,互不联动 */ html.editable .dossier:not(.on):not(:has(.pback.on)):not(:has(.flip-tg:checked)) .pen-f{display:grid} html.editable .dossier:not(.on):not(:has(.pback.on)):has(.flip-tg:checked) .pen-b{display:grid} .dossier.on .disk-f{display:grid} .dossier.on .x-f{display:grid} .dossier:has(.pback.on) .disk-b{display:grid} .dossier:has(.pback.on) .x-b{display:grid} /* ── 卡背:参数瓷贴 ── */ .pb-hd{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap} .pb-hd b{font-size:14px;font-weight:800;color:var(--ink)} .pb-lb{font-size:10.5px;font-weight:800;letter-spacing:.08em;color:var(--ink-4)} .pback{display:grid;grid-template-columns:1fr 1fr;gap:8px} .ptile{display:flex;flex-direction:column;gap:2px;border:1px solid var(--line-soft);border-radius:10px;background:var(--soft);padding:8px 10px;min-width:0} .pt-hd{display:flex;align-items:baseline;gap:6px;min-width:0} .pt-hd .jc-vcell{font-size:11px;font-weight:800;color:var(--ink-3)} .pt-unit{font-style:normal;font-size:10px;color:var(--ink-4);font-family:var(--mono)} .pt-val .jc-vcell{font-size:14px;font-weight:800;color:var(--ink)} .pt-note .jc-vcell{font-size:10.5px;color:var(--ink-3)} /* 三级占位:值必填红 / 说明建议橘 */ .ptile .pv .jc-vcell:empty::after{content:"必填";font-size:10.5px;font-weight:800;color:var(--danger);background:var(--danger-soft);border-radius:999px;padding:0 9px} /* 说明空着**什么都不摆**(2026-08-31 用户:「没写就什么都不要展示」)—— 连兜底破折号一起收 */ .ptile .sg .jc-vcell:empty{display:none} /* 参数编辑态:值与说明换输入,参数名照旧当标签摆着;两枚主键孪生件藏死(钥匙不是编辑面)。 藏钥匙用包装类(.pt-name / .rowkey),不用「data-col 属性选择器」—— 那段选择器文本会原样 出现在共享样式表里,把「落账确认全只读」那类字面断言踩翻(2026-08-31 踩过,连注释也不许写)。 */ .pback.on .pv > .jc-vcell,.pback.on .sg > .jc-vcell{display:none} .pback.on .pv > .jc-cell,.pback.on .sg > .jc-cell{display:block} .pback .pt-name .jc-cell{display:none} .pt-name{display:inline-flex;min-width:0} /* ================= 比对基准卡(类型 + 字段合一,只读、跟手)================= */ .basis{display:block;margin:0 0 10px} .basis:empty{border:1.5px dashed var(--line);border-radius:12px;padding:16px;display:block} .basis:empty::after{content:"还没定比对基准 —— 先在上面任一张档案卡上挑一个芯片类型,或展开下面的抽屉新建一个。";font-size:12.5px;color:var(--ink-3)} .basis-in{display:flex;flex-direction:column;gap:10px;border:1px solid var(--acc-line);border-radius:12px;background:var(--acc-wash);padding:12px 14px 14px} .basis-hd{display:flex;align-items:center;gap:12px;flex-wrap:wrap} .basis-lb{flex:none;font-size:10.5px;font-weight:800;letter-spacing:.08em;color:var(--acc-deep)} .basis-chip b{display:inline-block;font-size:13px;font-weight:800;color:#fff;background:var(--acc);border-radius:999px;padding:2px 14px;margin-right:8px} .basis-desc{font-style:normal;font-size:11.5px;color:var(--ink-3)} .basis-hd:has(.basis-chip:empty)::after{content:"待选择";font-size:11px;font-weight:700;color:var(--amber);background:var(--amber-soft);border:1px dashed #eeda9e;border-radius:999px;padding:1px 10px} .basis-hd .csvg{width:56px;flex:none} /* 类型图:层叠双封装 —— 后面那枚是「同类的别的芯片」,淡出成剪影 */ .basis-hd .tsvg{width:60px;flex:none} .tsvg{display:block} .t-ghost{opacity:.32} .basis-id{display:flex;flex-direction:column;gap:5px;min-width:0;flex:1 1 auto} .basis-in:has(.ftiles:empty) .ftiles{display:none} /* 降噪(2026-08-31 用户:「乱糟糟…没必要显示全就不要显示完全,鼠标指上去后再显示」): 字段收成一排丸(名 + 硬/软徽 + 单位),说明藏进悬浮气泡 —— 指上去才现身 */ .ftiles{display:flex;flex-wrap:wrap;gap:8px} .ftile{position:relative;display:flex;flex-direction:row;align-items:center;gap:7px;border:1px solid var(--line-soft);border-radius:999px;background:#fff;padding:6px 13px;min-width:0;transition:border-color .16s,box-shadow .16s} .ftile:hover{border-color:var(--acc-line);box-shadow:0 4px 12px rgba(18,38,63,.1)} .ft-hd{display:flex;align-items:baseline;gap:7px;white-space:nowrap} .ft-hd b{font-size:12px;font-weight:800;color:var(--ink)} .ft-unit{font-style:normal;font-size:10px;color:var(--ink-4);font-family:var(--mono)} .ft-desc{display:none;position:absolute;z-index:6;top:calc(100% + 7px);left:0;width:max-content;max-width:280px;margin:0;font-size:11px;line-height:1.65;color:var(--ink-2);background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px 11px;box-shadow:0 10px 24px rgba(18,38,63,.16)} .ftile:hover .ft-desc:not(:empty){display:block} /* 类型说明:默认一行截断,悬浮题头才放开 */ .basis-desc{display:block;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .basis-hd:hover .basis-desc{white-space:normal} /* ================= 新建类型工作抽屉(details,零脚本)================= */ .lab{margin:0 0 6px;border:1.5px dashed var(--line);border-radius:12px;background:var(--soft)} .lab[open]{border-style:solid;background:#fff} .lab-sm{cursor:pointer;list-style:none;display:flex;align-items:center;gap:8px;padding:11px 14px;font-size:12.5px;color:var(--ink-3);user-select:none} .lab-sm::-webkit-details-marker{display:none} .lab-sm b{color:var(--ink-2)} .lab-sm:hover{color:var(--acc-deep)} .lab-caret{margin-left:auto;flex:none;width:8px;height:8px;border-right:2px solid var(--ink-4);border-bottom:2px solid var(--ink-4);transform:rotate(45deg);transition:transform .16s} .lab[open] .lab-caret{transform:rotate(-135deg)} .lab-bd{padding:2px 14px 14px} .lab-brief{margin:0 0 16px} .lab-brief .brief{margin:2px 14px 14px;border-left-width:3px} /* ================= 窄屏 ================= */ @media(max-width:620px){ .card-head{padding:16px 14px 18px} .dz-grid{grid-template-columns:1fr} .swapfx{display:none} .dossiers{grid-template-columns:1fr} .dossiers > .dossier:nth-of-type(odd),.dossiers > .dossier:nth-of-type(even){grid-column:1} .pback{grid-template-columns:1fr} .ftiles{grid-template-columns:1fr} .card-bd{padding:16px 14px 6px} .hero-title{font-size:19.5px} .stage{gap:14px} .hchip{min-width:108px;padding:10px 8px 9px} .csvg{width:68px} .kv i{flex-basis:72px} .card-foot{padding:10px 14px} } `;