@musnows/scriverse 0.4.0 → 0.4.2
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/README.en.md +1 -1
- package/README.md +3 -1
- package/dist/app.js +13 -1
- package/dist/app.js.map +1 -1
- package/dist/database.js +36 -0
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +317 -134
- package/dist/public/character-version.js +3 -1
- package/dist/public/index.html +38 -9
- package/dist/public/keyboard-shortcuts.d.ts +9 -0
- package/dist/public/keyboard-shortcuts.js +4 -0
- package/dist/public/relationship-graph.js +62 -2
- package/dist/public/styles.css +173 -48
- package/dist/public/work-permissions.js +1 -1
- package/dist/server-runtime.js +5 -1
- package/dist/server-runtime.js.map +1 -1
- package/dist/store.js +10 -7
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +75 -3
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/work-permissions.js +1 -1
- package/package.json +1 -1
package/dist/public/styles.css
CHANGED
|
@@ -19,6 +19,39 @@
|
|
|
19
19
|
--toast-fg: #fffefa;
|
|
20
20
|
--toast-error-bg: #6e2e21;
|
|
21
21
|
--toast-error-fg: #fffefa;
|
|
22
|
+
--relationship-card-border: #d9dfe8;
|
|
23
|
+
--relationship-card-surface: #f4f6fa;
|
|
24
|
+
--relationship-toolbar-surface: #f8fafc;
|
|
25
|
+
--relationship-toolbar-ink: #28364c;
|
|
26
|
+
--relationship-toolbar-muted: #6b7890;
|
|
27
|
+
--relationship-control-border: #cdd6e4;
|
|
28
|
+
--relationship-control-ink: #53627a;
|
|
29
|
+
--relationship-control-hover-border: #9dacbf;
|
|
30
|
+
--relationship-control-hover-surface: #e8edf4;
|
|
31
|
+
--relationship-control-hover-ink: #27364e;
|
|
32
|
+
--relationship-network-surface: #eef2f7;
|
|
33
|
+
--relationship-edge: rgba(76,93,120,.34);
|
|
34
|
+
--relationship-edge-directed: rgba(70,88,117,.58);
|
|
35
|
+
--relationship-edge-pending: rgba(107,121,145,.5);
|
|
36
|
+
--relationship-edge-highlight: rgba(45,80,133,.78);
|
|
37
|
+
--relationship-edge-selected: rgba(38,69,118,.9);
|
|
38
|
+
--relationship-label-ink: rgba(40,52,73,.9);
|
|
39
|
+
--relationship-label-stroke: #eef2f7;
|
|
40
|
+
--relationship-node-ink: rgba(36,51,74,.9);
|
|
41
|
+
--relationship-node-label: rgba(48,62,86,.88);
|
|
42
|
+
--relationship-node-label-active: rgba(24,44,71,.98);
|
|
43
|
+
--relationship-node-text-shadow: 0 1px 2px rgba(255,255,255,.72);
|
|
44
|
+
--relationship-node-hover-shadow: 0 0 10px rgba(91,124,166,.28), 0 0 18px var(--node-glow, rgba(139,144,153,.4));
|
|
45
|
+
--relationship-node-selected-shadow: 0 0 10px rgba(91,124,166,.34), 0 0 20px var(--node-glow, rgba(139,144,153,.46));
|
|
46
|
+
--relationship-node-endpoint-shadow: 0 0 10px rgba(91,124,166,.3), 0 0 18px var(--node-glow, rgba(139,144,153,.4));
|
|
47
|
+
--relationship-node-dragging-shadow: 0 0 10px rgba(91,124,166,.38), 0 0 18px var(--node-glow, rgba(139,144,153,.46));
|
|
48
|
+
--relationship-focus: #61708a;
|
|
49
|
+
--relationship-focus-strong: #31445e;
|
|
50
|
+
--relationship-focus-muted: #78869a;
|
|
51
|
+
--relationship-detail-border: #c9d3e1;
|
|
52
|
+
--relationship-detail-surface: rgba(248,250,253,.96);
|
|
53
|
+
--relationship-detail-ink: #2b3a52;
|
|
54
|
+
--relationship-detail-muted: #67758c;
|
|
22
55
|
--font-latin: "SFMono-Regular", "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono";
|
|
23
56
|
--font-cjk: "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", "Heiti SC";
|
|
24
57
|
--editor-font-size: 17px;
|
|
@@ -51,9 +84,9 @@
|
|
|
51
84
|
.pending-shelf-mode .auth-pending .topbar { grid-template-columns: 280px 1fr auto; }
|
|
52
85
|
.pending-shelf-mode .auth-pending .left-panel, .pending-shelf-mode .auth-pending .ai-panel { display: none; }
|
|
53
86
|
.pending-shelf-mode .auth-pending .main-panel { grid-column: 1 / -1; }
|
|
54
|
-
.auth-view { position: fixed; inset: 0; z-index: 1000; display: grid;
|
|
87
|
+
.auth-view { position: fixed; inset: 0; z-index: 1000; display: grid; grid-template-rows: minmax(min-content, 1fr) auto; gap: 18px; place-items: center; padding: 24px; overflow-y: auto; overscroll-behavior: contain; background: radial-gradient(circle at 18% 16%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 34%), var(--paper); }
|
|
55
88
|
.auth-view.hidden { display: none; }
|
|
56
|
-
.auth-card { box-sizing: border-box; width: min(440px, 100%); padding: 34px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); box-shadow: var(--shadow); }
|
|
89
|
+
.auth-card { align-self: center; box-sizing: border-box; width: min(440px, 100%); padding: 34px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); box-shadow: var(--shadow); }
|
|
57
90
|
.auth-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 34px; }
|
|
58
91
|
.auth-brand div { display: grid; }
|
|
59
92
|
.auth-brand small { color: var(--muted); }
|
|
@@ -185,6 +218,7 @@
|
|
|
185
218
|
.auth-captcha-image img[hidden], .auth-captcha-placeholder[hidden] { display: none; }
|
|
186
219
|
.auth-captcha-placeholder { color: var(--muted); font-size: 13px; padding: 0 14px; white-space: nowrap; }
|
|
187
220
|
.auth-captcha-hint { margin: -8px 0 0; color: var(--muted); font-size: 12px; line-height: 1.4; }
|
|
221
|
+
.auth-security-hint { margin: -8px 0 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
|
|
188
222
|
.auth-error { min-height: 20px; margin: 14px 0 0 !important; color: var(--accent-dark) !important; }
|
|
189
223
|
|
|
190
224
|
:root[data-theme="dark"] {
|
|
@@ -208,6 +242,39 @@
|
|
|
208
242
|
--toast-fg: #171714;
|
|
209
243
|
--toast-error-bg: #e08a72;
|
|
210
244
|
--toast-error-fg: #171714;
|
|
245
|
+
--relationship-card-border: #1c1c24;
|
|
246
|
+
--relationship-card-surface: #12121a;
|
|
247
|
+
--relationship-toolbar-surface: #12121a;
|
|
248
|
+
--relationship-toolbar-ink: #e8e8ef;
|
|
249
|
+
--relationship-toolbar-muted: #7a7a88;
|
|
250
|
+
--relationship-control-border: #2a2a36;
|
|
251
|
+
--relationship-control-ink: #a8a8b4;
|
|
252
|
+
--relationship-control-hover-border: #4a4a58;
|
|
253
|
+
--relationship-control-hover-surface: #1a1a24;
|
|
254
|
+
--relationship-control-hover-ink: #f0f0f5;
|
|
255
|
+
--relationship-network-surface: #12121a;
|
|
256
|
+
--relationship-edge: rgba(255,255,255,.26);
|
|
257
|
+
--relationship-edge-directed: rgba(214,218,232,.5);
|
|
258
|
+
--relationship-edge-pending: rgba(255,255,255,.18);
|
|
259
|
+
--relationship-edge-highlight: rgba(255,255,255,.72);
|
|
260
|
+
--relationship-edge-selected: rgba(220,220,235,.88);
|
|
261
|
+
--relationship-label-ink: rgba(230,230,240,.88);
|
|
262
|
+
--relationship-label-stroke: #12121a;
|
|
263
|
+
--relationship-node-ink: rgba(245,245,250,.88);
|
|
264
|
+
--relationship-node-label: rgba(235,235,245,.78);
|
|
265
|
+
--relationship-node-label-active: rgba(255,255,255,.95);
|
|
266
|
+
--relationship-node-text-shadow: 0 1px 2px rgba(0,0,0,.65);
|
|
267
|
+
--relationship-node-hover-shadow: 0 0 10px rgba(255,255,255,.5), 0 0 18px var(--node-glow, rgba(139,144,153,.55));
|
|
268
|
+
--relationship-node-selected-shadow: 0 0 10px rgba(255,255,255,.55), 0 0 20px var(--node-glow, rgba(139,144,153,.6));
|
|
269
|
+
--relationship-node-endpoint-shadow: 0 0 10px rgba(255,255,255,.5), 0 0 18px var(--node-glow, rgba(139,144,153,.55));
|
|
270
|
+
--relationship-node-dragging-shadow: 0 0 10px rgba(255,255,255,.6), 0 0 18px var(--node-glow, rgba(139,144,153,.6));
|
|
271
|
+
--relationship-focus: #7a7a88;
|
|
272
|
+
--relationship-focus-strong: #c8c8d4;
|
|
273
|
+
--relationship-focus-muted: #6a6a78;
|
|
274
|
+
--relationship-detail-border: #2a2a36;
|
|
275
|
+
--relationship-detail-surface: rgba(18,18,26,.94);
|
|
276
|
+
--relationship-detail-ink: #e2e2ea;
|
|
277
|
+
--relationship-detail-muted: #9a9aa8;
|
|
211
278
|
color-scheme: dark;
|
|
212
279
|
}
|
|
213
280
|
|
|
@@ -291,8 +358,11 @@ button { cursor: pointer; }
|
|
|
291
358
|
.user-avatar-fallback { display: grid; width: 100%; height: 100%; place-items: center; }
|
|
292
359
|
.account-button > .account-avatar { width: 26px; height: 26px; font-size: 11px; }
|
|
293
360
|
.account-button > span:last-child { max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
|
|
294
|
-
.account-menu { position: absolute; z-index: 80; top: 48px; right: 84px; display: grid; min-width:
|
|
361
|
+
.account-menu { position: absolute; z-index: 80; top: 48px; right: 84px; display: grid; width: 180px; min-width: 0; gap: 4px; padding: 12px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); box-shadow: var(--shadow); }
|
|
295
362
|
.account-menu.hidden { display: none; }
|
|
363
|
+
.account-menu-name { display: grid; min-width: 0; gap: 2px; }
|
|
364
|
+
.account-menu-name > span { overflow-wrap: anywhere; }
|
|
365
|
+
.account-menu-username { color: var(--muted); font-size: 10px; font-weight: 500; }
|
|
296
366
|
.account-menu small { margin-bottom: 8px; color: var(--muted); }
|
|
297
367
|
.account-menu button { min-height: 30px; padding: 6px 9px; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); text-align: left; font-size: 10px; }
|
|
298
368
|
.account-menu button:hover, .account-menu button:focus-visible { border-color: var(--accent); background: var(--paper-deep); color: var(--accent-dark); outline: none; }
|
|
@@ -378,11 +448,13 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
378
448
|
.app-shell.shelf-mode .save-state { display: none; }
|
|
379
449
|
.app-shell.shelf-mode .main-panel { grid-column: 1 / -1; }
|
|
380
450
|
|
|
381
|
-
.shelf-view { height: 100%; overflow-y: auto; padding: 48px clamp(32px, 7vw, 110px) 90px; }
|
|
451
|
+
.shelf-view { display: flex; flex-direction: column; height: 100%; overflow-y: auto; padding: 48px clamp(32px, 7vw, 110px) 90px; }
|
|
452
|
+
#shelf-view, #settings-hub-view { padding-bottom: 24px; }
|
|
382
453
|
.shelf-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 30px; max-width: 1400px; margin: 0 auto 38px; }
|
|
383
454
|
.shelf-header h1 { margin: 0 0 10px; font-size: clamp(30px, 4vw, 52px); font-weight: 560; letter-spacing: -.04em; }
|
|
384
455
|
.shelf-header p { margin: 0; color: var(--muted); }
|
|
385
456
|
.settings-hub-header { align-items: center; }
|
|
457
|
+
.settings-hub-header h1 { font-size: clamp(26px, 3vw, 36px); line-height: 1.15; letter-spacing: -.02em; }
|
|
386
458
|
.settings-hub-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; max-width: 1000px; margin: 0 auto; }
|
|
387
459
|
.settings-hub-card { display: grid; grid-template-columns: 48px minmax(0, 1fr); grid-template-rows: auto auto; gap: 4px 14px; align-items: center; min-height: 128px; padding: 22px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-soft); text-align: left; }
|
|
388
460
|
.settings-hub-card:hover, .settings-hub-card:focus-visible { border-color: var(--accent); background: var(--paper-deep); box-shadow: var(--shadow); transform: translateY(-2px); }
|
|
@@ -391,6 +463,13 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
391
463
|
.settings-hub-card strong { align-self: end; font-size: 16px; }
|
|
392
464
|
.settings-hub-card small { align-self: start; color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
393
465
|
.settings-work-note { max-width: 1000px; margin: 18px auto 0; color: var(--muted); font-size: 11px; }
|
|
466
|
+
.product-footer { display: flex; flex: 0 0 auto; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 12px; width: 100%; max-width: 1400px; margin: auto auto 0; padding-top: 20px; border-top: 1px solid color-mix(in srgb, var(--line) 76%, transparent); color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
467
|
+
.product-footer-meta { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
|
|
468
|
+
.product-footer a { color: inherit; text-decoration: none; text-underline-offset: 3px; transition: color .14s ease; }
|
|
469
|
+
.product-footer a:hover, .product-footer a:focus-visible { color: var(--accent-dark); text-decoration: underline; }
|
|
470
|
+
.product-footer-development { padding: 2px 8px; border: 1px solid color-mix(in srgb, var(--accent) 48%, var(--line)); border-radius: 999px; background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--accent-dark); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 9px; font-weight: 700; letter-spacing: .05em; }
|
|
471
|
+
.auth-product-footer { align-self: end; max-width: 440px; margin: 0; padding-top: 14px; }
|
|
472
|
+
.settings-product-footer { max-width: 1000px; }
|
|
394
473
|
.access-dialog-body { display: grid; gap: 16px; max-height: calc(88vh - 82px); overflow-y: auto; padding: 18px 24px 22px; }
|
|
395
474
|
.access-list { display: grid; gap: 8px; max-height: min(34vh, 340px); overflow: auto; padding: 0; }
|
|
396
475
|
.access-row {
|
|
@@ -500,6 +579,7 @@ body.work-viewer-mode [data-edit-event],
|
|
|
500
579
|
body.work-viewer-mode [data-split-event],
|
|
501
580
|
body.work-viewer-mode [data-event-select],
|
|
502
581
|
body.work-viewer-mode #create-timeline-track,
|
|
582
|
+
body.work-viewer-mode #timeline-multi-select-toggle,
|
|
503
583
|
body.work-viewer-mode #merge-events,
|
|
504
584
|
body.work-viewer-mode [data-edit-foreshadow],
|
|
505
585
|
body.work-viewer-mode [data-edit-outline],
|
|
@@ -618,7 +698,7 @@ body.work-viewer-mode .character-editor-actions { display: none !important; }
|
|
|
618
698
|
.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; }
|
|
619
699
|
.api-key-result button { min-height: 38px; }
|
|
620
700
|
.book-access-badge { display: inline-flex; width: fit-content; margin-top: 7px; padding: 2px 7px; border-radius: 10px; background: var(--paper-deep); color: var(--accent-dark); font-size: 9px; }
|
|
621
|
-
.book-shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)); gap: clamp(22px, 3vw, 38px); max-width: 1400px; margin: 0 auto; }
|
|
701
|
+
.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; }
|
|
622
702
|
.book-card { position: relative; min-width: 0; border: 0; background: transparent; text-align: left; }
|
|
623
703
|
.book-open { width: 100%; padding: 0; border: 0; background: transparent; text-align: left; }
|
|
624
704
|
.book-cover { position: relative; display: grid; place-items: center; aspect-ratio: 3 / 4.25; overflow: hidden; border-radius: 8px 13px 13px 8px; background: linear-gradient(145deg, #a96350, #612d27); color: rgba(255,255,255,.9); box-shadow: 0 20px 34px rgba(62,39,29,.18), inset 9px 0 0 rgba(0,0,0,.08); transition: transform .2s ease, box-shadow .2s ease; }
|
|
@@ -719,7 +799,9 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
719
799
|
.module-nav .nav-icon { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
|
|
720
800
|
#module-more-button[aria-expanded="true"] .nav-icon { transform: rotate(180deg); }
|
|
721
801
|
.module-nav button.active, .module-nav button:hover { background: var(--paper-deep); color: var(--ink); }
|
|
722
|
-
.module-nav .ai-analysis-entry
|
|
802
|
+
.module-nav .ai-analysis-entry,
|
|
803
|
+
.module-nav .ai-analysis-entry:hover,
|
|
804
|
+
.module-nav .ai-analysis-entry.active { background: transparent; color: var(--accent-dark); font-weight: 650; }
|
|
723
805
|
#module-more-button { grid-column: 1 / -1; color: var(--accent-dark); text-align: center; }
|
|
724
806
|
.panel-heading { display: flex; align-items: center; gap: 8px; padding: 15px 0 9px 7px; color: var(--muted); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
|
|
725
807
|
.panel-heading-actions { display: flex; align-items: center; gap: 7px; margin-left: auto; }
|
|
@@ -734,7 +816,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
734
816
|
.chapter-add-button { flex: none; }
|
|
735
817
|
.volume-chapters { display: block; }
|
|
736
818
|
.volume-node.is-collapsed .volume-chapters { display: none; }
|
|
737
|
-
.chapter-node { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: 8px; width: 100%; padding: 9px
|
|
819
|
+
.chapter-node { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: 8px; width: 100%; padding: 9px 0 9px 20px; border: 0; background: transparent; border-radius: 4px; text-align: left; font-size: 12px; }
|
|
738
820
|
.chapter-node:hover, .chapter-node.active { background: var(--row-active); }
|
|
739
821
|
.chapter-node.active { color: var(--accent-dark); font-weight: 700; }
|
|
740
822
|
.chapter-node > span:first-child { min-width: 0; overflow-wrap: anywhere; line-height: 1.45; white-space: normal; }
|
|
@@ -797,19 +879,26 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
797
879
|
.chapter-insight strong { color: var(--ink); margin-right: 8px; }
|
|
798
880
|
|
|
799
881
|
.module-view { height: 100%; overflow-y: auto; padding: 42px 6%; }
|
|
800
|
-
.module-header { display: flex; justify-content: space-between; align-items: flex-end; padding-bottom: 24px; border-bottom: 1px solid var(--line); }
|
|
882
|
+
.module-header { display: flex; justify-content: space-between; align-items: flex-end; gap: 18px; padding-bottom: 24px; border-bottom: 1px solid var(--line); }
|
|
883
|
+
.module-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
|
|
884
|
+
.module-header-actions > [data-module-header-action] { order: 1; }
|
|
885
|
+
.module-header-actions > #module-create-button { order: 2; min-height: 36px; }
|
|
801
886
|
.module-header h1 { margin: 0 0 8px; font-weight: 500; font-size: 34px; }
|
|
802
887
|
.module-header p { margin: 0; color: var(--muted); font-size: 13px; }
|
|
803
888
|
.module-content { padding: 24px 0 80px; }
|
|
804
889
|
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 13px; }
|
|
805
890
|
.record-card { position: relative; border: 1px solid var(--line); background: var(--surface-soft); padding: 18px; min-height: 130px; border-radius: 4px; }
|
|
891
|
+
.record-card.has-card-edit h3 { padding-right: 34px; }
|
|
892
|
+
.record-card-edit { position: absolute; top: 12px; right: 12px; display: inline-grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); }
|
|
893
|
+
.record-card-edit:hover, .record-card-edit:focus-visible { border-color: var(--accent); color: var(--accent-dark); outline: none; }
|
|
894
|
+
.record-card-edit svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.7; }
|
|
806
895
|
.record-card h3 { font-size: 16px; margin: 5px 0 10px; font-weight: 600; }
|
|
807
896
|
.record-card p { color: var(--muted); font-size: 12px; line-height: 1.55; margin: 0; white-space: pre-wrap; }
|
|
808
897
|
.record-card small { color: var(--accent); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; }
|
|
809
|
-
.settings-layout-toolbar, .module-layout-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-bottom:
|
|
898
|
+
.settings-layout-toolbar, .module-layout-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-bottom: 0; }
|
|
810
899
|
.settings-layout-hint, .module-layout-hint { color: var(--muted); font-size: 10px; }
|
|
811
900
|
.settings-layout-toggle, .module-layout-toggle { display: inline-flex; border: 1px solid var(--line); border-radius: 4px; overflow: hidden; background: var(--surface); }
|
|
812
|
-
.settings-layout-toggle button, .module-layout-toggle button { min-height:
|
|
901
|
+
.settings-layout-toggle button, .module-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; }
|
|
813
902
|
.settings-layout-toggle button:last-child, .module-layout-toggle button:last-child { border-right: 0; }
|
|
814
903
|
.settings-layout-toggle button:hover, .settings-layout-toggle button:focus-visible,
|
|
815
904
|
.module-layout-toggle button:hover, .module-layout-toggle button:focus-visible { color: var(--ink); background: var(--paper-deep); }
|
|
@@ -840,6 +929,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
840
929
|
.character-duplicate-actions { flex-wrap: wrap; }
|
|
841
930
|
.card-actions { display: flex; gap: 6px; margin-top: 15px; }
|
|
842
931
|
.card-actions button { border: 1px solid var(--line); background: transparent; border-radius: 3px; font-size: 10px; padding: 5px 8px; }
|
|
932
|
+
.danger-button { border: 1px solid color-mix(in srgb, var(--accent) 52%, var(--line)); border-radius: 4px; background: transparent; color: var(--accent-dark); padding: 8px 13px; font-size: 12px; }
|
|
933
|
+
.danger-button:hover, .danger-button:focus-visible { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); outline: none; }
|
|
843
934
|
.card-actions .danger-button { border-color: color-mix(in srgb, var(--accent) 52%, var(--line)); color: var(--accent-dark); }
|
|
844
935
|
.card-actions .danger-button:hover, .card-actions .danger-button:focus-visible { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); }
|
|
845
936
|
.card-actions .primary-button { border-color: var(--accent); background: var(--accent); color: #fff; padding: 8px 13px; font-size: 12px; }
|
|
@@ -867,6 +958,17 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
867
958
|
.race-settings .pill { display: inline-flex; align-items: center; gap: 5px; }
|
|
868
959
|
.race-settings .pill small { color: inherit; font-size: 8px; letter-spacing: 0; text-transform: none; opacity: .72; }
|
|
869
960
|
.race-settings .pill.inherited { border-style: dashed; }
|
|
961
|
+
.entity-dialog-management, .entity-editor-management { display: grid; gap: 10px; padding: 14px; border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--line)); border-radius: 5px; background: color-mix(in srgb, var(--accent) 4%, var(--surface)); }
|
|
962
|
+
.entity-dialog-management > div:first-child, .entity-editor-management > div:first-child { display: grid; gap: 4px; }
|
|
963
|
+
.entity-dialog-management strong, .entity-editor-management strong { color: var(--ink); font-size: 11px; }
|
|
964
|
+
.entity-dialog-management small, .entity-editor-management small { color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
965
|
+
.entity-dialog-management-actions, .entity-editor-management-actions { display: flex; flex-wrap: wrap; gap: 7px; }
|
|
966
|
+
.entity-dialog-management-actions button, .entity-editor-management-actions button { min-height: 32px; }
|
|
967
|
+
.danger-confirm-field { display: grid !important; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 9px !important; padding: 12px; border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--line)); border-radius: 5px; background: color-mix(in srgb, var(--accent) 5%, var(--surface)); }
|
|
968
|
+
.danger-confirm-field input { width: auto !important; margin-top: 3px; }
|
|
969
|
+
.danger-confirm-field span { display: grid; gap: 4px; }
|
|
970
|
+
.danger-confirm-field strong { color: var(--ink); font-size: 11px; }
|
|
971
|
+
.danger-confirm-field small { color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
870
972
|
.config-section { margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--line); }
|
|
871
973
|
.config-section:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
|
|
872
974
|
.platform-system-prompt-section { margin-bottom: 36px; }
|
|
@@ -940,7 +1042,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
940
1042
|
.table-list th, .table-list td { padding: 12px 10px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
|
|
941
1043
|
.table-list th { color: var(--muted); font-weight: 400; font-size: 10px; text-transform: uppercase; letter-spacing: .1em; }
|
|
942
1044
|
.danger-text { color: var(--accent); }
|
|
943
|
-
.timeline-tools { display: flex; justify-content: flex-end; gap: 8px;
|
|
1045
|
+
.timeline-tools { display: flex; justify-content: flex-end; gap: 8px; }
|
|
944
1046
|
.timeline-select { position: absolute; left: -33px; top: 0; }
|
|
945
1047
|
.timeline-kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(290px, 340px); gap: 14px; align-items: start; overflow-x: auto; padding: 3px 2px 18px; scroll-snap-type: x proximity; }
|
|
946
1048
|
.timeline-lane { display: flex; max-height: calc(100vh - 250px); min-height: 420px; flex-direction: column; overflow: hidden; border: 1px solid var(--line); border-radius: 7px; background: color-mix(in srgb, var(--paper-deep) 42%, transparent); scroll-snap-align: start; }
|
|
@@ -999,12 +1101,12 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
999
1101
|
.relationship-map-expanded-host .relationship-map-card { height: 100%; margin: 0; }
|
|
1000
1102
|
.relationship-map-expanded-host .relationship-map-toolbar { padding-right: 72px; }
|
|
1001
1103
|
.relationship-map-expanded-host .relationship-mindmap { height: calc(100% - 67px); min-height: 0; }
|
|
1002
|
-
.relationship-network-card { border-color:
|
|
1003
|
-
.relationship-network-card .relationship-map-toolbar { min-height: 58px; border-color:
|
|
1004
|
-
.relationship-network-card .relationship-map-toolbar small { color:
|
|
1005
|
-
.relationship-network-card .relationship-map-actions button { border-color:
|
|
1006
|
-
.relationship-network-card .relationship-map-actions button:hover, .relationship-network-card .relationship-map-actions button:focus-visible { border-color:
|
|
1007
|
-
.relationship-network { height: min(68vh, 650px); min-height: 520px; contain: layout paint style; touch-action: none; cursor: grab; background:
|
|
1104
|
+
.relationship-network-card { border-color: var(--relationship-card-border); background: var(--relationship-card-surface); box-shadow: none; }
|
|
1105
|
+
.relationship-network-card .relationship-map-toolbar { min-height: 58px; border-color: var(--relationship-card-border); background: var(--relationship-toolbar-surface); color: var(--relationship-toolbar-ink); }
|
|
1106
|
+
.relationship-network-card .relationship-map-toolbar small { color: var(--relationship-toolbar-muted); }
|
|
1107
|
+
.relationship-network-card .relationship-map-actions button { border-color: var(--relationship-control-border); background: transparent; color: var(--relationship-control-ink); }
|
|
1108
|
+
.relationship-network-card .relationship-map-actions button:hover, .relationship-network-card .relationship-map-actions button:focus-visible { border-color: var(--relationship-control-hover-border); background: var(--relationship-control-hover-surface); color: var(--relationship-control-hover-ink); }
|
|
1109
|
+
.relationship-network { height: min(68vh, 650px); min-height: 520px; contain: layout paint style; touch-action: none; cursor: grab; background: var(--relationship-network-surface); }
|
|
1008
1110
|
.relationship-network.is-panning { cursor: grabbing; }
|
|
1009
1111
|
.relationship-network-stage { contain: layout paint style; will-change: transform; }
|
|
1010
1112
|
.relationship-network-stage.is-view-animating { transition: transform .34s cubic-bezier(.22,.78,.3,1); }
|
|
@@ -1019,21 +1121,21 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1019
1121
|
stroke: transparent;
|
|
1020
1122
|
}
|
|
1021
1123
|
.relationship-network .mind-edge,
|
|
1022
|
-
.relationship-network .obsidian-edge { stroke:
|
|
1023
|
-
.relationship-network .mind-edge.is-directed { stroke:
|
|
1124
|
+
.relationship-network .obsidian-edge { stroke: var(--relationship-edge); stroke-width: 1px; opacity: 1; transition: opacity .12s ease, stroke .12s ease; }
|
|
1125
|
+
.relationship-network .mind-edge.is-directed { stroke: var(--relationship-edge-directed); }
|
|
1024
1126
|
.relationship-network .relationship-edge-arrow { pointer-events: none; }
|
|
1025
1127
|
.relationship-network .mind-edge.family,
|
|
1026
1128
|
.relationship-network .mind-edge.social,
|
|
1027
1129
|
.relationship-network .mind-edge.emotional,
|
|
1028
1130
|
.relationship-network .mind-edge.conflict,
|
|
1029
|
-
.relationship-network .mind-edge.uncertain { stroke:
|
|
1030
|
-
.relationship-network .mind-edge.is-pending { stroke:
|
|
1131
|
+
.relationship-network .mind-edge.uncertain { stroke: var(--relationship-edge); stroke-dasharray: none; }
|
|
1132
|
+
.relationship-network .mind-edge.is-pending { stroke: var(--relationship-edge-pending); stroke-dasharray: 4 6; }
|
|
1031
1133
|
.relationship-network .mind-edge.is-dimmed { opacity: .06; }
|
|
1032
|
-
.relationship-network .mind-edge.is-highlighted { stroke:
|
|
1033
|
-
.relationship-network .mind-edge.is-edge-selected { stroke:
|
|
1134
|
+
.relationship-network .mind-edge.is-highlighted { stroke: var(--relationship-edge-highlight); stroke-width: 1.35px; opacity: 1; }
|
|
1135
|
+
.relationship-network .mind-edge.is-edge-selected { stroke: var(--relationship-edge-selected); stroke-width: 1.6px; opacity: 1; }
|
|
1034
1136
|
.relationship-network .mind-edge-label {
|
|
1035
|
-
fill:
|
|
1036
|
-
stroke:
|
|
1137
|
+
fill: var(--relationship-label-ink);
|
|
1138
|
+
stroke: var(--relationship-label-stroke);
|
|
1037
1139
|
stroke-width: 2.5px;
|
|
1038
1140
|
font-size: 7px;
|
|
1039
1141
|
font-weight: 400;
|
|
@@ -1054,7 +1156,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1054
1156
|
border: 0;
|
|
1055
1157
|
border-radius: 50%;
|
|
1056
1158
|
background: var(--node-color, #8b9099);
|
|
1057
|
-
color:
|
|
1159
|
+
color: var(--relationship-node-ink);
|
|
1058
1160
|
box-shadow: 0 0 8px var(--node-glow, rgba(139,144,153,.42));
|
|
1059
1161
|
font-family: "SF Pro Text", "Segoe UI", "Helvetica Neue", sans-serif;
|
|
1060
1162
|
font-size: 9px;
|
|
@@ -1075,30 +1177,39 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1075
1177
|
text-overflow: ellipsis;
|
|
1076
1178
|
white-space: nowrap;
|
|
1077
1179
|
pointer-events: none;
|
|
1078
|
-
color:
|
|
1180
|
+
color: var(--relationship-node-label);
|
|
1079
1181
|
font-size: 9px;
|
|
1080
1182
|
font-weight: 400;
|
|
1081
1183
|
letter-spacing: .01em;
|
|
1082
|
-
text-shadow:
|
|
1184
|
+
text-shadow: var(--relationship-node-text-shadow);
|
|
1185
|
+
opacity: 0;
|
|
1186
|
+
transition: opacity .12s ease, color .12s ease;
|
|
1083
1187
|
}
|
|
1188
|
+
.relationship-network .mind-node.is-label-visible span,
|
|
1189
|
+
.relationship-network .mind-node:hover span,
|
|
1190
|
+
.relationship-network .mind-node:focus-visible span,
|
|
1191
|
+
.relationship-network .mind-node.is-hovered span,
|
|
1192
|
+
.relationship-network .mind-node.is-selected span,
|
|
1193
|
+
.relationship-network .mind-node.is-related span,
|
|
1194
|
+
.relationship-network .mind-node.is-edge-endpoint span { opacity: 1; }
|
|
1084
1195
|
.relationship-network .mind-node:hover,
|
|
1085
1196
|
.relationship-network .mind-node:focus-visible,
|
|
1086
1197
|
.relationship-network .mind-node.is-hovered {
|
|
1087
1198
|
transform: translate(-50%, -50%) scale(1.28);
|
|
1088
1199
|
outline: none;
|
|
1089
1200
|
z-index: 6;
|
|
1090
|
-
box-shadow:
|
|
1201
|
+
box-shadow: var(--relationship-node-hover-shadow);
|
|
1091
1202
|
}
|
|
1092
1203
|
.relationship-network .mind-node:hover span,
|
|
1093
1204
|
.relationship-network .mind-node:focus-visible span,
|
|
1094
1205
|
.relationship-network .mind-node.is-hovered span,
|
|
1095
1206
|
.relationship-network .mind-node.is-selected span,
|
|
1096
1207
|
.relationship-network .mind-node.is-related span,
|
|
1097
|
-
.relationship-network .mind-node.is-edge-endpoint span { color:
|
|
1208
|
+
.relationship-network .mind-node.is-edge-endpoint span { color: var(--relationship-node-label-active); }
|
|
1098
1209
|
.relationship-network .mind-node.is-selected {
|
|
1099
1210
|
transform: translate(-50%, -50%) scale(1.32);
|
|
1100
1211
|
z-index: 5;
|
|
1101
|
-
box-shadow:
|
|
1212
|
+
box-shadow: var(--relationship-node-selected-shadow);
|
|
1102
1213
|
}
|
|
1103
1214
|
.relationship-network .mind-node.is-related { opacity: 1; }
|
|
1104
1215
|
.relationship-network .mind-node.is-dimmed { opacity: .14; box-shadow: none; }
|
|
@@ -1106,7 +1217,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1106
1217
|
.relationship-network .mind-node.is-edge-endpoint {
|
|
1107
1218
|
opacity: 1;
|
|
1108
1219
|
transform: translate(-50%, -50%) scale(1.3);
|
|
1109
|
-
box-shadow:
|
|
1220
|
+
box-shadow: var(--relationship-node-endpoint-shadow);
|
|
1110
1221
|
}
|
|
1111
1222
|
.relationship-network[data-interaction="dragging"] .mind-edge,
|
|
1112
1223
|
.relationship-network[data-interaction="dragging"] .mind-node,
|
|
@@ -1126,7 +1237,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1126
1237
|
transition: none;
|
|
1127
1238
|
z-index: 8;
|
|
1128
1239
|
will-change: left, top;
|
|
1129
|
-
box-shadow:
|
|
1240
|
+
box-shadow: var(--relationship-node-dragging-shadow);
|
|
1130
1241
|
}
|
|
1131
1242
|
.relationship-network .mind-node.is-drag-neighbor {
|
|
1132
1243
|
opacity: 1;
|
|
@@ -1134,16 +1245,16 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1134
1245
|
will-change: left, top;
|
|
1135
1246
|
}
|
|
1136
1247
|
.relationship-network .mind-node.is-settling { animation: relationship-node-settle .18s ease-out; }
|
|
1137
|
-
.relationship-network-focus, .relationship-network-help { position: absolute; z-index: 6; color:
|
|
1248
|
+
.relationship-network-focus, .relationship-network-help { position: absolute; z-index: 6; color: var(--relationship-focus); pointer-events: none; }
|
|
1138
1249
|
.relationship-network-focus { top: 14px; left: 16px; display: grid; gap: 3px; }
|
|
1139
|
-
.relationship-network-focus strong { color:
|
|
1140
|
-
.relationship-network-focus span { color:
|
|
1250
|
+
.relationship-network-focus strong { color: var(--relationship-focus-strong); font-size: 10px; font-weight: 500; }
|
|
1251
|
+
.relationship-network-focus span { color: var(--relationship-focus-muted); font-size: 9px; }
|
|
1141
1252
|
.relationship-network-help { left: 16px; bottom: 13px; font-size: 9px; }
|
|
1142
|
-
.relationship-network .mind-edge-detail { left: 50%; right: auto; bottom: 38px; width: min(680px, calc(100% - 40px)); transform: translateX(-50%); border-color:
|
|
1143
|
-
.relationship-network .mind-edge-detail span { color:
|
|
1253
|
+
.relationship-network .mind-edge-detail { left: 50%; right: auto; bottom: 38px; width: min(680px, calc(100% - 40px)); transform: translateX(-50%); border-color: var(--relationship-detail-border); background: var(--relationship-detail-surface); color: var(--relationship-detail-ink); box-shadow: none; }
|
|
1254
|
+
.relationship-network .mind-edge-detail span { color: var(--relationship-detail-muted); }
|
|
1144
1255
|
.relationship-map-expanded-host .relationship-network { height: calc(100% - 63px); min-height: 0; }
|
|
1145
|
-
.relationship-map-dialog { background:
|
|
1146
|
-
.relationship-map-expanded-host { background:
|
|
1256
|
+
.relationship-map-dialog { background: var(--relationship-card-surface); border-color: var(--relationship-card-border); }
|
|
1257
|
+
.relationship-map-expanded-host { background: var(--relationship-card-surface); }
|
|
1147
1258
|
@keyframes relationship-node-settle { from { transform: translate(-50%, -50%) scale(1.36); } to { transform: translate(-50%, -50%) scale(1.32); } }
|
|
1148
1259
|
@media (prefers-reduced-motion: reduce) { .relationship-network .mind-node, .relationship-network-stage { transition-duration: .01ms; animation-duration: .01ms; } }
|
|
1149
1260
|
|
|
@@ -1204,7 +1315,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1204
1315
|
.field-label select { padding: 8px; font-size: 12px; }
|
|
1205
1316
|
.book-summary-context-percent-field { width: min(100%, 280px); }
|
|
1206
1317
|
.context-compact-threshold-field { width: min(100%, 280px); }
|
|
1207
|
-
.book-summary-context-percent-field input, .context-compact-threshold-field input { min-height:
|
|
1318
|
+
.book-summary-context-percent-field input, .context-compact-threshold-field input { width: 64px; min-height: 32px; padding: 5px 8px; font-size: 13px; font-family: var(--font-latin), monospace; }
|
|
1208
1319
|
.field-label textarea {
|
|
1209
1320
|
width: 100%;
|
|
1210
1321
|
min-height: 140px;
|
|
@@ -1459,8 +1570,14 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1459
1570
|
.section-list-row { grid-template-columns: minmax(0, 1fr) auto; }
|
|
1460
1571
|
.section-list-row textarea { grid-column: 1 / -1; min-height: 130px; }
|
|
1461
1572
|
.structured-list-row button { grid-column: -2 / -1; grid-row: 1; border: 1px solid var(--line); border-radius: 4px; padding: 0 10px; background: var(--panel); color: var(--muted); font-size: 10px; }
|
|
1462
|
-
.character-
|
|
1463
|
-
.character-
|
|
1573
|
+
.character-card h3 { margin-bottom: 5px; }
|
|
1574
|
+
.character-identity { margin: 0 0 6px !important; color: var(--ink) !important; font-weight: 600; line-height: 1.55 !important; }
|
|
1575
|
+
.character-aliases { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 0; }
|
|
1576
|
+
.character-aliases .pill { margin: 0; }
|
|
1577
|
+
.character-code { display: flex; align-items: center; gap: 7px; margin-top: 10px; color: var(--muted); font-size: 10px; }
|
|
1578
|
+
.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; }
|
|
1579
|
+
.character-species b { font-weight: 500; }
|
|
1580
|
+
.character-species .pill { justify-self: start; min-width: 0; max-width: 100%; margin: 0; overflow-wrap: anywhere; }
|
|
1464
1581
|
.character-detail-list { display: grid; gap: 5px; margin: 12px 0; }
|
|
1465
1582
|
.character-detail-list div { display: grid; grid-template-columns: minmax(70px, .42fr) minmax(0, 1fr); gap: 8px; font-size: 10px; }
|
|
1466
1583
|
.character-detail-list dt { color: var(--muted); }
|
|
@@ -1528,7 +1645,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1528
1645
|
.setting-editor-lock b { color: var(--ink); font-size: 10px; }
|
|
1529
1646
|
.setting-editor-lock small { display: none; }
|
|
1530
1647
|
.setting-editor-change-note { align-items: center; gap: 6px; }
|
|
1531
|
-
.setting-editor-workspace { min-height: 0; }
|
|
1648
|
+
.setting-editor-workspace { display: grid; grid-template-rows: auto minmax(0, 1fr); min-height: 0; overflow: hidden; }
|
|
1532
1649
|
.setting-editor-content { height: 100%; min-height: 0; padding: 16px clamp(16px, 2vw, 32px) 24px; overflow: hidden; }
|
|
1533
1650
|
.setting-markdown-field { display: grid; grid-template-rows: minmax(0, 1fr); height: 100%; min-height: 0; }
|
|
1534
1651
|
.setting-markdown-heading, .markdown-editor-field-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; color: var(--ink); font-size: 14px; }
|
|
@@ -1544,7 +1661,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1544
1661
|
.vditor-editor-host .vditor-reset { color: var(--ink); font-family: var(--font-cjk), var(--font-latin), sans-serif; }
|
|
1545
1662
|
.vditor-editor-host .vditor-ir, .vditor-editor-host .vditor-sv, .vditor-editor-host .vditor-wysiwyg { background: var(--surface); color: var(--ink); }
|
|
1546
1663
|
.vditor-editor-host .vditor-sv textarea { color: var(--ink); }
|
|
1547
|
-
.record-markdown-preview {
|
|
1664
|
+
.record-markdown-preview { display: -webkit-box; margin: 12px 0 8px; overflow: hidden; overflow-wrap: anywhere; color: var(--ink); font-size: 12px; line-height: 1.7; -webkit-box-orient: vertical; -webkit-line-clamp: 12; }
|
|
1548
1665
|
.record-markdown-preview > :first-child, .knowledge-markdown-block .message-body > :first-child { margin-top: 0; }
|
|
1549
1666
|
.record-markdown-preview > :last-child, .knowledge-markdown-block .message-body > :last-child { margin-bottom: 0; }
|
|
1550
1667
|
.knowledge-markdown-block { min-width: 0; margin: 10px 0 0; padding: 11px 13px; border: 1px solid var(--line); border-radius: 5px; background: var(--surface); }
|
|
@@ -1645,6 +1762,9 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1645
1762
|
.character-section-editor-header .entity-editor-back { grid-column: 1; grid-row: 1; z-index: 1; }
|
|
1646
1763
|
.character-section-editor-header h2 { margin: 3px 0 0; font-size: 22px; font-weight: 600; }
|
|
1647
1764
|
.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); }
|
|
1765
|
+
.character-markdown-editor > .vditor-editor-host { width: 100%; max-width: 960px; justify-self: center; }
|
|
1766
|
+
.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; }
|
|
1767
|
+
.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); }
|
|
1648
1768
|
.character-markdown-editor-meta { display: grid; grid-template-columns: minmax(140px, .55fr) minmax(220px, 1fr) minmax(280px, 1.45fr); gap: 12px; }
|
|
1649
1769
|
.character-markdown-editor label { display: grid; gap: 6px; color: var(--muted); font-size: 10px; }
|
|
1650
1770
|
.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; }
|
|
@@ -1686,6 +1806,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1686
1806
|
.appearance-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 22px 24px; }
|
|
1687
1807
|
.appearance-grid label { display: grid; gap: 6px; color: var(--muted); font-size: 11px; }
|
|
1688
1808
|
.appearance-grid select { width: 100%; padding: 9px 10px; font-size: 13px; }
|
|
1809
|
+
.appearance-whitespace-field { grid-column: 1 / -1; }
|
|
1689
1810
|
.font-preview { grid-column: 1 / -1; padding: 16px; border: 1px solid var(--line); border-radius: 4px; background: var(--paper); }
|
|
1690
1811
|
.font-preview strong, .font-preview span { display: block; }
|
|
1691
1812
|
.font-preview strong { margin-bottom: 8px; font-size: 17px; }
|
|
@@ -1715,8 +1836,11 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1715
1836
|
.entity-version-card > button.is-confirming { border-color: var(--accent); background: var(--accent); color: #fff; }
|
|
1716
1837
|
.entity-version-card > button:disabled { cursor: default; opacity: .68; }
|
|
1717
1838
|
.entity-history-empty { margin: 0; padding: 28px 12px; color: var(--muted); font-size: 11px; text-align: center; }
|
|
1718
|
-
.relationship-table .relationship-actions { white-space: nowrap; }
|
|
1719
|
-
.relationship-table .relationship-actions button
|
|
1839
|
+
.relationship-table .relationship-actions { white-space: nowrap; vertical-align: middle; }
|
|
1840
|
+
.relationship-table .relationship-actions button { display: inline-block; min-height: 30px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--muted); font: inherit; font-size: 10px; line-height: 1.2; vertical-align: middle; appearance: none; transition: border-color .14s ease, background .14s ease, color .14s ease; }
|
|
1841
|
+
.relationship-table .relationship-actions button + button { margin-left: 6px; }
|
|
1842
|
+
.relationship-table .relationship-actions button:hover, .relationship-table .relationship-actions button:focus-visible { border-color: var(--accent); background: var(--surface-hover); color: var(--accent-dark); outline: none; }
|
|
1843
|
+
.relationship-table .relationship-actions button[data-edit-relationship] { color: var(--ink); }
|
|
1720
1844
|
|
|
1721
1845
|
@media (max-width: 540px) {
|
|
1722
1846
|
.member-permission-grid { grid-template-columns: minmax(0, 1fr); }
|
|
@@ -1759,7 +1883,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1759
1883
|
.setting-editor-header { min-height: 102px; }
|
|
1760
1884
|
.setting-editor-header-fields { flex-wrap: wrap; gap: 8px 12px; }
|
|
1761
1885
|
.setting-editor-title-input { font-size: 18px; }
|
|
1762
|
-
.setting-editor-
|
|
1886
|
+
.setting-editor-workspace { overflow-y: auto; }
|
|
1887
|
+
.setting-editor-content { height: auto; min-height: 70dvh; padding: 16px; }
|
|
1763
1888
|
.setting-markdown-field { height: 70dvh; }
|
|
1764
1889
|
.setting-markdown-heading, .markdown-editor-field-heading { align-items: flex-start; flex-direction: column; gap: 4px; }
|
|
1765
1890
|
.setting-markdown-field > .vditor-editor-host, .markdown-editor-field .vditor-editor-host { min-height: 42dvh; }
|
|
@@ -6,7 +6,7 @@ export const WORK_PERMISSION_MODULES = Object.freeze([
|
|
|
6
6
|
{ id: "organizations", uiModule: "organizations", label: "组织" },
|
|
7
7
|
{ id: "timeline", uiModule: "timeline", label: "时间轴" },
|
|
8
8
|
{ id: "relationships", uiModule: "relationships", label: "关系" },
|
|
9
|
-
{ id: "outlines", uiModule: "outlines", label: "
|
|
9
|
+
{ id: "outlines", uiModule: "outlines", label: "大纲/伏笔" },
|
|
10
10
|
{ id: "reviews", uiModule: "reviews", label: "审核" },
|
|
11
11
|
{ id: "ai-chat", uiModule: null, label: "AI 对话" },
|
|
12
12
|
{ id: "ai-analysis", uiModule: "tasks", label: "AI 分析" },
|
package/dist/server-runtime.js
CHANGED
|
@@ -5,6 +5,9 @@ import { loadMasterSecret } from "./credential-vault.js";
|
|
|
5
5
|
import { isDevelopmentAuthBypassEnabled, resolveRuntimeSecurity } from "./security.js";
|
|
6
6
|
import { logger, sanitizeError } from "./logger.js";
|
|
7
7
|
const publicPath = fileURLToPath(new URL("./public/", import.meta.url));
|
|
8
|
+
export function isDevelopmentServer(environment) {
|
|
9
|
+
return environment.NODE_ENV === "development" || environment.npm_lifecycle_event === "dev";
|
|
10
|
+
}
|
|
8
11
|
export async function startLocalServer(options) {
|
|
9
12
|
logger.info("server.starting", { host: options.host, port: options.port, dataDirectory: options.dataDirectory, databasePath: options.databasePath });
|
|
10
13
|
let security;
|
|
@@ -19,7 +22,8 @@ export async function startLocalServer(options) {
|
|
|
19
22
|
publicPath,
|
|
20
23
|
security,
|
|
21
24
|
disableUserAuth: devAuthBypass,
|
|
22
|
-
devAuthBypass
|
|
25
|
+
devAuthBypass,
|
|
26
|
+
developmentServer: isDevelopmentServer(options.env)
|
|
23
27
|
});
|
|
24
28
|
}
|
|
25
29
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-runtime.js","sourceRoot":"","sources":["../src/server-runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAgB,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAA+B,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAsBpD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAExE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA2B;IAChE,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACrJ,IAAI,QAAgC,CAAC;IACrC,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,aAAa,GAAG,8BAA8B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClE,OAAO,GAAG,aAAa,CAAC;YACtB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC;YAC/D,YAAY,EAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC1G,UAAU;YACV,QAAQ;YACR,eAAe,EAAE,aAAa;YAC9B,aAAa;
|
|
1
|
+
{"version":3,"file":"server-runtime.js","sourceRoot":"","sources":["../src/server-runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/store.js
CHANGED
|
@@ -2193,6 +2193,7 @@ export class Store {
|
|
|
2193
2193
|
delete profile.sections;
|
|
2194
2194
|
return {
|
|
2195
2195
|
name: String(character.name),
|
|
2196
|
+
code: String(character.code),
|
|
2196
2197
|
aliases: [...character.aliases],
|
|
2197
2198
|
raceId: character.raceId,
|
|
2198
2199
|
species: String(character.species),
|
|
@@ -2245,9 +2246,9 @@ export class Store {
|
|
|
2245
2246
|
const organizationIds = [...new Set(input.organizationIds ?? [])];
|
|
2246
2247
|
this.assertOrganizationsInWork(workId, organizationIds);
|
|
2247
2248
|
this.db.transaction(() => {
|
|
2248
|
-
this.db.run(`INSERT INTO characters (id, work_id, name, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
|
|
2249
|
+
this.db.run(`INSERT INTO characters (id, work_id, name, code, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
|
|
2249
2250
|
locked_fields_json, visibility, first_chapter_id, created_at, updated_at)
|
|
2250
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, JSON.stringify(names.aliases), species, raceId, JSON.stringify(input.attributes ?? {}), JSON.stringify(input.profile ?? {}), JSON.stringify(input.currentState ?? {}), JSON.stringify(input.lockedFields ?? []), input.visibility ?? "author", input.firstChapterId ?? null, timestamp, timestamp);
|
|
2251
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, input.code?.trim() ?? "", JSON.stringify(names.aliases), species, raceId, JSON.stringify(input.attributes ?? {}), JSON.stringify(input.profile ?? {}), JSON.stringify(input.currentState ?? {}), JSON.stringify(input.lockedFields ?? []), input.visibility ?? "author", input.firstChapterId ?? null, timestamp, timestamp);
|
|
2251
2252
|
this.insertCharacterNames(workId, characterId, names.entries);
|
|
2252
2253
|
this.replaceCharacterOrganizations(characterId, organizationIds);
|
|
2253
2254
|
this.insertCharacterVersion(characterId, 1, "create", null, "建立人物档案", timestamp);
|
|
@@ -2596,8 +2597,8 @@ export class Store {
|
|
|
2596
2597
|
this.db.transaction(() => {
|
|
2597
2598
|
const lockedCurrent = this.getCharacter(characterId);
|
|
2598
2599
|
this.assertExpectedRevision("character", characterId, expectedVersionNo, "人物", Number(lockedCurrent.versionNo));
|
|
2599
|
-
this.db.run(`UPDATE characters SET name = ?, aliases_json = ?, species = ?, race_id = ?, attributes_json = ?, profile_json = ?, current_state_json = ?,
|
|
2600
|
-
locked_fields_json = ?, visibility = ?, first_chapter_id = ?, updated_at = ? WHERE id = ?`, names.name, JSON.stringify(names.aliases), species, raceId, JSON.stringify(attributes), JSON.stringify(input.profile ?? current.profile), JSON.stringify(input.currentState ?? current.currentState), JSON.stringify(input.lockedFields ?? current.lockedFields), input.visibility ?? String(current.visibility), input.firstChapterId === undefined ? current.firstChapterId : input.firstChapterId, now(), characterId);
|
|
2600
|
+
this.db.run(`UPDATE characters SET name = ?, code = ?, aliases_json = ?, species = ?, race_id = ?, attributes_json = ?, profile_json = ?, current_state_json = ?,
|
|
2601
|
+
locked_fields_json = ?, visibility = ?, first_chapter_id = ?, updated_at = ? WHERE id = ?`, names.name, input.code === undefined ? String(current.code) : input.code.trim(), JSON.stringify(names.aliases), species, raceId, JSON.stringify(attributes), JSON.stringify(input.profile ?? current.profile), JSON.stringify(input.currentState ?? current.currentState), JSON.stringify(input.lockedFields ?? current.lockedFields), input.visibility ?? String(current.visibility), input.firstChapterId === undefined ? current.firstChapterId : input.firstChapterId, now(), characterId);
|
|
2601
2602
|
this.db.run("DELETE FROM character_names WHERE character_id = ?", characterId);
|
|
2602
2603
|
this.insertCharacterNames(workId, characterId, names.entries);
|
|
2603
2604
|
if (organizationIds)
|
|
@@ -2666,7 +2667,7 @@ export class Store {
|
|
|
2666
2667
|
this.assertExpectedRevision("character", characterId, expectedVersionNo, "人物", this.currentCharacterVersionNo(characterId));
|
|
2667
2668
|
return this.recreateCharacterFromVersion(characterId, version, snapshot, versionNo);
|
|
2668
2669
|
}
|
|
2669
|
-
return this.updateCharacter(characterId, snapshot, "restore", requiredString(version, "id"), `恢复至 v${versionNo}`, expectedVersionNo);
|
|
2670
|
+
return this.updateCharacter(characterId, { ...snapshot, code: snapshot.code ?? "" }, "restore", requiredString(version, "id"), `恢复至 v${versionNo}`, expectedVersionNo);
|
|
2670
2671
|
}
|
|
2671
2672
|
recreateCharacterFromVersion(characterId, version, snapshot, versionNo) {
|
|
2672
2673
|
const workId = requiredString(version, "work_id");
|
|
@@ -2683,9 +2684,9 @@ export class Store {
|
|
|
2683
2684
|
const timestamp = now();
|
|
2684
2685
|
const nextVersionNo = numberValue(this.db.get("SELECT COALESCE(MAX(version_no), 0) AS version_no FROM character_versions WHERE character_id = ?", characterId) ?? {}, "version_no") + 1;
|
|
2685
2686
|
this.db.transaction(() => {
|
|
2686
|
-
this.db.run(`INSERT INTO characters (id, work_id, name, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
|
|
2687
|
+
this.db.run(`INSERT INTO characters (id, work_id, name, code, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
|
|
2687
2688
|
locked_fields_json, visibility, first_chapter_id, version_no, created_at, updated_at)
|
|
2688
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, JSON.stringify(names.aliases), species, raceId, JSON.stringify(snapshot.attributes ?? {}), JSON.stringify(snapshot.profile ?? {}), JSON.stringify(snapshot.currentState ?? {}), JSON.stringify(snapshot.lockedFields ?? []), snapshot.visibility ?? "author", snapshot.firstChapterId ?? null, nextVersionNo, timestamp, timestamp);
|
|
2689
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, snapshot.code ?? "", JSON.stringify(names.aliases), species, raceId, JSON.stringify(snapshot.attributes ?? {}), JSON.stringify(snapshot.profile ?? {}), JSON.stringify(snapshot.currentState ?? {}), JSON.stringify(snapshot.lockedFields ?? []), snapshot.visibility ?? "author", snapshot.firstChapterId ?? null, nextVersionNo, timestamp, timestamp);
|
|
2689
2690
|
this.insertCharacterNames(workId, characterId, names.entries);
|
|
2690
2691
|
this.replaceCharacterOrganizations(characterId, organizationIds);
|
|
2691
2692
|
this.insertCharacterVersion(characterId, nextVersionNo, "restore", requiredString(version, "id"), `恢复至 v${versionNo}`, timestamp, workId);
|
|
@@ -2758,6 +2759,7 @@ export class Store {
|
|
|
2758
2759
|
id: characterId,
|
|
2759
2760
|
workId: requiredString(row, "work_id"),
|
|
2760
2761
|
name: requiredString(row, "name"),
|
|
2762
|
+
code: requiredString(row, "code"),
|
|
2761
2763
|
aliases: indexedAliases.length > 0 ? indexedAliases : json(requiredString(row, "aliases_json"), []),
|
|
2762
2764
|
raceId: race ? String(race.id) : null,
|
|
2763
2765
|
race: race ? {
|
|
@@ -2842,6 +2844,7 @@ export class Store {
|
|
|
2842
2844
|
.filter((alias) => normalizeCharacterName(alias) !== normalizeCharacterName(String(target.name)))
|
|
2843
2845
|
.map((alias) => [normalizeCharacterName(alias), alias])).values()];
|
|
2844
2846
|
this.updateCharacter(targetId, {
|
|
2847
|
+
code: String(target.code) || String(source.code),
|
|
2845
2848
|
aliases: uniqueAliases,
|
|
2846
2849
|
raceId: target.raceId ?? source.raceId,
|
|
2847
2850
|
organizationIds: [...new Set([...target.organizationIds, ...source.organizationIds])],
|