@musnows/scriverse 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +10 -6
- package/dist/app.js.map +1 -1
- package/dist/cli-contract.js +0 -1
- package/dist/cli-contract.js.map +1 -1
- package/dist/database.js +15 -2
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +162 -64
- package/dist/public/character-filters.d.ts +24 -0
- package/dist/public/character-filters.js +35 -0
- package/dist/public/character-version.js +0 -1
- package/dist/public/display-labels.d.ts +0 -1
- package/dist/public/display-labels.js +0 -4
- package/dist/public/index.html +6 -4
- package/dist/public/relationship-graph.js +108 -26
- package/dist/public/styles.css +47 -17
- package/dist/store.js +66 -47
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +1 -1
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/public/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<link rel="icon" href="/icon.svg?v=20260712" type="image/svg+xml">
|
|
11
11
|
<link rel="manifest" href="/site.webmanifest">
|
|
12
12
|
<link rel="stylesheet" href="/vendor/vditor/dist/index.css?v=3.11.2">
|
|
13
|
-
<link rel="stylesheet" href="/styles.css?v=20260725-
|
|
13
|
+
<link rel="stylesheet" href="/styles.css?v=20260725-develop-galaxy-ripple">
|
|
14
14
|
</head>
|
|
15
15
|
<body class="auth-pending">
|
|
16
16
|
<section id="auth-view" class="auth-view hidden" aria-labelledby="auth-title">
|
|
@@ -376,6 +376,7 @@
|
|
|
376
376
|
<button id="setting-editor-back" class="entity-editor-back" type="button">返回设定库</button>
|
|
377
377
|
<div class="entity-editor-heading">
|
|
378
378
|
<span id="setting-editor-eyebrow" class="eyebrow">新建设定</span>
|
|
379
|
+
<span id="setting-editor-readonly-badge" class="entity-editor-readonly-badge hidden">只读模式</span>
|
|
379
380
|
<input id="setting-editor-name" class="setting-editor-title-input" name="title" maxlength="200" placeholder="新建设定" aria-label="设定标题">
|
|
380
381
|
<div class="setting-editor-header-fields">
|
|
381
382
|
<label>分类<select id="setting-editor-category" name="category">
|
|
@@ -408,7 +409,7 @@
|
|
|
408
409
|
<button id="character-editor-close" class="entity-editor-back" type="button">返回角色列表</button>
|
|
409
410
|
<div>
|
|
410
411
|
<span id="character-editor-eyebrow" class="eyebrow">人物主档案</span>
|
|
411
|
-
<div class="character-editor-title-row"><h1 id="character-editor-title">新建角色</h1><span id="character-editor-version" class="character-version-badge">新档案</span></div>
|
|
412
|
+
<div class="character-editor-title-row"><h1 id="character-editor-title">新建角色</h1><span id="character-editor-version" class="character-version-badge">新档案</span><span id="character-editor-readonly-badge" class="entity-editor-readonly-badge hidden">只读模式</span></div>
|
|
412
413
|
</div>
|
|
413
414
|
<div class="character-editor-header-actions">
|
|
414
415
|
<button id="character-editor-edit" class="primary-button hidden" type="button">编辑角色</button>
|
|
@@ -442,7 +443,7 @@
|
|
|
442
443
|
<button id="knowledge-editor-close" class="entity-editor-back" type="button">返回列表</button>
|
|
443
444
|
<div>
|
|
444
445
|
<span id="knowledge-editor-eyebrow" class="eyebrow">世界档案</span>
|
|
445
|
-
<div class="character-editor-title-row"><h1 id="knowledge-editor-title">新建档案</h1><span id="knowledge-editor-version" class="character-version-badge">新档案</span></div>
|
|
446
|
+
<div class="character-editor-title-row"><h1 id="knowledge-editor-title">新建档案</h1><span id="knowledge-editor-version" class="character-version-badge">新档案</span><span id="knowledge-editor-readonly-badge" class="entity-editor-readonly-badge hidden">只读模式</span></div>
|
|
446
447
|
</div>
|
|
447
448
|
<div class="character-editor-header-actions">
|
|
448
449
|
<span id="knowledge-editor-header-note" class="knowledge-editor-header-note">独立资料页</span>
|
|
@@ -682,6 +683,7 @@
|
|
|
682
683
|
<output id="galaxy-stats" class="galaxy-stats" aria-live="polite" data-testid="galaxy-stats"></output>
|
|
683
684
|
<aside class="galaxy-controls" aria-label="银河图控制">
|
|
684
685
|
<button id="galaxy-stars" type="button" aria-pressed="true" data-testid="galaxy-stars">隐藏背景星点</button>
|
|
686
|
+
<button id="galaxy-grid" type="button" aria-pressed="false" data-testid="galaxy-grid">显示空间网格</button>
|
|
685
687
|
<button id="galaxy-rotation" type="button" aria-pressed="false" data-testid="galaxy-rotation">暂停旋转</button>
|
|
686
688
|
<button id="galaxy-zoom-out" type="button" aria-label="缩小">−</button>
|
|
687
689
|
<button id="galaxy-zoom-in" type="button" aria-label="放大">+</button>
|
|
@@ -697,6 +699,6 @@
|
|
|
697
699
|
<div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
|
|
698
700
|
<script id="vditorIconScript" src="/vendor/vditor/dist/js/icons/ant.js?v=3.11.2"></script>
|
|
699
701
|
<script src="/vendor/vditor/dist/index.min.js?v=3.11.2"></script>
|
|
700
|
-
<script type="module" src="/app.js?v=20260725-
|
|
702
|
+
<script type="module" src="/app.js?v=20260725-develop-galaxy-ripple"></script>
|
|
701
703
|
</body>
|
|
702
704
|
</html>
|
|
@@ -1551,29 +1551,87 @@ export function layoutGalaxy(graph, seed) {
|
|
|
1551
1551
|
return { nodes, byId };
|
|
1552
1552
|
}
|
|
1553
1553
|
|
|
1554
|
-
export function createGalaxyStarfield(seed, count =
|
|
1554
|
+
export function createGalaxyStarfield(seed, count = 7200) {
|
|
1555
1555
|
const random = seededRandom(hashString(seed));
|
|
1556
1556
|
const stars = [];
|
|
1557
1557
|
const armCount = 4;
|
|
1558
1558
|
for (let index = 0; index < count; index += 1) {
|
|
1559
|
-
const
|
|
1559
|
+
const population = random();
|
|
1560
|
+
const isCore = population < 0.62;
|
|
1561
|
+
const isHalo = !isCore && population > 0.9;
|
|
1562
|
+
const radius = isCore
|
|
1563
|
+
? 32 + Math.pow(random(), 1.72) * 720
|
|
1564
|
+
: 160 + Math.pow(random(), 0.68) * 1510;
|
|
1560
1565
|
const arm = index % armCount;
|
|
1561
1566
|
const armAngle = arm / armCount * Math.PI * 2;
|
|
1562
|
-
const angle =
|
|
1563
|
-
|
|
1567
|
+
const angle = isHalo
|
|
1568
|
+
? random() * Math.PI * 2
|
|
1569
|
+
: armAngle + radius * 0.0065 + (random() - 0.5) * (isCore ? 0.72 : 0.42 + radius / 1100);
|
|
1570
|
+
const thickness = isHalo ? 70 + radius * 0.2 : (isCore ? 8 + radius * 0.045 : 22 + radius * 0.105);
|
|
1564
1571
|
const temperature = random();
|
|
1572
|
+
const x = Math.cos(angle) * radius + (random() - 0.5) * (isCore ? 42 : 78);
|
|
1573
|
+
const z = Math.sin(angle) * radius + (random() - 0.5) * (isCore ? 42 : 78);
|
|
1565
1574
|
stars.push({
|
|
1566
|
-
x
|
|
1575
|
+
x,
|
|
1567
1576
|
y: (random() + random() + random() - 1.5) * thickness,
|
|
1568
|
-
z
|
|
1569
|
-
|
|
1570
|
-
|
|
1577
|
+
z,
|
|
1578
|
+
originX: x,
|
|
1579
|
+
originZ: z,
|
|
1580
|
+
vx: 0,
|
|
1581
|
+
vz: 0,
|
|
1582
|
+
size: isCore && random() > 0.94 ? 1.25 + random() * 1.25 : 0.38 + random() * 0.82,
|
|
1583
|
+
brightness: isCore ? 0.3 + random() * 0.7 : 0.16 + random() * 0.66,
|
|
1571
1584
|
color: temperature < 0.2 ? "255,218,176" : temperature > 0.78 ? "174,211,255" : "226,237,255"
|
|
1572
1585
|
});
|
|
1573
1586
|
}
|
|
1574
1587
|
return stars;
|
|
1575
1588
|
}
|
|
1576
1589
|
|
|
1590
|
+
export function stepGalaxyStarfieldPhysics(stars, attractor = null, options = {}) {
|
|
1591
|
+
const deltaMs = clamp(Number(options.deltaMs) || 16.667, 1, 50);
|
|
1592
|
+
const timeScale = deltaMs / 16.667;
|
|
1593
|
+
const influenceRadius = Math.max(1, Number(options.influenceRadius) || 210);
|
|
1594
|
+
const repulsionStrength = Number(options.repulsionStrength) || 5.5;
|
|
1595
|
+
const springStrength = Number(options.springStrength) || 0.006;
|
|
1596
|
+
const damping = clamp(Number(options.damping) || 0.84, 0, 1);
|
|
1597
|
+
let energy = 0;
|
|
1598
|
+
|
|
1599
|
+
for (const star of stars) {
|
|
1600
|
+
const originX = Number(star.originX ?? star.x);
|
|
1601
|
+
const originZ = Number(star.originZ ?? star.z);
|
|
1602
|
+
star.originX = originX;
|
|
1603
|
+
star.originZ = originZ;
|
|
1604
|
+
star.vx = Number(star.vx) || 0;
|
|
1605
|
+
star.vz = Number(star.vz) || 0;
|
|
1606
|
+
|
|
1607
|
+
if (attractor) {
|
|
1608
|
+
const deltaX = star.x - attractor.x;
|
|
1609
|
+
const deltaZ = star.z - attractor.z;
|
|
1610
|
+
const distance = Math.hypot(deltaX, deltaZ);
|
|
1611
|
+
if (distance < influenceRadius) {
|
|
1612
|
+
const angle = Math.atan2(star.originZ, star.originX);
|
|
1613
|
+
const normalX = distance > 0.001 ? deltaX / distance : Math.cos(angle);
|
|
1614
|
+
const normalZ = distance > 0.001 ? deltaZ / distance : Math.sin(angle);
|
|
1615
|
+
const falloff = 1 - distance / influenceRadius;
|
|
1616
|
+
const force = falloff * falloff * repulsionStrength * timeScale;
|
|
1617
|
+
star.vx += normalX * force;
|
|
1618
|
+
star.vz += normalZ * force;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
star.vx += (originX - star.x) * springStrength * timeScale;
|
|
1623
|
+
star.vz += (originZ - star.z) * springStrength * timeScale;
|
|
1624
|
+
const frameDamping = Math.pow(damping, timeScale);
|
|
1625
|
+
star.vx *= frameDamping;
|
|
1626
|
+
star.vz *= frameDamping;
|
|
1627
|
+
star.x += star.vx * timeScale;
|
|
1628
|
+
star.z += star.vz * timeScale;
|
|
1629
|
+
energy += Math.abs(star.vx) + Math.abs(star.vz) + Math.abs(originX - star.x) + Math.abs(originZ - star.z);
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
return energy;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1577
1635
|
export function projectGalaxyPoint(point, camera, viewport) {
|
|
1578
1636
|
const relativeX = point.x - Number(camera.targetX ?? 0);
|
|
1579
1637
|
const relativeY = point.y - Number(camera.targetY ?? 0);
|
|
@@ -1697,13 +1755,18 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
1697
1755
|
let animationFrame = 0;
|
|
1698
1756
|
let previousFrameTime = 0;
|
|
1699
1757
|
let cameraFocus = null;
|
|
1758
|
+
let draggedNode = null;
|
|
1759
|
+
let starPhysicsEnergy = 0;
|
|
1700
1760
|
let paused = false;
|
|
1701
1761
|
let starsVisible = true;
|
|
1762
|
+
let gridVisible = false;
|
|
1702
1763
|
let destroyed = false;
|
|
1703
1764
|
|
|
1704
1765
|
shell.classList.add("is-three-dimensional");
|
|
1705
1766
|
shell.dataset.sceneDimension = "3";
|
|
1706
1767
|
shell.dataset.starCount = String(stars.length);
|
|
1768
|
+
shell.dataset.gridVisible = "false";
|
|
1769
|
+
shell.dataset.starPhysicsEnergy = "0";
|
|
1707
1770
|
shell.dataset.rotationSpeed = String(GALAXY_ROTATION_RADIANS_PER_MS);
|
|
1708
1771
|
shell.dataset.layoutMinimumRadius = String(GALAXY_LAYOUT_CONFIG.minimumRadius);
|
|
1709
1772
|
shell.dataset.layoutRadialSpan = String(GALAXY_LAYOUT_CONFIG.radialSpan);
|
|
@@ -1743,24 +1806,26 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
1743
1806
|
context.fillStyle = backdrop;
|
|
1744
1807
|
context.fillRect(0, 0, width, height);
|
|
1745
1808
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1809
|
+
if (gridVisible) {
|
|
1810
|
+
context.lineWidth = 1;
|
|
1811
|
+
context.strokeStyle = "rgba(105,142,182,.06)";
|
|
1812
|
+
for (let offset = -1200; offset <= 1200; offset += 160) {
|
|
1813
|
+
const horizontalStart = project({ x: -1200, y: 0, z: offset }, width, height);
|
|
1814
|
+
const horizontalEnd = project({ x: 1200, y: 0, z: offset }, width, height);
|
|
1815
|
+
const verticalStart = project({ x: offset, y: 0, z: -1200 }, width, height);
|
|
1816
|
+
const verticalEnd = project({ x: offset, y: 0, z: 1200 }, width, height);
|
|
1817
|
+
if (horizontalStart.visible && horizontalEnd.visible) {
|
|
1818
|
+
context.beginPath();
|
|
1819
|
+
context.moveTo(horizontalStart.x, horizontalStart.y);
|
|
1820
|
+
context.lineTo(horizontalEnd.x, horizontalEnd.y);
|
|
1821
|
+
context.stroke();
|
|
1822
|
+
}
|
|
1823
|
+
if (verticalStart.visible && verticalEnd.visible) {
|
|
1824
|
+
context.beginPath();
|
|
1825
|
+
context.moveTo(verticalStart.x, verticalStart.y);
|
|
1826
|
+
context.lineTo(verticalEnd.x, verticalEnd.y);
|
|
1827
|
+
context.stroke();
|
|
1828
|
+
}
|
|
1764
1829
|
}
|
|
1765
1830
|
}
|
|
1766
1831
|
|
|
@@ -1938,6 +2003,10 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
1938
2003
|
}
|
|
1939
2004
|
}
|
|
1940
2005
|
if (!paused && !cameraDrag) camera.yaw += elapsed * GALAXY_ROTATION_RADIANS_PER_MS;
|
|
2006
|
+
if (draggedNode || starPhysicsEnergy > 0.01) {
|
|
2007
|
+
starPhysicsEnergy = stepGalaxyStarfieldPhysics(stars, draggedNode, { deltaMs: elapsed || 16.667 });
|
|
2008
|
+
shell.dataset.starPhysicsEnergy = starPhysicsEnergy.toFixed(3);
|
|
2009
|
+
}
|
|
1941
2010
|
drawScene();
|
|
1942
2011
|
animationFrame = window.requestAnimationFrame(renderFrame);
|
|
1943
2012
|
};
|
|
@@ -2072,6 +2141,7 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
2072
2141
|
scale: Number(button.dataset.projectedScale) || 1,
|
|
2073
2142
|
dragged: false
|
|
2074
2143
|
};
|
|
2144
|
+
draggedNode = node;
|
|
2075
2145
|
button.setPointerCapture(event.pointerId);
|
|
2076
2146
|
button.classList.add("is-dragging");
|
|
2077
2147
|
button.setAttribute("aria-grabbed", "true");
|
|
@@ -2099,6 +2169,7 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
2099
2169
|
if (!nodeDrag || event.pointerId !== nodeDrag.pointerId) return;
|
|
2100
2170
|
suppressClick = nodeDrag.dragged;
|
|
2101
2171
|
nodeDrag = null;
|
|
2172
|
+
if (draggedNode === node) draggedNode = null;
|
|
2102
2173
|
button.classList.remove("is-dragging");
|
|
2103
2174
|
button.setAttribute("aria-grabbed", "false");
|
|
2104
2175
|
if (button.hasPointerCapture(event.pointerId)) button.releasePointerCapture(event.pointerId);
|
|
@@ -2156,9 +2227,13 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
2156
2227
|
if (!dialog.open) dialog.showModal();
|
|
2157
2228
|
paused = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
2158
2229
|
starsVisible = true;
|
|
2230
|
+
gridVisible = false;
|
|
2159
2231
|
background.classList.remove("hidden-stars");
|
|
2232
|
+
shell.dataset.gridVisible = "false";
|
|
2160
2233
|
dialog.querySelector("#galaxy-stars").setAttribute("aria-pressed", "true");
|
|
2161
2234
|
dialog.querySelector("#galaxy-stars").textContent = "隐藏背景星点";
|
|
2235
|
+
dialog.querySelector("#galaxy-grid").setAttribute("aria-pressed", "false");
|
|
2236
|
+
dialog.querySelector("#galaxy-grid").textContent = "显示空间网格";
|
|
2162
2237
|
updateRotationControl();
|
|
2163
2238
|
stats.value = `${graph.stats.nodeCount} 个节点 / ${graph.stats.edgeCount} 条关系`;
|
|
2164
2239
|
renderNodes();
|
|
@@ -2182,6 +2257,13 @@ export function createGalaxyRenderer(dialog, graph, options = {}) {
|
|
|
2182
2257
|
event.currentTarget.textContent = starsVisible ? "隐藏背景星点" : "显示背景星点";
|
|
2183
2258
|
drawScene();
|
|
2184
2259
|
});
|
|
2260
|
+
listen(dialog.querySelector("#galaxy-grid"), "click", (event) => {
|
|
2261
|
+
gridVisible = !gridVisible;
|
|
2262
|
+
shell.dataset.gridVisible = String(gridVisible);
|
|
2263
|
+
event.currentTarget.setAttribute("aria-pressed", String(gridVisible));
|
|
2264
|
+
event.currentTarget.textContent = gridVisible ? "隐藏空间网格" : "显示空间网格";
|
|
2265
|
+
drawScene();
|
|
2266
|
+
});
|
|
2185
2267
|
listen(dialog.querySelector("#galaxy-rotation"), "click", () => {
|
|
2186
2268
|
paused = !paused;
|
|
2187
2269
|
updateRotationControl();
|
package/dist/public/styles.css
CHANGED
|
@@ -758,7 +758,7 @@ body.work-viewer-mode .character-editor-actions { display: none !important; }
|
|
|
758
758
|
.api-key-result label { display: grid; gap: 6px; color: var(--muted); font-size: 11px; }
|
|
759
759
|
.api-key-result input { width: 100%; min-height: 38px; padding: 9px 10px; background: var(--surface); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; }
|
|
760
760
|
.api-key-result button { min-height: 38px; }
|
|
761
|
-
.book-access-badge { display: inline-flex; width: fit-content; margin-top: 7px; padding: 2px 7px; border-radius: 10px; background: var(--
|
|
761
|
+
.book-access-badge { display: inline-flex; width: fit-content; margin-top: 7px; padding: 2px 7px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--accent-dark); font-size: 9px; }
|
|
762
762
|
.book-shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)); gap: clamp(22px, 3vw, 38px); width: 100%; min-width: 0; max-width: 1400px; margin: 0 auto; }
|
|
763
763
|
.book-card { position: relative; min-width: 0; border: 0; background: transparent; text-align: left; }
|
|
764
764
|
.book-open { width: 100%; padding: 0; border: 0; background: transparent; text-align: left; }
|
|
@@ -877,13 +877,13 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
877
877
|
.chapter-add-button { flex: none; }
|
|
878
878
|
.volume-chapters { display: block; }
|
|
879
879
|
.volume-node.is-collapsed .volume-chapters { display: none; }
|
|
880
|
-
.chapter-node { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: 8px; width: calc(100% + 6px); padding: 9px
|
|
880
|
+
.chapter-node { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: 8px; width: calc(100% + 6px); padding: 9px 8px 9px 20px; border: 0; background: transparent; border-radius: 4px; text-align: left; font-size: 12px; }
|
|
881
881
|
.chapter-node:hover, .chapter-node.active { background: var(--row-active); }
|
|
882
882
|
.chapter-node.active { color: var(--accent-dark); font-weight: 700; }
|
|
883
883
|
.chapter-node > span:first-child { min-width: 0; overflow-wrap: anywhere; line-height: 1.45; white-space: normal; }
|
|
884
884
|
.chapter-node-meta { display: flex; flex: none; align-items: center; gap: 5px; margin-left: auto; overflow: visible; white-space: nowrap; }
|
|
885
885
|
.chapter-node small { color: var(--muted); font-size: 9px; }
|
|
886
|
-
.chapter-type-badge { max-width: 58px; overflow: hidden; padding: 2px 5px; border-radius: 9px; background:
|
|
886
|
+
.chapter-type-badge { max-width: 58px; overflow: hidden; padding: 2px 5px; border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--line)); border-radius: 9px; background: color-mix(in srgb, var(--accent) 12%, var(--surface)); color: var(--accent-dark); font-size: 8px; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }
|
|
887
887
|
|
|
888
888
|
.ghost-button, .primary-button { border-radius: 4px; padding: 8px 13px; font-size: 12px; }
|
|
889
889
|
.ghost-button { border: 1px solid var(--line); background: transparent; }
|
|
@@ -957,6 +957,11 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
957
957
|
.record-card p { color: var(--muted); font-size: 12px; line-height: 1.55; margin: 0; white-space: pre-wrap; }
|
|
958
958
|
.record-card small { color: var(--accent); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; }
|
|
959
959
|
.settings-layout-toolbar, .module-layout-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-bottom: 0; }
|
|
960
|
+
.module-filter-toggle { display: inline-grid; width: 36px; height: 36px; place-items: center; padding: 8px; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); }
|
|
961
|
+
.module-filter-toggle:hover, .module-filter-toggle[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
|
|
962
|
+
.module-filter-toggle svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.7; }
|
|
963
|
+
.module-filter-toggle + .module-layout-toolbar { order: 2; }
|
|
964
|
+
.module-filter-toggle ~ #module-create-button { order: 3; }
|
|
960
965
|
.settings-layout-hint { color: var(--muted); font-size: 10px; }
|
|
961
966
|
.settings-layout-toggle, .module-layout-toggle { display: inline-flex; border: 1px solid var(--line); border-radius: 4px; overflow: hidden; background: var(--surface); }
|
|
962
967
|
.settings-layout-toggle button { min-height: 34px; padding: 0 12px; border: 0; border-right: 1px solid var(--line); background: transparent; color: var(--muted); font-size: 11px; }
|
|
@@ -977,18 +982,31 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
977
982
|
.setting-row .card-actions, .module-row .card-actions { margin-top: 0; flex-wrap: wrap; justify-content: flex-end; }
|
|
978
983
|
.module-row .card-actions > .record-card-edit { position: static; }
|
|
979
984
|
.character-card { cursor: pointer; }
|
|
985
|
+
.character-filter-toolbar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) auto; gap: 12px; align-items: start; width: 100%; min-width: 0; box-sizing: border-box; margin-bottom: 18px; padding: 12px 14px; border: 1px solid var(--line); background: var(--surface-soft); }
|
|
986
|
+
.character-filter-dropdown { position: relative; min-width: 0; }
|
|
987
|
+
.character-filter-dropdown summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 38px; padding: 0 11px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--ink); cursor: pointer; list-style: none; }
|
|
988
|
+
.character-filter-dropdown summary::-webkit-details-marker { display: none; }
|
|
989
|
+
.character-filter-dropdown summary::after { content: "⌄"; color: var(--muted); font-size: 14px; }
|
|
990
|
+
.character-filter-dropdown[open] summary { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 14%, transparent); }
|
|
991
|
+
.character-filter-dropdown[open] summary::after { content: "⌃"; }
|
|
992
|
+
.character-filter-dropdown summary span { color: var(--ink); font-size: 11px; }
|
|
993
|
+
.character-filter-dropdown summary strong { overflow: hidden; color: var(--muted); font-size: 10px; font-weight: 400; text-overflow: ellipsis; white-space: nowrap; }
|
|
994
|
+
.character-filter-options { display: grid; position: absolute; z-index: 20; top: calc(100% + 6px); right: 0; left: 0; max-height: 230px; overflow-y: auto; padding: 7px; border: 1px solid var(--line-strong); border-radius: 4px; background: var(--surface); box-shadow: 0 12px 28px rgb(0 0 0 / 18%); }
|
|
995
|
+
.character-filter-option { display: flex; grid-template-columns: auto 1fr; align-items: center; gap: 8px; padding: 7px 6px; color: var(--ink); cursor: pointer; font-size: 11px; line-height: 1.35; }
|
|
996
|
+
.character-filter-option:hover { background: var(--surface-soft); }
|
|
997
|
+
.character-filter-option input { accent-color: var(--accent); margin: 0; }
|
|
998
|
+
.character-filter-toolbar-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; min-height: 38px; }
|
|
999
|
+
.character-filter-result-count { color: var(--muted); font-size: 11px; white-space: nowrap; }
|
|
1000
|
+
.character-filter-toolbar-actions button:disabled { cursor: default; opacity: .45; }
|
|
980
1001
|
.character-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
981
|
-
.character-audit-panel { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-bottom: 18px; padding: 15px 17px; border: 1px solid var(--line); background: var(--surface-soft); }
|
|
982
|
-
.character-audit-panel div { display: grid; gap: 5px; }
|
|
983
|
-
.character-audit-panel small { max-width: 760px; color: var(--muted); line-height: 1.55; }
|
|
984
1002
|
.character-duplicate-review { grid-column: 1 / -1; }
|
|
985
1003
|
.character-duplicate-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 14px 0; }
|
|
986
1004
|
.character-duplicate-pair section { display: grid; align-content: start; gap: 8px; min-width: 0; padding: 13px; border: 1px solid var(--line); background: var(--surface-soft); }
|
|
987
1005
|
.character-duplicate-pair section > small { color: var(--muted); }
|
|
988
1006
|
.character-duplicate-pair section p { margin: 0; }
|
|
989
1007
|
.character-duplicate-evidence { display: grid; gap: 8px; margin: 13px 0; padding: 0; list-style: none; }
|
|
990
|
-
.character-duplicate-evidence li { display: grid; gap: 5px; padding: 10px 12px; border-left: 2px solid var(--accent); background: var(--surface-soft); }
|
|
991
|
-
.character-duplicate-evidence q { color: var(--text); line-height: 1.
|
|
1008
|
+
.character-duplicate-evidence li { display: grid; gap: 5px; padding: 10px 12px; border-left: 2px solid var(--accent); background: var(--surface-soft); font-size: 12px; }
|
|
1009
|
+
.character-duplicate-evidence q { color: var(--text); font-size: 12px; line-height: 1.45; }
|
|
992
1010
|
.character-duplicate-evidence small, .review-resolution-note { color: var(--muted); }
|
|
993
1011
|
.character-duplicate-actions { flex-wrap: wrap; }
|
|
994
1012
|
.card-actions { display: flex; gap: 6px; margin-top: 15px; }
|
|
@@ -1007,8 +1025,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1007
1025
|
.provider-card .model-pill { max-width: 100%; margin: 0; border: 0; text-align: left; white-space: normal; cursor: pointer; }
|
|
1008
1026
|
.provider-card .model-pill:hover, .provider-card .model-pill:focus-visible { background: var(--surface-hover); color: var(--ink); }
|
|
1009
1027
|
.provider-card .card-actions { flex-wrap: wrap; }
|
|
1010
|
-
.pill { display: inline-block; padding: 3px 7px; margin: 0 4px 4px 0; border-radius: 12px; background: var(--
|
|
1011
|
-
.organization-links { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin: 8px 0 6px; }.organization-links b { color: var(--muted); font-size: 9px; font-weight: 500; }.organization-links .pill { margin: 0; }.organization-empty { color: var(--muted); font-size: 9px; }.organization-pill { color: var(--accent-dark); background:
|
|
1028
|
+
.pill { display: inline-block; padding: 3px 7px; margin: 0 4px 4px 0; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: var(--muted); font-size: 9px; }
|
|
1029
|
+
.organization-links { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin: 8px 0 6px; }.organization-links b { color: var(--muted); font-size: 9px; font-weight: 500; }.organization-links .pill { margin: 0; }.organization-empty { color: var(--muted); font-size: 9px; }.organization-pill { border: 1px solid color-mix(in srgb, var(--accent) 48%, var(--line)); color: var(--accent-dark); background: color-mix(in srgb, var(--accent) 20%, var(--surface)); }.organization-settings { margin: 10px 0 6px; }.organization-members { margin-top: 9px !important; }.relationship-keyword { white-space: nowrap; }
|
|
1012
1030
|
.race-settings { display: flex; flex-wrap: wrap; gap: 5px; margin: 10px 0 6px; }.race-settings .pill { margin: 0; }.race-members { margin-top: 9px !important; }
|
|
1013
1031
|
.race-tree { display: grid; gap: 12px; }
|
|
1014
1032
|
.race-tree-node { min-width: 0; }
|
|
@@ -1339,9 +1357,9 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1339
1357
|
.galaxy-node { --node-size: 12px; position: absolute; left: 0; top: 0; display: grid; grid-template-rows: var(--node-size) auto; justify-items: center; align-items: start; gap: 5px; padding: 8px; border: 0; background: transparent; color: #edf7ff; cursor: grab; touch-action: none; pointer-events: auto; transform-origin: center; opacity: var(--depth-opacity, 1); will-change: transform, opacity; }
|
|
1340
1358
|
.galaxy-node i { position: relative; isolation: isolate; width: var(--node-size); height: var(--node-size); border-radius: 50%; background: radial-gradient(circle at 32% 27%, var(--node-core, #fff) 0 7%, color-mix(in srgb, var(--node-color) 62%, #fff) 18%, var(--node-color) 52%, var(--node-rim, #07101f) 100%); box-shadow: inset -3px -4px 7px color-mix(in srgb, var(--node-rim, #07101f) 74%, transparent), 0 0 4px rgba(255,255,255,.82), 0 0 calc(7px + var(--node-glow) * 11px) var(--node-color), 0 0 calc(15px + var(--node-glow) * 25px) var(--node-atmosphere, color-mix(in srgb, var(--node-color) 72%, transparent)); filter: brightness(var(--node-brightness)); transition: filter .18s ease, box-shadow .18s ease; }
|
|
1341
1359
|
.galaxy-node i::before, .galaxy-node i::after { content: ""; position: absolute; pointer-events: none; }
|
|
1342
|
-
.galaxy-node i::before { z-index: -1; inset: -
|
|
1360
|
+
.galaxy-node i::before { z-index: -1; inset: -34%; border-radius: 50%; background: radial-gradient(circle, var(--node-atmosphere) 0, transparent 68%); opacity: .64; }
|
|
1343
1361
|
.galaxy-node[data-celestial-type="star"] i { background: radial-gradient(circle at 38% 34%, #fff 0 10%, var(--node-core) 22%, var(--node-color) 53%, var(--node-rim) 100%); box-shadow: 0 0 5px #fff, 0 0 calc(10px + var(--node-glow) * 15px) var(--node-color), 0 0 calc(24px + var(--node-glow) * 34px) var(--node-atmosphere); }
|
|
1344
|
-
.galaxy-node[data-celestial-type="star"] i::before { inset: -
|
|
1362
|
+
.galaxy-node[data-celestial-type="star"] i::before { inset: -48%; opacity: .92; background: radial-gradient(circle, var(--node-atmosphere) 0 12%, transparent 66%); }
|
|
1345
1363
|
.galaxy-node[data-celestial-type="gas-giant"] i { background: linear-gradient(168deg, transparent 0 17%, color-mix(in srgb, var(--node-core) 78%, transparent) 18% 25%, transparent 26% 40%, color-mix(in srgb, var(--node-rim) 64%, transparent) 41% 50%, transparent 51% 68%, color-mix(in srgb, var(--node-core) 54%, transparent) 69% 75%, transparent 76%), radial-gradient(circle at 34% 28%, var(--node-core) 0 7%, var(--node-color) 42%, var(--node-rim) 100%); }
|
|
1346
1364
|
.galaxy-node[data-celestial-type="ringed"] i::after { z-index: 2; left: 50%; top: 50%; width: 168%; height: 48%; border: 1px solid var(--node-ring); border-left-color: color-mix(in srgb, var(--node-ring) 28%, transparent); border-right-color: color-mix(in srgb, var(--node-ring) 88%, #fff); border-radius: 50%; box-shadow: 0 0 3px var(--node-atmosphere); transform: translate(-50%, -50%) rotate(-19deg); }
|
|
1347
1365
|
.galaxy-node[data-celestial-type="ocean"] i { background: radial-gradient(ellipse at 67% 63%, color-mix(in srgb, var(--node-core) 48%, transparent) 0 10%, transparent 12%), radial-gradient(circle at 28% 24%, var(--node-core) 0 6%, var(--node-color) 38%, color-mix(in srgb, var(--node-color) 58%, #0b2f62) 72%, var(--node-rim) 100%); }
|
|
@@ -1640,7 +1658,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1640
1658
|
.character-card h3 { margin-bottom: 5px; }
|
|
1641
1659
|
.character-identity { margin: 0 0 6px !important; color: var(--ink) !important; font-weight: 600; line-height: 1.55 !important; }
|
|
1642
1660
|
.character-aliases { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 0; }
|
|
1643
|
-
.character-aliases .pill { margin: 0; }
|
|
1661
|
+
.character-aliases .pill { margin: 0; border: 1px solid var(--line); background: var(--surface); }
|
|
1644
1662
|
.character-code { display: flex; align-items: center; gap: 7px; margin-top: 10px; color: var(--muted); font-size: 10px; }
|
|
1645
1663
|
.character-species { display: grid; grid-template-columns: max-content minmax(0, 1fr); align-items: center; gap: 6px; margin-top: 8px; color: var(--muted); font-size: 10px; }
|
|
1646
1664
|
.character-species b { font-weight: 500; }
|
|
@@ -1683,6 +1701,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1683
1701
|
@media (max-width: 560px) {
|
|
1684
1702
|
.import-mode-options { grid-template-columns: 1fr; }
|
|
1685
1703
|
.import-mode-dialog .dialog-actions { flex-wrap: wrap; }
|
|
1704
|
+
.character-filter-toolbar { grid-template-columns: minmax(0, 1fr); }
|
|
1705
|
+
.character-filter-toolbar-actions { justify-content: flex-start; }
|
|
1686
1706
|
}
|
|
1687
1707
|
.entity-editor-open { overflow: hidden; }
|
|
1688
1708
|
.preview-record-card { cursor: pointer; }
|
|
@@ -1701,6 +1721,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1701
1721
|
.entity-editor-header, .character-editor-header { display: grid; grid-template-columns: minmax(160px, 1fr) minmax(0, 2fr) minmax(160px, 1fr); align-items: center; gap: 24px; min-height: 78px; padding: 14px clamp(18px, 3vw, 44px); border-bottom: 1px solid var(--line); background: var(--panel); }
|
|
1702
1722
|
.entity-editor-heading { min-width: 0; text-align: center; }
|
|
1703
1723
|
.entity-editor-heading h1 { overflow: hidden; margin: 2px 0 0; font-size: 24px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
|
|
1724
|
+
.entity-editor-readonly-badge { display: inline-block; width: fit-content; margin: 0 auto; padding: 3px 7px; border: 1px solid color-mix(in srgb, var(--muted) 55%, var(--line)); border-radius: 999px; color: var(--muted); font-size: 10px; line-height: 1.2; }
|
|
1725
|
+
.character-editor-title-row .entity-editor-readonly-badge { margin-left: 6px; vertical-align: middle; }
|
|
1704
1726
|
.entity-editor-header > .primary-button { justify-self: end; min-width: 112px; }
|
|
1705
1727
|
.entity-editor-back { justify-self: start; min-height: 36px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); font-size: 11px; }
|
|
1706
1728
|
.entity-editor-back::before { content: "←"; margin-right: 7px; }
|
|
@@ -1731,8 +1753,13 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1731
1753
|
.vditor-editor-host.vditor { height: 100% !important; min-height: 0; overflow: hidden; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); color: var(--ink); }
|
|
1732
1754
|
.vditor-editor-host.vditor:not(.vditor--dark) { --border-color: var(--line); --panel-background-color: var(--surface); --toolbar-background-color: var(--surface-soft); --toolbar-icon-color: var(--muted); --toolbar-icon-hover-color: var(--accent-dark); --textarea-background-color: var(--surface); --textarea-text-color: var(--ink); --heading-border-color: var(--line); --blockquote-color: var(--muted); }
|
|
1733
1755
|
.vditor-editor-host.vditor--dark { --border-color: var(--line); --panel-background-color: var(--surface); --toolbar-background-color: var(--surface-soft); --toolbar-icon-color: var(--muted); --toolbar-icon-hover-color: var(--accent); --textarea-background-color: var(--surface); --textarea-text-color: var(--ink); --heading-border-color: var(--line); --blockquote-color: var(--muted); }
|
|
1734
|
-
.vditor-editor-host .vditor-toolbar { flex: 0 0 auto; }
|
|
1735
|
-
.vditor-editor-host .markdown-word-count { display: inline-flex; align-items: center; min-height: 28px; margin-left:
|
|
1756
|
+
.vditor-editor-host .vditor-toolbar { display: flex; align-items: center; flex: 0 0 auto; }
|
|
1757
|
+
.vditor-editor-host .markdown-word-count { display: inline-flex; align-items: center; align-self: center; min-height: 28px; margin-left: 24px; padding: 0 10px; color: var(--muted); font: 10px/1 var(--font-latin), var(--font-cjk), sans-serif; white-space: nowrap; }
|
|
1758
|
+
.vditor-editor-host .vditor-content { position: relative; }
|
|
1759
|
+
.vditor-editor-host .vditor-line-numbers { display: none; position: absolute; z-index: 1; inset: 0 auto 0 0; width: 42px; padding: 16px 8px 16px 0; overflow: hidden; border-right: 1px solid var(--line); background: color-mix(in srgb, var(--surface-soft) 88%, transparent); color: var(--muted); font: 12px/1.75 var(--font-latin), monospace; text-align: right; user-select: none; pointer-events: none; }
|
|
1760
|
+
.vditor-editor-host.vditor.show-line-numbers .vditor-line-numbers { display: grid; align-content: start; }
|
|
1761
|
+
.vditor-editor-host.vditor.show-line-numbers .vditor-ir, .vditor-editor-host.vditor.show-line-numbers .vditor-wysiwyg, .vditor-editor-host.vditor.show-line-numbers .vditor-sv textarea { padding-left: 42px; }
|
|
1762
|
+
.vditor-editor-host .vditor-line-number-button[aria-pressed="true"] { color: var(--accent-dark); background: color-mix(in srgb, var(--accent) 16%, transparent); }
|
|
1736
1763
|
.vditor-editor-host .vditor-content { min-height: 0; }
|
|
1737
1764
|
.vditor-editor-host .vditor-reset { color: var(--ink); font-family: var(--font-cjk), var(--font-latin), sans-serif; }
|
|
1738
1765
|
.vditor-editor-host .vditor-ir, .vditor-editor-host .vditor-sv, .vditor-editor-host .vditor-wysiwyg { background: var(--surface); color: var(--ink); }
|
|
@@ -1837,11 +1864,14 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1837
1864
|
.character-section-editor-header > div { grid-column: 1; grid-row: 1; justify-self: center; text-align: center; }
|
|
1838
1865
|
.character-section-editor-header .entity-editor-back { grid-column: 1; grid-row: 1; z-index: 1; }
|
|
1839
1866
|
.character-section-editor-header h2 { margin: 3px 0 0; font-size: 22px; font-weight: 600; }
|
|
1867
|
+
.character-section-editor-title-input { width: min(100%, 520px); margin: 3px auto 0; padding: 0 0 4px; border: 0; border-bottom: 1px solid transparent; border-radius: 0; background: transparent; color: var(--ink); font-size: 22px; font-weight: 600; line-height: 1.2; text-align: center; }
|
|
1868
|
+
.character-section-editor-title-input::placeholder { color: var(--ink); opacity: .92; }
|
|
1869
|
+
.character-section-editor-title-input:focus { border-color: var(--accent); box-shadow: none; }
|
|
1840
1870
|
.character-markdown-editor { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 12px; min-height: 0; padding: 16px 22px 18px; overflow: hidden; background: var(--surface-soft); }
|
|
1841
1871
|
.character-markdown-editor > .vditor-editor-host { width: 100%; max-width: 960px; justify-self: center; }
|
|
1842
1872
|
.character-markdown-editor > .vditor-editor-host.vditor { border-color: color-mix(in srgb, var(--accent) 22%, var(--line)); box-shadow: 0 12px 34px color-mix(in srgb, var(--ink) 12%, transparent); transition: border-color .16s ease, box-shadow .16s ease; }
|
|
1843
1873
|
.character-markdown-editor > .vditor-editor-host.vditor:focus-within { border-color: color-mix(in srgb, var(--accent) 62%, var(--line)); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 15%, transparent), 0 16px 42px color-mix(in srgb, var(--ink) 16%, transparent); }
|
|
1844
|
-
.character-markdown-editor-meta { display: grid; grid-template-columns: minmax(
|
|
1874
|
+
.character-markdown-editor-meta { display: grid; grid-template-columns: minmax(160px, .55fr) minmax(280px, 1.45fr); gap: 12px; }
|
|
1845
1875
|
.character-markdown-editor label { display: grid; gap: 6px; color: var(--muted); font-size: 10px; }
|
|
1846
1876
|
.character-markdown-editor input, .character-markdown-editor select, .character-markdown-editor textarea { width: 100%; padding: 9px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--ink); font-size: 12px; }
|
|
1847
1877
|
.character-markdown-summary-field textarea { min-height: 42px; height: 42px; resize: vertical; }
|
|
@@ -1868,7 +1898,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1868
1898
|
.character-version-card-heading span, .character-version-card-heading time { color: var(--muted); font-size: 8px; }
|
|
1869
1899
|
.character-version-card p { margin: 0; color: var(--ink); font-size: 10px; line-height: 1.5; overflow-wrap: anywhere; }
|
|
1870
1900
|
.character-version-changes { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
1871
|
-
.character-version-changes span { padding: 2px 6px; border-radius: 10px; background: var(--
|
|
1901
|
+
.character-version-changes span { padding: 2px 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--muted); font-size: 8px; }
|
|
1872
1902
|
.character-version-card > button { justify-self: end; padding: 6px 8px; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); font-size: 9px; }
|
|
1873
1903
|
.character-version-card > button:not(:disabled):hover { border-color: var(--accent); color: var(--accent-dark); }
|
|
1874
1904
|
.character-version-card > button.is-confirming { border-color: var(--accent); background: var(--accent); color: #fff; }
|