dsh-chef 0.3.44 → 0.3.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -1306,6 +1306,23 @@ window.__ModuleLoader__.load({
1306
1306
  }
1307
1307
  };
1308
1308
  //#endregion
1309
+ //#region ../plugin-manager/src/seal-vocabulary.generated.ts
1310
+ /** 自动生成 · **勿手改**:源 `seals.yaml`(仓库根),生成器 `node tooling/gen-seals.mjs`。 */
1311
+ /** 档位话:卷轴标题下那一行 = 悬停章的气泡(同一句话,两处渲染)。 */
1312
+ const TIER_TEXT = {
1313
+ "gold": "精雕细琢中",
1314
+ "silver": "全场景打通中",
1315
+ "copper": "基础建设中"
1316
+ };
1317
+ /** 卷轴三段小标题(行首朱砂小印取首字)。 */
1318
+ const SECTION_LABEL = {
1319
+ "progress": "进展",
1320
+ "status": "状态",
1321
+ "plan": "计划"
1322
+ };
1323
+ /** 关闭钮(绦带)上的字。 */
1324
+ const CLOSE_LABEL = "收卷";
1325
+ //#endregion
1309
1326
  //#region ../plugin-manager/src/seal-paper-schemes.ts
1310
1327
  /** 卷轴纸面字排 + 关闭钮样子 · **定稿件**(2026-10-06 定档,原型选型期结束)。
1311
1328
  *
@@ -1314,20 +1331,23 @@ window.__ModuleLoader__.load({
1314
1331
  * 末行吃回 0.5em 行距(不然底比顶空一截);饰线上距加宽到 `0.5em 0 0.75em`;纸底与头部沿用原样式。
1315
1332
  * 档位语:该档金属渐变压进字里(金=鎏金/银=冷银/铜=暖铜),不再一律金。
1316
1333
  * 关闭钮:右上角斜披的朱砂菱形绦带(正立「收卷」字独立成层),两条飘尾沿菱形两条下边各向底尖收,
1317
- * 各自朝外 26°(左尾朝左下、右尾朝右下);尾是两层——外层过糙边出毛边,内层纯色芯不受滤镜。
1334
+ * 各自朝外 26°(左尾朝左下、右尾朝右下);尾是两层——外层过糙边出毛边,内层纯色芯不受滤镜;
1335
+ * 糙边滤镜住 `SealFilterDefs` 的 CSS(按 `data-ilife-close-ribbon`/`data-ilife-close-tail` 挂),
1336
+ * 因为悬停要"糙边+提亮"一起写而 `filter` 是单属性。
1318
1337
  *
1319
1338
  * 为什么单独一件:`seal-scroll.ts` 已接近告警线(外框/纸/浮层/滤镜都住那里),纸面字排与关闭钮住这里。
1320
1339
  * 本件是纯函数:吃 ctx 回五件,不留状态、不取数。原型期的二十余档方案已按「定稿后只留胜出那一档」删除。
1321
1340
  */
1322
1341
  /** 材质底层:**糙边滤镜只挂这一层**——文字住在它外面,所以字是清晰的(照插件章「金属带+印文」的老做法)。 */
1323
- function bgLayer(style, children) {
1342
+ function bgLayer(style, children, attrs) {
1324
1343
  return react.createElement("span", {
1325
1344
  "aria-hidden": true,
1326
1345
  style: {
1327
1346
  position: "absolute",
1328
1347
  inset: 0,
1329
1348
  ...style
1330
- }
1349
+ },
1350
+ ...attrs ?? {}
1331
1351
  }, children ?? null);
1332
1352
  }
1333
1353
  /** 清晰字面:压在材质层之上,不参与任何滤镜。 */
@@ -1342,7 +1362,8 @@ window.__ModuleLoader__.load({
1342
1362
  const edgeOf = (tierKey) => TIER_EDGE[tierKey] ?? TIER_EDGE.gold;
1343
1363
  const metalOf = (tierKey) => TIER_METAL[tierKey] ?? TIER_METAL.gold;
1344
1364
  const KAI = "\"Kaiti SC\",\"KaiTi\",\"STKaiti\",serif";
1345
- /** 关闭钮(定稿:绦带·飘尾)。右上角一枚斜披 45° 的朱砂菱形,两条飘尾分挂两条下边,尾先画、带后画压住尾根。 */
1365
+ /** 关闭钮(定稿:绦带·飘尾)。右上角一枚斜披 45° 的朱砂菱形,两条飘尾分挂两条下边,尾先画、带后画压住尾根。
1366
+ * 悬停/焦点时**菱形那层**淡入一圈辉光——按钮方框是透明的,反馈的形状必须跟菱形走(见 `SealFilterDefs`)。 */
1346
1367
  function closeLook(tierKey) {
1347
1368
  const crimson = "linear-gradient(135deg,#c63d2a 8%,#a32216 50%,#7e1a10)";
1348
1369
  /** 档位金属边(铜/银/金):绦带**只借这一条**——主体恒朱砂,边随档走,跟章「红底+金属边」同构。 */
@@ -1351,9 +1372,8 @@ window.__ModuleLoader__.load({
1351
1372
  borderRadius: "0.375em",
1352
1373
  background: crimson,
1353
1374
  boxShadow: "0 0 0 1px #5c110a59, 0 2px 8px #3d241066, inset 0 0 0 2px " + edge,
1354
- transform: "rotate(45deg)",
1355
- filter: "url(#" + SEAL_ROUGH_METAL_ID + ")"
1356
- }, null);
1375
+ transform: "rotate(45deg)"
1376
+ }, null, { "data-ilife-close-ribbon": "tie" });
1357
1377
  /** 尾色=绦带上亮一档的朱砂(悬在纸上也不发灰、不发黑):两条尾同色。 */
1358
1378
  const TAIL_FILL = "linear-gradient(180deg,#e8573c 0%,#c33a24 55%,#a52612 100%)";
1359
1379
  /** 飘尾:屏幕坐标(不随菱形旋转)——左尾往左下、右尾往右下(CSS 正角=尾梢往左)。
@@ -1373,9 +1393,8 @@ window.__ModuleLoader__.load({
1373
1393
  }, bgLayer({
1374
1394
  borderRadius: "0 0 0.1875em 0.1875em",
1375
1395
  background: TAIL_FILL,
1376
- boxShadow: "0 0 0 1.5px " + edge + "cc, 0 1px 3px #00000055",
1377
- filter: "url(#" + SEAL_ROUGH_METAL_ID + ")"
1378
- }), react.createElement("span", {
1396
+ boxShadow: "0 0 0 1.5px " + edge + "cc, 0 1px 3px #00000055"
1397
+ }, void 0, { "data-ilife-close-tail": "tie" }), react.createElement("span", {
1379
1398
  "aria-hidden": true,
1380
1399
  style: {
1381
1400
  position: "absolute",
@@ -1384,8 +1403,22 @@ window.__ModuleLoader__.load({
1384
1403
  background: TAIL_FILL
1385
1404
  }
1386
1405
  }));
1406
+ /** 悬停辉光:与绦带**同角度、同圆角、不过滤镜**的一层。形状与颜色全在 CSS(`SealFilterDefs` 的
1407
+ * `[data-ilife-close-glow]`,悬停/焦点淡入);这里只给几何。画在绦带之后 ⇒ 顺带压一层暖洗色(读成提亮)。 */
1408
+ const glow = react.createElement("span", {
1409
+ key: "glow",
1410
+ "aria-hidden": true,
1411
+ "data-ilife-close-glow": "tie",
1412
+ style: {
1413
+ position: "absolute",
1414
+ inset: 0,
1415
+ borderRadius: "0.375em",
1416
+ transform: "rotate(45deg)",
1417
+ pointerEvents: "none"
1418
+ }
1419
+ });
1387
1420
  return {
1388
- label: crisp("收卷", {
1421
+ label: crisp(CLOSE_LABEL, {
1389
1422
  fontFamily: KAI,
1390
1423
  fontSize: "0.8125em",
1391
1424
  letterSpacing: "0.22em",
@@ -1393,7 +1426,7 @@ window.__ModuleLoader__.load({
1393
1426
  color: "#f8f1e2",
1394
1427
  textShadow: "0 1px 2px #000000aa"
1395
1428
  }),
1396
- decor: react.createElement(react.Fragment, null, loose("tL", "calc(50% - 0.8125em)", 26, "2em", "2.8125em"), loose("tR", "calc(50% + 0.4375em)", -26, "2em", "2.8125em"), ribbon),
1429
+ decor: react.createElement(react.Fragment, null, loose("tL", "calc(50% - 0.8125em)", 26, "2em", "2.8125em"), loose("tR", "calc(50% + 0.4375em)", -26, "2em", "2.8125em"), ribbon, glow),
1397
1430
  style: {
1398
1431
  boxSizing: "border-box",
1399
1432
  padding: 0,
@@ -1431,8 +1464,8 @@ window.__ModuleLoader__.load({
1431
1464
  /** 行首那枚朱砂小印(进/状/计):**两层**——材质层过印那条糙边滤镜(印泥压出来的毛边与斑驳),
1432
1465
  * 字独立成层保持清晰;方块各带一点歪斜(真印章不会次次压得方正)。
1433
1466
  * 外框仍是 0.7em 字/1.6 行高/左右 0.375em 垫——换的是质感,版面逐值不动。 */
1434
- function inkMark(name) {
1435
- const tilt = name === "进展" ? -2.4 : name === "状态" ? 1.6 : -1.2;
1467
+ function inkMark(section, name) {
1468
+ const tilt = section === "progress" ? -2.4 : section === "status" ? 1.6 : -1.2;
1436
1469
  return react.createElement("span", { style: {
1437
1470
  position: "relative",
1438
1471
  flex: "0 0 auto",
@@ -1473,7 +1506,7 @@ window.__ModuleLoader__.load({
1473
1506
  alignItems: "baseline",
1474
1507
  gap: "0.5em"
1475
1508
  }
1476
- }, inkMark(name), react.createElement("span", { style: {
1509
+ }, inkMark(key, name), react.createElement("span", { style: {
1477
1510
  ...st.label,
1478
1511
  flex: "0 0 auto",
1479
1512
  display: "inline",
@@ -1487,7 +1520,7 @@ window.__ModuleLoader__.load({
1487
1520
  margin: 0,
1488
1521
  fontSize: "0.9em"
1489
1522
  } }, text));
1490
- return react.createElement(react.Fragment, null, one("progress", "进展", ctx.progress), one("status", "状态", ctx.status), one("plan", "计划", ctx.plan, true));
1523
+ return react.createElement(react.Fragment, null, one("progress", SECTION_LABEL.progress, ctx.progress), one("status", SECTION_LABEL.status, ctx.status), one("plan", SECTION_LABEL.plan, ctx.plan, true));
1491
1524
  }
1492
1525
  /** 档位语(一行):该档金属渐变压进字里。 */
1493
1526
  function tierNode(ctx) {
@@ -1546,16 +1579,8 @@ window.__ModuleLoader__.load({
1546
1579
  /** 印泥那条(行首那几枚小印):同 2.2 的抖动,末尾再加一点高斯模糊——印泥压在纸上边缘会洇开,
1547
1580
  * 光有抖动边只会读成「毛边贴纸」。字住在滤镜之外,所以糊的只有泥、不是字。 */
1548
1581
  const ROUGH_INK = "dshLifeSealInkEdge";
1549
- /** 中等件那条糙边 id(关闭钮引用;定义只此一处)。 */
1550
- const SEAL_ROUGH_METAL_ID = ROUGH_METAL;
1551
1582
  /** 印泥那条糙边 id(纸面行首小印引用;定义只此一处)。 */
1552
1583
  const SEAL_ROUGH_INK_ID = ROUGH_INK;
1553
- /** 档位话:标题下那一行不再印档位字,直接说档位所处的阶段(渲染期用,顶层可放行)。 */
1554
- const TIER_TEXT = {
1555
- gold: "精雕细琢中",
1556
- silver: "全打通中",
1557
- copper: "基础建设中"
1558
- };
1559
1584
  /** 纸面四色是印自带的(羊皮纸底+ availability 墨色),不跟宿主主题跑——
1560
1585
  * 深色下宿主变量会把纸染黑,故这里写死定稿值;字族仍继承(定稿零字族)。 */
1561
1586
  const PAPER_BG = "#fdfaf2";
@@ -1716,13 +1741,8 @@ window.__ModuleLoader__.load({
1716
1741
  rivet: role === "plugin" ? SEAL_RIVET[tier] : void 0
1717
1742
  };
1718
1743
  }
1719
- /** 糙边滤镜定义:两条分开(印用 edge,卷轴外框用 frame),每页只挂一次。
1720
- *
1721
- * 挂在文档任意位置都行(`width/height=0` 不占位),同页重复挂会撞 id。
1722
- * 印章交互(悬停上浮高亮/按压回缩/焦点环/级别 tooltip)也住这里:scoped 类名,纯 CSS、无 hook。
1723
- * 悬停高亮须把糙边 url 原样带上(filter 单属性,另写会把糙边冲掉)。 */
1724
1744
  function SealFilterDefs() {
1725
- return react.createElement(react.Fragment, null, react.createElement("style", null, ".dshLifeSealBtn{position:relative;transition:transform 160ms ease-out,filter 160ms ease-out}.dshLifeSealBtn:hover{transform:translateY(-2px);filter:url(#dshLifeSealRoughEdge) brightness(1.12)}.dshLifeSealBtn:active{transform:translateY(0) scale(.96)}.dshLifeSealBtn:focus-visible{outline:2px solid #f5d97a;outline-offset:2px}.dshLifeSealBtn::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:#241f19ee;color:#f8f1e2;font-size:.72em;letter-spacing:.1em;padding:.4em .9em;border-radius:.5em;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity 150ms ease;z-index:30}.dshLifeSealBtn:hover::after,.dshLifeSealBtn:focus-visible::after{opacity:1}[data-ilife-press][data-ilife-close]{overflow:visible}[data-tip]{position:relative}[data-tip]::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:#241f19ee;color:#f8f1e2;font-size:.72em;letter-spacing:.1em;padding:.4em .9em;border-radius:.5em;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity 150ms ease;z-index:60}[data-tip]:hover::after,[data-tip]:focus-within::after{opacity:1}.dshLifeSealSlot .dshLifeSealBtn::after{content:none}"), react.createElement("svg", {
1745
+ return react.createElement(react.Fragment, null, react.createElement("style", null, ".dshLifeSealBtn{position:relative;transition:transform 160ms ease-out,filter 160ms ease-out}.dshLifeSealBtn:hover{transform:translateY(-2px);filter:url(#dshLifeSealRoughEdge) brightness(1.12)}.dshLifeSealBtn:active{transform:translateY(0) scale(.96)}.dshLifeSealBtn:focus-visible{outline:2px solid #f5d97a;outline-offset:2px}.dshLifeSealBtn::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:#241f19ee;color:#f8f1e2;font-size:.72em;letter-spacing:.1em;padding:.4em .9em;border-radius:.5em;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity 150ms ease;z-index:30}.dshLifeSealBtn:hover::after,.dshLifeSealBtn:focus-visible::after{opacity:1}[data-ilife-press][data-ilife-close]{overflow:visible}[data-ilife-press][data-ilife-close]:hover:not(:disabled){box-shadow:none;background:transparent!important}[data-ilife-press][data-ilife-close]:focus-visible:hover:not(:disabled){box-shadow:0 0 0 " + String(2) + "px var(--dsw-alias-bg-layer-1, #232324),0 0 0 " + String(5) + "px var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55));background:transparent!important}[data-ilife-press][data-ilife-close]::before{display:none}.dshLifeSealBtn[data-ilife-close]:hover{filter:none}[data-ilife-close-ribbon],[data-ilife-close-tail]{filter:url(#dshLifeSealRoughMetal)}[data-ilife-close]:hover [data-ilife-close-ribbon],[data-ilife-close]:focus-visible [data-ilife-close-ribbon],[data-ilife-close]:hover [data-ilife-close-tail],[data-ilife-close]:focus-visible [data-ilife-close-tail]{filter:url(#dshLifeSealRoughMetal) brightness(1.12)}[data-ilife-close-glow]{opacity:0;transition:opacity 160ms ease;background:color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) 14%, transparent);box-shadow:0 0 0 1px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) 65%, transparent),0 0 12px 4px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) 45%, transparent)}[data-ilife-close]:hover [data-ilife-close-glow],[data-ilife-close]:focus-visible [data-ilife-close-glow]{opacity:1}@media (prefers-reduced-motion:reduce){[data-ilife-close-glow]{transition:none}}[data-tip]{position:relative}[data-tip]::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:#241f19ee;color:#f8f1e2;font-size:.72em;letter-spacing:.1em;padding:.4em .9em;border-radius:.5em;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity 150ms ease;z-index:60}[data-tip]:hover::after,[data-tip]:focus-within::after{opacity:1}[data-tip]:hover,[data-tip]:focus-within{z-index:40 !important}.dshLifeSealSlot .dshLifeSealBtn::after{content:none}"), react.createElement("svg", {
1726
1746
  width: 0,
1727
1747
  height: 0,
1728
1748
  "aria-hidden": true,
@@ -1996,9 +2016,9 @@ window.__ModuleLoader__.load({
1996
2016
  silver: "inset 0 1px 0 #ffffffdd,inset 0 -2px 5px #0005,0 0 0 1px #6f767c",
1997
2017
  gold: "inset 0 1px 0 #fff8d8dd,inset 0 -2px 5px #0005,0 0 0 1px #8a6a15,0 3px 14px #c9a22766"
1998
2018
  };
1999
- /** 级别 tooltip 那一句(印本体与面板槽位共用一份定义):档位名 + 档位话。 */
2019
+ /** 级别 tooltip 那一句(印本体与面板槽位共用一份定义):**只说档位话**(金=精雕细琢中/银=全场景打通中/铜=基础建设中)。 */
2000
2020
  function sealTipOf(tier) {
2001
- return (tier === "copper" ? "铜" : tier === "silver" ? "银" : "金") + "章 · " + TIER_TEXT[tier];
2021
+ return TIER_TEXT[tier];
2002
2022
  }
2003
2023
  /** 一枚印章(button,点章弹卷)。未知组合直接抛错,不静默退化。 */
2004
2024
  function SealStamp(props) {
@@ -2126,8 +2146,13 @@ window.__ModuleLoader__.load({
2126
2146
  /** 骨架条:浅色 ≈`#c9ccd2`(1.6:1)⇔ 深色 ≈`#404143`。 */
2127
2147
  const PANEL_SKELETON_FILL = inkMix(21);
2128
2148
  function interactionCss() {
2129
- return "[data-ilife-press]{transition:" + INTERACTION_TRANSITION + "}[data-ilife-focus]{transition:" + INTERACTION_TRANSITION + "}[data-ilife-press]:active{transform:scale(" + String(PRESS_SCALE) + ")}[data-ilife-press]:focus-visible,[data-ilife-focus]:focus-visible{outline:none;box-shadow:0 0 0 " + String(2) + "px var(--dsw-alias-bg-layer-1, #232324),0 0 0 " + String(5) + "px var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55))}[data-ilife-press]{position:relative;overflow:hidden}[data-ilife-press]:hover:not(:disabled){background:color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(13) + "%, transparent);border-color:var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55));box-shadow:0 0 0 1px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(55) + "%, transparent),0 4px 16px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(25) + "%, transparent);transform:translateY(-" + String(1) + "px)}[data-ilife-press]:active:hover:not(:disabled){transform:scale(" + String(PRESS_SCALE) + ")}[data-ilife-press]:focus-visible:hover:not(:disabled){box-shadow:0 0 0 " + String(2) + "px var(--dsw-alias-bg-layer-1, #232324),0 0 0 " + String(5) + "px var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)),0 4px 16px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(25) + "%, transparent)}[data-ilife-press]::before{content:\"\";position:absolute;inset:0;background:radial-gradient(" + String(120) + "px circle at var(--mx,50%) var(--my,50%),color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(22) + "%, transparent),transparent 65%);opacity:0;transition:opacity " + String(180 / 1e3) + "s ease;pointer-events:none}[data-ilife-press]:hover:not(:disabled)::before{opacity:1}[data-ilife-press]:disabled{cursor:not-allowed;opacity:" + String(DISABLED_OPACITY) + "}[data-ilife-press]:disabled:hover{animation:ilifeShake " + String(300 / 1e3) + "s ease}@keyframes ilifeShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-2px)}75%{transform:translateX(2px)}}[data-ilife-longpress]{position:relative;overflow:hidden}[data-ilife-longpress]::after{content:\"\";position:absolute;left:0;bottom:0;height:" + String(3) + "px;width:0;background:var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55));pointer-events:none}[data-ilife-longpress]:active:not(:disabled)::after{animation:ilifeLongRing " + String(500 / 1e3) + "s linear forwards}@keyframes ilifeLongRing{from{width:0}to{width:100%}}[data-ilife-advanced=\"head\"]{transition:background .15s ease,transform .15s ease,box-shadow .15s ease,border-color .15s ease}[data-ilife-advanced=\"mark\"]{display:inline-block;transition:transform " + String(200 / 1e3) + "s ease}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"mark\"]{transform:rotate(90deg)}[data-ilife-advanced=\"head\"]:hover [data-ilife-advanced=\"mark\"]{color:var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55));transform:translateX(" + String(2) + "px)}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"body\"]{animation:ilifeFoldIn " + String(220 / 1e3) + "s ease}@keyframes ilifeFoldIn{from{max-height:0;opacity:0}to{max-height:" + String(300) + "px;opacity:1}}[data-ilife-notice=\"line\"]{animation:ilifeToastIn " + String(180 / 1e3) + "s ease}@keyframes ilifeToastIn{from{opacity:0;transform:translateY(" + String(8) + "px)}to{opacity:1;transform:none}}@media (hover:none){[data-ilife-press]:hover:not(:disabled){transform:none}[data-ilife-press]::before{display:none}}@media (prefers-reduced-motion:reduce){[data-ilife-press],[data-ilife-focus]{transition:none}[data-ilife-press]:disabled:hover{animation:none}[data-ilife-longpress]:active:not(:disabled)::after{animation:none;width:100%}[data-ilife-advanced=\"mark\"]{transition:none}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"body\"]{animation:none}[data-ilife-notice=\"line\"]{animation:none}}@media (update: slow){[data-ilife-press],[data-ilife-focus]{transition:none}[data-ilife-press]::before{display:none}[data-ilife-press]:disabled:hover{animation:none}[data-ilife-longpress]:active:not(:disabled)::after{animation:none;width:100%}[data-ilife-advanced=\"mark\"]{transition:none}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"body\"]{animation:none}[data-ilife-notice=\"line\"]{animation:none}}";
2149
+ return "[data-ilife-press]{transition:" + INTERACTION_TRANSITION + "}[data-ilife-focus]{transition:" + INTERACTION_TRANSITION + "}[data-ilife-press]:active{transform:scale(" + String(PRESS_SCALE) + ")}[data-ilife-press]:focus-visible,[data-ilife-focus]:focus-visible{outline:none;box-shadow:0 0 0 " + String(2) + "px var(--dsw-alias-bg-layer-1, #232324),0 0 0 " + String(5) + "px var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55))}[data-ilife-press]{position:relative;overflow:hidden}[data-ilife-press]:hover:not(:disabled){background:color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(13) + "%, transparent)!important;border-color:var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55))!important;box-shadow:0 0 0 1px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(55) + "%, transparent),0 4px 16px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(25) + "%, transparent);transform:translateY(-" + String(1) + "px)}[data-ilife-press]:active:hover:not(:disabled){transform:scale(" + String(PRESS_SCALE) + ")}[data-ilife-press]:focus-visible:hover:not(:disabled){box-shadow:0 0 0 " + String(2) + "px var(--dsw-alias-bg-layer-1, #232324),0 0 0 " + String(5) + "px var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)),0 4px 16px color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(25) + "%, transparent)}[data-ilife-press]::before{content:\"\";position:absolute;inset:0;background:radial-gradient(" + String(120) + "px circle at var(--mx,50%) var(--my,50%),color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(22) + "%, transparent),transparent 65%);opacity:0;transition:opacity " + String(180 / 1e3) + "s ease;pointer-events:none}[data-ilife-press]:hover:not(:disabled)::before{opacity:1}[data-ilife-press]:disabled{cursor:not-allowed;opacity:" + String(DISABLED_OPACITY) + "}[data-ilife-press]:disabled:hover{animation:ilifeShake " + String(300 / 1e3) + "s ease}@keyframes ilifeShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-2px)}75%{transform:translateX(2px)}}[data-ilife-longpress]{position:relative;overflow:hidden}[data-ilife-longpress]::after{content:\"\";position:absolute;left:0;bottom:0;height:" + String(3) + "px;width:0;background:var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55));pointer-events:none}[data-ilife-longpress]:active:not(:disabled)::after{animation:ilifeLongRing " + String(500 / 1e3) + "s linear forwards}@keyframes ilifeLongRing{from{width:0}to{width:100%}}[data-ilife-advanced=\"head\"]{transition:background .15s ease,transform .15s ease,box-shadow .15s ease,border-color .15s ease;border-radius:8px}[data-ilife-advanced=\"head\"]:hover{background:color-mix(in srgb, var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55)) " + String(13) + "%, transparent)!important}[data-ilife-advanced=\"mark\"]{display:inline-block;transition:transform " + String(200 / 1e3) + "s ease}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"mark\"]{transform:rotate(90deg)}[data-ilife-advanced=\"head\"]:hover [data-ilife-advanced=\"mark\"]{color:var(--ilife-focus, var(--dsw-alias-brand-primary, #f6ad55));transform:translateX(" + String(2) + "px)}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"body\"]{animation:ilifeFoldIn " + String(220 / 1e3) + "s ease}@keyframes ilifeFoldIn{from{max-height:0;opacity:0}to{max-height:" + String(300) + "px;opacity:1}}[data-ilife-notice=\"line\"]{animation:ilifeToastIn " + String(180 / 1e3) + "s ease}@keyframes ilifeToastIn{from{opacity:0;transform:translateY(" + String(8) + "px)}to{opacity:1;transform:none}}@media (hover:none){[data-ilife-press]:hover:not(:disabled){transform:none}[data-ilife-press]::before{display:none}}@media (prefers-reduced-motion:reduce){[data-ilife-press],[data-ilife-focus]{transition:none}[data-ilife-press]:disabled:hover{animation:none}[data-ilife-longpress]:active:not(:disabled)::after{animation:none;width:100%}[data-ilife-advanced=\"mark\"]{transition:none}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"body\"]{animation:none}[data-ilife-notice=\"line\"]{animation:none}}@media (update: slow){[data-ilife-press],[data-ilife-focus]{transition:none}[data-ilife-press]::before{display:none}[data-ilife-press]:disabled:hover{animation:none}[data-ilife-longpress]:active:not(:disabled)::after{animation:none;width:100%}[data-ilife-advanced=\"mark\"]{transition:none}[data-ilife-advanced=\"group\"][open] [data-ilife-advanced=\"body\"]{animation:none}[data-ilife-notice=\"line\"]{animation:none}}";
2130
2150
  }
2151
+ /** 三枚章的整体缩放(定:当前显示大小 × 0.7)。**一个系数管全簇**——章面字号、三行落位、右间距、
2152
+ * 浮层锚点全乘它:只缩章不缩槽位,三行之间会空出一截;只缩槽位不缩章,章会互相压上。 */
2153
+ const SEAL_SCALE = .7;
2154
+ /** 卡面 em 值(乘缩放后收 4 位小数:0.3×0.7 在浮点里是 0.21000000000000002,直接拼串会带尾巴)。 */
2155
+ const sealEm = (n) => String(Math.round(n * SEAL_SCALE * 1e4) / 1e4) + "em";
2131
2156
  const S = {
2132
2157
  /** `.ic-card`:`background:var(--ic-surface)`(=bg-layer-1)+`border:1px solid var(--ic-line-strong)`
2133
2158
  * +`border-radius:12px`+`padding:14px`+`box-shadow:inset 0 1px 0 rgba(255,255,255,.06)`。
@@ -2157,7 +2182,7 @@ window.__ModuleLoader__.load({
2157
2182
  top: 0,
2158
2183
  right: 0,
2159
2184
  width: "38%",
2160
- height: "9em",
2185
+ height: sealEm(9),
2161
2186
  pointerEvents: "none",
2162
2187
  zIndex: 15
2163
2188
  },
@@ -2744,29 +2769,30 @@ window.__ModuleLoader__.load({
2744
2769
  "plugin"
2745
2770
  ].map((role) => seals.findIndex((s) => s.role === role)).filter((index) => index >= 0);
2746
2771
  /** 三行槽位几何 · **唯一出处**:章的落位与卷轴浮层的锚点都从这里取,免得两处各写一套数字。
2747
- * 行高(上/中/下;纵向净空各留约 10px,糙边抖动也碰不到)/轻微倾角(±0.5°~±2.5°,家下标×槽位哈希,
2748
- * 纯函数每次同值)/右间距(三枚全部居右收敛,各家各行 0.2em~1.1em 错开,永不出面板右边界)。
2749
- * `dialog` 是卷轴浮层那一份:贴该行下方 1.9em(章高约 1.5em + 0.4em 缝),右缘与那枚章对齐,
2772
+ * 下列数字是**设计基准**(未缩放):行高上/中/下 0.3/3.4/6.2em(纵向净空各留约 10px,糙边抖动也碰不到)、
2773
+ * 轻微倾角 ±0.5°~±2.5°(家下标×槽位哈希,纯函数每次同值)、右间距 0.2em~1.1em(三枚全部居右收敛,
2774
+ * 各家各行错开,永不出面板右边界)。整簇一律乘 `SEAL_SCALE` 落到卡面(`sealEm`)——缩放只此一处。
2775
+ * `dialog` 是卷轴浮层那一份:贴该行下方 1.9em(章高 + 缝),右缘与那枚章对齐,
2750
2776
  * 再往左让 1.25em 给绦带(关闭钮骑在浮层右上方,不让它越出卡片)。 */
2751
2777
  const slotGeom = (slot, seed) => {
2752
- const top = [
2753
- "0.3em",
2754
- "3.4em",
2755
- "6.2em"
2756
- ][slot] ?? "0.3em";
2778
+ const top = sealEm([
2779
+ .3,
2780
+ 3.4,
2781
+ 6.2
2782
+ ][slot] ?? .3);
2757
2783
  const q = (seed * 5 + slot * 11 + 3) % 10;
2758
2784
  const tilt = String((q % 2 === 0 ? -1 : 1) * (.5 + Math.floor(q / 2) * .5));
2759
- const padRight = String(.2 + (seed * 7 + slot * 3 + 1) % 6 * .18) + "em";
2785
+ const padRight = sealEm(.2 + (seed * 7 + slot * 3 + 1) % 6 * .18);
2760
2786
  return {
2761
2787
  top,
2762
2788
  tilt,
2763
2789
  padRight,
2764
2790
  dialog: {
2765
- top: "calc(" + top + " + 1.9em)",
2766
- right: "calc(" + padRight + " + 1.25em)",
2791
+ top: "calc(" + top + " + " + sealEm(1.9) + ")",
2792
+ right: "calc(" + padRight + " + " + sealEm(1.25) + ")",
2767
2793
  left: "auto",
2768
2794
  justifyContent: "flex-end",
2769
- maxWidth: "calc(100% - " + padRight + " - 1.75em)"
2795
+ maxWidth: "calc(100% - " + padRight + " - " + sealEm(1.75) + ")"
2770
2796
  }
2771
2797
  };
2772
2798
  };
@@ -2788,7 +2814,7 @@ window.__ModuleLoader__.load({
2788
2814
  };
2789
2815
  })()
2790
2816
  }, react.createElement("span", { style: {
2791
- fontSize: "0.8em",
2817
+ fontSize: "0.56em",
2792
2818
  display: "inline-flex"
2793
2819
  } }, react.createElement(SealStamp, {
2794
2820
  role: seals[dataIndex].role,
@@ -3307,6 +3333,37 @@ window.__ModuleLoader__.load({
3307
3333
  const SLOT_TITLE = "私家大厨";
3308
3334
  const PLUGIN = "dsh-chef";
3309
3335
  //#endregion
3336
+ //#region src/seal-states.generated.ts
3337
+ /** 三枚章(HELP/技能/插件;面板按角色定序)。label 用 `seals.yaml` 的 vocabulary.label 约定。 */
3338
+ function sealStates(product) {
3339
+ return [
3340
+ {
3341
+ role: "help",
3342
+ tier: "silver",
3343
+ label: product + " HELP",
3344
+ progress: "完成度 50%",
3345
+ status: "全打通",
3346
+ plan: "将所有功能和场景全部打通"
3347
+ },
3348
+ {
3349
+ role: "skill",
3350
+ tier: "copper",
3351
+ label: "技能",
3352
+ progress: "完成度 60%",
3353
+ status: "基本可用",
3354
+ plan: "修复明显bug并将未打通场景打通"
3355
+ },
3356
+ {
3357
+ role: "plugin",
3358
+ tier: "copper",
3359
+ label: "插件",
3360
+ progress: "完成度 60%",
3361
+ status: "基本可用",
3362
+ plan: "修复明显bug并将未打通场景打通"
3363
+ }
3364
+ ];
3365
+ }
3366
+ //#endregion
3310
3367
  //#region src/settings.ts
3311
3368
  /** 常用项:改了就影响「库与产物落在哪」,放页面上。 */
3312
3369
  const COMMON = [
@@ -3394,32 +3451,7 @@ window.__ModuleLoader__.load({
3394
3451
  channel: RPC_CHANNEL,
3395
3452
  items: CONFIG_ITEMS,
3396
3453
  title: SLOT_TITLE,
3397
- seals: [
3398
- {
3399
- role: "help",
3400
- tier: "silver",
3401
- label: SLOT_TITLE + " HELP",
3402
- progress: "完成度 50%",
3403
- status: "全打通",
3404
- plan: "将所有功能和场景全部打通"
3405
- },
3406
- {
3407
- role: "skill",
3408
- tier: "copper",
3409
- label: "技能",
3410
- progress: "完成度 60%",
3411
- status: "基本可用",
3412
- plan: "修复明显bug并将未打通场景打通"
3413
- },
3414
- {
3415
- role: "plugin",
3416
- tier: "copper",
3417
- label: "插件",
3418
- progress: "完成度 60%",
3419
- status: "基本可用",
3420
- plan: "修复明显bug并将未打通场景打通"
3421
- }
3422
- ],
3454
+ seals: sealStates(SLOT_TITLE),
3423
3455
  sealSeed: 2,
3424
3456
  followKeysOf,
3425
3457
  getCall,