feat(entity): Chunk #4 data layer + entity UI (characters & world-building)
Data layer: - Fuzzy scorer (packages/core/src/fuzzy.ts) with index recovery + unit tests - Backlink computation (packages/core/src/backlinks.ts) incl. entity-level backlinks - Consistency checker (packages/core/src/consistency.ts) incl. reciprocity/scope + unit tests - StorageAdapter contract extended with listEntities/searchEntities/saveEntity/deleteEntity; implemented in Local (Dexie) and Server adapters; contract tests cover entity CRUD + ?q= search - WorldItem.fields now supports list values (keyPeople, rivals); expanded RelationshipKind - @mention autocomplete extension + picker in the editor package Entity UI (apps/web/src/features/entities/): - Generic field renderer (EntityFields) driven by ENTITY_FIELDS/FieldDef - Tabbed directory with fuzzy search + entity cards (EntitiesView) - Create/edit/delete drawer (EntityEditor) reusing shared fields - Relationship editor + force-directed SVG relationship map - Entity engine stylesheet; wired into nav Store: project-store entity methods (load/create/update/delete) over the StorageAdapter contract. CI-green: typecheck, lint, 65 tests, and web build all pass.
This commit is contained in:
@@ -126,6 +126,115 @@ body {
|
||||
line-height: var(--ps-font-leading, 1.75);
|
||||
}
|
||||
|
||||
/* ---- Writing surface: toolbar, focus/typewriter modes ---- */
|
||||
.ps-writing {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
.ps-writing-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 8px 16px;
|
||||
border-bottom: 1px solid var(--ps-border);
|
||||
background: var(--ps-surface);
|
||||
flex: none;
|
||||
}
|
||||
.ps-chapter-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.ps-chapter-select-label {
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--ps-text-muted);
|
||||
}
|
||||
.ps-chapter-select select {
|
||||
padding: 6px 10px;
|
||||
border: 1px solid var(--ps-border);
|
||||
border-radius: 8px;
|
||||
background: var(--ps-canvas);
|
||||
color: var(--ps-text);
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
}
|
||||
.ps-toolbar-group {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
.ps-tool {
|
||||
padding: 5px 12px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
color: var(--ps-text-muted);
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ps-tool:hover {
|
||||
color: var(--ps-text);
|
||||
background: var(--ps-canvas);
|
||||
}
|
||||
.ps-tool.is-active {
|
||||
color: var(--ps-text);
|
||||
border-color: var(--ps-accent);
|
||||
background: color-mix(in srgb, var(--ps-accent) 12%, transparent);
|
||||
}
|
||||
.ps-autosave-indicator {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
font-size: 12px;
|
||||
color: var(--ps-text-muted);
|
||||
}
|
||||
.ps-autosave-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: var(--ps-text-muted);
|
||||
}
|
||||
.ps-autosave-indicator[data-status="saving"] .ps-autosave-dot {
|
||||
background: #d9a441;
|
||||
}
|
||||
.ps-autosave-indicator[data-status="dirty"] .ps-autosave-dot {
|
||||
background: #d96c4b;
|
||||
}
|
||||
.ps-autosave-indicator[data-status="saved"] .ps-autosave-dot {
|
||||
background: #4f9d69;
|
||||
}
|
||||
|
||||
/* Focus mode: dim the whole document, then restore the block under the cursor. */
|
||||
.ps-editor-focus .ps-editor-content {
|
||||
opacity: 0.22;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
.ps-editor-focus .ps-editor-content .ps-focus-active,
|
||||
.ps-editor-focus .ps-editor-content .ps-focus-active * {
|
||||
opacity: 1;
|
||||
transition: opacity 0.05s ease;
|
||||
}
|
||||
|
||||
.ps-writing-status {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
padding: 6px 16px;
|
||||
border-top: 1px solid var(--ps-border);
|
||||
background: var(--ps-surface);
|
||||
color: var(--ps-text-muted);
|
||||
font-size: 12px;
|
||||
flex: none;
|
||||
}
|
||||
.ps-writing-status-note {
|
||||
margin-left: auto;
|
||||
color: var(--ps-text);
|
||||
}
|
||||
|
||||
/* ---- Sidebar nav ---- */
|
||||
.ps-logo {
|
||||
font-weight: 700;
|
||||
|
||||
Reference in New Issue
Block a user