dsh-dock 0.6.0 → 0.7.1

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/client.js CHANGED
@@ -195,12 +195,6 @@ function fmtCompact(n) {
195
195
  if (n >= 1e3) return (n / 1e3).toFixed(1) + "K";
196
196
  return String(Math.round(n));
197
197
  }
198
- function fmtCost(n) {
199
- const v = Number(n) || 0;
200
- if (v >= 10) return "$" + v.toFixed(2);
201
- if (v >= 0.01) return "$" + v.toFixed(4);
202
- return "$" + v.toFixed(6);
203
- }
204
198
  function fmtCostCny(usd, rate) {
205
199
  const v = (Number(usd) || 0) * (Number(rate) > 0 ? Number(rate) : 7.2);
206
200
  if (v >= 1e4) return "\xA5" + (v / 1e4).toFixed(2) + "\u4E07";
@@ -323,7 +317,7 @@ function Detail({ rec, onClose, rate }) {
323
317
  ["\u8BA1\u8D39\u8F93\u5165", fmtNum(rec.billedInput)],
324
318
  ["\u7F13\u5B58\u547D\u4E2D\u7387", rec.cacheHitPercent + "%"],
325
319
  ["\u603B Token", fmtNum(rec.totalTokens)],
326
- ["\u6D88\u8017\u91D1\u989D(\u4F30\u7B97)", fmtCost(rec.cost) + " \u2248 " + fmtCostCny(rec.cost, rateCny)],
320
+ ["\u6D88\u8017\u91D1\u989D(\u4F30\u7B97)", fmtCostCny(rec.cost, rateCny)],
327
321
  ["\u63A8\u7406\u5F3A\u5EA6", rec.effort || "\u2014"],
328
322
  ["\u8017\u65F6", fmtDuration(rec.llmMs)],
329
323
  ["Turn / Step", rec.turn + " / " + rec.step]
@@ -489,8 +483,7 @@ function TokenLogView(props) {
489
483
  { v: fmtCompact(totals.cacheReadTokens), l: "\u7F13\u5B58\u547D\u4E2D" },
490
484
  { v: totals.cacheHitPct + "%", l: "\u7F13\u5B58\u547D\u4E2D\u7387" },
491
485
  { v: fmtCompact(totals.outputTokens), l: "\u8F93\u51FA" },
492
- { v: fmtCost(totals.cost), l: "\u6D88\u8017\u91D1\u989D(\u4F30\u7B97)" },
493
- { v: fmtCostCny(totals.cost, rateCny), l: "\u6D88\u8017\u91D1\u989D(\xA5)" },
486
+ { v: fmtCostCny(totals.cost, rateCny), l: "\u6D88\u8017\u91D1\u989D(\u4F30\u7B97\xB7\u4EBA\u6C11\u5E01)" },
494
487
  { v: fmtDuration(totals.llmMs), l: "\u7D2F\u8BA1\u8017\u65F6" + (totals.timed ? " (" + totals.timed + "\u6B65)" : "") }
495
488
  ] : [];
496
489
  const opts = (arr) => (arr || []).map((x) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: x, children: x || "(\u7A7A)" }, x || "(none)"));
@@ -503,7 +496,6 @@ function TokenLogView(props) {
503
496
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: r.cacheHitPct + "%" }),
504
497
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtCompact(r.outputTokens) }),
505
498
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtCompact(r.totalTokens) }),
506
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtCost(r.cost) }),
507
499
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtCostCny(r.cost, rateCny) }),
508
500
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtDuration(r.llmMs) })
509
501
  ] }, r.key));
@@ -527,7 +519,6 @@ function TokenLogView(props) {
527
519
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtNum(r.outputTokens) }),
528
520
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtNum(r.reasoningTokens) }),
529
521
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtNum(r.totalTokens) }),
530
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtCost(r.cost) }),
531
522
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: fmtCostCny(r.cost, rateCny) }),
532
523
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: r.effort || "\u2014" }),
533
524
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
@@ -565,8 +556,7 @@ function TokenLogView(props) {
565
556
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u547D\u4E2D\u7387" }),
566
557
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u51FA" }),
567
558
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u603BToken" }),
568
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u91D1\u989D" }),
569
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u91D1\u989D(\xA5)" }),
559
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u91D1\u989D\uFF08\u4EBA\u6C11\u5E01\uFF09" }),
570
560
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8017\u65F6" })
571
561
  ] }) }),
572
562
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: summaryRows })
@@ -610,8 +600,7 @@ function TokenLogView(props) {
610
600
  sortTh("\u8F93\u51FA", "outputTokens"),
611
601
  sortTh("\u63A8\u7406", "reasoningTokens"),
612
602
  sortTh("\u603B\u989D", "totalTokens"),
613
- sortTh("\u91D1\u989D", "cost"),
614
- sortTh("\u91D1\u989D(\xA5)", "cost"),
603
+ sortTh("\u91D1\u989D\uFF08\u4EBA\u6C11\u5E01\uFF09", "cost"),
615
604
  sortTh("\u5F3A\u5EA6", "effort"),
616
605
  sortTh("\u72B6\u6001", "status"),
617
606
  sortTh("\u8017\u65F6", "llmMs")
@@ -696,22 +685,19 @@ function TokenLogHomeStat() {
696
685
  " \u6B21\u8C03\u7528 \xB7 ",
697
686
  fmtCompact(t.totalTokens),
698
687
  " Token \xB7 ",
699
- fmtCost(t.cost),
700
- "\uFF08",
701
- fmtCostCny(t.cost, snap.rate),
702
- "\uFF09"
688
+ fmtCostCny(t.cost, snap.rate)
703
689
  ] });
704
690
  }
705
691
  function TokenLogChip(props) {
706
692
  const sid = props && props.sessionId || props && props.session && props.session.sessionId || null;
707
- const [snap, setSnap] = (0, import_react2.useState)({ totals: null, err: "" });
693
+ const [snap, setSnap] = (0, import_react2.useState)({ totals: null, rate: 7.2, err: "" });
708
694
  (0, import_react2.useEffect)(() => {
709
695
  if (!sid) return;
710
696
  let cancel = false;
711
697
  const load = () => rpcCall("query", { sessionId: sid }).then((d) => {
712
- if (!cancel) setSnap({ totals: d && d.totals, err: "" });
698
+ if (!cancel) setSnap({ totals: d && d.totals, rate: d && d.rateUsdCny || 7.2, err: "" });
713
699
  }).catch((e) => {
714
- if (!cancel) setSnap((s) => ({ totals: s.totals, err: String(e && e.message || e) }));
700
+ if (!cancel) setSnap((s) => ({ totals: s.totals, rate: s.rate, err: String(e && e.message || e) }));
715
701
  });
716
702
  load();
717
703
  const timer = setInterval(load, 1e4);
@@ -722,8 +708,8 @@ function TokenLogChip(props) {
722
708
  }, [sid]);
723
709
  if (!sid) return null;
724
710
  const t = snap.totals;
725
- const label = snap.err && !t ? snap.err.includes("\u91CD\u542F") ? "\u7528\u91CF\xB7\u9700\u91CD\u542F\u5BBF\u4E3B" : "\u7528\u91CF\xB7\u5931\u8D25" : t ? "\u26C1 " + fmtCompact(t.totalTokens) + (t.cost > 0 ? " \xB7 $" + t.cost.toFixed(2) : "") : "\u26C1 \u2026";
726
- const title = t ? "\u672C\u4F1A\u8BDD " + fmtNum(t.calls) + " \u6B21\u8C03\u7528 \xB7 " + fmtNum(t.totalTokens) + " Token \xB7 " + fmtCost(t.cost) + "\uFF08\u4F30\u7B97\uFF09\n\u70B9\u51FB\u5728\u529F\u80FD\u575E\u67E5\u770B\u7528\u91CF\u8BB0\u5F55" : (snap.err ? snap.err + "\n" : "") + "\u70B9\u51FB\u5728\u529F\u80FD\u575E\u67E5\u770B\u7528\u91CF\u8BB0\u5F55";
711
+ const label = snap.err && !t ? snap.err.includes("\u91CD\u542F") ? "\u7528\u91CF\xB7\u9700\u91CD\u542F\u5BBF\u4E3B" : "\u7528\u91CF\xB7\u5931\u8D25" : t ? "\u26C1 " + fmtCompact(t.totalTokens) + (t.cost > 0 ? " \xB7 " + fmtCostCny(t.cost, snap.rate) : "") : "\u26C1 \u2026";
712
+ const title = t ? "\u672C\u4F1A\u8BDD " + fmtNum(t.calls) + " \u6B21\u8C03\u7528 \xB7 " + fmtNum(t.totalTokens) + " Token \xB7 " + fmtCostCny(t.cost, snap.rate) + "\uFF08\u4F30\u7B97\uFF09\n\u70B9\u51FB\u5728\u529F\u80FD\u575E\u67E5\u770B\u7528\u91CF\u8BB0\u5F55" : (snap.err ? snap.err + "\n" : "") + "\u70B9\u51FB\u5728\u529F\u80FD\u575E\u67E5\u770B\u7528\u91CF\u8BB0\u5F55";
727
713
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
728
714
  "button",
729
715
  {
@@ -1397,6 +1383,7 @@ var CURATED_ACCENTS = {
1397
1383
  var C_GRANTED = "#22d3ee";
1398
1384
  var C_TOPUP = "#fbbf24";
1399
1385
  var C_ERR = "#f87171";
1386
+ var USD_CNY_RATE = 7.2;
1400
1387
  function accentOf(id) {
1401
1388
  if (CURATED_ACCENTS[id]) return CURATED_ACCENTS[id];
1402
1389
  let h = 0;
@@ -1405,6 +1392,22 @@ function accentOf(id) {
1405
1392
  return ACCENT_PALETTE[h % ACCENT_PALETTE.length];
1406
1393
  }
1407
1394
  var fmt = (v) => v == null || v === "" ? "\u2014" : String(v);
1395
+ function cnyBalanceInfo(info) {
1396
+ if (!info) return info;
1397
+ if (info.currency === "CNY") return Object.assign({}, info, { currency: "\u4EBA\u6C11\u5E01" });
1398
+ if (info.currency !== "USD") return info;
1399
+ const convert = (value) => {
1400
+ if (value == null) return value;
1401
+ const n = Number(value);
1402
+ return Number.isFinite(n) ? n * USD_CNY_RATE : value;
1403
+ };
1404
+ return Object.assign({}, info, {
1405
+ currency: "\u4EBA\u6C11\u5E01\uFF08\u4F30\u7B97\uFF09",
1406
+ totalBalance: convert(info.totalBalance),
1407
+ grantedBalance: convert(info.grantedBalance),
1408
+ toppedUpBalance: convert(info.toppedUpBalance)
1409
+ });
1410
+ }
1408
1411
  var balanceStore = {
1409
1412
  snap: { data: null, loading: false, error: null },
1410
1413
  listeners: /* @__PURE__ */ new Set(),
@@ -1520,18 +1523,21 @@ function BalanceView(props) {
1520
1523
  balBody = import_react7.default.createElement(
1521
1524
  "div",
1522
1525
  { className: "dkb-mains" },
1523
- infos.map((i, idx) => import_react7.default.createElement(
1524
- "div",
1525
- { key: idx, className: "dkb-main" },
1526
- import_react7.default.createElement("span", { className: "dkb-main-label", style: { color: accent } }, i.currency),
1527
- import_react7.default.createElement("span", { className: "dkb-main-value" }, fmt(i.totalBalance)),
1528
- import_react7.default.createElement(
1529
- "span",
1530
- { className: "dkb-main-parts" },
1531
- i.grantedBalance != null ? import_react7.default.createElement("span", { className: "dkb-main-part", style: { color: C_GRANTED } }, "\u8D60\u9001 " + fmt(i.grantedBalance)) : null,
1532
- i.toppedUpBalance != null ? import_react7.default.createElement("span", { className: "dkb-main-part", style: { color: C_TOPUP } }, "\u5145\u503C " + fmt(i.toppedUpBalance)) : null
1533
- )
1534
- ))
1526
+ infos.map((rawInfo, idx) => {
1527
+ const i = cnyBalanceInfo(rawInfo);
1528
+ return import_react7.default.createElement(
1529
+ "div",
1530
+ { key: idx, className: "dkb-main" },
1531
+ import_react7.default.createElement("span", { className: "dkb-main-label", style: { color: accent } }, i.currency),
1532
+ import_react7.default.createElement("span", { className: "dkb-main-value" }, fmt(i.totalBalance)),
1533
+ import_react7.default.createElement(
1534
+ "span",
1535
+ { className: "dkb-main-parts" },
1536
+ i.grantedBalance != null ? import_react7.default.createElement("span", { className: "dkb-main-part", style: { color: C_GRANTED } }, "\u8D60\u9001 " + fmt(i.grantedBalance)) : null,
1537
+ i.toppedUpBalance != null ? import_react7.default.createElement("span", { className: "dkb-main-part", style: { color: C_TOPUP } }, "\u5145\u503C " + fmt(i.toppedUpBalance)) : null
1538
+ )
1539
+ );
1540
+ })
1535
1541
  );
1536
1542
  } else if (b && b.status === "login-required" && b.consoleUrl) {
1537
1543
  balBody = import_react7.default.createElement(
@@ -1649,9 +1655,9 @@ function chipBalanceText(p) {
1649
1655
  const s2 = Number.isFinite(v2) ? v2 >= 1e4 ? (v2 / 1e4).toFixed(1) + "\u4E07" : String(Math.round(v2)) : fmt(b.remaining);
1650
1656
  return "\u4F59\u989D \u5269 " + s2 + (b.unit ? " " + b.unit : "");
1651
1657
  }
1652
- const info = Array.isArray(b.infos) && b.infos[0] ? b.infos[0] : null;
1658
+ const info = cnyBalanceInfo(Array.isArray(b.infos) && b.infos[0] ? b.infos[0] : null);
1653
1659
  if (!info) return "\u4F59\u989D \u2026";
1654
- const cur = info.currency === "USD" ? "$" : "\xA5";
1660
+ const cur = info.currency === "CNY" || info.currency === "\u4EBA\u6C11\u5E01\uFF08\u4F30\u7B97\uFF09" ? "\xA5" : "";
1655
1661
  const v = Number(info.totalBalance);
1656
1662
  const s = Number.isFinite(v) ? v >= 1e4 ? (v / 1e4).toFixed(2) + "\u4E07" : String(Math.round(v * 100) / 100) : fmt(info.totalBalance);
1657
1663
  return "\u4F59\u989D " + cur + s;
@@ -1763,8 +1769,20 @@ var EFFECT_MODES = [
1763
1769
  { id: "robot", name: "\u684C\u9762\u4F19\u4F34", desc: "\u771F\u4EBA\u5316\u53CC\u5DE5\u4F4D\uFF1A\u67E5\u8D44\u6599\u770B\u5DE6\u5C4F\u3001\u5199\u5165/\u6539\u4EE3\u7801\u79FB\u5230\u53F3\u5C4F\uFF1B\u5EA7\u6905\u548C\u8F6C\u5934\u968F\u5B9E\u65F6\u4EFB\u52A1\u8282\u594F\u52A0\u901F" },
1764
1770
  { id: "matrix", name: "\u4EE3\u7801\u96E8", desc: "\u5B57\u7B26\u6CBF\u5C4F\u5E55\u7F13\u843D\u5982\u6570\u636E\u6D41\uFF0C\u901F\u5EA6\u968F\u4EFB\u52A1\u541E\u5410\uFF0C\u514B\u5236\u7684\u4F4E\u900F\u660E\u5EA6" },
1765
1771
  { id: "stars", name: "\u661F\u91CE", desc: "\u7EC6\u788E\u661F\u70B9\u7F13\u6162\u98D8\u79FB\u95EA\u70C1\uFF0C\u5B89\u9759\u8010\u770B\u7684\u80CC\u666F\u6C1B\u56F4" },
1766
- { id: "aurora", name: "\u6781\u5149", desc: "\u5C4F\u5E55\u9876\u90E8\u67D4\u5149\u5E26\u7F13\u6162\u547C\u5438\u6D41\u52A8\uFF0C\u50CF\u6781\u5149\u62C2\u8FC7" }
1772
+ { id: "aurora", name: "\u6781\u5149", desc: "\u5C4F\u5E55\u9876\u90E8\u67D4\u5149\u5E26\u7F13\u6162\u547C\u5438\u6D41\u52A8\uFF0C\u50CF\u6781\u5149\u62C2\u8FC7" },
1773
+ { id: "space", name: "\u661F\u9645\u8FDC\u5F81", desc: "\u4EFB\u52A1\u4E2D\u661F\u7403\u4E0E\u98DE\u8239\u5DE1\u822A\uFF1B\u5B8C\u6210\u540E\u8D27\u8FD0\u65D7\u8230\u643A\u5B9E\u9645\u8F93\u51FA\u91CF\u505C\u9760\u8F93\u5165\u6846" },
1774
+ { id: "nebula", name: "\u661F\u4E91\u6F6E\u6C50", desc: "\u56DB\u56E2\u5F69\u8272\u661F\u4E91\u5728\u5C4F\u5E55\u8FB9\u7F18\u7F13\u6162\u6F6E\u6C50\uFF0C\u9636\u6BB5\u8272\u968F\u4EFB\u52A1\u6539\u53D8" },
1775
+ { id: "warp", name: "\u66F2\u901F\u822A\u9053", desc: "\u5149\u675F\u4ECE\u5C4F\u5E55\u4E2D\u5FC3\u5411\u5916\u62C9\u4F38\uFF0C\u541E\u5410\u8D8A\u9AD8\u66F2\u901F\u8D8A\u5FEB" },
1776
+ { id: "radar", name: "\u91CF\u5B50\u96F7\u8FBE", desc: "\u4E09\u5EA7\u8FB9\u7F18\u96F7\u8FBE\u6301\u7EED\u626B\u63CF\uFF0C\u4EFB\u52A1\u6D3B\u52A8\u5316\u4F5C\u8DF3\u52A8\u4FE1\u6807" },
1777
+ { id: "constellation", name: "\u661F\u5EA7\u7F51\u7EDC", desc: "\u8282\u70B9\u4E0E\u8FDE\u7EBF\u9010\u6BB5\u70B9\u4EAE\uFF0C\u50CF\u4EFB\u52A1\u77E5\u8BC6\u56FE\u8C31\u5728\u751F\u957F" },
1778
+ { id: "fireflies", name: "\u6570\u636E\u8424\u706B", desc: "\u8F7B\u76C8\u5149\u70B9\u5728\u7A7A\u767D\u533A\u6E38\u5F0B\uFF0C\u6D3B\u8DC3\u9636\u6BB5\u4F1A\u66F4\u660E\u4EAE" },
1779
+ { id: "ocean", name: "\u6DF1\u6D77\u8109\u52A8", desc: "\u4F4E\u900F\u660E\u5EA6\u6CE2\u5C42\u4E0E\u6C14\u6CE1\u7F13\u6162\u4E0A\u6D6E\uFF0C\u5B89\u9759\u4F46\u5BCC\u6709\u751F\u547D\u611F" },
1780
+ { id: "prism", name: "\u68F1\u955C\u5149\u8C31", desc: "\u5F69\u8272\u5149\u675F\u4ECE\u5C4F\u5E55\u8FB9\u7F18\u6298\u5C04\u7A7F\u884C\uFF0C\u5F62\u6210\u514B\u5236\u7684\u73BB\u7483\u5149\u611F" },
1781
+ { id: "circuit", name: "\u795E\u7ECF\u7535\u8DEF", desc: "\u7535\u8DEF\u8DEF\u5F84\u4F9D\u6B21\u901A\u7535\uFF0C\u8109\u51B2\u901F\u5EA6\u8DDF\u968F\u4EE3\u7801\u4E0E\u5DE5\u5177\u6D3B\u52A8" },
1782
+ { id: "gravity", name: "\u5F15\u529B\u6D9F\u6F2A", desc: "\u591A\u4E2A\u5F15\u529B\u6E90\u5411\u5916\u6269\u6563\u6CE2\u7EB9\uFF0C\u4EFB\u52A1\u8D8A\u5FEB\u6D9F\u6F2A\u8D8A\u7D27\u5BC6" },
1783
+ { id: "lantern", name: "\u7075\u611F\u5929\u706F", desc: "\u5FAE\u578B\u7075\u611F\u706F\u4ECE\u5C4F\u5E55\u5E95\u90E8\u7F13\u6162\u5347\u8D77\uFF0C\u7559\u4E0B\u6E29\u6696\u5149\u8FF9" }
1767
1784
  ];
1785
+ var AMBIENT_EFFECT_MODES = /* @__PURE__ */ new Set(["matrix", "stars", "aurora", "space", "nebula", "warp", "radar", "constellation", "fireflies", "ocean", "prism", "circuit", "gravity", "lantern"]);
1768
1786
  var PHASE_LABELS = { think: "\u601D\u8003\u4E2D", write: "\u8F93\u51FA\u4E2D", code: "\u7F16\u5199\u4EE3\u7801", search: "\u67E5\u8D44\u6599" };
1769
1787
  function phaseLabel(p) {
1770
1788
  return PHASE_LABELS[p] || "\u5DE5\u4F5C\u4E2D";
@@ -2102,29 +2120,69 @@ var MATRIX_CHARS = "01</>;{}=+*#";
2102
2120
  function AmbientLayer(props) {
2103
2121
  const mode = props.mode;
2104
2122
  const speed = props.speed;
2105
- const matrix = (0, import_react8.useMemo)(() => makeBits(34, () => ({
2106
- l: Math.random() * 100,
2107
- d: 4 + Math.random() * 6,
2108
- delay: -Math.random() * 8,
2109
- o: 0.28 + Math.random() * 0.34,
2110
- s: 11 + Math.round(Math.random() * 4),
2111
- c: MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)] + MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)] + MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)]
2112
- })), []);
2113
- const stars = (0, import_react8.useMemo)(() => makeBits(80, () => ({
2114
- l: Math.random() * 100,
2115
- t: Math.random() * 100,
2116
- sz: 1.5 + Math.random() * 2,
2117
- d: 2 + Math.random() * 4,
2118
- delay: -Math.random() * 6,
2119
- dx: (Math.random() - 0.5) * 40,
2120
- dy: (Math.random() - 0.5) * 24
2121
- })), []);
2123
+ const particles = (0, import_react8.useMemo)(() => {
2124
+ if (mode === "matrix") return { matrix: makeBits(34, () => ({
2125
+ l: Math.random() * 100,
2126
+ d: 4 + Math.random() * 6,
2127
+ delay: -Math.random() * 8,
2128
+ o: 0.28 + Math.random() * 0.34,
2129
+ s: 11 + Math.round(Math.random() * 4),
2130
+ c: MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)] + MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)] + MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)]
2131
+ })) };
2132
+ if (mode === "stars") return { stars: makeBits(80, () => ({
2133
+ l: Math.random() * 100,
2134
+ t: Math.random() * 100,
2135
+ sz: 1.5 + Math.random() * 2,
2136
+ d: 2 + Math.random() * 4,
2137
+ delay: -Math.random() * 6,
2138
+ dx: (Math.random() - 0.5) * 40,
2139
+ dy: (Math.random() - 0.5) * 24
2140
+ })) };
2141
+ if (mode === "space") return { dust: makeBits(22, () => ({
2142
+ l: Math.random() * 100,
2143
+ t: Math.random() * 82,
2144
+ sz: 1 + Math.random() * 2.2,
2145
+ d: 2.4 + Math.random() * 3.8,
2146
+ delay: -Math.random() * 6
2147
+ })) };
2148
+ if (mode === "warp") return { warp: makeBits(28, () => ({
2149
+ a: Math.random() * 360,
2150
+ len: 54 + Math.random() * 130,
2151
+ d: 1.8 + Math.random() * 2.4,
2152
+ delay: -Math.random() * 4
2153
+ })) };
2154
+ if (mode === "fireflies") return { fireflies: makeBits(28, () => ({
2155
+ l: 4 + Math.random() * 92,
2156
+ t: 8 + Math.random() * 78,
2157
+ sz: 3 + Math.random() * 5,
2158
+ dx: -42 + Math.random() * 84,
2159
+ dy: -32 + Math.random() * 64,
2160
+ d: 4.8 + Math.random() * 5.4,
2161
+ delay: -Math.random() * 8
2162
+ })) };
2163
+ if (mode === "ocean") return { bubbles: makeBits(18, () => ({
2164
+ l: 3 + Math.random() * 94,
2165
+ sz: 4 + Math.random() * 12,
2166
+ d: 5 + Math.random() * 6,
2167
+ delay: -Math.random() * 9,
2168
+ drift: -34 + Math.random() * 68
2169
+ })) };
2170
+ if (mode === "lantern") return { lanterns: makeBits(18, () => ({
2171
+ l: 4 + Math.random() * 92,
2172
+ sz: 8 + Math.random() * 9,
2173
+ d: 7 + Math.random() * 7,
2174
+ delay: -Math.random() * 12,
2175
+ drift: -48 + Math.random() * 96
2176
+ })) };
2177
+ return {};
2178
+ }, [mode]);
2179
+ const ambientStyle = { "--dkan-speed": speed, "--dkan-phase": phaseColor(props.phase) };
2122
2180
  if (mode === "matrix") {
2123
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-matrix", style: { "--dkan-speed": speed }, "aria-hidden": "true", children: matrix.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { left: p.l + "%", animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s", opacity: p.o, fontSize: p.s }, children: p.c }, i)) });
2181
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-matrix", style: { "--dkan-speed": speed }, "aria-hidden": "true", children: particles.matrix.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { left: p.l + "%", animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s", opacity: p.o, fontSize: p.s }, children: p.c }, i)) });
2124
2182
  }
2125
2183
  if (mode === "stars") {
2126
2184
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-amb dkan-stars", style: { "--dkan-speed": speed }, "aria-hidden": "true", children: [
2127
- stars.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-star", style: { left: p.l + "%", top: p.t + "%", width: p.sz, height: p.sz, animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s", "--dx": p.dx + "px", "--dy": p.dy + "px" } }, i)),
2185
+ particles.stars.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-star", style: { left: p.l + "%", top: p.t + "%", width: p.sz, height: p.sz, animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s", "--dx": p.dx + "px", "--dy": p.dy + "px" } }, i)),
2128
2186
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-moon" }),
2129
2187
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-meteor", style: { top: "12%", left: "72%", animationDelay: "0s" } }),
2130
2188
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-meteor", style: { top: "28%", left: "88%", animationDelay: "2.8s" } }),
@@ -2138,21 +2196,377 @@ function AmbientLayer(props) {
2138
2196
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {})
2139
2197
  ] });
2140
2198
  }
2199
+ if (mode === "nebula") {
2200
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-amb dkan-nebula", style: ambientStyle, "aria-hidden": "true", children: [
2201
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2202
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2203
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2204
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {})
2205
+ ] });
2206
+ }
2207
+ if (mode === "warp") {
2208
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-warp", style: ambientStyle, "aria-hidden": "true", children: particles.warp.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { style: { "--a": p.a + "deg", "--len": p.len + "px", animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s" } }, i)) });
2209
+ }
2210
+ if (mode === "radar") {
2211
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-radar", style: ambientStyle, "aria-hidden": "true", children: ["a", "b", "c"].map((id) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-radar-station " + id, children: [
2212
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2213
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", {})
2214
+ ] }, id)) });
2215
+ }
2216
+ if (mode === "constellation") {
2217
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-constellation", style: ambientStyle, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 100 100", preserveAspectRatio: "none", children: [
2218
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { pathLength: "1", d: "M6 68 L18 30 L31 48 L45 18 L58 42 L73 25 L91 58 L78 78 L58 42 L31 48 L18 76 L6 68" }),
2219
+ [[6, 68], [18, 30], [31, 48], [45, 18], [58, 42], [73, 25], [91, 58], [78, 78], [18, 76]].map(([cx, cy], i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx, cy, r: i % 3 === 0 ? 1.1 : 0.7, style: { animationDelay: -i * 0.24 + "s" } }, i))
2220
+ ] }) });
2221
+ }
2222
+ if (mode === "fireflies") {
2223
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-fireflies", style: ambientStyle, "aria-hidden": "true", children: particles.fireflies.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { style: { left: p.l + "%", top: p.t + "%", width: p.sz, height: p.sz, "--dx": p.dx + "px", "--dy": p.dy + "px", animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s" } }, i)) });
2224
+ }
2225
+ if (mode === "ocean") {
2226
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-amb dkan-ocean", style: ambientStyle, "aria-hidden": "true", children: [
2227
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-ocean-waves", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}, i)) }),
2228
+ particles.bubbles.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { style: { left: p.l + "%", width: p.sz, height: p.sz, "--drift": p.drift + "px", animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s" } }, i))
2229
+ ] });
2230
+ }
2231
+ if (mode === "prism") {
2232
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-prism", style: ambientStyle, "aria-hidden": "true", children: Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}, i)) });
2233
+ }
2234
+ if (mode === "circuit") {
2235
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-circuit", style: ambientStyle, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 1000 600", preserveAspectRatio: "none", children: [
2236
+ ["M0 92 H180 V210 H390 V128 H610 V260 H820 V104 H1000", "M0 486 H144 V358 H334 V470 H520 V338 H748 V448 H1000", "M82 0 V126 H264 V286 H472 V196 H694 V320 H914 V600", "M936 0 V148 H776 V278 H566 V410 H350 V548 H112 V600"].map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { pathLength: "1", d, style: { animationDelay: -i * 0.7 + "s" } }, i)),
2237
+ [[180, 210], [390, 128], [610, 260], [144, 358], [520, 338], [264, 286], [694, 320], [566, 410]].map(([cx, cy], i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx, cy, r: "5" }, i))
2238
+ ] }) });
2239
+ }
2240
+ if (mode === "gravity") {
2241
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-gravity", style: ambientStyle, "aria-hidden": "true", children: ["a", "b", "c"].map((id) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-gravity-source " + id, children: [
2242
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", {}),
2243
+ Array.from({ length: 4 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { style: { animationDelay: "calc(" + -i * 0.9 + "s / var(--dkan-speed,1))" } }, i))
2244
+ ] }, id)) });
2245
+ }
2246
+ if (mode === "lantern") {
2247
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-amb dkan-lantern", style: ambientStyle, "aria-hidden": "true", children: particles.lanterns.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { style: { left: p.l + "%", width: p.sz, height: p.sz * 1.28, "--drift": p.drift + "px", animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s" } }, i)) });
2248
+ }
2249
+ if (mode === "space") {
2250
+ const taskCount = Math.max(1, Math.min(3, Array.isArray(props.tasks) ? props.tasks.length : 1));
2251
+ const runnerCount = Math.max(6, Math.min(9, taskCount * 3));
2252
+ const galaxies = props.galaxies;
2253
+ if (!galaxies) return null;
2254
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-amb dkan-space", style: {
2255
+ "--dkan-speed": speed,
2256
+ "--dkan-space-ships": taskCount,
2257
+ "--dkan-alpha-x": galaxies.alpha.cx + "px",
2258
+ "--dkan-alpha-y": galaxies.alpha.cy + "px",
2259
+ "--dkan-beta-x": galaxies.beta.cx + "px",
2260
+ "--dkan-beta-y": galaxies.beta.cy + "px",
2261
+ "--dkan-gamma-x": galaxies.gamma.cx + "px",
2262
+ "--dkan-gamma-y": galaxies.gamma.cy + "px"
2263
+ }, "aria-hidden": "true", children: [
2264
+ particles.dust.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-space-dust", style: { left: p.l + "%", top: p.t + "%", width: p.sz, height: p.sz, animationDuration: "calc(" + p.d + "s / var(--dkan-speed,1))", animationDelay: p.delay + "s" } }, i)),
2265
+ ["alpha", "beta", "gamma"].map((galaxy) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-space-system " + galaxy, style: { left: galaxies[galaxy].x, top: galaxies[galaxy].y, "--dkan-system-scale": galaxies[galaxy].scale }, children: [
2266
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-space-sun" }),
2267
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-space-orbit a", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}) }),
2268
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-space-orbit b", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}) }),
2269
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-space-orbit c", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}) })
2270
+ ] }, galaxy)),
2271
+ Array.from({ length: runnerCount }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-space-runner route-" + i % 3, style: { "--dkan-run-delay": -i * 1.8 + "s" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 1, empty: true }) }, i))
2272
+ ] });
2273
+ }
2274
+ return null;
2275
+ }
2276
+ function outputCargo(outputTokens) {
2277
+ const tokens = Math.max(0, Number(outputTokens) || 0);
2278
+ return { tokens, units: Math.max(1, Math.min(8, Math.ceil(tokens / 900))) };
2279
+ }
2280
+ function fallbackComposerDockPoint(side = "right") {
2281
+ const vw = typeof window === "undefined" ? 1280 : window.innerWidth;
2282
+ const vh = typeof window === "undefined" ? 900 : window.innerHeight;
2283
+ return {
2284
+ // 待命位贴近输入框右上;右侧远端只保留给旧的通用停靠计算。
2285
+ x: side === "left" ? Math.max(304, Math.min(520, Math.round(vw * 0.18))) : side === "ready" ? Math.max(316, vw - 640) : Math.max(16, vw - 232),
2286
+ y: Math.max(32, vh - 218)
2287
+ };
2288
+ }
2289
+ function visibleRect(el) {
2290
+ if (!el || typeof window === "undefined") return null;
2291
+ const r = el.getBoundingClientRect();
2292
+ return r.width > 0 && r.height > 0 && r.bottom > 0 && r.top < window.innerHeight ? r : null;
2293
+ }
2294
+ var COMPOSER_SEND_SELECTOR = 'button[aria-label="Send message"],button[aria-label*="\u53D1\u9001"],button[data-testid*="send"],button[data-testid*="submit"],button[type="submit"]';
2295
+ function conversationComposer() {
2296
+ if (typeof document === "undefined" || typeof window === "undefined") return null;
2297
+ const sendButtons = document.querySelectorAll(COMPOSER_SEND_SELECTOR);
2298
+ for (const button of sendButtons) {
2299
+ let el = button.parentElement;
2300
+ for (let depth = 0; el && depth < 9; depth += 1, el = el.parentElement) {
2301
+ const r = visibleRect(el);
2302
+ if (r && r.width >= 360 && r.height >= 72 && r.height <= 360 && r.top > window.innerHeight * 0.42) return { element: el, rect: r };
2303
+ }
2304
+ }
2141
2305
  return null;
2142
2306
  }
2307
+ function conversationComposerRect() {
2308
+ const composer = conversationComposer();
2309
+ return composer ? composer.rect : null;
2310
+ }
2311
+ function composerPointFromRect(composer, side) {
2312
+ return {
2313
+ x: side === "ready" ? Math.max(composer.left + 16, composer.right - 210) : fallbackComposerDockPoint(side).x,
2314
+ y: Math.max(22, composer.top - 92)
2315
+ };
2316
+ }
2317
+ function composerDockPoint(side = "right") {
2318
+ if (typeof document === "undefined" || typeof window === "undefined") return fallbackComposerDockPoint(side);
2319
+ const composer = conversationComposerRect();
2320
+ if (composer) return composerPointFromRect(composer, side);
2321
+ const selectors = [
2322
+ '[data-testid*="composer"]',
2323
+ '[data-testid*="conversation-input"]',
2324
+ '[data-slot*="conversation.input"]',
2325
+ 'textarea[placeholder*="Message"]',
2326
+ 'textarea[placeholder*="\u6D88\u606F"]',
2327
+ "textarea",
2328
+ '[contenteditable="true"][data-testid*="composer"]',
2329
+ '[contenteditable="true"][aria-label*="\u6D88\u606F"]',
2330
+ '[contenteditable="true"][data-slot*="conversation.input"]'
2331
+ ];
2332
+ const seen = /* @__PURE__ */ new Set();
2333
+ const candidates = [];
2334
+ for (const selector of selectors) {
2335
+ for (const el of document.querySelectorAll(selector)) {
2336
+ if (seen.has(el)) continue;
2337
+ seen.add(el);
2338
+ const r2 = el.getBoundingClientRect();
2339
+ if (r2.width > 80 && r2.height > 16 && r2.bottom > window.innerHeight * 0.48) candidates.push({ el, r: r2 });
2340
+ }
2341
+ }
2342
+ const best = candidates.sort((a, b) => b.r.bottom - a.r.bottom)[0];
2343
+ if (!best) return fallbackComposerDockPoint(side);
2344
+ const r = best.r;
2345
+ const x = side === "ready" ? Math.max(r.left + 16, r.right - 210) : fallbackComposerDockPoint(side).x;
2346
+ return {
2347
+ // 纵向以真实输入控件上沿停靠,飞船底部和输入框保留间隙。
2348
+ x,
2349
+ y: Math.max(22, r.top - 92)
2350
+ };
2351
+ }
2352
+ function useSpaceDocks(enabled) {
2353
+ const [docks, setDocks] = (0, import_react8.useState)(null);
2354
+ (0, import_react8.useEffect)(() => {
2355
+ if (!enabled || typeof window === "undefined") {
2356
+ setDocks(null);
2357
+ return void 0;
2358
+ }
2359
+ let disposed = false;
2360
+ let frame = 0;
2361
+ let idle = 0;
2362
+ let timer = 0;
2363
+ let pollTimer = 0;
2364
+ let retries = 0;
2365
+ let pending = false;
2366
+ let observedComposer = null;
2367
+ let resizeObserver = null;
2368
+ const samePoint = (a, b) => !!a && !!b && Math.abs(a.x - b.x) < 1 && Math.abs(a.y - b.y) < 1;
2369
+ const bindComposerResize = (element) => {
2370
+ if (!resizeObserver || observedComposer === element) return;
2371
+ if (observedComposer) resizeObserver.unobserve(observedComposer);
2372
+ observedComposer = element;
2373
+ if (observedComposer) resizeObserver.observe(observedComposer);
2374
+ };
2375
+ const measure = () => {
2376
+ if (disposed) return;
2377
+ const found = conversationComposer();
2378
+ if (!found) {
2379
+ bindComposerResize(null);
2380
+ setDocks(null);
2381
+ if (retries++ < 20) schedule(140);
2382
+ return;
2383
+ }
2384
+ retries = 0;
2385
+ bindComposerResize(found.element);
2386
+ const composer = found.rect;
2387
+ const right = composerPointFromRect(composer, "right");
2388
+ const next = {
2389
+ right,
2390
+ left: composerPointFromRect(composer, "left"),
2391
+ ready: composerPointFromRect(composer, "ready")
2392
+ };
2393
+ setDocks((current) => current && samePoint(current.right, next.right) && samePoint(current.left, next.left) && samePoint(current.ready, next.ready) ? current : next);
2394
+ };
2395
+ function schedule(delay = 0, deferUntilIdle = false) {
2396
+ if (disposed || pending) return;
2397
+ pending = true;
2398
+ const queueFrame = () => {
2399
+ frame = window.requestAnimationFrame(() => {
2400
+ pending = false;
2401
+ measure();
2402
+ });
2403
+ };
2404
+ if (delay > 0) timer = window.setTimeout(queueFrame, delay);
2405
+ else if (deferUntilIdle && typeof window.requestIdleCallback === "function") idle = window.requestIdleCallback(queueFrame, { timeout: 350 });
2406
+ else queueFrame();
2407
+ }
2408
+ ;
2409
+ if (typeof window.ResizeObserver === "function") resizeObserver = new window.ResizeObserver(() => schedule());
2410
+ const mutationObserver = typeof window.MutationObserver === "function" ? new window.MutationObserver((mutations) => {
2411
+ const hasComposerChange = mutations.some((mutation) => Array.from(mutation.addedNodes).concat(Array.from(mutation.removedNodes)).some((node) => {
2412
+ if (!node || node.nodeType !== 1) return false;
2413
+ return node.matches && node.matches(COMPOSER_SEND_SELECTOR) || node.querySelector && node.querySelector(COMPOSER_SEND_SELECTOR);
2414
+ }));
2415
+ if (hasComposerChange) schedule(40);
2416
+ }) : null;
2417
+ if (mutationObserver && document.body) mutationObserver.observe(document.body, { childList: true, subtree: true });
2418
+ schedule(0, true);
2419
+ pollTimer = window.setInterval(() => schedule(), 700);
2420
+ const onResize = () => {
2421
+ if (idle && typeof window.cancelIdleCallback === "function") window.cancelIdleCallback(idle);
2422
+ if (timer) window.clearTimeout(timer);
2423
+ pending = false;
2424
+ schedule();
2425
+ };
2426
+ window.addEventListener("resize", onResize, { passive: true });
2427
+ return () => {
2428
+ disposed = true;
2429
+ window.cancelAnimationFrame(frame);
2430
+ if (idle && typeof window.cancelIdleCallback === "function") window.cancelIdleCallback(idle);
2431
+ if (timer) window.clearTimeout(timer);
2432
+ if (pollTimer) window.clearInterval(pollTimer);
2433
+ if (mutationObserver) mutationObserver.disconnect();
2434
+ if (resizeObserver) resizeObserver.disconnect();
2435
+ window.removeEventListener("resize", onResize);
2436
+ };
2437
+ }, [enabled]);
2438
+ return docks;
2439
+ }
2440
+ function spaceGalaxyLayout() {
2441
+ const vw = typeof window === "undefined" ? 1280 : window.innerWidth;
2442
+ const vh = typeof window === "undefined" ? 900 : window.innerHeight;
2443
+ const contentLeft = 316;
2444
+ const make = (x, y, scale) => ({ x, y, scale, cx: x + 123, cy: y + 123 });
2445
+ return {
2446
+ alpha: make(Math.max(contentLeft + 420, vw - 360), 72, 0.5),
2447
+ beta: make(contentLeft, Math.max(142, Math.min(232, vh * 0.18)), 0.48),
2448
+ gamma: make(contentLeft + 18, Math.max(420, vh - 382), 0.48)
2449
+ };
2450
+ }
2451
+ function freighterAnchorAt(point) {
2452
+ return { x: Math.round(point.x - 88), y: Math.round(point.y - 32) };
2453
+ }
2454
+ function flightAngle(from, to) {
2455
+ return Math.round(Math.atan2(to.y - from.y, to.x - from.x) * 180 / Math.PI);
2456
+ }
2457
+ function FreighterHull(props) {
2458
+ const units = Math.max(1, Number(props.units) || 1);
2459
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-freighter", children: [
2460
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("i", { className: "dkan-freighter-engine", children: [
2461
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2462
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {})
2463
+ ] }),
2464
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-freighter-wing left" }),
2465
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-freighter-wing right" }),
2466
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-freighter-fin" }),
2467
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-freighter-hull" }),
2468
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-freighter-canopy" }),
2469
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "dkan-freighter-nose" }),
2470
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-freighter-cargo" + (props.empty ? " empty" : ""), children: Array.from({ length: units }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}, i)) })
2471
+ ] });
2472
+ }
2473
+ function DeliveryFreighter(props) {
2474
+ const d = props.delivery;
2475
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-delivery", style: {
2476
+ "--dkan-from-x": d.from.x + "px",
2477
+ "--dkan-from-y": d.from.y + "px",
2478
+ "--dkan-to-x": d.to.x + "px",
2479
+ "--dkan-to-y": d.to.y + "px",
2480
+ "--dkan-delivery-duration": d.duration + "ms"
2481
+ }, "aria-hidden": "true", children: [
2482
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-delivery-trail" }),
2483
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: d.units }),
2484
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-delivery-label", children: [
2485
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", { children: "\u5F52\u822A\u8D27\u8FD0\u8230" }),
2486
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
2487
+ "\u8F93\u51FA ",
2488
+ fmtCompact2(d.tokens),
2489
+ " Tokens \xB7 ",
2490
+ d.units,
2491
+ " \u8231"
2492
+ ] })
2493
+ ] })
2494
+ ] });
2495
+ }
2496
+ function ReadyFreighter(props) {
2497
+ const dock = props.dock || fallbackComposerDockPoint("ready");
2498
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-ready-freighter", style: { left: dock.x, top: dock.y }, "aria-hidden": "true", children: [
2499
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 3, empty: true }),
2500
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u5F85\u547D \xB7 \u7B49\u5F85\u4E0B\u4E00\u6761\u4EFB\u52A1" })
2501
+ ] });
2502
+ }
2503
+ function MissionDeparture(props) {
2504
+ const d = props.departure;
2505
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-departure", style: {
2506
+ "--dkan-from-x": d.from.x + "px",
2507
+ "--dkan-from-y": d.from.y + "px",
2508
+ "--dkan-to-x": d.to.x + "px",
2509
+ "--dkan-to-y": d.to.y + "px",
2510
+ "--dkan-flight-angle": d.angle + "deg",
2511
+ "--dkan-departure-duration": d.duration + "ms"
2512
+ }, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 3, empty: true }) });
2513
+ }
2514
+ function ProgrammingStuck(props) {
2515
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-space-stuck", "aria-hidden": "true", children: [
2516
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 3, empty: true }),
2517
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-stuck-code", children: [
2518
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2519
+ `{ }`
2520
+ ] }),
2521
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u7F16\u7A0B\u7B49\u5F85\u4E2D" }),
2522
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: truncate(props.task && props.task.title || "\u5DE5\u5177\u6682\u65E0\u65B0\u54CD\u5E94", 28) })
2523
+ ] });
2524
+ }
2143
2525
  function AnimationOverlay(props) {
2144
2526
  const ctx = props && props.ctx;
2145
2527
  const snap = useAnimation();
2146
2528
  const [toasts, setToasts] = (0, import_react8.useState)([]);
2147
2529
  const [flourish, setFlourish] = (0, import_react8.useState)(null);
2148
2530
  const [bursts, setBursts] = (0, import_react8.useState)([]);
2531
+ const [deliveries, setDeliveries] = (0, import_react8.useState)([]);
2532
+ const [departures, setDepartures] = (0, import_react8.useState)([]);
2149
2533
  const prevActiveRef = (0, import_react8.useRef)(null);
2150
2534
  const burstIdRef = (0, import_react8.useRef)(0);
2535
+ const deliveryIdRef = (0, import_react8.useRef)(0);
2536
+ const departureTimersRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
2537
+ const lastImmediateDepartureRef = (0, import_react8.useRef)(0);
2538
+ (0, import_react8.useEffect)(() => () => {
2539
+ for (const timer of departureTimersRef.current.values()) clearTimeout(timer);
2540
+ departureTimersRef.current.clear();
2541
+ }, []);
2151
2542
  const pushBurst = (0, import_react8.useCallback)((type, x, y, bits) => {
2152
2543
  const id = ++burstIdRef.current;
2153
2544
  setBursts((prev) => prev.concat([{ id, type, x, y, bits }]).slice(-6));
2154
2545
  setTimeout(() => setBursts((prev) => prev.filter((b) => b.id !== id)), 2600);
2155
2546
  }, []);
2547
+ const launchMission = (0, import_react8.useCallback)(() => {
2548
+ const cfg2 = animationStore.snap.status && animationStore.snap.status.config;
2549
+ if (!cfg2 || !cfg2.animationEnabled || cfg2.effectMode !== "space") return false;
2550
+ const id = ++deliveryIdRef.current;
2551
+ const from = composerDockPoint("left");
2552
+ const targetGalaxy = spaceGalaxyLayout().alpha;
2553
+ const to = freighterAnchorAt({ x: targetGalaxy.cx, y: targetGalaxy.cy });
2554
+ const departure = {
2555
+ id,
2556
+ from,
2557
+ to,
2558
+ angle: flightAngle(from, to),
2559
+ duration: 8600
2560
+ };
2561
+ lastImmediateDepartureRef.current = Date.now();
2562
+ setDeliveries([]);
2563
+ setDepartures((prev) => prev.concat([departure]).slice(-3));
2564
+ departureTimersRef.current.set(id, setTimeout(() => {
2565
+ departureTimersRef.current.delete(id);
2566
+ setDepartures((prev) => prev.filter((item) => item.id !== id));
2567
+ }, departure.duration));
2568
+ return true;
2569
+ }, []);
2156
2570
  (0, import_react8.useEffect)(() => {
2157
2571
  if (typeof document === "undefined") return;
2158
2572
  const onClick = (e) => {
@@ -2164,6 +2578,7 @@ function AnimationOverlay(props) {
2164
2578
  const sessionItem = t.closest('[role="treeitem"]');
2165
2579
  if (sendBtn) {
2166
2580
  pushBurst("plane", e.clientX, e.clientY);
2581
+ launchMission();
2167
2582
  } else if (newSession) {
2168
2583
  pushBurst("spark", e.clientX, e.clientY, makeBits(10, () => ({
2169
2584
  dx: (Math.random() - 0.5) * 70,
@@ -2178,15 +2593,19 @@ function AnimationOverlay(props) {
2178
2593
  };
2179
2594
  document.addEventListener("click", onClick, true);
2180
2595
  return () => document.removeEventListener("click", onClick, true);
2181
- }, [pushBurst]);
2596
+ }, [pushBurst, launchMission]);
2182
2597
  const taskCountRef = (0, import_react8.useRef)(0);
2183
2598
  (0, import_react8.useEffect)(() => {
2184
2599
  const st2 = snap.status;
2185
2600
  if (!st2 || !st2.active) return;
2186
2601
  const n = st2.active.length;
2187
- if (n > taskCountRef.current) pushBurst("surge");
2602
+ if (n > taskCountRef.current) {
2603
+ pushBurst("surge");
2604
+ const cfg2 = st2.config || {};
2605
+ if (cfg2.animationEnabled && cfg2.effectMode === "space" && Date.now() - lastImmediateDepartureRef.current > 1e4) launchMission();
2606
+ }
2188
2607
  taskCountRef.current = n;
2189
- }, [snap.status, pushBurst]);
2608
+ }, [snap.status, pushBurst, launchMission]);
2190
2609
  (0, import_react8.useEffect)(() => {
2191
2610
  let stopped = false;
2192
2611
  let timer = null;
@@ -2227,6 +2646,18 @@ function AnimationOverlay(props) {
2227
2646
  const info = endInfo(reason);
2228
2647
  if (cfg2.animationEnabled) {
2229
2648
  setFlourish({ key: Date.now(), err: !success });
2649
+ if (cfg2.effectMode === "space") {
2650
+ const cargo = outputCargo(record && record.outputTokens || task.outputTokens);
2651
+ const id = ++deliveryIdRef.current;
2652
+ const taskSpeed = Math.max(0.9, Number(speed) || 1);
2653
+ const duration = Math.round(Math.max(8e3, Math.min(9400, 1e4 / Math.sqrt(taskSpeed))));
2654
+ const galaxies = spaceGalaxyLayout();
2655
+ const returnGalaxy = galaxies[["alpha", "beta", "gamma"][Math.floor(Math.random() * 3)]];
2656
+ const from = freighterAnchorAt({ x: returnGalaxy.cx, y: returnGalaxy.cy });
2657
+ const to = composerDockPoint("left");
2658
+ const delivery = Object.assign({ id, from, to, duration }, cargo);
2659
+ setDeliveries([delivery]);
2660
+ }
2230
2661
  if (success) {
2231
2662
  pushBurst("confetti", 0, 0, makeBits(18, (i) => ({
2232
2663
  l: 4 + i / 18 * 92 + Math.random() * 3,
@@ -2309,6 +2740,10 @@ function AnimationOverlay(props) {
2309
2740
  speedRef.current = { ticks, at: t };
2310
2741
  }, [snap.status]);
2311
2742
  const ambientOn = animOn && !panelOpen;
2743
+ const spaceModeOn = !!(cfg && cfg.animationEnabled && mode === "space" && !panelOpen);
2744
+ const spaceDocks = useSpaceDocks(spaceModeOn);
2745
+ const spaceGalaxies = spaceModeOn && spaceDocks ? spaceGalaxyLayout() : null;
2746
+ const stuckTask = active.find((task) => task.phase === "code" && now - (task.lastActivityAt || task.phaseAt || now) >= 18e3) || null;
2312
2747
  const robotScaleFromConfig = Math.max(0.85, Math.min(2.2, Number(cfg && cfg.robotScale) || 1.35));
2313
2748
  const speedStyle = { "--dkan-speed": Number(speed).toFixed(2) };
2314
2749
  const saveRobotScale = (0, import_react8.useCallback)((robotScale) => {
@@ -2421,7 +2856,10 @@ function AnimationOverlay(props) {
2421
2856
  if (!st) return null;
2422
2857
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2423
2858
  ambientOn && mode === "flow" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-line", style: speedStyle, "aria-hidden": "true" }) : null,
2424
- ambientOn && (mode === "matrix" || mode === "stars" || mode === "aurora") ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AmbientLayer, { mode, speed: Number(speed).toFixed(2) }) : null,
2859
+ ambientOn && AMBIENT_EFFECT_MODES.has(mode) && (mode !== "space" || spaceGalaxies) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AmbientLayer, { mode, phase, speed: Number(speed).toFixed(2), tasks: active, galaxies: spaceGalaxies }) : null,
2860
+ spaceModeOn && spaceDocks && active.length === 0 && deliveries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReadyFreighter, { dock: spaceDocks.ready }) : null,
2861
+ spaceModeOn && stuckTask ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ProgrammingStuck, { task: stuckTask }) : null,
2862
+ !panelOpen ? departures.map((departure) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MissionDeparture, { departure }, departure.id)) : null,
2425
2863
  ambientOn && mode === "orbit" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-orbit", style: speedStyle, "aria-hidden": "true" }) : null,
2426
2864
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BurstLayer, { bursts }),
2427
2865
  ambientOn && mode === "robot" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
@@ -2509,6 +2947,7 @@ function AnimationOverlay(props) {
2509
2947
  },
2510
2948
  flourish.key
2511
2949
  ) : null,
2950
+ !panelOpen ? deliveries.map((delivery) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DeliveryFreighter, { delivery }, delivery.id)) : null,
2512
2951
  toasts.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-toasts", children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Toast, { t, onClose: (id) => setToasts((prev) => prev.filter((x) => x.id !== id)) }, t.id)) }) : null
2513
2952
  ] });
2514
2953
  }
@@ -2542,12 +2981,22 @@ function ModePreview({ id }) {
2542
2981
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {})
2543
2982
  ] });
2544
2983
  }
2984
+ if (id === "space") {
2985
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-prev dkan-prev-space", children: [
2986
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2987
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("b", {}),
2988
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", {})
2989
+ ] });
2990
+ }
2545
2991
  if (id === "aurora") {
2546
2992
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-prev dkan-prev-aurora", children: [
2547
2993
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
2548
2994
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {})
2549
2995
  ] });
2550
2996
  }
2997
+ if (["nebula", "warp", "radar", "constellation", "fireflies", "ocean", "prism", "circuit", "gravity", "lantern"].includes(id)) {
2998
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-prev dkan-prev-new dkan-prev-" + id, children: Array.from({ length: id === "warp" ? 8 : 6 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}, i)) });
2999
+ }
2551
3000
  if (id === "robot") {
2552
3001
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-prev dkan-prev-bot", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RobotScene, { phase: "code" }) });
2553
3002
  }
@@ -3073,12 +3522,66 @@ var css2 = [
3073
3522
  ".dkan-meteor{position:absolute;width:110px;height:2px;border-radius:2px;background:linear-gradient(90deg,#fff,color-mix(in srgb,#8ab6ff 60%,transparent) 40%,transparent);transform:rotate(35deg);transform-origin:left center;opacity:0;animation:dkan-meteor 8.4s linear infinite;}",
3074
3523
  '.dkan-meteor::before{content:"";position:absolute;left:-2px;top:-2px;width:6px;height:6px;border-radius:50%;background:#fff;box-shadow:0 0 8px 2px color-mix(in srgb,#cfe3ff 70%,transparent);}',
3075
3524
  "@keyframes dkan-meteor{0%{opacity:0;transform:rotate(35deg) translateX(0)}3%{opacity:1}10%{opacity:0;transform:rotate(35deg) translateX(46vh)}100%{opacity:0;transform:rotate(35deg) translateX(46vh)}}",
3525
+ // 星际远征:星尘、行星轨道和任务飞船都只在任务运行时出现,统一由 --dkan-speed 加速。
3526
+ ".dkan-space{background:radial-gradient(ellipse 34% 28% at 84% 11%,color-mix(in srgb,#426aaf 15%,transparent),transparent 72%),radial-gradient(ellipse 26% 22% at 14% 58%,color-mix(in srgb,#7c4dff 10%,transparent),transparent 74%);}",
3527
+ ".dkan-space-dust{position:absolute;border-radius:50%;background:#dbeafe;box-shadow:0 0 5px color-mix(in srgb,#93c5fd 62%,transparent);opacity:.2;animation:dkan-space-dust ease-in-out infinite alternate;will-change:transform,opacity;}",
3528
+ "@keyframes dkan-space-dust{0%{opacity:.14;transform:translate3d(0,0,0) scale(.7)}55%{opacity:.78}100%{opacity:.26;transform:translate3d(22px,-8px,0) scale(1.15)}}",
3529
+ ".dkan-space-system{position:fixed;width:246px;height:246px;border-radius:50%;opacity:.78;transform:translateZ(0) scale(var(--dkan-system-scale,1));transform-origin:center;contain:layout paint style;}.dkan-space-system.alpha{opacity:.76}.dkan-space-system.beta{opacity:.68}.dkan-space-system.gamma{opacity:.64}",
3530
+ ".dkan-space-sun{position:absolute;left:50%;top:50%;width:34px;height:34px;border-radius:50%;transform:translate(-50%,-50%);background:radial-gradient(circle at 32% 28%,#fff7c2 0 9%,#ffc85a 30%,#e76f2e 74%);box-shadow:0 0 12px 4px color-mix(in srgb,#ffc85a 58%,transparent),0 0 36px 12px color-mix(in srgb,#f97316 20%,transparent);}",
3531
+ ".dkan-space-orbit{position:absolute;left:50%;top:50%;border:1px solid color-mix(in srgb,#93c5fd 28%,transparent);border-radius:50%;animation:dkan-space-orbit linear infinite;transform-origin:center;}",
3532
+ ".dkan-space-orbit i{position:absolute;top:50%;left:-5px;width:10px;height:10px;border-radius:50%;transform:translateY(-50%);box-shadow:0 0 9px 2px currentColor;}",
3533
+ ".dkan-space-orbit.a{width:82px;height:50px;margin:-25px 0 0 -41px;animation-duration:calc(5.4s / var(--dkan-speed,1));}.dkan-space-orbit.a i{color:#67e8f9;background:#22d3ee;}",
3534
+ ".dkan-space-orbit.b{width:142px;height:86px;margin:-43px 0 0 -71px;animation-duration:calc(9.2s / var(--dkan-speed,1));animation-direction:reverse;}.dkan-space-orbit.b i{width:15px;height:15px;color:#c4b5fd;background:radial-gradient(circle at 30% 28%,#ede9fe,#8b5cf6 72%);}",
3535
+ ".dkan-space-orbit.c{width:212px;height:130px;margin:-65px 0 0 -106px;animation-duration:calc(15.6s / var(--dkan-speed,1));}.dkan-space-orbit.c i{width:18px;height:18px;color:#fda4af;background:radial-gradient(circle at 32% 28%,#ffe4e6,#e11d48 74%);}",
3536
+ "@keyframes dkan-space-orbit{to{transform:rotate(360deg)}}",
3537
+ ".dkan-space-runner{position:fixed;left:0;top:0;width:108px;height:56px;opacity:0;animation-duration:calc(10.8s / var(--dkan-speed,1));animation-timing-function:linear;animation-iteration-count:infinite;animation-delay:var(--dkan-run-delay,0s);will-change:transform,opacity;contain:layout paint style;backface-visibility:hidden;}.dkan-space-runner .dkan-freighter{left:0;top:0;transform:translateZ(0) scale(.52);transform-origin:top left;filter:none}.dkan-space-runner .dkan-freighter-engine i{animation:none;opacity:.76;box-shadow:-6px 0 8px #22d3ee}.dkan-space-runner .dkan-freighter-nose{filter:none}.dkan-space-runner.route-0{animation-name:dkan-space-route-a}.dkan-space-runner.route-1{animation-name:dkan-space-route-b}.dkan-space-runner.route-2{animation-name:dkan-space-route-c}",
3538
+ "@keyframes dkan-space-route-a{0%{opacity:0;transform:translate3d(var(--dkan-alpha-x),var(--dkan-alpha-y),0) rotate(151deg)}7%,86%{opacity:.9}100%{opacity:0;transform:translate3d(var(--dkan-beta-x),var(--dkan-beta-y),0) rotate(151deg)}}@keyframes dkan-space-route-b{0%{opacity:0;transform:translate3d(var(--dkan-beta-x),var(--dkan-beta-y),0) rotate(-90deg)}7%,86%{opacity:.9}100%{opacity:0;transform:translate3d(var(--dkan-gamma-x),var(--dkan-gamma-y),0) rotate(-90deg)}}@keyframes dkan-space-route-c{0%{opacity:0;transform:translate3d(var(--dkan-gamma-x),var(--dkan-gamma-y),0) rotate(-18deg)}7%,86%{opacity:.9}100%{opacity:0;transform:translate3d(var(--dkan-alpha-x),var(--dkan-alpha-y),0) rotate(-18deg)}}",
3539
+ // 完成归航:一艘货运旗舰从航线飞到真实会话输入框上方,货舱逐格表达实际输出量。
3540
+ ".dkan-delivery{position:fixed;left:0;top:0;width:210px;height:88px;z-index:9994;pointer-events:none;will-change:transform,opacity;contain:layout paint style;isolation:isolate;animation:dkan-delivery-flight var(--dkan-delivery-duration,8600ms) cubic-bezier(.22,.61,.36,1) forwards;}",
3541
+ "@keyframes dkan-delivery-flight{0%{opacity:0;transform:translate3d(var(--dkan-from-x),var(--dkan-from-y),0) scale(.5) rotate(-12deg)}6%{opacity:1;transform:translate3d(var(--dkan-from-x),var(--dkan-from-y),0) scale(.56) rotate(-10deg)}100%{opacity:1;transform:translate3d(var(--dkan-to-x),var(--dkan-to-y),0) scale(1) rotate(0)}}",
3542
+ ".dkan-delivery-trail{position:absolute;left:-132px;top:26px;width:154px;height:4px;border-radius:999px;background:linear-gradient(90deg,transparent,#34d399 48%,#d9f99d 78%,transparent);opacity:.9;animation:dkan-delivery-trail var(--dkan-delivery-duration,8600ms) linear forwards;}@keyframes dkan-delivery-trail{0%,82%{opacity:.9}100%{opacity:0}}.dkan-freighter{position:absolute;left:10px;top:10px;width:176px;height:45px;display:block;filter:drop-shadow(0 0 9px color-mix(in srgb,#7dd3fc 62%,transparent));}.dkan-delivery .dkan-freighter,.dkan-departure .dkan-freighter{filter:none}.dkan-delivery .dkan-freighter-engine i,.dkan-departure .dkan-freighter-engine i{animation:none;opacity:.76;box-shadow:-6px 0 8px #22d3ee}.dkan-delivery .dkan-freighter-nose,.dkan-departure .dkan-freighter-nose{filter:none}.dkan-freighter-hull{position:absolute;z-index:3;left:21px;top:7px;width:126px;height:31px;background:linear-gradient(150deg,#f8fbff 0%,#9cc8ff 30%,#385d91 72%,#1d3150);clip-path:polygon(0 30%,43% 0,83% 17%,100% 50%,83% 83%,43% 100%,0 70%,12% 50%);box-shadow:inset 0 1px 0 rgb(255 255 255 / .7),inset -7px -5px 9px rgb(8 24 49 / .38);}.dkan-freighter-nose{position:absolute;z-index:4;right:10px;top:16px;width:28px;height:14px;background:linear-gradient(90deg,#a9d1ff,#e8f5ff);clip-path:polygon(0 0,100% 50%,0 100%,22% 50%);filter:drop-shadow(5px 0 5px color-mix(in srgb,#93c5fd 62%,transparent));}.dkan-freighter-canopy{position:absolute;z-index:5;left:77px;top:10px;width:39px;height:11px;border-radius:70% 48% 42% 32%;background:linear-gradient(135deg,#ecfeff 0%,#67e8f9 32%,#2563eb 75%);transform:skewX(-18deg);box-shadow:inset 0 2px 2px rgb(255 255 255 / .7),0 0 8px color-mix(in srgb,#67e8f9 42%,transparent);}.dkan-freighter-fin{position:absolute;z-index:2;left:48px;top:3px;width:24px;height:17px;background:linear-gradient(135deg,#31557f,#a7caf7);clip-path:polygon(0 100%,58% 0,100% 100%);}.dkan-freighter-wing{position:absolute;z-index:1;left:48px;width:60px;height:18px;background:linear-gradient(135deg,#24436d,#8ebaf4);}.dkan-freighter-wing.left{top:2px;clip-path:polygon(0 100%,100% 0,68% 100%)}.dkan-freighter-wing.right{top:26px;clip-path:polygon(0 0,68% 0,100% 100%)}",
3543
+ ".dkan-freighter-cargo{position:absolute;z-index:6;left:37px;top:31px;width:74px;height:7px;display:flex;align-items:center;gap:2px;padding:1px 3px;border-radius:4px;background:#172842;border:1px solid color-mix(in srgb,#b8d8ff 48%,transparent);box-shadow:inset 0 1px 0 rgb(255 255 255 / .2);}.dkan-freighter-cargo i{display:block;flex:1;min-width:4px;height:5px;border-radius:1px;background:linear-gradient(135deg,#fef3c7,#f59e0b 58%,#b45309);box-shadow:0 0 4px color-mix(in srgb,#fbbf24 58%,transparent);}.dkan-freighter-cargo.empty i{background:linear-gradient(135deg,#dbeafe,#38bdf8 58%,#1d4ed8);box-shadow:0 0 4px color-mix(in srgb,#38bdf8 55%,transparent);}.dkan-freighter-engine{position:absolute;z-index:0;left:5px;top:19px;display:flex;gap:3px;align-items:center;height:11px;}.dkan-freighter-engine i{width:18px;height:5px;border-radius:60% 0 0 60%;background:linear-gradient(90deg,transparent,#67e8f9);box-shadow:-9px 0 12px #22d3ee;animation:dkan-engine .34s ease-in-out infinite alternate;}.dkan-freighter-engine i:nth-child(2){animation-delay:-.14s}",
3544
+ "@keyframes dkan-engine{to{transform:scaleX(.55);opacity:.5}}",
3545
+ ".dkan-delivery-label{position:absolute;left:21px;top:58px;display:flex;align-items:baseline;gap:6px;padding:4px 8px;border:1px solid color-mix(in srgb,#93c5fd 30%,var(--dsw-alias-border-l1));border-radius:999px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 82%,transparent);backdrop-filter:blur(10px);color:var(--dsw-alias-label-secondary);font:10px/1.2 var(--ds-font-family,system-ui,sans-serif);white-space:nowrap;}.dkan-delivery-label b{color:var(--dsw-alias-label-primary);font-weight:650}.dkan-delivery-label span{color:#7dd3fc;}",
3546
+ "@media (max-width:1100px){.dkan-space-system,.dkan-space-runner{display:none}}",
3547
+ ".dkan-ready-freighter{position:fixed;width:210px;height:88px;z-index:9994;pointer-events:none;filter:drop-shadow(0 10px 14px rgb(0 0 0 / .18));}.dkan-ready-freighter>span:last-child{position:absolute;left:21px;top:58px;padding:4px 8px;border:1px solid color-mix(in srgb,#93c5fd 28%,var(--dsw-alias-border-l1));border-radius:999px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 80%,transparent);backdrop-filter:blur(10px);color:var(--dsw-alias-label-secondary);font:10px/1.2 var(--ds-font-family,system-ui,sans-serif);white-space:nowrap;}.dkan-departure{position:fixed;left:0;top:0;width:210px;height:88px;z-index:9994;pointer-events:none;will-change:transform,opacity;contain:layout paint style;isolation:isolate;animation:dkan-departure-flight var(--dkan-departure-duration,8600ms) cubic-bezier(.42,0,.85,.45) forwards;}@keyframes dkan-departure-flight{0%{opacity:0;transform:translate3d(var(--dkan-from-x),var(--dkan-from-y),0) scale(1) rotate(var(--dkan-flight-angle,0deg))}6%{opacity:1;transform:translate3d(var(--dkan-from-x),var(--dkan-from-y),0) scale(1) rotate(var(--dkan-flight-angle,0deg))}100%{opacity:0;transform:translate3d(var(--dkan-to-x),var(--dkan-to-y),0) scale(.24) rotate(var(--dkan-flight-angle,0deg))}}",
3548
+ ".dkan-space-stuck{position:fixed;left:50%;top:50%;width:244px;height:160px;z-index:9993;pointer-events:none;transform:translate(-50%,-50%);border:1px solid color-mix(in srgb,#f59e0b 48%,var(--dsw-alias-border-l1));border-radius:20px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 88%,transparent);backdrop-filter:blur(16px);box-shadow:0 18px 54px rgb(0 0 0 / .28),0 0 30px color-mix(in srgb,#f59e0b 15%,transparent);}.dkan-space-stuck .dkan-freighter{left:37px;top:11px;transform:scale(.9);transform-origin:top left;}.dkan-stuck-code{position:absolute;left:17px;right:17px;top:60px;height:36px;border-radius:7px;background:linear-gradient(90deg,color-mix(in srgb,#f59e0b 18%,transparent),transparent);color:#fbbf24;font:700 14px/36px var(--ds-font-family-code,monospace);letter-spacing:.12em;text-align:center;overflow:hidden;}.dkan-stuck-code::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,transparent,color-mix(in srgb,#fef3c7 70%,transparent),transparent);transform:translateX(-110%);animation:dkan-stuck-scan 1.25s linear infinite;}.dkan-stuck-code i{display:inline-block;width:7px;height:7px;margin-right:8px;border-radius:50%;background:#f59e0b;box-shadow:0 0 9px #f59e0b;animation:dkan-stuck-pulse .8s ease-in-out infinite alternate;}.dkan-space-stuck strong{position:absolute;left:0;right:0;top:108px;color:var(--dsw-alias-label-primary);font:650 13px/1.2 var(--ds-font-family,system-ui,sans-serif);text-align:center;}.dkan-space-stuck small{position:absolute;left:18px;right:18px;top:128px;color:var(--dsw-alias-label-secondary);font:11px/1.25 var(--ds-font-family,system-ui,sans-serif);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}@keyframes dkan-stuck-scan{to{transform:translateX(110%)}}@keyframes dkan-stuck-pulse{to{transform:scale(.55);opacity:.45}}",
3076
3549
  // 极光:顶部柔光带呼吸流动(加浓)
3077
3550
  ".dkan-aurora i{position:absolute;top:-40%;left:-20%;width:70%;height:80%;border-radius:50%;filter:blur(50px);opacity:.32;animation:dkan-aurora ease-in-out infinite alternate;}",
3078
3551
  ".dkan-aurora i:nth-child(1){background:#4d9fff;}",
3079
3552
  ".dkan-aurora i:nth-child(2){background:#34d399;left:20%;animation-delay:-2s;}",
3080
3553
  ".dkan-aurora i:nth-child(3){background:#a78bfa;left:55%;animation-delay:-4s;}",
3081
3554
  "@keyframes dkan-aurora{0%{transform:translateX(-8%) scaleY(1)}100%{transform:translateX(10%) scaleY(1.3)}}",
3555
+ // 星云潮汐:无动态模糊,柔边由径向渐变生成,移动只发生在合成层。
3556
+ ".dkan-nebula{contain:strict}.dkan-nebula i{position:absolute;width:48vw;aspect-ratio:1;border-radius:50%;opacity:.22;background:radial-gradient(circle,color-mix(in srgb,var(--dkan-phase,#60a5fa) 48%,transparent),color-mix(in srgb,#8b5cf6 18%,transparent) 42%,transparent 70%);animation:dkan-nebula-drift calc(18s / var(--dkan-speed,1)) cubic-bezier(.45,0,.55,1) infinite alternate;will-change:transform,opacity}.dkan-nebula i:nth-child(1){left:-18%;top:-24%}.dkan-nebula i:nth-child(2){right:-18%;top:4%;background:radial-gradient(circle,color-mix(in srgb,#22d3ee 34%,transparent),color-mix(in srgb,#3b82f6 15%,transparent) 45%,transparent 72%);animation-delay:-5s}.dkan-nebula i:nth-child(3){left:4%;bottom:-34%;background:radial-gradient(circle,color-mix(in srgb,#f472b6 28%,transparent),color-mix(in srgb,#8b5cf6 14%,transparent) 48%,transparent 72%);animation-delay:-10s}.dkan-nebula i:nth-child(4){right:8%;bottom:-26%;width:36vw;animation-delay:-14s}",
3557
+ "@keyframes dkan-nebula-drift{0%{opacity:.14;transform:translate3d(-3vw,-2vh,0) scale(.92)}100%{opacity:.3;transform:translate3d(5vw,4vh,0) scale(1.12)}}",
3558
+ // 曲速航道:从视口中心放射的独立光束。
3559
+ ".dkan-warp{background:radial-gradient(circle at center,color-mix(in srgb,var(--dkan-phase,#60a5fa) 10%,transparent),transparent 34%);contain:strict}.dkan-warp i{position:absolute;left:50%;top:50%;width:var(--len);height:1px;border-radius:999px;transform-origin:left center;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dkan-phase,#60a5fa) 48%,transparent),#e0f2fe);opacity:0;animation-name:dkan-warp-ray;animation-timing-function:cubic-bezier(.3,.1,.8,1);animation-iteration-count:infinite;will-change:transform,opacity}",
3560
+ "@keyframes dkan-warp-ray{0%{opacity:0;transform:rotate(var(--a)) translate3d(18px,0,0) scaleX(.05)}18%{opacity:.6}100%{opacity:0;transform:rotate(var(--a)) translate3d(58vw,0,0) scaleX(1.55)}}",
3561
+ // 量子雷达:三个边缘站点各自扫描,避免占据会话正文中心。
3562
+ ".dkan-radar{contain:strict}.dkan-radar-station{position:absolute;width:176px;height:176px;border-radius:50%;opacity:.44;background:repeating-radial-gradient(circle,color-mix(in srgb,var(--dkan-phase,#60a5fa) 28%,transparent) 0 1px,transparent 1px 29px);border:1px solid color-mix(in srgb,var(--dkan-phase,#60a5fa) 22%,transparent)}.dkan-radar-station.a{right:4%;top:8%}.dkan-radar-station.b{left:1%;top:38%;transform:scale(.72)}.dkan-radar-station.c{right:7%;bottom:9%;transform:scale(.58)}.dkan-radar-station i{position:absolute;inset:0;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 76%,color-mix(in srgb,var(--dkan-phase,#60a5fa) 44%,transparent) 92%,transparent);animation:dkan-radar-sweep calc(4.8s / var(--dkan-speed,1)) linear infinite;will-change:transform}.dkan-radar-station b{position:absolute;left:67%;top:31%;width:7px;height:7px;border-radius:50%;background:var(--dkan-phase,#60a5fa);box-shadow:0 0 12px 4px color-mix(in srgb,var(--dkan-phase,#60a5fa) 58%,transparent);animation:dkan-radar-blip calc(2.4s / var(--dkan-speed,1)) ease-in-out infinite}",
3563
+ "@keyframes dkan-radar-sweep{to{transform:rotate(360deg)}}@keyframes dkan-radar-blip{0%,70%,100%{opacity:.15;transform:scale(.65)}78%{opacity:1;transform:scale(1.25)}}",
3564
+ // 星座网络:轻量 SVG 线网分段点亮。
3565
+ ".dkan-constellation svg{position:absolute;left:8%;top:7%;width:86%;height:78%;overflow:visible}.dkan-constellation path{fill:none;stroke:color-mix(in srgb,var(--dkan-phase,#60a5fa) 42%,transparent);stroke-width:.16;vector-effect:non-scaling-stroke;stroke-dasharray:.08 .025;animation:dkan-constellation-line calc(7s / var(--dkan-speed,1)) linear infinite}.dkan-constellation circle{fill:var(--dkan-phase,#60a5fa);filter:drop-shadow(0 0 2px var(--dkan-phase,#60a5fa));animation:dkan-constellation-star calc(2.8s / var(--dkan-speed,1)) ease-in-out infinite alternate;transform-box:fill-box;transform-origin:center}",
3566
+ "@keyframes dkan-constellation-line{to{stroke-dashoffset:-1}}@keyframes dkan-constellation-star{0%{opacity:.28;transform:scale(.68)}100%{opacity:.92;transform:scale(1.22)}}",
3567
+ // 数据萤火:二维漂移和明暗呼吸组合在同一个 transform 动画中。
3568
+ ".dkan-fireflies{contain:strict}.dkan-fireflies i{position:absolute;border-radius:50%;background:color-mix(in srgb,var(--dkan-phase,#60a5fa) 78%,#fff);box-shadow:0 0 8px 2px color-mix(in srgb,var(--dkan-phase,#60a5fa) 46%,transparent);opacity:.2;animation-name:dkan-firefly;animation-timing-function:cubic-bezier(.45,0,.55,1);animation-iteration-count:infinite;animation-direction:alternate;will-change:transform,opacity}",
3569
+ "@keyframes dkan-firefly{0%{opacity:.12;transform:translate3d(0,0,0) scale(.65)}48%{opacity:.86}100%{opacity:.26;transform:translate3d(var(--dx),var(--dy),0) scale(1.18)}}",
3570
+ // 深海脉动:波层在底部横向漂移,气泡只做向上合成位移。
3571
+ ".dkan-ocean{background:linear-gradient(0deg,color-mix(in srgb,#0284c7 12%,transparent),transparent 46%);contain:strict}.dkan-ocean-waves{position:absolute;left:-12%;right:-12%;bottom:0;height:42%}.dkan-ocean-waves i{position:absolute;left:0;width:112%;height:52%;border-top:1px solid color-mix(in srgb,#67e8f9 28%,transparent);border-radius:50%;animation:dkan-ocean-wave calc(9s / var(--dkan-speed,1)) ease-in-out infinite alternate;will-change:transform}.dkan-ocean-waves i:nth-child(1){top:2%}.dkan-ocean-waves i:nth-child(2){top:18%;animation-delay:-2s}.dkan-ocean-waves i:nth-child(3){top:34%;animation-delay:-4s}.dkan-ocean-waves i:nth-child(4){top:50%;animation-delay:-6s}.dkan-ocean-waves i:nth-child(5){top:66%;animation-delay:-8s}.dkan-ocean>b{position:absolute;bottom:-20px;border:1px solid color-mix(in srgb,#a5f3fc 54%,transparent);border-radius:50%;opacity:0;animation-name:dkan-ocean-bubble;animation-timing-function:linear;animation-iteration-count:infinite;will-change:transform,opacity}",
3572
+ "@keyframes dkan-ocean-wave{to{transform:translate3d(7%,5px,0) scaleY(1.08)}}@keyframes dkan-ocean-bubble{0%{opacity:0;transform:translate3d(0,0,0) scale(.7)}14%{opacity:.58}100%{opacity:0;transform:translate3d(var(--drift),-82vh,0) scale(1.18)}}",
3573
+ // 棱镜光谱:七条低透明度光带错峰穿过视口。
3574
+ ".dkan-prism{contain:strict}.dkan-prism i{position:absolute;left:-32vw;width:160vw;height:2px;border-radius:999px;opacity:0;background:linear-gradient(90deg,transparent,#ef4444,#f59e0b,#facc15,#22c55e,#22d3ee,#6366f1,#a855f7,transparent);animation:dkan-prism-ray calc(8s / var(--dkan-speed,1)) cubic-bezier(.45,0,.55,1) infinite;will-change:transform,opacity}.dkan-prism i:nth-child(1){top:12%;animation-delay:0s}.dkan-prism i:nth-child(2){top:25%;animation-delay:-1.1s}.dkan-prism i:nth-child(3){top:38%;animation-delay:-2.2s}.dkan-prism i:nth-child(4){top:51%;animation-delay:-3.3s}.dkan-prism i:nth-child(5){top:64%;animation-delay:-4.4s}.dkan-prism i:nth-child(6){top:77%;animation-delay:-5.5s}.dkan-prism i:nth-child(7){top:90%;animation-delay:-6.6s}",
3575
+ "@keyframes dkan-prism-ray{0%{opacity:0;transform:translate3d(-12vw,0,0) rotate(-7deg) scaleX(.7)}34%{opacity:.2}66%{opacity:.36}100%{opacity:0;transform:translate3d(20vw,0,0) rotate(-7deg) scaleX(1.05)}}",
3576
+ // 神经电路:少量 SVG 路径的虚线脉冲,节点保持低透明度。
3577
+ ".dkan-circuit svg{position:absolute;inset:5% 3% 9% 8%;width:89%;height:86%;overflow:visible}.dkan-circuit path{fill:none;stroke:color-mix(in srgb,var(--dkan-phase,#60a5fa) 40%,transparent);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:.045 .12;animation:dkan-circuit-pulse calc(5.6s / var(--dkan-speed,1)) linear infinite}.dkan-circuit circle{fill:var(--dkan-phase,#60a5fa);opacity:.58;filter:drop-shadow(0 0 4px var(--dkan-phase,#60a5fa));animation:dkan-circuit-node calc(2.2s / var(--dkan-speed,1)) ease-in-out infinite alternate}",
3578
+ "@keyframes dkan-circuit-pulse{to{stroke-dashoffset:-1}}@keyframes dkan-circuit-node{to{opacity:.16}}",
3579
+ // 引力涟漪:三个边缘引力源按错峰节奏扩散。
3580
+ ".dkan-gravity{contain:strict}.dkan-gravity-source{position:absolute;width:260px;height:260px}.dkan-gravity-source.a{right:2%;top:5%}.dkan-gravity-source.b{left:-4%;top:39%;transform:scale(.76)}.dkan-gravity-source.c{right:17%;bottom:-10%;transform:scale(.62)}.dkan-gravity-source b{position:absolute;left:50%;top:50%;width:12px;height:12px;margin:-6px;border-radius:50%;background:var(--dkan-phase,#60a5fa);box-shadow:0 0 16px 5px color-mix(in srgb,var(--dkan-phase,#60a5fa) 42%,transparent)}.dkan-gravity-source i{position:absolute;left:50%;top:50%;width:26px;height:26px;margin:-13px;border:1px solid color-mix(in srgb,var(--dkan-phase,#60a5fa) 42%,transparent);border-radius:50%;opacity:0;animation:dkan-gravity-wave calc(4.6s / var(--dkan-speed,1)) cubic-bezier(.2,.55,.35,1) infinite;will-change:transform,opacity}",
3581
+ "@keyframes dkan-gravity-wave{0%{opacity:.64;transform:scale(.3)}100%{opacity:0;transform:scale(9)}}",
3582
+ // 灵感天灯:暖色灯体从屏幕底部缓慢升起,尾迹由伪元素提供。
3583
+ ".dkan-lantern{contain:strict}.dkan-lantern i{position:absolute;bottom:-30px;border-radius:45% 45% 34% 34%;background:linear-gradient(150deg,#fff7c2 0%,#fbbf24 46%,#f97316 100%);box-shadow:0 0 10px 3px color-mix(in srgb,#fbbf24 36%,transparent);opacity:0;animation-name:dkan-lantern-rise;animation-timing-function:cubic-bezier(.34,.02,.6,1);animation-iteration-count:infinite;will-change:transform,opacity}.dkan-lantern i::after{content:'';position:absolute;left:42%;top:100%;width:16%;height:13px;background:linear-gradient(#f59e0b,transparent)}",
3584
+ "@keyframes dkan-lantern-rise{0%{opacity:0;transform:translate3d(0,0,0) rotate(-3deg) scale(.72)}12%{opacity:.72}78%{opacity:.48}100%{opacity:0;transform:translate3d(var(--drift),-104vh,0) rotate(4deg) scale(1.04)}}",
3082
3585
  // ===== 交互反馈层 =====
3083
3586
  ".dkan-fxwrap{position:fixed;inset:0;z-index:9992;pointer-events:none;overflow:hidden;}",
3084
3587
  ".dkan-fx{position:absolute;}",
@@ -3184,11 +3687,24 @@ var css2 = [
3184
3687
  ".dkan-prev-stars i:nth-child(5){left:28%;top:70%;animation-delay:-.6s;}",
3185
3688
  ".dkan-prev-stars i:nth-child(6){left:70%;top:75%;animation-delay:-1s;}",
3186
3689
  "@keyframes dkan-prev-star{0%{opacity:.2}100%{opacity:.9}}",
3690
+ // 预览:星际远征(行星、轨道与飞船)
3691
+ ".dkan-prev-space i{position:absolute;left:49%;top:50%;width:9px;height:9px;border-radius:50%;background:#fbbf24;box-shadow:0 0 6px #fbbf24;}.dkan-prev-space b{position:absolute;left:21%;top:23%;width:15px;height:8px;border:1px solid #93c5fd;border-radius:50%;animation:dkan-prev-space-orbit 2.4s linear infinite;}.dkan-prev-space b::after{content:'';position:absolute;left:-3px;top:0;width:5px;height:5px;border-radius:50%;background:#a78bfa;box-shadow:0 0 4px #a78bfa;}.dkan-prev-space em{position:absolute;left:5%;top:65%;width:19px;height:4px;border-radius:50% 0 0 50%;background:linear-gradient(90deg,#22d3ee,#dbeafe);animation:dkan-prev-space-ship 1.8s linear infinite;}.dkan-prev-space em::after{content:'';position:absolute;right:-7px;top:-3px;border-left:9px solid #93c5fd;border-top:5px solid transparent;border-bottom:5px solid transparent;}.dkan-prev-space{background:radial-gradient(ellipse at 78% 20%,color-mix(in srgb,#6366f1 18%,transparent),transparent 58%);}.dkan-prev-space i,.dkan-prev-space b,.dkan-prev-space em{font-style:normal;}.dkan-prev-space b{transform-origin:34px 11px;}@keyframes dkan-prev-space-orbit{to{transform:rotate(360deg)}}@keyframes dkan-prev-space-ship{to{transform:translateX(105px)}}",
3187
3692
  // 预览:极光(柔光带呼吸)
3188
3693
  ".dkan-prev-aurora i{position:absolute;top:-30%;width:60%;height:120%;border-radius:50%;filter:blur(8px);opacity:.35;animation:dkan-prev-aurora 2.4s ease-in-out infinite alternate;}",
3189
3694
  ".dkan-prev-aurora i:nth-child(1){left:5%;background:#4d9fff;}",
3190
3695
  ".dkan-prev-aurora i:nth-child(2){left:45%;background:#34d399;animation-delay:-1.2s;}",
3191
3696
  "@keyframes dkan-prev-aurora{0%{transform:translateX(-10%)}100%{transform:translateX(15%)}}",
3697
+ // 十种新增模式的缩微预览:复用主体运动语言,但把节点数和振幅压到卡片内。
3698
+ ".dkan-prev-new{--dkan-phase:var(--dsw-alias-accent,#4d9fff)}.dkan-prev-new i{position:absolute;display:block}",
3699
+ ".dkan-prev-nebula i{width:48px;height:48px;border-radius:50%;background:radial-gradient(circle,color-mix(in srgb,var(--dkan-phase) 48%,transparent),transparent 70%);animation:dkan-prev-nebula 3s ease-in-out infinite alternate}.dkan-prev-nebula i:nth-child(1){left:2%;top:-60%}.dkan-prev-nebula i:nth-child(2){right:4%;bottom:-65%;background:radial-gradient(circle,color-mix(in srgb,#a855f7 42%,transparent),transparent 70%);animation-delay:-1.4s}.dkan-prev-nebula i:nth-child(n+3){display:none}@keyframes dkan-prev-nebula{to{transform:translateX(24px) scale(1.18)}}",
3700
+ ".dkan-prev-warp i{left:50%;top:50%;width:36px;height:1px;transform-origin:left;background:linear-gradient(90deg,transparent,var(--dkan-phase),#fff);animation:dkan-prev-warp 1.8s linear infinite;opacity:0}.dkan-prev-warp i:nth-child(1){--a:0deg}.dkan-prev-warp i:nth-child(2){--a:45deg;animation-delay:-.2s}.dkan-prev-warp i:nth-child(3){--a:90deg;animation-delay:-.4s}.dkan-prev-warp i:nth-child(4){--a:135deg;animation-delay:-.6s}.dkan-prev-warp i:nth-child(5){--a:180deg;animation-delay:-.8s}.dkan-prev-warp i:nth-child(6){--a:225deg;animation-delay:-1s}.dkan-prev-warp i:nth-child(7){--a:270deg;animation-delay:-1.2s}.dkan-prev-warp i:nth-child(8){--a:315deg;animation-delay:-1.4s}@keyframes dkan-prev-warp{0%{opacity:0;transform:rotate(var(--a)) translateX(2px) scaleX(.1)}35%{opacity:.8}100%{opacity:0;transform:rotate(var(--a)) translateX(40px) scaleX(1.3)}}",
3701
+ ".dkan-prev-radar i{left:50%;top:50%;width:24px;height:24px;margin:-12px;border:1px solid color-mix(in srgb,var(--dkan-phase) 48%,transparent);border-radius:50%;animation:dkan-prev-radar 2.6s ease-out infinite;opacity:0}.dkan-prev-radar i:nth-child(2){animation-delay:-.85s}.dkan-prev-radar i:nth-child(3){animation-delay:-1.7s}.dkan-prev-radar i:nth-child(n+4){display:none}@keyframes dkan-prev-radar{0%{opacity:.8;transform:scale(.2)}100%{opacity:0;transform:scale(1.25)}}",
3702
+ ".dkan-prev-constellation::after{content:'';position:absolute;left:12%;right:12%;top:50%;height:1px;background:linear-gradient(90deg,transparent,var(--dkan-phase),transparent);transform:rotate(-9deg)}.dkan-prev-constellation i,.dkan-prev-fireflies i{width:4px;height:4px;border-radius:50%;background:var(--dkan-phase);box-shadow:0 0 5px var(--dkan-phase);animation:dkan-prev-twinkle 1.8s ease-in-out infinite alternate}.dkan-prev-constellation i:nth-child(1),.dkan-prev-fireflies i:nth-child(1){left:12%;top:62%}.dkan-prev-constellation i:nth-child(2),.dkan-prev-fireflies i:nth-child(2){left:28%;top:26%;animation-delay:-.3s}.dkan-prev-constellation i:nth-child(3),.dkan-prev-fireflies i:nth-child(3){left:45%;top:52%;animation-delay:-.6s}.dkan-prev-constellation i:nth-child(4),.dkan-prev-fireflies i:nth-child(4){left:61%;top:18%;animation-delay:-.9s}.dkan-prev-constellation i:nth-child(5),.dkan-prev-fireflies i:nth-child(5){left:76%;top:58%;animation-delay:-1.2s}.dkan-prev-constellation i:nth-child(6),.dkan-prev-fireflies i:nth-child(6){left:88%;top:34%;animation-delay:-1.5s}@keyframes dkan-prev-twinkle{to{opacity:.2;transform:translateY(4px) scale(.65)}}",
3703
+ ".dkan-prev-ocean i{left:-10%;width:120%;height:18px;border-top:1px solid color-mix(in srgb,#22d3ee 52%,transparent);border-radius:50%;animation:dkan-prev-wave 2.8s ease-in-out infinite alternate}.dkan-prev-ocean i:nth-child(1){top:15%}.dkan-prev-ocean i:nth-child(2){top:35%;animation-delay:-.5s}.dkan-prev-ocean i:nth-child(3){top:55%;animation-delay:-1s}.dkan-prev-ocean i:nth-child(4){top:75%;animation-delay:-1.5s}.dkan-prev-ocean i:nth-child(n+5){display:none}@keyframes dkan-prev-wave{to{transform:translateX(12px) scaleY(1.2)}}",
3704
+ ".dkan-prev-prism i{left:-10%;width:120%;height:1px;background:linear-gradient(90deg,transparent,#ef4444,#fbbf24,#22c55e,#22d3ee,#8b5cf6,transparent);transform:rotate(-6deg);animation:dkan-prev-prism 2.8s ease-in-out infinite}.dkan-prev-prism i:nth-child(1){top:18%}.dkan-prev-prism i:nth-child(2){top:34%;animation-delay:-.4s}.dkan-prev-prism i:nth-child(3){top:50%;animation-delay:-.8s}.dkan-prev-prism i:nth-child(4){top:66%;animation-delay:-1.2s}.dkan-prev-prism i:nth-child(5){top:82%;animation-delay:-1.6s}.dkan-prev-prism i:nth-child(n+6){display:none}@keyframes dkan-prev-prism{0%,100%{opacity:.12;transform:translateX(-8px) rotate(-6deg)}50%{opacity:.72;transform:translateX(10px) rotate(-6deg)}}",
3705
+ ".dkan-prev-circuit i{height:1px;background:var(--dkan-phase);box-shadow:0 0 4px var(--dkan-phase);animation:dkan-prev-circuit 2.4s linear infinite}.dkan-prev-circuit i:nth-child(1){left:5%;top:30%;width:42%}.dkan-prev-circuit i:nth-child(2){left:47%;top:30%;width:1px;height:45%}.dkan-prev-circuit i:nth-child(3){left:47%;top:74%;width:38%}.dkan-prev-circuit i:nth-child(4){left:68%;top:15%;width:1px;height:60%}.dkan-prev-circuit i:nth-child(5){left:68%;top:15%;width:26%}.dkan-prev-circuit i:nth-child(6){left:12%;top:62%;width:35%}@keyframes dkan-prev-circuit{0%,100%{opacity:.18}50%{opacity:.9}}",
3706
+ ".dkan-prev-gravity i{left:50%;top:50%;width:18px;height:18px;margin:-9px;border:1px solid var(--dkan-phase);border-radius:50%;opacity:0;animation:dkan-prev-gravity 2.6s ease-out infinite}.dkan-prev-gravity i:nth-child(2){animation-delay:-.65s}.dkan-prev-gravity i:nth-child(3){animation-delay:-1.3s}.dkan-prev-gravity i:nth-child(4){animation-delay:-1.95s}.dkan-prev-gravity i:nth-child(n+5){display:none}@keyframes dkan-prev-gravity{0%{opacity:.8;transform:scale(.15)}100%{opacity:0;transform:scale(2.4)}}",
3707
+ ".dkan-prev-lantern i{bottom:-8px;width:6px;height:8px;border-radius:3px;background:#fbbf24;box-shadow:0 0 5px #f59e0b;animation:dkan-prev-lantern 3.2s linear infinite}.dkan-prev-lantern i:nth-child(1){left:12%}.dkan-prev-lantern i:nth-child(2){left:27%;animation-delay:-.6s}.dkan-prev-lantern i:nth-child(3){left:43%;animation-delay:-1.2s}.dkan-prev-lantern i:nth-child(4){left:61%;animation-delay:-1.8s}.dkan-prev-lantern i:nth-child(5){left:76%;animation-delay:-2.4s}.dkan-prev-lantern i:nth-child(6){left:90%;animation-delay:-2.8s}@keyframes dkan-prev-lantern{0%{opacity:0;transform:translateY(0)}20%{opacity:.9}100%{opacity:0;transform:translateY(-38px)}}",
3192
3708
  ".dkan-prev-bot{height:92px;justify-content:center;}",
3193
3709
  ".dkan-prev-bot .dkan-bot-scene{--dkan-bot-scale:1;transform:scale(.56);transform-origin:center;}",
3194
3710
  // ===== 桌面伙伴:具象人物 + 紧凑双工位(尺寸可调,整卡可拖拽) =====
@@ -3352,7 +3868,7 @@ var css2 = [
3352
3868
  "@keyframes dkan-search-head{0%,28%{transform:var(--dk3-head-turn) rotateZ(1deg)}48%,68%{transform:var(--dk3-head-turn) rotateZ(6deg) translate(1px,1px)}88%,100%{transform:var(--dk3-head-turn) rotateZ(2deg)}}",
3353
3869
  "@keyframes dkan-search-wrist{0%,34%{transform:translateX(-1px)}62%,100%{transform:translateX(1.5px)}}",
3354
3870
  // 减少动态时停止空间位移,保留屏幕亮暗与思考状态的淡入反馈。
3355
- "@media (prefers-reduced-motion:reduce){.dk3-person,.dk3-upper3,.dk3-head3,.dk3-arm3,.dk3-elbow,.dk3-wrist3,.dk3-wheel,.dk3-code,.dk3-search-results{animation:none!important;transition:none!important}.dk3-screen,.dkan-bubble{transition:opacity .2s cubic-bezier(.23,1,.32,1)!important}}",
3871
+ "@media (prefers-reduced-motion:reduce){.dkan-amb *,.dkan-prev *,.dkan-space-system,.dkan-space-dust,.dkan-space-runner,.dkan-delivery,.dkan-departure,.dkan-freighter-engine i,.dkan-stuck-code::after,.dkan-stuck-code i{animation:none!important}.dkan-space-runner,.dkan-departure{display:none}.dkan-delivery{opacity:1;transform:translate3d(var(--dkan-to-x),var(--dkan-to-y),0)}.dkan-delivery-trail{display:none}.dk3-person,.dk3-upper3,.dk3-head3,.dk3-arm3,.dk3-elbow,.dk3-wrist3,.dk3-wheel,.dk3-code,.dk3-search-results{animation:none!important;transition:none!important}.dk3-screen,.dkan-bubble{transition:opacity .2s cubic-bezier(.23,1,.32,1)!important}}",
3356
3872
  // 通知子选项行
3357
3873
  ".dkan-rows-narrow{display:flex;flex-direction:column;gap:6px;}",
3358
3874
  ".dkan-row{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--dsw-alias-label-secondary);flex-wrap:wrap;}",
@@ -3397,7 +3913,7 @@ var feature6 = {
3397
3913
  name: "\u4EFB\u52A1\u52A8\u753B",
3398
3914
  order: 130,
3399
3915
  accent: "#f472b6",
3400
- description: "\u4EFB\u52A1\u8FD0\u884C\u52A8\u753B\uFF08\u6D41\u5149\u7EC6\u7EBF/\u547C\u5438\u5149\u70B9/\u8F68\u9053\u5149\u73AF\uFF09\u4E0E\u5B8C\u6210\u901A\u77E5\uFF0C\u4E24\u7EC4\u5F00\u5173\u72EC\u7ACB\u3001\u914D\u7F6E\u6301\u4E45\u5316",
3916
+ description: "19 \u79CD\u4EFB\u52A1\u8FD0\u884C\u52A8\u753B\u4E0E\u5B8C\u6210\u901A\u77E5\uFF1A\u901F\u5EA6\u968F\u4EFB\u52A1\u6D3B\u52A8\u8054\u52A8\uFF0C\u4E24\u7EC4\u5F00\u5173\u72EC\u7ACB\u3001\u914D\u7F6E\u6301\u4E45\u5316",
3401
3917
  css: css2,
3402
3918
  View: AnimationView,
3403
3919
  HomeStat: AnimationStat,
@@ -3405,7 +3921,7 @@ var feature6 = {
3405
3921
  };
3406
3922
 
3407
3923
  // src/client.jsx
3408
- var DOCK_VERSION = "0.5.0";
3924
+ var DOCK_VERSION = "0.7.1";
3409
3925
  var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6];
3410
3926
  var PLANNED_FEATURES = [];
3411
3927
  var PLANNED_NOTES = {};
@@ -3536,6 +4052,10 @@ var SHELL_CSS = [
3536
4052
  ".dockm-foot-sw{margin-left:auto;flex:none;display:inline-flex;align-items:center;gap:8px;}",
3537
4053
  ".dockm-foot-swlabel{font-size:11px;color:var(--dsw-alias-label-tertiary);}",
3538
4054
  ".dockm-foot-swlabel.on{color:var(--dsw-alias-state-success-primary);}",
4055
+ // 窄屏:功能坞是一级工作台而不是被压扁的桌面弹窗。全屏承接安全区,导航改横向,
4056
+ // 禁用桌面拖拽/缩放,所有导航和关闭动作保持至少 44px 的可点击面积。
4057
+ "@media (max-width:680px){.dockm-backdrop{align-items:stretch;justify-content:stretch;background:var(--dsw-alias-bg-layer-2);backdrop-filter:none}.dockm-dialog,.dockm-dialog.dockm-max{position:fixed!important;left:0!important;top:0!important;right:auto!important;bottom:auto!important;width:100dvw!important;height:100dvh!important;min-height:100dvh;border:0;border-radius:0;box-shadow:none}.dockm-dialog.dockm-min .dockm-body{display:flex}.dockm-head{min-height:60px;box-sizing:border-box;padding:calc(env(safe-area-inset-top) + 8px) 12px 8px;cursor:default;touch-action:manipulation}.dockm-sub,.dockm-win,.dockm-resize{display:none}.dockm-title{font-size:16px}.dockm-close{width:44px;height:44px;font-size:17px}.dockm-body{flex-direction:column;min-height:0}.dockm-nav{box-sizing:border-box;width:auto;max-width:100%;min-height:56px;flex-direction:row;gap:6px;padding:6px 10px;overflow-x:auto;overflow-y:hidden;border-right:0;border-bottom:1px solid var(--dsw-alias-border-l1);scrollbar-width:none;overscroll-behavior-x:contain}.dockm-nav::-webkit-scrollbar{display:none}.dockm-nav-item{flex:none;min-height:44px;padding:0 12px;font-size:13px;touch-action:manipulation}.dockm-nav-item .dockm-badge{display:none}.dockm-content{padding:16px max(16px,env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left));gap:14px;overscroll-behavior:contain}.dockm-content-head{gap:5px}.dockm-name{font-size:16px}.dockm-desc{font-size:13px;line-height:1.55}.dockm-foot{padding-top:12px;font-size:11px}.dockm-foot-sw{width:100%;margin-left:0;justify-content:space-between}.dock-sw{width:44px;height:26px}.dock-sw::after{top:3px;left:3px;width:18px;height:18px}.dock-sw.on::after{transform:translateX(18px)}.dockh-grid{grid-template-columns:1fr;gap:10px}.dockh-card{padding:12px}.dockh-desc{font-size:13px}.dockh-go{font-size:12px}}",
4058
+ "@media (prefers-reduced-motion:reduce){.dockm-backdrop,.dockm-dialog{animation:none}.dockm-nav-item,.dockm-close,.dockm-win,.dock-sw{transition:none}}",
3539
4059
  ".dockh-desc{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5;}",
3540
4060
  ".dockh-stat{color:var(--dsw-alias-label-tertiary);font-size:12px;border-top:1px solid var(--dsw-alias-border-l1);padding-top:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
3541
4061
  ".dockh-foot{display:flex;align-items:center;gap:8px;}",
@@ -3544,17 +4064,29 @@ var SHELL_CSS = [
3544
4064
  // 溢出兼容(两层防护,缺一不可):
3545
4065
  // 1) 宽度上限:宿主 .row 是 flex-wrap:wrap 且换行优先于收缩,chips 一长 tools 整行变宽,
3546
4066
  // 右侧模型选择器/发送键被挤到第二行(左右错位)。宿主 .row 带 container-type:inline-size,
3547
- // 用容器单位 cqw 让上限随输入卡宽度自适应(窄卡少占、宽卡多占);不支持 cqw 的老内核退回固定 280px。
4067
+ // 用容器单位 cqw 让上限随输入卡宽度自适应(窄卡少占、宽卡多占);不支持 cqw 的老内核退回固定值。
4068
+ // 注意:旧上限 min(280px,36cqw) 仍偏宽——标准 780px 输入卡下(.row 内容约 762px),
4069
+ // add 钮(28)+工作区选择器(~214)+chips(280) 已与右侧模型选择器+发送键(~345px)合计超宽,
4070
+ // 即便 chips 未截断 .row 也会换行把模型选择器/发送键挤到第二行。实测把上限收到 189px
4071
+ // (≈25cqw)并使 chips 内距收紧(padding 2px 6px、gap 2px)后,实测 4~6M 用量 + 余额
4072
+ // 两 chip 可完整显示且不再换行;超限时仍被省略号截断,完整值在 title 悬浮提示里。
3548
4073
  // 2) 截断:超限部分用省略号截断(完整数值在 title 悬浮提示里),防 chips 凸出输入卡圆角(悬空)。
3549
- ".dockchip-row{display:inline-flex;align-items:center;gap:4px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:280px;}",
3550
- "@supports (width:1cqw){.dockchip-row{max-width:min(280px,36cqw);}}",
3551
- ".dockchip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:8px;padding:2px 8px;font-family:inherit;font-size:11px;line-height:18px;white-space:nowrap;min-width:0;overflow:hidden;transition:background .15s var(--ds-ease-in-out),color .15s var(--ds-ease-in-out);}",
4074
+ ".dockchip-row{display:inline-flex;align-items:center;gap:2px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:189px;}",
4075
+ "@supports (width:1cqw){.dockchip-row{max-width:min(189px,25cqw);}}",
4076
+ ".dockchip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:8px;padding:2px 6px;font-family:inherit;font-size:11px;line-height:18px;white-space:nowrap;min-width:0;overflow:hidden;transition:background .15s var(--ds-ease-in-out),color .15s var(--ds-ease-in-out);}",
3552
4077
  ".dockchip > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}",
3553
4078
  ".dockchip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
3554
4079
  ".dockchip .dockchip-dot{width:6px;height:6px;border-radius:50%;flex:none;}",
3555
4080
  ".dockchip.err{color:var(--dsw-alias-state-error-primary);}"
3556
4081
  ].join("\n");
3557
4082
  var dockCssTag = null;
4083
+ var initialCssSchedule = null;
4084
+ function cancelInitialCssSchedule() {
4085
+ if (!initialCssSchedule || typeof window === "undefined") return;
4086
+ if (initialCssSchedule.type === "idle" && typeof window.cancelIdleCallback === "function") window.cancelIdleCallback(initialCssSchedule.id);
4087
+ if (initialCssSchedule.type === "timer") window.clearTimeout(initialCssSchedule.id);
4088
+ initialCssSchedule = null;
4089
+ }
3558
4090
  function fullDockCss() {
3559
4091
  const parts = [SHELL_CSS];
3560
4092
  for (const f of BUILTIN_FEATURES) if (f.css) parts.push(f.css);
@@ -3563,6 +4095,7 @@ function fullDockCss() {
3563
4095
  }
3564
4096
  function ensureCss() {
3565
4097
  if (typeof document === "undefined") return;
4098
+ cancelInitialCssSchedule();
3566
4099
  try {
3567
4100
  if (!dockCssTag || !dockCssTag.isConnected) {
3568
4101
  if (document.querySelector('style[data-plugin-css="dsh-dock"]')) {
@@ -3578,6 +4111,18 @@ function ensureCss() {
3578
4111
  console.error("[dsh-dock] ensureCss failed:", e && e.message ? e.message : String(e));
3579
4112
  }
3580
4113
  }
4114
+ function scheduleInitialCss() {
4115
+ if (typeof document === "undefined" || initialCssSchedule || dockCssTag && dockCssTag.isConnected) return;
4116
+ const run = () => {
4117
+ initialCssSchedule = null;
4118
+ ensureCss();
4119
+ };
4120
+ if (typeof window !== "undefined" && typeof window.requestIdleCallback === "function") {
4121
+ initialCssSchedule = { type: "idle", id: window.requestIdleCallback(run, { timeout: 350 }) };
4122
+ } else {
4123
+ initialCssSchedule = { type: "timer", id: setTimeout(run, 48) };
4124
+ }
4125
+ }
3581
4126
  function useExternalVersion() {
3582
4127
  const [, bump] = import_react9.default.useReducer((n) => n + 1, 0);
3583
4128
  import_react9.default.useEffect(() => {
@@ -3623,9 +4168,13 @@ function DockModal() {
3623
4168
  useExternalVersion();
3624
4169
  const [win, setWin] = import_react9.default.useState(() => ({ mode: "normal", x: null, y: null, w: null, h: null }));
3625
4170
  const dlgRef = import_react9.default.useRef(null);
4171
+ const contentRef = import_react9.default.useRef(null);
3626
4172
  import_react9.default.useEffect(() => {
3627
4173
  if (lastGeom.w) setWin({ mode: "normal", x: lastGeom.x, y: lastGeom.y, w: lastGeom.w, h: lastGeom.h });
3628
4174
  }, []);
4175
+ import_react9.default.useEffect(() => {
4176
+ if (open && contentRef.current) contentRef.current.scrollTop = 0;
4177
+ }, [active, open]);
3629
4178
  function beginDrag(e, type) {
3630
4179
  if (win.mode !== "normal" || e.button !== 0) return;
3631
4180
  if (type === "move" && e.target && e.target.closest && e.target.closest("button,select,input")) return;
@@ -3753,7 +4302,7 @@ function DockModal() {
3753
4302
  ),
3754
4303
  import_react9.default.createElement(
3755
4304
  "div",
3756
- { className: "dockm-content" },
4305
+ { className: "dockm-content", ref: contentRef },
3757
4306
  import_react9.default.createElement(
3758
4307
  "div",
3759
4308
  { className: "dockm-content-head" },
@@ -3999,7 +4548,7 @@ function FeatureOverlays() {
3999
4548
  var ctxRef = { current: null };
4000
4549
  function apply(ctx) {
4001
4550
  ctxRef.current = ctx;
4002
- ensureCss();
4551
+ scheduleInitialCss();
4003
4552
  initFeatureState(BUILTIN_FEATURES.concat(PLANNED_FEATURES));
4004
4553
  const slots = ctx.get("slots");
4005
4554
  if (slots === void 0) return;