dsh-chef 0.3.42 → 0.3.43

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
@@ -1208,6 +1208,104 @@ window.__ModuleLoader__.load({
1208
1208
  }, react.createElement("span", { style: S$2.product }, props.product), react.createElement("span", { style: S$2.purpose }, props.purpose));
1209
1209
  }
1210
1210
  //#endregion
1211
+ //#region ../plugin-manager/src/seal-palette.ts
1212
+ /** 九档调色板(3 角色 × 3 档)。键就是契约里的 `role`/`tier`。 */
1213
+ const SEAL_PALETTE = {
1214
+ skill: {
1215
+ copper: {
1216
+ background: "linear-gradient(180deg,#8a4a28,#6e3418)",
1217
+ border: "3px solid #a5652f",
1218
+ accent: "#9a5f2a",
1219
+ ruler: "#c08145b3"
1220
+ },
1221
+ silver: {
1222
+ background: "linear-gradient(180deg,#b73124,#8e1f14)",
1223
+ border: "3px double #eef3f6",
1224
+ accent: "#6f767c",
1225
+ ruler: "#9aa0a6b3"
1226
+ },
1227
+ gold: {
1228
+ background: "linear-gradient(180deg,#d34a35,#a32216)",
1229
+ border: "3px double #f5d97a",
1230
+ accent: "#9c7a16",
1231
+ ruler: "#d8b338b3"
1232
+ }
1233
+ },
1234
+ help: {
1235
+ copper: {
1236
+ background: "linear-gradient(180deg,#b06a3a,#7e3f1d)",
1237
+ border: "3px solid #a5652f",
1238
+ accent: "#9a5f2a",
1239
+ ruler: "#c08145b3"
1240
+ },
1241
+ silver: {
1242
+ background: "linear-gradient(180deg,#8f979e,#5f666d)",
1243
+ border: "3px double #e8eef2",
1244
+ accent: "#6f767c",
1245
+ ruler: "#9aa0a6b3"
1246
+ },
1247
+ gold: {
1248
+ background: "linear-gradient(180deg,#c63d2a,#a32216)",
1249
+ border: "3px double #f5d97a",
1250
+ accent: "#9c7a16",
1251
+ ruler: "#d8b338b3"
1252
+ }
1253
+ },
1254
+ plugin: {
1255
+ copper: {
1256
+ background: "linear-gradient(180deg,#b4773c,#7e3f1d 60%,#66300f)",
1257
+ accent: "#9a5f2a",
1258
+ ruler: "#c08145b3"
1259
+ },
1260
+ silver: {
1261
+ background: "linear-gradient(180deg,#d8dee3,#a7aeb4 55%,#818990)",
1262
+ accent: "#6f767c",
1263
+ ruler: "#9aa0a6b3"
1264
+ },
1265
+ gold: {
1266
+ background: "linear-gradient(180deg,#f2dc86,#c9a227 55%,#9c7d16)",
1267
+ accent: "#9c7a16",
1268
+ ruler: "#d8b338b3"
1269
+ }
1270
+ }
1271
+ };
1272
+ /** 插件档那两颗铆钉(**两处共用的小件**:印面两颗、卷轴外框四角,必须同形,故住这一层)。 */
1273
+ const SEAL_RIVET = {
1274
+ copper: {
1275
+ background: "radial-gradient(circle at 34% 28%,#f0c088,#a5652f 55%,#6a3216)",
1276
+ boxShadow: "inset 0 -1px 1px #00000055,0 1px 2px #00000088"
1277
+ },
1278
+ silver: {
1279
+ background: "radial-gradient(circle at 34% 28%,#ffffff,#c3cad0 50%,#7d848b)",
1280
+ boxShadow: "inset 0 -1px 1px #00000044,0 1px 2px #00000077"
1281
+ },
1282
+ gold: {
1283
+ background: "radial-gradient(circle at 34% 28%,#fffbe0,#e3c565 50%,#a5841d)",
1284
+ boxShadow: "inset 0 -1px 1px #00000044,0 1px 2px #00000077,0 0 6px #c9a22788"
1285
+ }
1286
+ };
1287
+ /** 档位金属边(铜/银/金):绦带(关闭钮)只借这一条,主体恒朱砂。 */
1288
+ const TIER_EDGE = {
1289
+ gold: "#f5d97a",
1290
+ silver: "#d8dee3",
1291
+ copper: "#a5652f"
1292
+ };
1293
+ /** 档位语三档金属(鎏金/冷银/暖铜):主色+渐变(`backgroundClip:text` 描出金属光泽)。 */
1294
+ const TIER_METAL = {
1295
+ gold: {
1296
+ flat: "#b8912a",
1297
+ gradient: "linear-gradient(180deg,#f6e27a 0%,#d9b53c 45%,#a5811b 100%)"
1298
+ },
1299
+ silver: {
1300
+ flat: "#8b959d",
1301
+ gradient: "linear-gradient(180deg,#f7fafc 0%,#c3ccd3 45%,#8b959d 100%)"
1302
+ },
1303
+ copper: {
1304
+ flat: "#a8663a",
1305
+ gradient: "linear-gradient(180deg,#f0bd8e 0%,#c07b45 45%,#8a4a24 100%)"
1306
+ }
1307
+ };
1308
+ //#endregion
1211
1309
  //#region ../plugin-manager/src/seal-paper-schemes.ts
1212
1310
  /** 卷轴纸面字排 + 关闭钮样子 · **定稿件**(2026-10-06 定档,原型选型期结束)。
1213
1311
  *
@@ -1240,33 +1338,15 @@ window.__ModuleLoader__.load({
1240
1338
  ...style
1241
1339
  } }, text);
1242
1340
  }
1243
- /** 档位语三档金属(鎏金/冷银/暖铜):主色+渐变(`backgroundClip:text` 描出金属光泽)。 */
1244
- const TIER_METAL = {
1245
- gold: {
1246
- flat: "#b8912a",
1247
- gradient: "linear-gradient(180deg,#f6e27a 0%,#d9b53c 45%,#a5811b 100%)"
1248
- },
1249
- silver: {
1250
- flat: "#8b959d",
1251
- gradient: "linear-gradient(180deg,#f7fafc 0%,#c3ccd3 45%,#8b959d 100%)"
1252
- },
1253
- copper: {
1254
- flat: "#a8663a",
1255
- gradient: "linear-gradient(180deg,#f0bd8e 0%,#c07b45 45%,#8a4a24 100%)"
1256
- }
1257
- };
1258
- /** 档位金属边(铜/银/金):章与绦带共用这一份取值。 */
1259
- const TIER_EDGE = {
1260
- gold: "#f5d97a",
1261
- silver: "#d8dee3",
1262
- copper: "#a5652f"
1263
- };
1341
+ /** 档位级两个色(金属边、档位语金属渐变)从九档总表引,本件不再各写一份。 */
1342
+ const edgeOf = (tierKey) => TIER_EDGE[tierKey] ?? TIER_EDGE.gold;
1343
+ const metalOf = (tierKey) => TIER_METAL[tierKey] ?? TIER_METAL.gold;
1264
1344
  const KAI = "\"Kaiti SC\",\"KaiTi\",\"STKaiti\",serif";
1265
1345
  /** 关闭钮(定稿:绦带·飘尾)。右上角一枚斜披 45° 的朱砂菱形,两条飘尾分挂两条下边,尾先画、带后画压住尾根。 */
1266
1346
  function closeLook(tierKey) {
1267
1347
  const crimson = "linear-gradient(135deg,#c63d2a 8%,#a32216 50%,#7e1a10)";
1268
1348
  /** 档位金属边(铜/银/金):绦带**只借这一条**——主体恒朱砂,边随档走,跟章「红底+金属边」同构。 */
1269
- const edge = TIER_EDGE[tierKey] ?? TIER_EDGE["gold"];
1349
+ const edge = edgeOf(tierKey);
1270
1350
  const ribbon = bgLayer({
1271
1351
  borderRadius: "0.375em",
1272
1352
  background: crimson,
@@ -1411,7 +1491,7 @@ window.__ModuleLoader__.load({
1411
1491
  }
1412
1492
  /** 档位语(一行):该档金属渐变压进字里。 */
1413
1493
  function tierNode(ctx) {
1414
- const metal = TIER_METAL[ctx.tierKey] ?? TIER_METAL["gold"];
1494
+ const metal = metalOf(ctx.tierKey);
1415
1495
  return react.createElement("div", { style: {
1416
1496
  ...ctx.styles.tier,
1417
1497
  fontFamily: KAI,
@@ -1480,106 +1560,6 @@ window.__ModuleLoader__.load({
1480
1560
  * 深色下宿主变量会把纸染黑,故这里写死定稿值;字族仍继承(定稿零字族)。 */
1481
1561
  const PAPER_BG = "#fdfaf2";
1482
1562
  const PAPER_EDGE = "#e6d9bd";
1483
- const LABEL_SUB = "#4b4335";
1484
- /** 九档材质(3 角色 × 3 档)。键就是原型里的 `role`/`tier`。 */
1485
- const MATERIALS = {
1486
- skill: {
1487
- copper: {
1488
- frame: {
1489
- background: "linear-gradient(180deg,#8a4a28,#6e3418)",
1490
- border: "3px solid #a5652f",
1491
- boxShadow: "inset 0 0 0 1px #f8f1e2aa, inset 0 2px 0 #ffffff26, inset 0 -3px 6px #0000004d"
1492
- },
1493
- accent: "#9a5f2a",
1494
- ruler: "#c08145b3"
1495
- },
1496
- silver: {
1497
- frame: {
1498
- background: "linear-gradient(180deg,#b73124,#8e1f14)",
1499
- border: "3px double #eef3f6",
1500
- boxShadow: "inset 0 0 0 1px #fff, inset 0 2px 0 #ffffff2e, inset 0 -3px 6px #0000004d"
1501
- },
1502
- accent: "#6f767c",
1503
- ruler: "#9aa0a6b3"
1504
- },
1505
- gold: {
1506
- frame: {
1507
- background: "linear-gradient(180deg,#d34a35,#a32216)",
1508
- border: "3px double #f5d97a",
1509
- boxShadow: "inset 0 0 0 1px #fff8, inset 0 2px 0 #ffffff33, inset 0 -3px 6px #0000004d"
1510
- },
1511
- accent: "#9c7a16",
1512
- ruler: "#d8b338b3"
1513
- }
1514
- },
1515
- help: {
1516
- copper: {
1517
- frame: {
1518
- background: "linear-gradient(180deg,#b06a3a,#7e3f1d)",
1519
- border: "3px solid #a5652f",
1520
- boxShadow: "inset 0 2px 0 #ffffff26, inset 0 -3px 6px #0000004d"
1521
- },
1522
- accent: "#9a5f2a",
1523
- ruler: "#c08145b3"
1524
- },
1525
- silver: {
1526
- frame: {
1527
- background: "linear-gradient(180deg,#8f979e,#5f666d)",
1528
- border: "3px double #e8eef2",
1529
- boxShadow: "inset 0 2px 0 #ffffff2e, inset 0 -3px 6px #0000004d"
1530
- },
1531
- accent: "#6f767c",
1532
- ruler: "#9aa0a6b3"
1533
- },
1534
- gold: {
1535
- frame: {
1536
- background: "linear-gradient(180deg,#c63d2a,#a32216)",
1537
- border: "3px double #f5d97a",
1538
- boxShadow: "inset 0 2px 0 #ffffff33, inset 0 -3px 6px #0000004d"
1539
- },
1540
- accent: "#9c7a16",
1541
- ruler: "#d8b338b3"
1542
- }
1543
- },
1544
- plugin: {
1545
- copper: {
1546
- frame: {
1547
- background: "linear-gradient(180deg,#b4773c,#7e3f1d 60%,#66300f)",
1548
- boxShadow: "inset 0 1px 0 #d99a5e88, inset 0 -2px 5px #0006, 0 0 0 1px #5e2c12, inset 0 2px 0 #ffffff26"
1549
- },
1550
- accent: "#9a5f2a",
1551
- ruler: "#c08145b3",
1552
- rivet: {
1553
- background: "radial-gradient(circle at 34% 28%,#f0c088,#a5652f 55%,#6a3216)",
1554
- boxShadow: "inset 0 -1px 1px #00000055,0 1px 2px #00000088"
1555
- }
1556
- },
1557
- silver: {
1558
- frame: {
1559
- background: "linear-gradient(180deg,#d8dee3,#a7aeb4 55%,#818990)",
1560
- boxShadow: "inset 0 1px 0 #ffffffdd, inset 0 -2px 5px #0005, 0 0 0 1px #6f767c, inset 0 2px 0 #ffffff33"
1561
- },
1562
- accent: "#6f767c",
1563
- ruler: "#9aa0a6b3",
1564
- rivet: {
1565
- background: "radial-gradient(circle at 34% 28%,#ffffff,#c3cad0 50%,#7d848b)",
1566
- boxShadow: "inset 0 -1px 1px #00000044,0 1px 2px #00000077"
1567
- }
1568
- },
1569
- gold: {
1570
- frame: {
1571
- background: "linear-gradient(180deg,#f2dc86,#c9a227 55%,#9c7d16)",
1572
- boxShadow: "inset 0 1px 0 #fff8d8dd, inset 0 -2px 5px #0005, 0 0 0 1px #8a6a15"
1573
- },
1574
- accent: "#9c7a16",
1575
- ruler: "#d8b338b3",
1576
- rivet: {
1577
- background: "radial-gradient(circle at 34% 28%,#fffbe0,#e3c565 50%,#a5841d)",
1578
- boxShadow: "inset 0 -1px 1px #00000044,0 1px 2px #00000077,0 0 6px #c9a22788"
1579
- }
1580
- }
1581
- }
1582
- };
1583
1563
  const S$1 = {
1584
1564
  /** 外框(`.frame`):绝对铺满,挂糙边滤镜;纸压在它上面,只露一圈。 */
1585
1565
  frame: {
@@ -1664,7 +1644,7 @@ window.__ModuleLoader__.load({
1664
1644
  fontSize: "0.84em",
1665
1645
  lineHeight: 1.9,
1666
1646
  letterSpacing: "0.02em",
1667
- color: LABEL_SUB
1647
+ color: "#4b4335"
1668
1648
  },
1669
1649
  /** 卷轴浮层:卡片内绝对定位(卡片 `S.card` 是 relative 定位祖先),上沿悬在三枚章之下、左右各留半 em——
1670
1650
  * 不是 modal:无遮罩、不锁滚动,点章切换、点「关闭」收起。 */
@@ -1702,10 +1682,39 @@ window.__ModuleLoader__.load({
1702
1682
  cursor: "pointer"
1703
1683
  }
1704
1684
  };
1685
+ /** 外框专有的内阴影(随档;底色与边线不在这张表里,从调色板来)。
1686
+ * 外框比印面大得多,同一圈金色在小章上够、在几百像素的框上会被稀释,故这一层是外框自己的排法。 */
1687
+ const FRAME_INSET = {
1688
+ skill: {
1689
+ copper: "inset 0 0 0 1px #f8f1e2aa, inset 0 2px 0 #ffffff26, inset 0 -3px 6px #0000004d",
1690
+ silver: "inset 0 0 0 1px #fff, inset 0 2px 0 #ffffff2e, inset 0 -3px 6px #0000004d",
1691
+ gold: "inset 0 0 0 1px #fff8, inset 0 2px 0 #ffffff33, inset 0 -3px 6px #0000004d"
1692
+ },
1693
+ help: {
1694
+ copper: "inset 0 2px 0 #ffffff26, inset 0 -3px 6px #0000004d",
1695
+ silver: "inset 0 2px 0 #ffffff2e, inset 0 -3px 6px #0000004d",
1696
+ gold: "inset 0 2px 0 #ffffff33, inset 0 -3px 6px #0000004d"
1697
+ },
1698
+ plugin: {
1699
+ copper: "inset 0 1px 0 #d99a5e88, inset 0 -2px 5px #0006, 0 0 0 1px #5e2c12, inset 0 2px 0 #ffffff26",
1700
+ silver: "inset 0 1px 0 #ffffffdd, inset 0 -2px 5px #0005, 0 0 0 1px #6f767c, inset 0 2px 0 #ffffff33",
1701
+ gold: "inset 0 1px 0 #fff8d8dd, inset 0 -2px 5px #0005, 0 0 0 1px #8a6a15"
1702
+ }
1703
+ };
1704
+ /** 取一档材质:底色与边线从调色板来(与印共用一份取值),外框专有的内阴影与铆钉在这里合成。 */
1705
1705
  function materialOf(role, tier) {
1706
- const found = MATERIALS[role]?.[tier];
1707
- if (!found) throw new Error("未知的印档:" + role + "/" + tier);
1708
- return found;
1706
+ const palette = SEAL_PALETTE[role]?.[tier];
1707
+ if (palette === void 0) throw new Error("未知的印档:" + role + "/" + tier);
1708
+ return {
1709
+ frame: {
1710
+ background: palette.background,
1711
+ ...palette.border === void 0 ? {} : { border: palette.border },
1712
+ boxShadow: FRAME_INSET[role][tier]
1713
+ },
1714
+ accent: palette.accent,
1715
+ ruler: palette.ruler,
1716
+ rivet: role === "plugin" ? SEAL_RIVET[tier] : void 0
1717
+ };
1709
1718
  }
1710
1719
  /** 糙边滤镜定义:两条分开(印用 edge,卷轴外框用 frame),每页只挂一次。
1711
1720
  *
@@ -1954,73 +1963,43 @@ window.__ModuleLoader__.load({
1954
1963
  color: "#f8f1e2"
1955
1964
  }
1956
1965
  };
1957
- /** 九档印面(底色加边线都照抄对应那枚印,不许简化)。 */
1958
- const FACE = {
1966
+ /** 印面专有的内圈高光与外发光(随档;底色与边线不在这张表里,从调色板来)。 */
1967
+ const FACE_EXTRA = {
1959
1968
  skill: {
1960
1969
  copper: {
1961
- background: "linear-gradient(180deg,#8a4a28,#6e3418)",
1962
1970
  color: "#f8f1e2",
1963
- border: "3px solid #a5652f",
1964
1971
  boxShadow: "inset 0 0 0 1px #f8f1e2aa"
1965
1972
  },
1966
1973
  silver: {
1967
- background: "linear-gradient(180deg,#b73124,#8e1f14)",
1968
1974
  color: "#f8f1e2",
1969
- border: "3px double #eef3f6",
1970
1975
  boxShadow: "inset 0 0 0 1px #fff"
1971
1976
  },
1972
1977
  gold: {
1973
- background: "linear-gradient(180deg,#d34a35,#a32216)",
1974
1978
  color: "#fff8e0",
1975
- border: "3px double #f5d97a",
1976
1979
  boxShadow: "inset 0 0 0 1px #fff8,0 4px 16px #c9a22755"
1977
1980
  }
1978
1981
  },
1979
1982
  help: {
1980
- copper: {
1981
- background: "linear-gradient(180deg,#b06a3a,#7e3f1d)",
1982
- border: "3px solid #a5652f"
1983
- },
1984
- silver: {
1985
- background: "linear-gradient(180deg,#8f979e,#5f666d)",
1986
- border: "3px double #e8eef2"
1987
- },
1988
- gold: {
1989
- background: "linear-gradient(180deg,#c63d2a,#a32216)",
1990
- border: "3px double #f5d97a"
1991
- }
1983
+ copper: {},
1984
+ silver: {},
1985
+ gold: {}
1992
1986
  },
1993
1987
  plugin: {
1994
- copper: { background: "linear-gradient(180deg,#b4773c,#7e3f1d 60%,#66300f)" },
1995
- silver: { background: "linear-gradient(180deg,#d8dee3,#a7aeb4 55%,#818990)" },
1996
- gold: { background: "linear-gradient(180deg,#f2dc86,#c9a227 55%,#9c7d16)" }
1988
+ copper: {},
1989
+ silver: {},
1990
+ gold: {}
1997
1991
  }
1998
1992
  };
1999
1993
  /** 插件整面金属带的描边(随档)。 */
2000
1994
  const BAND_EDGE = {
2001
- copper: { boxShadow: "inset 0 1px 0 #d99a5e88,inset 0 -2px 5px #0006,0 0 0 1px #5e2c12" },
2002
- silver: { boxShadow: "inset 0 1px 0 #ffffffdd,inset 0 -2px 5px #0005,0 0 0 1px #6f767c" },
2003
- gold: { boxShadow: "inset 0 1px 0 #fff8d8dd,inset 0 -2px 5px #0005,0 0 0 1px #8a6a15,0 3px 14px #c9a22766" }
2004
- };
2005
- /** 插件左右铆钉(随档,两颗)。 */
2006
- const RIVET = {
2007
- copper: {
2008
- background: "radial-gradient(circle at 34% 28%,#f0c088,#a5652f 55%,#6a3216)",
2009
- boxShadow: "inset 0 -1px 1px #00000055,0 1px 2px #00000088"
2010
- },
2011
- silver: {
2012
- background: "radial-gradient(circle at 34% 28%,#ffffff,#c3cad0 50%,#7d848b)",
2013
- boxShadow: "inset 0 -1px 1px #00000044,0 1px 2px #00000077"
2014
- },
2015
- gold: {
2016
- background: "radial-gradient(circle at 34% 28%,#fffbe0,#e3c565 50%,#a5841d)",
2017
- boxShadow: "inset 0 -1px 1px #00000044,0 1px 2px #00000077,0 0 6px #c9a22788"
2018
- }
1995
+ copper: "inset 0 1px 0 #d99a5e88,inset 0 -2px 5px #0006,0 0 0 1px #5e2c12",
1996
+ silver: "inset 0 1px 0 #ffffffdd,inset 0 -2px 5px #0005,0 0 0 1px #6f767c",
1997
+ gold: "inset 0 1px 0 #fff8d8dd,inset 0 -2px 5px #0005,0 0 0 1px #8a6a15,0 3px 14px #c9a22766"
2019
1998
  };
2020
1999
  /** 一枚印章(button,点章弹卷)。未知组合直接抛错,不静默退化。 */
2021
2000
  function SealStamp(props) {
2022
- const face = FACE[props.role][props.tier];
2023
- if (face === void 0) throw new Error("未知印章组合:" + String(props.role) + "/" + String(props.tier));
2001
+ const palette = SEAL_PALETTE[props.role]?.[props.tier];
2002
+ if (palette === void 0) throw new Error("未知印章组合:" + String(props.role) + "/" + String(props.tier));
2024
2003
  const style = {
2025
2004
  display: "inline-flex",
2026
2005
  alignItems: "center",
@@ -2030,7 +2009,9 @@ window.__ModuleLoader__.load({
2030
2009
  whiteSpace: "nowrap",
2031
2010
  filter: "url(#dshLifeSealRoughEdge)",
2032
2011
  ...ROLE_BASE[props.role],
2033
- ...face
2012
+ background: palette.background,
2013
+ ...palette.border === void 0 ? {} : { border: palette.border },
2014
+ ...FACE_EXTRA[props.role][props.tier]
2034
2015
  };
2035
2016
  const tierName = props.tier === "copper" ? "铜" : props.tier === "silver" ? "银" : "金";
2036
2017
  const buttonProps = {
@@ -2051,7 +2032,8 @@ window.__ModuleLoader__.load({
2051
2032
  right: "-1px",
2052
2033
  zIndex: 1,
2053
2034
  borderRadius: "4px",
2054
- ...BAND_EDGE[props.tier]
2035
+ boxShadow: BAND_EDGE[props.tier],
2036
+ background: palette.background
2055
2037
  };
2056
2038
  const rivet = {
2057
2039
  position: "absolute",
@@ -2061,13 +2043,10 @@ window.__ModuleLoader__.load({
2061
2043
  borderRadius: "50%",
2062
2044
  top: "50%",
2063
2045
  transform: "translateY(-50%)",
2064
- ...RIVET[props.tier]
2046
+ ...SEAL_RIVET[props.tier]
2065
2047
  };
2066
2048
  return react.createElement("button", buttonProps, react.createElement("span", {
2067
- style: {
2068
- ...band,
2069
- background: face.background
2070
- },
2049
+ style: band,
2071
2050
  "data-seal-band": "1"
2072
2051
  }), react.createElement("span", {
2073
2052
  style: {
@@ -2754,37 +2733,56 @@ window.__ModuleLoader__.load({
2754
2733
  const product = title ?? "";
2755
2734
  const seals = props.seals ?? [];
2756
2735
  const seed = props.sealSeed ?? 0;
2757
- /** 三行定序(六家一致:HELP 上/技能中/插件下;HELP 永远 z 最上)。 */
2736
+ /** 三行定序:**由面板按角色定**(HELP 上/技能中/插件下;HELP 永远 z 最上)。
2737
+ * 调用方给的数组顺序无关紧要,缺哪一枚就只画剩下的(位置顺次上移)——
2738
+ * 少给一枚不该把整块面板炸掉(旧写法按位置取 `seals[2]`,两枚时直接 TypeError)。 */
2758
2739
  const order = [
2759
- 0,
2760
- 1,
2761
- 2
2762
- ];
2763
- /** 三行行高(上/中/下;纵向净空各留约 10px,糙边抖动也碰不到)。 */
2764
- const TOPS = [
2765
- "0.3em",
2766
- "3.4em",
2767
- "6.2em"
2768
- ];
2769
- /** 轻微倾角(±0.5°~±2.5°,方向随机):家下标×槽位哈希,纯函数、每次同值,不过大。 */
2770
- const tiltOfSlot = (slot) => {
2740
+ "help",
2741
+ "skill",
2742
+ "plugin"
2743
+ ].map((role) => seals.findIndex((s) => s.role === role)).filter((index) => index >= 0);
2744
+ /** 三行槽位几何 · **唯一出处**:章的落位与卷轴浮层的锚点都从这里取,免得两处各写一套数字。
2745
+ * 行高(上/中/下;纵向净空各留约 10px,糙边抖动也碰不到)/轻微倾角(±0.5°~±2.5°,家下标×槽位哈希,
2746
+ * 纯函数每次同值)/右间距(三枚全部居右收敛,各家各行 0.2em~1.1em 错开,永不出面板右边界)。
2747
+ * `dialog` 是卷轴浮层那一份:贴该行下方 1.9em(章高约 1.5em + 0.4em 缝),右缘与那枚章对齐,
2748
+ * 再往左让 1.25em 给绦带(关闭钮骑在浮层右上方,不让它越出卡片)。 */
2749
+ const slotGeom = (slot, seed) => {
2750
+ const top = [
2751
+ "0.3em",
2752
+ "3.4em",
2753
+ "6.2em"
2754
+ ][slot] ?? "0.3em";
2771
2755
  const q = (seed * 5 + slot * 11 + 3) % 10;
2772
- return String((q % 2 === 0 ? -1 : 1) * (.5 + Math.floor(q / 2) * .5));
2756
+ const tilt = String((q % 2 === 0 ? -1 : 1) * (.5 + Math.floor(q / 2) * .5));
2757
+ const padRight = String(.2 + (seed * 7 + slot * 3 + 1) % 6 * .18) + "em";
2758
+ return {
2759
+ top,
2760
+ tilt,
2761
+ padRight,
2762
+ dialog: {
2763
+ top: "calc(" + top + " + 1.9em)",
2764
+ right: "calc(" + padRight + " + 1.25em)",
2765
+ left: "auto",
2766
+ justifyContent: "flex-end",
2767
+ maxWidth: "calc(100% - " + padRight + " - 1.75em)"
2768
+ }
2769
+ };
2773
2770
  };
2774
- /** 右间距(三枚全部居右收敛,各家各行 0.2em~1.1em 错开,永不出面板右边界)。 */
2775
- const padRightOfSlot = (slot) => String(.2 + (seed * 7 + slot * 3 + 1) % 6 * .18) + "em";
2776
2771
  const zOfRole = (role) => role === "help" ? 4 : role === "skill" ? 3 : 2;
2777
2772
  const overlay = seals.length === 0 ? null : react.createElement("div", { style: S.sealOverlay }, react.createElement(SealFilterDefs, {}), ...order.map((dataIndex, slot) => react.createElement("span", {
2778
2773
  key: seals[dataIndex].role + ":" + seals[dataIndex].tier,
2779
- style: {
2780
- position: "absolute",
2781
- top: TOPS[slot],
2782
- right: padRightOfSlot(slot),
2783
- zIndex: zOfRole(seals[dataIndex].role),
2784
- pointerEvents: "auto",
2785
- display: "inline-flex",
2786
- transform: "rotate(" + tiltOfSlot(slot) + "deg)"
2787
- }
2774
+ style: (() => {
2775
+ const g = slotGeom(slot, seed);
2776
+ return {
2777
+ position: "absolute",
2778
+ top: g.top,
2779
+ right: g.padRight,
2780
+ zIndex: zOfRole(seals[dataIndex].role),
2781
+ pointerEvents: "auto",
2782
+ display: "inline-flex",
2783
+ transform: "rotate(" + g.tilt + "deg)"
2784
+ };
2785
+ })()
2788
2786
  }, react.createElement("span", { style: {
2789
2787
  fontSize: "0.8em",
2790
2788
  display: "inline-flex"
@@ -2795,16 +2793,9 @@ window.__ModuleLoader__.load({
2795
2793
  onSelect: props.onSealSelect === void 0 ? void 0 : props.onSealSelect.bind(null, dataIndex)
2796
2794
  })))));
2797
2795
  const openSeal = props.selectedSeal === null || props.selectedSeal === void 0 ? null : seals[props.selectedSeal] ?? null;
2798
- /** 卷轴浮层跟着**被点的那枚章**:贴在该行下方一小段(1.9em = 章高约 1.5em + 0.4em 缝),
2799
- * 右缘与那枚章的右缘对齐,再往左让 1.25em 给绦带(关闭钮骑在浮层右上方,不让它越出卡片)。 */
2800
- const openSlot = props.selectedSeal ?? -1;
2801
- const anchor = openSlot < 0 || openSlot >= order.length ? void 0 : {
2802
- top: "calc(" + TOPS[openSlot] + " + 1.9em)",
2803
- right: "calc(" + padRightOfSlot(openSlot) + " + 1.25em)",
2804
- left: "auto",
2805
- justifyContent: "flex-end",
2806
- maxWidth: "calc(100% - " + padRightOfSlot(openSlot) + " - 1.75em)"
2807
- };
2796
+ /** 卷轴浮层跟着**被点的那枚章**:锚点与章的落位同出一处(`slotGeom`),两处不会各自漂。 */
2797
+ const openSlot = props.selectedSeal === null || props.selectedSeal === void 0 ? -1 : order.indexOf(props.selectedSeal);
2798
+ const anchor = openSlot < 0 ? void 0 : slotGeom(openSlot, seed).dialog;
2808
2799
  const dialog = openSeal === null ? null : react.createElement(SealScrollDialog, {
2809
2800
  open: true,
2810
2801
  onClose: props.onSealClose ?? (() => void 0),