@happyvertical/smrt-content 0.55.20 → 0.55.22
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/agents/content-list.md +8 -0
- package/dist/chunks/{content-query-BWXPkWCP.js → content-query-rs3ZnYTt.js} +43 -5
- package/dist/chunks/{content-query-BWXPkWCP.js.map → content-query-rs3ZnYTt.js.map} +1 -1
- package/dist/chunks/{content-versions-CIjd0SzY.js → content-versions-CPwoZxE9.js} +2 -2
- package/dist/chunks/{content-versions-CIjd0SzY.js.map → content-versions-CPwoZxE9.js.map} +1 -1
- package/dist/chunks/{contents-CKXK2zFy.js → contents-DAn_oDOb.js} +2 -2
- package/dist/chunks/{contents-CKXK2zFy.js.map → contents-DAn_oDOb.js.map} +1 -1
- package/dist/content-query.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/manifest.json +1 -1
- package/dist/server.js +1 -1
- package/dist/smrt-knowledge.json +5 -5
- package/dist/svelte/components/ContentAgentChat.svelte +2 -2
- package/dist/svelte/components/ContentBodyEditor.svelte +9 -9
- package/dist/svelte/components/ContentClaimAuditTool.svelte +1 -1
- package/dist/svelte/components/ContentContributionInbox.svelte +1 -1
- package/dist/svelte/components/ContentContributionPortal.svelte +1 -1
- package/dist/svelte/components/ContentContributionTypeManager.svelte +1 -1
- package/dist/svelte/components/ContentContributorManager.svelte +1 -1
- package/dist/svelte/components/ContentCorrectionsTool.svelte +1 -1
- package/dist/svelte/components/ContentEditor.svelte +17 -17
- package/dist/svelte/components/ContentGovernanceManager.svelte +1 -1
- package/dist/svelte/components/ContentGovernancePanel.svelte +6 -6
- package/dist/svelte/components/ContentImageBrowser.svelte +1 -1
- package/dist/svelte/components/ContentImageChooser.svelte +1 -1
- package/dist/svelte/components/ContentList.svelte +21 -21
- package/dist/svelte/components/ContentReferencesPanel.svelte +1 -1
- package/dist/svelte/components/ContentReviewStatusTray.svelte +1 -1
- package/dist/svelte/components/ContentTransparencyReport.svelte +2 -2
- package/dist/svelte/components/ContentTransparencyTool.svelte +1 -1
- package/dist/svelte/components/ContentVersionsTool.svelte +1 -1
- package/dist/svelte/components/GovernedContentEditor.svelte +1 -1
- package/dist/svelte/routes/ContentContributionsRoute.svelte +4 -4
- package/dist/svelte/routes/ContentFactsRoute.svelte +7 -7
- package/dist/svelte/routes/ContentGovernanceRoute.svelte +2 -2
- package/dist/svelte/routes/ContentWorkspaceRoute.svelte +2 -2
- package/dist/svelte/routes/PublishedArticleRoute.svelte +2 -2
- package/package.json +16 -16
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-content",
|
|
6
|
-
"packageVersion": "0.55.
|
|
6
|
+
"packageVersion": "0.55.22",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "150a542bc28a99143d5b4d67d4dbcb7aff3e6486891fe7064cbe7c68e50d7897",
|
|
11
|
+
"packageJson": "ebf1851ebe8db4c863a16fd7c4b1e666ea626f3b1576e24750e0abd898aba326",
|
|
12
12
|
"agents": "dffe54f5b13fa274d24056c6dc48179bd3bb4ef93c4e47670651f27b67523826",
|
|
13
|
-
"moduleDoc:agents/content-list.md": "
|
|
13
|
+
"moduleDoc:agents/content-list.md": "f616b006826d48af3e16e4f3e0693a7b656e9228b7aa987a791c31660a58da0f"
|
|
14
14
|
},
|
|
15
15
|
"exports": [
|
|
16
16
|
".",
|
|
@@ -14235,7 +14235,7 @@
|
|
|
14235
14235
|
{
|
|
14236
14236
|
"path": "agents/content-list.md",
|
|
14237
14237
|
"module": "content-list",
|
|
14238
|
-
"content": "<!-- Module doc for packages/content/AGENTS.md. -->\n\n# ContentList contracts\n\nRead for changes to `src/svelte/content-list-*.ts`, `ContentList.svelte`, or the\nserver content-query/action adapters. Browser exports come from `/svelte`;\nprincipal-bound query/action factories come from `/server`.\n\n## Ownership and integration\n\n- `content-list-controller.ts` is the shared adapter over `DataTableController`.\n Search, filters, sort, paging, selection, columns, and action eligibility have\n one implementation across grid, detailed, and compact presentations. Controller\n modes are manual. Local arrays use `toContentListRows`, `selectContentListRows`,\n then `paginateContentListRows`; server rows must never be transformed again.\n- `query`, `urlState`, `savedViews`, `lifecycle`, `jobs`, and `dataSurface` are\n optional bindings. Without query, rows come from `contents`; with it, contents\n is ignored. `type` locks/hides the type filter; `defaultViewMode` seeds once.\n Existing callbacks (`onEdit`, `onDelete`, `onAdd`, `getViewHref`) remain usable.\n- `query.bind()` runs once during component initialization so a structural\n `remoteQuery(collection, transport)` binding registers teardown in that scope.\n Do not import smrt-svelte/web or its browser data runtime into the content\n Svelte barrel: public content pages depend on that code-split boundary.\n- The default query transport targets `POST /api/v1/contents/query`.\n `CONTENT_LIST_QUERY_FIELDS` maps column IDs to server fields;\n `ROW_FIELD_TO_CONTENT_KEY` maps response fields to ContentData. For example,\n column `updated`, client `updatedAt`, and server `updated_at` differ.\n `publish` maps to `publish_date`. Derived `site` comes from url/source and has\n no server field; server filtering/sorting on it is dropped and reported.\n- Missing/duplicate durable IDs still render with positional keys but are\n `identified: false`. Disable and explain their selection controls. Page select\n all and normalization exclude synthetic IDs; server selection must survive\n page changes, so current-page membership is not a durability test.\n- Compact uses content-owned `select` and `actions` columns, included in\n `CONTENT_LIST_TABLE_COLUMN_IDS`. DataTable's generic selection cannot enforce\n per-row eligibility. Resolve links/actions through the shared adapter.\n\n## Paging and freshness\n\nContentList owns the pager in every presentation and passes no `totalRows` to\nDataTable, whose independent clamp would mutate the shared controller without\nknowing which query produced a count.\n\n- Clamp on the local full-array count or an exact total for the active settled\n server query only. Never clamp on an estimate, unavailable total, page length,\n previous-query response, or before the current response arrives. An estimate\n may still drive the displayed pager. Test paging in grid and compact modes.\n- Resolve one page-size ceiling with `resolveContentListMaxPageSize`: the minimum\n of configured limits and schema limit (default 200). Use it for controller\n seed, URL/saved-view sanitizers, translator, and live state. Server seed defaults\n to 50; null page size becomes the seed and oversized values become the ceiling,\n with reported drops. Local mode may remain unpaginated. Omitted URL size must\n restore the server seed. `setPageSize` resets page.\n- Offset only; maximum offset is 1,000,000. Report capping and update the marker\n to `effectivePage`; retain the notice until the operator leaves that page.\n Pager maximum is `floor(MAX_OFFSET / pageSize) + 1`, while clamp uses the true\n total so crafted out-of-range pages receive the explanatory notice.\n- Subscribe after the first request; query changes rebind the exact subscription.\n Offline retains usable stale rows. Online calls live `reconnect()` (refresh\n before resubscription), otherwise `refresh()`. Refresh errors are inline over\n retained rows. Show loading, retry, refreshing, last update, offline, truncation,\n and warnings across presentations. Read completeness flags from retry envelopes\n as well as execute envelopes; a successful retry replaces old flags.\n\n## Query authority and protocol\n\n`executeContentQuery()` applies tenancy, failing closed to global rows. Host\napplication scope comes from authenticated context, never request body; caller\nfilters only narrow it. Omitted scope means no extra application restriction;\n`scope: []` means no permitted rows (`id IS NULL`). AND scope into every query\nbranch alongside tenancy. Empty object conditions are configuration errors.\n\nKeep field maps, projectable fields, operator/search vocabulary, and mirrored\nlimits asserted against `buildContentQuerySchema()` and core constants or their\nobservable acceptance boundaries.\n\n- No cursor paging, body queries, metadata-path filters, or ETag/version slot.\n Read body through GET by ID; use queryFingerprint/freshness.asOf for freshness.\n- Search emits an `any` of `like` over title/description/author, escaping caller\n `%`/`_`. Drop and report unsupported `notContains`, datetime LIKE operators,\n invalid datetime inputs, unknown projection fields, and derived site queries.\n- Bound normalized request bytes, including default sort. Always emit sort\n (fall back to `CONTENT_LIST_QUERY_DEFAULT_SORT`) so client accounting is not\n smaller than the normalizer's. Limits: 100 list values, 50 filter nodes\n (containers count; search costs four), 128 DNF branches, 50 projection fields\n with 1–256-character IDs, 128-character request ID, 4096 UTF-16 units per scalar,\n 100,000 serialized request bytes. Count escapes and surrogate pairs without\n splitting code points. DNF costs include null unions and De Morgan negation.\n- Preserve comparands exactly or omit/report the filter. Oversized/unusable `in`\n entries may be removed as a reported subset (`out-of-range`/`unsupported-value`).\n Never partially apply `notIn`: drop/report `filter-widened`. Shed conjuncts for\n node/branch/byte budgets with that same report. Shortened LIKE/search patterns\n report widening; retain leading code points for contains/startsWith and trailing\n ones for endsWith. Never shorten scalar eq/ne/ordered comparands into a value\n the caller did not name. Every change is either exact, a reported superset,\n a reported subset, or a reported omitted predicate.\n- Datetimes require a real calendar day, four-digit year, T separator and an\n offset when time is present. Date-only means midnight UTC; minutes without\n seconds and lowercase t/z are accepted. Trim and uppercase before parsing,\n validate that same string, and calendar-round-trip to reject rolled dates.\n\n### Comparison semantics and dialect limits\n\nFold token filter values (type/status/state); preserve free-text case. Local\ntext comparison is case-insensitive; server free-text matching follows its SQL\noperator/dialect. PostgreSQL/DuckDB LIKE is case-sensitive; SQLite LIKE is ASCII\ncase-insensitive. Do not promise uniform free-text matching.\n\nSQLite's LIKE lacks the default backslash escape used by PostgreSQL/DuckDB;\nescaped wildcards can fail closed there. Fixing portability needs SQL-boundary\nESCAPE support. Null placement is likewise dialect-dependent: local sorts absent\nlast ascending/first descending, matching PostgreSQL/DuckDB; SQLite defaults\noppositely. The query sort grammar cannot express NULLS FIRST/LAST.\n\n- Read absence from original ContentData, not flattened display text. Type's\n `content` and title's `Untitled content` fallbacks are presentation only; missing\n values compare/search as null, genuinely blank strings remain present.\n- eq/in/LIKE exclude absent values unless null is explicitly listed. ne of a\n non-null value and notIn without null include absence. notIn containing null\n excludes absence. eq/ne null lower to IS NULL/IS NOT NULL. Direct ordered\n comparisons exclude absence; their negations include it. Every supported\n predicate and its negation must partition rows without gaps or overlap,\n including nested all/any and double negation. Negated LIKE is refused.\n- Preserve literal null through sanitization, saved views, translation and local\n evaluation; only undefined denotes unusable input. Test null, false, zero and\n empty strings. Blank scalar clears a filter; an empty entry within a list is\n real text, but a wholly empty list parameter is refused/reported.\n\n## Result budgets\n\nCall `assertContentQuerySchema(schema)` at configuration time. Every executor\nmode, including count, rejects maxResultBytes below\n`CONTENT_QUERY_MIN_RESULT_BYTES`; this is a host error, not caller validation.\n\n- Never drop rows to fit bytes: offset advances by requested limit, so omitted\n rows would become unreachable. Seat every row's irreducible floor first, then\n distribute surplus max-min fairly by appetite (cost minus floor).\n `allocateRowBytes` guarantees a page whenever floors fit; otherwise fail loudly.\n Preserve `floor <= cost` and refund the final unused array separator at exact\n byte boundaries.\n- Within rows use one sorted water-filling walk. Strings may shorten; datetime\n and JSON values are all-or-nothing (null only if smaller). Numbers, booleans,\n null, and identity never shrink. Prefer shortening free text before losing a\n format-constrained value; new constrained types are all-or-nothing by default.\n Report shortening with truncated/warnings.\n- Bound JSON documents before result normalization: strings 65,536 characters,\n containers 1,000 items, depth 16; finite numbers, no cycles, plain values only.\n Drop forbidden __proto__/constructor/prototype keys and build with null\n prototypes. Report truncation rather than allowing one stored document to\n invalidate an entire page.\n- Facets share the result byte budget; drop excess facet values and flag both\n facet and result. Per-value caps alone do not bound the envelope.\n\n## URL state and saved views\n\nRead urlState.params once; later onChange(params, state) preserves foreign\nparameters and lets the host own routing. `applyContentListViewState` is the\npublic application boundary: sanitize every patch, including raw saved snapshots,\nthen merge over current state without resetting restored page. Sanitize the patch,\nnot the merged result, because selection is intentionally absent from sanitizer\noutput. Keep raw saved-view payloads so stale-field drops remain reportable.\n\n- Escape list separators and double literal backslashes. List null uses the\n collision-free `\\0` token; a literal backslash-zero string is doubled. Scalar\n null serializes through isNull/isNotNull. Preserve foreign parameters by base\n name, even when they have a known operator suffix; unknown suffixed columns\n may still be reported as refused without being deleted.\n- The type lock applies to live state, including agent reset/filter commands.\n Fold it into restored patches to preserve paging. Clear it only on an actual\n lock-removal transition, not every unlocked render.\n- Toolbar selects must state the live predicate honestly. Unlisted equals values\n render as extra options and produce a notice. Lists, non-equals operators, and\n multiple predicates render a disabled summary and notice. Use operator-aware\n `readContentListSelectFilter`, not value-only `readContentListFilter`.\n Choosing a real option replaces all filters on that column. Summary sentinel\n uses U+001F; NUL changes during HTML parsing and breaks hydration.\n- Review is an ordinary status; deleted belongs exclusively to opt-in trash\n mode. Type options are display vocabulary, not the freeform model domain.\n Restore/translation refusals appear in one dismissible notice; stale state\n should still open with the refused parts omitted.\n\n## Shared mutations and lifecycle\n\nHuman transports and agent/bulk callers terminate at the same\n`createContentListActionAdapter()` instance. Preview/apply is principal-bound;\nrendered rows are never mutation authority.\n\n- Supported workflows: trash, draft, review submission, publish, archive, restore,\n automated review, formatting, categorization, optimization. Applications inject\n formatting/optimization handlers; handlers mutate supplied objects but must\n not save them because the adapter owns guarded writes.\n- Explicit/current-page/all-matching selections share a default 200-row cap.\n Match server and browser maxSelectionSize. All-matching is canonical query,\n fingerprint and exact count, never browser-page expansion. Above-cap requests\n fail closed, including forged/agent requests; UI asks the operator to narrow.\n- Read-only preview returns resolved scope/count/labels/eligibility/consequences.\n Apply uses opaque token and idempotency key, re-resolves query under live\n principal/tenant, rechecks tool/operation permissions and eligibility, and\n compares aggregate updated_at revision. Query/count/membership/row drift fails\n before mutation. Each save also guards updated_at atomically at UPDATE.\n Required projection: id, title, status, updated_at, even under host overrides.\n- Publication workflows require every snapshot read permission, explicitly\n including contentassets:read and assets:read. Keep assertions aligned with\n `ContentVersion.createSnapshot()`; embedded adapters rely on them without RLS.\n- Declare workflowStorage capability. PostgreSQL, SQLite, ordinary DuckDB and\n non-immediate exported-file modes are supported. JSON default/immediate and\n DuckDB immediate writes are rejected at setup because exports cannot roll back.\n- Partial results separate accepted/skipped/failed rows; clear only accepted IDs.\n Failures retain selection. Refresh the exact query and expose progress,\n exceptions, representative labels, resourceType/resourceId and auditReference.\n\nLifecycle binding enables trash controls; trash mode locks deleted and hides\nordinary status/edit/delete controls. Without it legacy onDelete remains.\n`createContentListLifecycleRoute()` mounts POST /api/v1/contents/lifecycle;\nits host authenticates every native Request and supplies current action context.\nOnly move-to-trash, restore, permanent-delete are accepted; malformed/auth/internal\nfailures use bounded envelopes without private error text.\n\n| Action | Eligible state | Contract |\n|---|---|---|\n| move-to-trash | not deleted | soft deletion |\n| restore | deleted | draft/review/published; recheck permissions and publication readiness |\n| permanent-delete | deleted | type exact server count; irreversible |\n\nPermanent DELETE binds updated_at in PostgreSQL's predicate with transactional\ncascade; embedded adapters compare under the shared write queue before cascade.\nRaces return row_revision_drifted. Empty-trash requires exact server count plus\ncanonical query. Query/selection changes invalidate previews; expiry, stale\nrevision, row/query/count drift or token failures require new preview. Preview,\ninitial apply and replay each get distinct attempt request IDs; apply/replay keep\nconfirmation/idempotency authority, and auditReference identifies original execution.\n\n## Jobs and agent surfaces\n\n- Automated review/formatting/optimization return job IDs. Queue callbacks repeat\n guarded apply with idempotency. Hosts must provide resolveDeferredPrincipal to\n re-resolve the complete live persona/TenantAgent binding; absent, mismatched or\n incomplete bindings fail closed. Authenticated jobStatusPath or client.status\n keeps identical intents locked while running, reconciles terminal outcomes,\n and allows failed/cancelled retry. Disable selection during status requests and\n recheck captured intent before reconciling responses.\n- `createContentListJobController().submit({ actionId, submissionKey, target },\n start)` coalesces duplicate active keys; rejected submissions stay failed until\n retry. update(job) cannot regress terminal state. Pending row work disables\n selection/edit/delete. Only succeeded transitions refresh: row targets require\n an affected visible row; query targets require the active request key. Failed\n jobs show error/retry and never masquerade as success.\n- Register dataSurface once at ContentList boundary across presentations and\n loading/empty/error states. Publish rendered columns plus required id (hidden\n description stays search-only), explicit fieldName mapping, available operators,\n query fingerprint/total, normalized selection, presentation and freshness.\n Derived site becomes read-only in server mode. Expose only mounted executable\n workflow/lifecycle actions. Context changes advance the same revision stream;\n stale revisions and disconnected registry commands are refused. set-view\n acknowledgements describe accepted state before renderer changes.\n- Silent reads use server `createContentListDataSurfaceDefinition({ collection,\n scope })` in createDataSurfaceTools. Resolve collection/scope from live principal;\n executeContentQuery owns rows/counts/facets/offset continuation. Exclude tenant,\n hidden and sensitive fields from discovery/projection. Durable agent mutations\n use the action adapter, never browser registry authority.\n\n## Validation\n\nUse package `pnpm test` (which generates routes through SvelteKit sync), never\nbare Vitest. Narrow with `-- <test-file>` to the affected content-list, query,\naction, lifecycle or component tests; include both grid and compact paging\nscenarios for reachability changes. Run package `pnpm typecheck` for Svelte\nchanges and root knowledge checks for this module documentation.\n"
|
|
14238
|
+
"content": "<!-- Module doc for packages/content/AGENTS.md. -->\n\n# ContentList contracts\n\nRead for changes to `src/svelte/content-list-*.ts`, `ContentList.svelte`, or the\nserver content-query/action adapters. Browser exports come from `/svelte`;\nprincipal-bound query/action factories come from `/server`.\n\n## Ownership and integration\n\n- `content-list-controller.ts` is the shared adapter over `DataTableController`.\n Search, filters, sort, paging, selection, columns, and action eligibility have\n one implementation across grid, detailed, and compact presentations. Controller\n modes are manual. Local arrays use `toContentListRows`, `selectContentListRows`,\n then `paginateContentListRows`; server rows must never be transformed again.\n- `query`, `urlState`, `savedViews`, `lifecycle`, `jobs`, and `dataSurface` are\n optional bindings. Without query, rows come from `contents`; with it, contents\n is ignored. `type` locks/hides the type filter; `defaultViewMode` seeds once.\n Existing callbacks (`onEdit`, `onDelete`, `onAdd`, `getViewHref`) remain usable.\n- `query.bind()` runs once during component initialization so a structural\n `remoteQuery(collection, transport)` binding registers teardown in that scope.\n Do not import smrt-svelte/web or its browser data runtime into the content\n Svelte barrel: public content pages depend on that code-split boundary.\n- The default query transport targets `POST /api/v1/contents/query`.\n `CONTENT_LIST_QUERY_FIELDS` maps column IDs to server fields;\n `ROW_FIELD_TO_CONTENT_KEY` maps response fields to ContentData. For example,\n column `updated`, client `updatedAt`, and server `updated_at` differ.\n `publish` maps to `publish_date`. Derived `site` comes from url/source and has\n no server field; server filtering/sorting on it is dropped and reported.\n- Missing/duplicate durable IDs still render with positional keys but are\n `identified: false`. Disable and explain their selection controls. Page select\n all and normalization exclude synthetic IDs; server selection must survive\n page changes, so current-page membership is not a durability test.\n- Compact uses content-owned `select` and `actions` columns, included in\n `CONTENT_LIST_TABLE_COLUMN_IDS`. DataTable's generic selection cannot enforce\n per-row eligibility. Resolve links/actions through the shared adapter.\n\n## Paging and freshness\n\nContentList owns the pager in every presentation and passes no `totalRows` to\nDataTable, whose independent clamp would mutate the shared controller without\nknowing which query produced a count.\n\n- Clamp on the local full-array count or an exact total for the active settled\n server query only. Never clamp on an estimate, unavailable total, page length,\n previous-query response, or before the current response arrives. An estimate\n may still drive the displayed pager. Test paging in grid and compact modes.\n- Resolve one page-size ceiling with `resolveContentListMaxPageSize`: the minimum\n of configured limits and schema limit (default 200). Use it for controller\n seed, URL/saved-view sanitizers, translator, and live state. Server seed defaults\n to 50; null page size becomes the seed and oversized values become the ceiling,\n with reported drops. Local mode may remain unpaginated. Omitted URL size must\n restore the server seed. `setPageSize` resets page.\n- Offset only; maximum offset is 1,000,000. Report capping and update the marker\n to `effectivePage`; retain the notice until the operator leaves that page.\n Pager maximum is `floor(MAX_OFFSET / pageSize) + 1`, while clamp uses the true\n total so crafted out-of-range pages receive the explanatory notice.\n- Subscribe after the first request; query changes rebind the exact subscription.\n Offline retains usable stale rows. Online calls live `reconnect()` (refresh\n before resubscription), otherwise `refresh()`. Refresh errors are inline over\n retained rows. Show loading, retry, refreshing, last update, offline, truncation,\n and warnings across presentations. Read completeness flags from retry envelopes\n as well as execute envelopes; a successful retry replaces old flags.\n\n## Query authority and protocol\n\n`executeContentQuery()` applies tenancy, failing closed to global rows. Host\napplication scope comes from authenticated context, never request body; caller\nfilters only narrow it. Omitted scope means no extra application restriction;\n`scope: []` means no permitted rows (`id IS NULL`). AND scope into every query\nbranch alongside tenancy. Empty object conditions are configuration errors.\n\nKeep field maps, projectable fields, operator/search vocabulary, and mirrored\nlimits asserted against `buildContentQuerySchema()` and core constants or their\nobservable acceptance boundaries.\n\n- No cursor paging, body queries, metadata-path filters, or ETag/version slot.\n Read body through GET by ID; use queryFingerprint/freshness.asOf for freshness.\n- Search emits an `any` of `like` over title/description/author, escaping caller\n `%`/`_`. Drop and report unsupported `notContains`, datetime LIKE operators,\n invalid datetime inputs, unknown projection fields, and derived site queries.\n- Bound normalized request bytes, including default sort. Always emit sort\n (fall back to `CONTENT_LIST_QUERY_DEFAULT_SORT`) so client accounting is not\n smaller than the normalizer's. Limits: 100 list values, 50 filter nodes\n (containers count; search costs four), 128 DNF branches, 50 projection fields\n with 1–256-character IDs, 128-character request ID, 4096 UTF-16 units per scalar,\n 100,000 serialized request bytes. Count escapes and surrogate pairs without\n splitting code points. DNF costs include null unions and De Morgan negation.\n- Preserve comparands exactly or omit/report the filter. Oversized/unusable `in`\n entries may be removed as a reported subset (`out-of-range`/`unsupported-value`).\n Never partially apply `notIn`: drop/report `filter-widened`. Shed conjuncts for\n node/branch/byte budgets with that same report. Shortened LIKE/search patterns\n report widening; retain leading code points for contains/startsWith and trailing\n ones for endsWith. Never shorten scalar eq/ne/ordered comparands into a value\n the caller did not name. Every change is either exact, a reported superset,\n a reported subset, or a reported omitted predicate.\n- Datetimes require a real calendar day, four-digit year, T separator and an\n offset when time is present. Date-only means midnight UTC; minutes without\n seconds and lowercase t/z are accepted. Trim and uppercase before parsing,\n validate that same string, and calendar-round-trip to reject rolled dates.\n\n### Comparison semantics and dialect limits\n\nFold token filter values (type/status/state); preserve free-text case. Local\ntext comparison is case-insensitive; server free-text matching follows its SQL\noperator/dialect. PostgreSQL/DuckDB LIKE is case-sensitive; SQLite LIKE is ASCII\ncase-insensitive. Do not promise uniform free-text matching.\n\nSQLite's LIKE lacks the default backslash escape used by PostgreSQL/DuckDB;\nescaped wildcards can fail closed there. Fixing portability needs SQL-boundary\nESCAPE support. Null placement is likewise dialect-dependent: local sorts absent\nlast ascending/first descending, matching PostgreSQL/DuckDB; SQLite defaults\noppositely. The query sort grammar cannot express NULLS FIRST/LAST.\n\n- Read absence from original ContentData, not flattened display text. Type's\n `content` and title's `Untitled content` fallbacks are presentation only; missing\n values compare/search as null, genuinely blank strings remain present.\n- eq/in/LIKE exclude absent values unless null is explicitly listed. ne of a\n non-null value and notIn without null include absence. notIn containing null\n excludes absence. eq/ne null lower to IS NULL/IS NOT NULL. Direct ordered\n comparisons exclude absence; their negations include it. Every supported\n predicate and its negation must partition rows without gaps or overlap,\n including nested all/any and double negation. Negated LIKE is refused.\n- Preserve literal null through sanitization, saved views, translation and local\n evaluation; only undefined denotes unusable input. Test null, false, zero and\n empty strings. Blank scalar clears a filter; an empty entry within a list is\n real text, but a wholly empty list parameter is refused/reported.\n\n## Result budgets\n\nCall `assertContentQuerySchema(schema)` at configuration time. Every executor\nmode, including count, rejects maxResultBytes below\n`CONTENT_QUERY_MIN_RESULT_BYTES`; this is a host error, not caller validation.\n\n- Never drop rows to fit bytes: offset advances by requested limit, so omitted\n rows would become unreachable. Seat every row's irreducible floor first, then\n distribute surplus max-min fairly by appetite (cost minus floor).\n `allocateRowBytes` guarantees a page whenever floors fit; otherwise fail loudly.\n Preserve `floor <= cost` and refund the final unused array separator at exact\n byte boundaries.\n- Within rows use one sorted water-filling walk. Strings may shorten; datetime\n and JSON values are all-or-nothing (null only if smaller). Numbers, booleans,\n null, and identity never shrink. Prefer shortening free text before losing a\n format-constrained value; new constrained types are all-or-nothing by default.\n Report shortening with truncated/warnings.\n- Bound JSON documents before result normalization: strings 65,536 characters,\n containers 1,000 items, depth 16; finite numbers, no cycles, plain values only.\n Drop forbidden __proto__/constructor/prototype keys and build with null\n prototypes. Report truncation rather than allowing one stored document to\n invalidate an entire page.\n- Facets share the result byte budget; drop excess facet values and flag both\n facet and result. Per-value caps alone do not bound the envelope.\n\n## URL state and saved views\n\nRead urlState.params once; later onChange(params, state) preserves foreign\nparameters and lets the host own routing. `applyContentListViewState` is the\npublic application boundary: sanitize every patch, including raw saved snapshots,\nthen merge over current state without resetting restored page. Sanitize the patch,\nnot the merged result, because selection is intentionally absent from sanitizer\noutput. Keep raw saved-view payloads so stale-field drops remain reportable.\n\n- Escape list separators and double literal backslashes. List null uses the\n collision-free `\\0` token; a literal backslash-zero string is doubled. Scalar\n null serializes through isNull/isNotNull. Preserve foreign parameters by base\n name, even when they have a known operator suffix; unknown suffixed columns\n may still be reported as refused without being deleted.\n- The type lock applies to live state, including agent reset/filter commands.\n Fold it into restored patches to preserve paging. Clear it only on an actual\n lock-removal transition, not every unlocked render.\n- Toolbar selects must state the live predicate honestly. Unlisted equals values\n render as extra options and produce a notice. Lists, non-equals operators, and\n multiple predicates render a disabled summary and notice. Use operator-aware\n `readContentListSelectFilter`, not value-only `readContentListFilter`.\n Choosing a real option replaces all filters on that column. Summary sentinel\n uses U+001F; NUL changes during HTML parsing and breaks hydration.\n- Review is an ordinary status; deleted belongs exclusively to opt-in trash\n mode. Type options are display vocabulary, not the freeform model domain.\n Restore/translation refusals appear in one dismissible notice; stale state\n should still open with the refused parts omitted.\n\n## Shared mutations and lifecycle\n\nHuman transports and agent/bulk callers terminate at the same\n`createContentListActionAdapter()` instance. Preview/apply is principal-bound;\nrendered rows are never mutation authority.\n\n- Supported workflows: trash, draft, review submission, publish, archive, restore,\n automated review, formatting, categorization, optimization. Applications inject\n formatting/optimization handlers; handlers mutate supplied objects but must\n not save them because the adapter owns guarded writes.\n- Explicit/current-page/all-matching selections share a default 200-row cap.\n Match server and browser maxSelectionSize. All-matching is canonical query,\n fingerprint and exact count, never browser-page expansion. Above-cap requests\n fail closed, including forged/agent requests; UI asks the operator to narrow.\n- Read-only preview returns resolved scope/count/labels/eligibility/consequences.\n Apply uses opaque token and idempotency key, re-resolves query under live\n principal/tenant, rechecks tool/operation permissions and eligibility, and\n compares aggregate updated_at revision. Query/count/membership/row drift fails\n before mutation. Each save also guards updated_at atomically at UPDATE.\n Required projection: id, title, status, updated_at, even under host overrides.\n- Publication workflows require every snapshot read permission, explicitly\n including contentassets:read and assets:read. Keep assertions aligned with\n `ContentVersion.createSnapshot()`; embedded adapters rely on them without RLS.\n- Declare workflowStorage capability. PostgreSQL, SQLite, ordinary DuckDB and\n non-immediate exported-file modes are supported. JSON default/immediate and\n DuckDB immediate writes are rejected at setup because exports cannot roll back.\n- Partial results separate accepted/skipped/failed rows; clear only accepted IDs.\n Failures retain selection. Refresh the exact query and expose progress,\n exceptions, representative labels, resourceType/resourceId and auditReference.\n\nLifecycle binding enables trash controls; trash mode locks deleted and hides\nordinary status/edit/delete controls. Without it legacy onDelete remains.\n`createContentListLifecycleRoute()` mounts POST /api/v1/contents/lifecycle;\nits host authenticates every native Request and supplies current action context.\nOnly move-to-trash, restore, permanent-delete are accepted; malformed/auth/internal\nfailures use bounded envelopes without private error text.\n\n| Action | Eligible state | Contract |\n|---|---|---|\n| move-to-trash | not deleted | soft deletion |\n| restore | deleted | draft/review/published; recheck permissions and publication readiness |\n| permanent-delete | deleted | type exact server count; irreversible |\n\nPermanent DELETE binds updated_at in PostgreSQL's predicate with transactional\ncascade; embedded adapters compare under the shared write queue before cascade.\nRaces return row_revision_drifted. Empty-trash requires exact server count plus\ncanonical query. Query/selection changes invalidate previews; expiry, stale\nrevision, row/query/count drift or token failures require new preview. Preview,\ninitial apply and replay each get distinct attempt request IDs; apply/replay keep\nconfirmation/idempotency authority, and auditReference identifies original execution.\n\n## Jobs and agent surfaces\n\n- Automated review/formatting/optimization return job IDs. Queue callbacks repeat\n guarded apply with idempotency. Hosts must provide resolveDeferredPrincipal to\n re-resolve the complete live persona/TenantAgent binding; absent, mismatched or\n incomplete bindings fail closed. Authenticated jobStatusPath or client.status\n keeps identical intents locked while running, reconciles terminal outcomes,\n and allows failed/cancelled retry. Disable selection during status requests and\n recheck captured intent before reconciling responses.\n- `createContentListJobController().submit({ actionId, submissionKey, target },\n start)` coalesces duplicate active keys; rejected submissions stay failed until\n retry. update(job) cannot regress terminal state. Pending row work disables\n selection/edit/delete. Only succeeded transitions refresh: row targets require\n an affected visible row; query targets require the active request key. Failed\n jobs show error/retry and never masquerade as success.\n- Register dataSurface once at ContentList boundary across presentations and\n loading/empty/error states. Publish rendered columns plus required id (hidden\n description stays search-only), explicit fieldName mapping, available operators,\n query fingerprint/total, normalized selection, presentation and freshness.\n Derived site becomes read-only in server mode. Expose only mounted executable\n workflow/lifecycle actions. Context changes advance the same revision stream;\n stale revisions and disconnected registry commands are refused. set-view\n acknowledgements describe accepted state before renderer changes.\n- Silent reads use server `createContentListDataSurfaceDefinition({ collection,\n scope })` in createDataSurfaceTools. Resolve collection/scope from live principal;\n executeContentQuery owns rows/counts/facets/offset continuation. Exclude tenant,\n hidden and sensitive fields from discovery/projection. Durable agent mutations\n use the action adapter, never browser registry authority.\n\n## Validation\n\nUse package `pnpm test` (which generates routes through SvelteKit sync), never\nbare Vitest. Narrow with `-- <test-file>` to the affected content-list, query,\naction, lifecycle or component tests; include both grid and compact paging\nscenarios for reachability changes. Run package `pnpm typecheck` for Svelte\nchanges and root knowledge checks for this module documentation.\n\n### Hydrated result values\n\nThe query boundary normalizes values against their declared descriptors before\nbyte budgeting. Objects hydrated from text columns become JSON strings and use\nthe existing scalar shortening/warning path; JSON columns retain their document\nlimits. Date-only and timezone-less datetime strings mean UTC, including facet\nbuckets. Bigint values must remain safely representable as JavaScript numbers.\n"
|
|
14239
14239
|
}
|
|
14240
14240
|
],
|
|
14241
14241
|
"browser": {
|
|
@@ -629,7 +629,7 @@ async function handleSendMessage(content: string) {
|
|
|
629
629
|
align-items: center;
|
|
630
630
|
gap: var(--smrt-spacing-1);
|
|
631
631
|
padding: var(--smrt-spacing-1) var(--smrt-spacing-2);
|
|
632
|
-
border:
|
|
632
|
+
border: var(--smrt-hairline);
|
|
633
633
|
border-radius: var(--smrt-radius-sm);
|
|
634
634
|
background: none;
|
|
635
635
|
color: var(--smrt-color-on-surface-variant);
|
|
@@ -660,7 +660,7 @@ async function handleSendMessage(content: string) {
|
|
|
660
660
|
.new-topic-row :global(.new-topic-input) {
|
|
661
661
|
flex: 1;
|
|
662
662
|
padding: var(--smrt-spacing-1) var(--smrt-spacing-2);
|
|
663
|
-
border:
|
|
663
|
+
border: var(--smrt-hairline);
|
|
664
664
|
border-radius: var(--smrt-radius-sm);
|
|
665
665
|
font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
|
|
666
666
|
outline: none;
|
|
@@ -1935,7 +1935,7 @@ function handleEditorDragEnd() {
|
|
|
1935
1935
|
position: relative;
|
|
1936
1936
|
display: flex;
|
|
1937
1937
|
flex-direction: column;
|
|
1938
|
-
border:
|
|
1938
|
+
border: var(--smrt-hairline);
|
|
1939
1939
|
border-radius: 0.85rem;
|
|
1940
1940
|
background: var(--smrt-color-surface);
|
|
1941
1941
|
overflow: visible;
|
|
@@ -1946,7 +1946,7 @@ function handleEditorDragEnd() {
|
|
|
1946
1946
|
align-items: center;
|
|
1947
1947
|
gap: 0.35rem;
|
|
1948
1948
|
padding: 0.45rem 0.55rem;
|
|
1949
|
-
border-bottom:
|
|
1949
|
+
border-bottom: var(--smrt-hairline);
|
|
1950
1950
|
background: var(--smrt-color-surface-container-low, var(--smrt-color-surface-container));
|
|
1951
1951
|
}
|
|
1952
1952
|
|
|
@@ -1997,7 +1997,7 @@ function handleEditorDragEnd() {
|
|
|
1997
1997
|
}
|
|
1998
1998
|
|
|
1999
1999
|
.body-editor-toolbar :global(.editor-toolbar-button:hover) {
|
|
2000
|
-
border-color: var(--smrt-color
|
|
2000
|
+
border-color: var(--smrt-hairline-color);
|
|
2001
2001
|
background: var(--smrt-color-surface-container);
|
|
2002
2002
|
}
|
|
2003
2003
|
|
|
@@ -2009,7 +2009,7 @@ function handleEditorDragEnd() {
|
|
|
2009
2009
|
the story rather than below it. Full width, in the page flow (no modal),
|
|
2010
2010
|
so it works the same on a phone. */
|
|
2011
2011
|
.body-editor-image-panel {
|
|
2012
|
-
border-bottom:
|
|
2012
|
+
border-bottom: var(--smrt-hairline);
|
|
2013
2013
|
background: var(--smrt-color-surface-container-lowest, var(--smrt-color-surface));
|
|
2014
2014
|
padding: 0.75rem;
|
|
2015
2015
|
max-height: min(70vh, 40rem);
|
|
@@ -2031,9 +2031,9 @@ function handleEditorDragEnd() {
|
|
|
2031
2031
|
color: var(--smrt-color-on-surface-variant);
|
|
2032
2032
|
}
|
|
2033
2033
|
|
|
2034
|
-
.format-select :global(
|
|
2034
|
+
.format-select :global([data-smrt-component="Select"]) {
|
|
2035
2035
|
min-height: 2rem;
|
|
2036
|
-
border:
|
|
2036
|
+
border: var(--smrt-hairline);
|
|
2037
2037
|
border-radius: 0.45rem;
|
|
2038
2038
|
background: var(--smrt-color-surface);
|
|
2039
2039
|
color: var(--smrt-color-on-surface);
|
|
@@ -2211,7 +2211,7 @@ function handleEditorDragEnd() {
|
|
|
2211
2211
|
inline-size: 44px;
|
|
2212
2212
|
block-size: 44px;
|
|
2213
2213
|
padding: 0;
|
|
2214
|
-
border:
|
|
2214
|
+
border: var(--smrt-hairline);
|
|
2215
2215
|
border-radius: var(--smrt-radius-full);
|
|
2216
2216
|
background: color-mix(in srgb, var(--smrt-color-surface) 94%, transparent);
|
|
2217
2217
|
color: var(--smrt-color-primary);
|
|
@@ -2255,7 +2255,7 @@ function handleEditorDragEnd() {
|
|
|
2255
2255
|
align-items: center;
|
|
2256
2256
|
gap: 0.1rem;
|
|
2257
2257
|
padding: 0.25rem;
|
|
2258
|
-
border:
|
|
2258
|
+
border: var(--smrt-hairline);
|
|
2259
2259
|
border-radius: var(--smrt-radius-full);
|
|
2260
2260
|
background: color-mix(in srgb, var(--smrt-color-surface) 96%, transparent);
|
|
2261
2261
|
color: var(--smrt-color-on-surface);
|
|
@@ -2324,7 +2324,7 @@ function handleEditorDragEnd() {
|
|
|
2324
2324
|
z-index: 21;
|
|
2325
2325
|
width: 1.45rem;
|
|
2326
2326
|
height: 1.45rem;
|
|
2327
|
-
border:
|
|
2327
|
+
border: var(--smrt-hairline);
|
|
2328
2328
|
border-radius: var(--smrt-radius-full);
|
|
2329
2329
|
background: var(--smrt-color-surface);
|
|
2330
2330
|
box-shadow: var(--smrt-elevation-4, 0 0.45rem 1rem color-mix(in srgb, var(--smrt-color-shadow) 18%, transparent));
|
|
@@ -358,7 +358,7 @@ async function recheckFactClaims(claimIds: string[]) {
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
.tool-card {
|
|
361
|
-
border: var(--smrt-card-border,
|
|
361
|
+
border: var(--smrt-card-border, var(--smrt-hairline));
|
|
362
362
|
box-shadow: var(--smrt-card-shadow, none);
|
|
363
363
|
border-radius: 0.65rem;
|
|
364
364
|
background: var(--smrt-card-background, var(--smrt-color-surface));
|
|
@@ -133,7 +133,7 @@ function canWithdraw(contribution: ContentContributionData) {
|
|
|
133
133
|
|
|
134
134
|
.portal__list button,
|
|
135
135
|
.portal__detail {
|
|
136
|
-
border:
|
|
136
|
+
border: var(--smrt-hairline);
|
|
137
137
|
border-radius: 0.75rem;
|
|
138
138
|
padding: 0.85rem;
|
|
139
139
|
background: var(--smrt-color-surface);
|
|
@@ -284,7 +284,7 @@ function handleSubmit() {
|
|
|
284
284
|
|
|
285
285
|
.card,
|
|
286
286
|
.editor-shell :global(.editor) {
|
|
287
|
-
border:
|
|
287
|
+
border: var(--smrt-hairline);
|
|
288
288
|
border-radius: 0.75rem;
|
|
289
289
|
padding: 0.9rem;
|
|
290
290
|
background: var(--smrt-color-surface);
|
|
@@ -121,7 +121,7 @@ function handleSubmit() {
|
|
|
121
121
|
|
|
122
122
|
.card,
|
|
123
123
|
.editor-shell :global(.editor) {
|
|
124
|
-
border:
|
|
124
|
+
border: var(--smrt-hairline);
|
|
125
125
|
border-radius: 0.75rem;
|
|
126
126
|
padding: 0.9rem;
|
|
127
127
|
background: var(--smrt-color-surface);
|
|
@@ -282,7 +282,7 @@ async function issueCorrection() {
|
|
|
282
282
|
flex-direction: column;
|
|
283
283
|
gap: 0.4rem;
|
|
284
284
|
background: var(--smrt-card-background, var(--smrt-color-surface));
|
|
285
|
-
border: var(--smrt-card-border,
|
|
285
|
+
border: var(--smrt-card-border, var(--smrt-hairline));
|
|
286
286
|
box-shadow: var(--smrt-card-shadow, none);
|
|
287
287
|
border-radius: 0.75rem;
|
|
288
288
|
padding: 0.85rem;
|
|
@@ -1584,7 +1584,7 @@ function removeAsset(id: string) {
|
|
|
1584
1584
|
justify-content: space-between;
|
|
1585
1585
|
padding-bottom: 1.5rem;
|
|
1586
1586
|
margin-bottom: 1.5rem;
|
|
1587
|
-
border-bottom:
|
|
1587
|
+
border-bottom: var(--smrt-hairline);
|
|
1588
1588
|
}
|
|
1589
1589
|
|
|
1590
1590
|
.editor-toolbar-left {
|
|
@@ -1623,7 +1623,7 @@ function removeAsset(id: string) {
|
|
|
1623
1623
|
.mui-field :global(.mui-input) {
|
|
1624
1624
|
padding: 0.5rem 0.75rem;
|
|
1625
1625
|
border-radius: 0.375rem;
|
|
1626
|
-
border:
|
|
1626
|
+
border: var(--smrt-hairline);
|
|
1627
1627
|
background: transparent;
|
|
1628
1628
|
color: var(--smrt-color-on-surface);
|
|
1629
1629
|
font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
|
|
@@ -1703,7 +1703,7 @@ function removeAsset(id: string) {
|
|
|
1703
1703
|
height: 600px;
|
|
1704
1704
|
background: var(--smrt-color-surface);
|
|
1705
1705
|
border-radius: 1rem;
|
|
1706
|
-
border:
|
|
1706
|
+
border: var(--smrt-hairline);
|
|
1707
1707
|
overflow: hidden;
|
|
1708
1708
|
}
|
|
1709
1709
|
|
|
@@ -1743,7 +1743,7 @@ function removeAsset(id: string) {
|
|
|
1743
1743
|
flex-direction: column;
|
|
1744
1744
|
gap: 0.75rem;
|
|
1745
1745
|
background: var(--smrt-color-surface-container-low);
|
|
1746
|
-
border:
|
|
1746
|
+
border: var(--smrt-hairline);
|
|
1747
1747
|
padding: 1rem;
|
|
1748
1748
|
border-radius: 0.5rem;
|
|
1749
1749
|
}
|
|
@@ -1758,7 +1758,7 @@ function removeAsset(id: string) {
|
|
|
1758
1758
|
display: flex;
|
|
1759
1759
|
align-items: center;
|
|
1760
1760
|
background: var(--smrt-color-surface);
|
|
1761
|
-
border:
|
|
1761
|
+
border: var(--smrt-hairline-strong);
|
|
1762
1762
|
border-radius: var(--smrt-radius-full);
|
|
1763
1763
|
padding: 0.25rem 0.25rem 0.25rem 0.75rem;
|
|
1764
1764
|
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
@@ -1794,7 +1794,7 @@ function removeAsset(id: string) {
|
|
|
1794
1794
|
}
|
|
1795
1795
|
|
|
1796
1796
|
.reference-detail {
|
|
1797
|
-
border:
|
|
1797
|
+
border: var(--smrt-hairline);
|
|
1798
1798
|
background: var(--smrt-color-surface);
|
|
1799
1799
|
border-radius: 0.5rem;
|
|
1800
1800
|
padding: 0.75rem;
|
|
@@ -1828,7 +1828,7 @@ function removeAsset(id: string) {
|
|
|
1828
1828
|
|
|
1829
1829
|
.references-section :global(.evidence-action-button) {
|
|
1830
1830
|
background: var(--smrt-color-surface);
|
|
1831
|
-
border:
|
|
1831
|
+
border: var(--smrt-hairline);
|
|
1832
1832
|
border-radius: 0.375rem;
|
|
1833
1833
|
color: var(--smrt-color-on-surface);
|
|
1834
1834
|
cursor: pointer;
|
|
@@ -1845,7 +1845,7 @@ function removeAsset(id: string) {
|
|
|
1845
1845
|
.evidence-bulk-toolbar {
|
|
1846
1846
|
align-items: center;
|
|
1847
1847
|
background: var(--smrt-color-surface);
|
|
1848
|
-
border:
|
|
1848
|
+
border: var(--smrt-hairline);
|
|
1849
1849
|
border-radius: 0.5rem;
|
|
1850
1850
|
display: flex;
|
|
1851
1851
|
flex-wrap: wrap;
|
|
@@ -1859,8 +1859,8 @@ function removeAsset(id: string) {
|
|
|
1859
1859
|
font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
|
|
1860
1860
|
}
|
|
1861
1861
|
|
|
1862
|
-
.evidence-bulk-toolbar :global(
|
|
1863
|
-
border:
|
|
1862
|
+
.evidence-bulk-toolbar :global([data-smrt-component="Select"]) {
|
|
1863
|
+
border: var(--smrt-hairline);
|
|
1864
1864
|
border-radius: 0.375rem;
|
|
1865
1865
|
padding: 0.25rem 0.5rem;
|
|
1866
1866
|
}
|
|
@@ -1926,7 +1926,7 @@ function removeAsset(id: string) {
|
|
|
1926
1926
|
}
|
|
1927
1927
|
|
|
1928
1928
|
.resource-claim {
|
|
1929
|
-
border-top:
|
|
1929
|
+
border-top: var(--smrt-hairline);
|
|
1930
1930
|
padding-top: 0.65rem;
|
|
1931
1931
|
}
|
|
1932
1932
|
|
|
@@ -1949,7 +1949,7 @@ function removeAsset(id: string) {
|
|
|
1949
1949
|
|
|
1950
1950
|
.evidence-status {
|
|
1951
1951
|
align-items: center;
|
|
1952
|
-
border:
|
|
1952
|
+
border: var(--smrt-hairline);
|
|
1953
1953
|
border-radius: var(--smrt-radius-full);
|
|
1954
1954
|
display: inline-flex;
|
|
1955
1955
|
font-size: var(--smrt-typography-label-medium-size, 0.75rem);
|
|
@@ -2037,13 +2037,13 @@ function removeAsset(id: string) {
|
|
|
2037
2037
|
gap: 0.5rem;
|
|
2038
2038
|
}
|
|
2039
2039
|
|
|
2040
|
-
.add-reference-row :global(
|
|
2040
|
+
.add-reference-row :global([data-smrt-component="Input"]) {
|
|
2041
2041
|
flex: 1;
|
|
2042
2042
|
}
|
|
2043
2043
|
|
|
2044
2044
|
.add-reference-row :global(.add-reference-button) {
|
|
2045
2045
|
background: var(--smrt-color-surface);
|
|
2046
|
-
border:
|
|
2046
|
+
border: var(--smrt-hairline-strong);
|
|
2047
2047
|
color: var(--smrt-color-on-surface-variant);
|
|
2048
2048
|
padding: 0 1rem;
|
|
2049
2049
|
border-radius: 0.5rem;
|
|
@@ -2060,7 +2060,7 @@ function removeAsset(id: string) {
|
|
|
2060
2060
|
align-items: center;
|
|
2061
2061
|
gap: 0.5rem;
|
|
2062
2062
|
background: var(--smrt-color-surface, white);
|
|
2063
|
-
border:
|
|
2063
|
+
border: var(--smrt-hairline-strong);
|
|
2064
2064
|
padding: 0.75rem 1.25rem;
|
|
2065
2065
|
border-radius: var(--smrt-radius-md, 0.5rem);
|
|
2066
2066
|
color: var(--smrt-color-on-surface-variant);
|
|
@@ -2112,7 +2112,7 @@ function removeAsset(id: string) {
|
|
|
2112
2112
|
max-height: 60vh;
|
|
2113
2113
|
overflow-y: auto;
|
|
2114
2114
|
background: var(--smrt-color-surface);
|
|
2115
|
-
border:
|
|
2115
|
+
border: var(--smrt-hairline);
|
|
2116
2116
|
margin-top: 1rem;
|
|
2117
2117
|
border-radius: 0.75rem;
|
|
2118
2118
|
box-shadow: var(--smrt-elevation-2, 0 4px 6px -1px color-mix(in srgb, var(--smrt-color-shadow) 5%, transparent), 0 2px 4px -1px color-mix(in srgb, var(--smrt-color-shadow) 3%, transparent));
|
|
@@ -2160,7 +2160,7 @@ function removeAsset(id: string) {
|
|
|
2160
2160
|
.undo-banner :global(.undo-banner__btn) {
|
|
2161
2161
|
background: var(--smrt-color-surface);
|
|
2162
2162
|
color: var(--smrt-color-primary);
|
|
2163
|
-
border:
|
|
2163
|
+
border: var(--smrt-hairline-strong);
|
|
2164
2164
|
padding: 0.375rem 0.875rem;
|
|
2165
2165
|
border-radius: 0.375rem;
|
|
2166
2166
|
font-size: var(--smrt-typography-label-large-size, 0.8125rem);
|
|
@@ -1916,7 +1916,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
|
|
|
1916
1916
|
|
|
1917
1917
|
.workflow-section {
|
|
1918
1918
|
background: var(--smrt-color-surface-container-low);
|
|
1919
|
-
border:
|
|
1919
|
+
border: var(--smrt-hairline);
|
|
1920
1920
|
border-radius: 0.75rem;
|
|
1921
1921
|
padding: 1rem;
|
|
1922
1922
|
display: flex;
|
|
@@ -2012,7 +2012,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
|
|
|
2012
2012
|
}
|
|
2013
2013
|
|
|
2014
2014
|
.claim-audit-item {
|
|
2015
|
-
border:
|
|
2015
|
+
border: var(--smrt-hairline);
|
|
2016
2016
|
border-radius: 0.6rem;
|
|
2017
2017
|
background: var(--smrt-color-surface);
|
|
2018
2018
|
padding: 0.75rem;
|
|
@@ -2049,7 +2049,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
|
|
|
2049
2049
|
.fact-result,
|
|
2050
2050
|
.review-card {
|
|
2051
2051
|
background: var(--smrt-color-surface);
|
|
2052
|
-
border:
|
|
2052
|
+
border: var(--smrt-hairline);
|
|
2053
2053
|
border-radius: 0.75rem;
|
|
2054
2054
|
padding: 0.85rem;
|
|
2055
2055
|
}
|
|
@@ -2096,7 +2096,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
|
|
|
2096
2096
|
flex-direction: column;
|
|
2097
2097
|
gap: 0.75rem;
|
|
2098
2098
|
background: var(--smrt-color-surface);
|
|
2099
|
-
border:
|
|
2099
|
+
border: var(--smrt-hairline);
|
|
2100
2100
|
border-radius: 0.75rem;
|
|
2101
2101
|
padding: 0.85rem;
|
|
2102
2102
|
}
|
|
@@ -2130,7 +2130,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
|
|
|
2130
2130
|
|
|
2131
2131
|
.review-profile-item {
|
|
2132
2132
|
padding: 0.65rem 0.75rem;
|
|
2133
|
-
border:
|
|
2133
|
+
border: var(--smrt-hairline);
|
|
2134
2134
|
border-radius: 0.65rem;
|
|
2135
2135
|
background: var(--smrt-color-surface-container-low);
|
|
2136
2136
|
}
|
|
@@ -2180,7 +2180,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
|
|
|
2180
2180
|
.transparency-card,
|
|
2181
2181
|
.transparency-list__item {
|
|
2182
2182
|
background: var(--smrt-color-surface);
|
|
2183
|
-
border:
|
|
2183
|
+
border: var(--smrt-hairline);
|
|
2184
2184
|
border-radius: 0.75rem;
|
|
2185
2185
|
}
|
|
2186
2186
|
|
|
@@ -216,7 +216,7 @@ function handleSelect(selected: ImageLike | File | string) {
|
|
|
216
216
|
justify-content: center;
|
|
217
217
|
gap: 0.45rem;
|
|
218
218
|
min-height: 2.35rem;
|
|
219
|
-
border:
|
|
219
|
+
border: var(--smrt-hairline-strong);
|
|
220
220
|
border-radius: 0.5rem;
|
|
221
221
|
background: var(--smrt-color-surface-container);
|
|
222
222
|
color: var(--smrt-color-on-surface);
|
|
@@ -108,7 +108,7 @@ function cycle(delta: number) {
|
|
|
108
108
|
|
|
109
109
|
.content-image-chooser :global(.chooser-arrow),
|
|
110
110
|
.content-image-chooser :global(.chooser-preview) {
|
|
111
|
-
border:
|
|
111
|
+
border: var(--smrt-hairline);
|
|
112
112
|
background: var(--smrt-color-surface-container);
|
|
113
113
|
color: var(--smrt-color-on-surface);
|
|
114
114
|
border-radius: var(--smrt-radius-full);
|
|
@@ -3457,10 +3457,10 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3457
3457
|
align-items: center;
|
|
3458
3458
|
}
|
|
3459
3459
|
|
|
3460
|
-
.search-filters :global(
|
|
3461
|
-
.search-filters :global(
|
|
3460
|
+
.search-filters :global([data-smrt-component="Input"]),
|
|
3461
|
+
.search-filters :global([data-smrt-component="Select"]) {
|
|
3462
3462
|
padding: 0.5rem 0.9rem;
|
|
3463
|
-
border:
|
|
3463
|
+
border: var(--smrt-hairline-strong);
|
|
3464
3464
|
border-radius: 0.5rem;
|
|
3465
3465
|
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
3466
3466
|
height: 38px;
|
|
@@ -3479,7 +3479,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3479
3479
|
background: var(--smrt-color-surface-container-low);
|
|
3480
3480
|
border-radius: 0.5rem;
|
|
3481
3481
|
padding: 0.25rem;
|
|
3482
|
-
border:
|
|
3482
|
+
border: var(--smrt-hairline);
|
|
3483
3483
|
}
|
|
3484
3484
|
|
|
3485
3485
|
.view-toggles :global(.view-toggle-btn) {
|
|
@@ -3551,7 +3551,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3551
3551
|
gap: 0.75rem;
|
|
3552
3552
|
margin-bottom: 1rem;
|
|
3553
3553
|
padding: 0.75rem;
|
|
3554
|
-
border:
|
|
3554
|
+
border: var(--smrt-hairline);
|
|
3555
3555
|
border-radius: 0.65rem;
|
|
3556
3556
|
background: var(--smrt-color-surface-container-low);
|
|
3557
3557
|
}
|
|
@@ -3613,7 +3613,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3613
3613
|
background: var(--smrt-color-surface);
|
|
3614
3614
|
border-radius: 0.75rem;
|
|
3615
3615
|
padding: 1.5rem;
|
|
3616
|
-
border:
|
|
3616
|
+
border: var(--smrt-hairline);
|
|
3617
3617
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
3618
3618
|
display: flex;
|
|
3619
3619
|
flex-direction: column;
|
|
@@ -3628,7 +3628,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3628
3628
|
width: calc(100% + 3rem);
|
|
3629
3629
|
margin: -1.5rem -1.5rem 1rem -1.5rem;
|
|
3630
3630
|
height: 160px;
|
|
3631
|
-
border-bottom:
|
|
3631
|
+
border-bottom: var(--smrt-hairline);
|
|
3632
3632
|
overflow: hidden;
|
|
3633
3633
|
background: var(--smrt-color-surface-container-high);
|
|
3634
3634
|
}
|
|
@@ -3675,7 +3675,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3675
3675
|
|
|
3676
3676
|
.status-published { background: var(--smrt-color-success-container); color: var(--smrt-color-on-success-container); border: 1px solid var(--smrt-color-success); }
|
|
3677
3677
|
.status-draft { background: var(--smrt-color-warning-container); color: var(--smrt-color-on-warning-container); border: 1px solid var(--smrt-color-warning); }
|
|
3678
|
-
.status-archived { background: var(--smrt-color-surface-container); color: var(--smrt-color-on-surface-variant); border:
|
|
3678
|
+
.status-archived { background: var(--smrt-color-surface-container); color: var(--smrt-color-on-surface-variant); border: var(--smrt-hairline); }
|
|
3679
3679
|
|
|
3680
3680
|
.state-highlighted { background: var(--smrt-color-warning-container); color: var(--smrt-color-on-warning-container); border: 1px solid var(--smrt-color-warning);}
|
|
3681
3681
|
.state-active { background: var(--smrt-color-success-container); color: var(--smrt-color-on-success-container); border: 1px solid var(--smrt-color-success); }
|
|
@@ -3722,7 +3722,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3722
3722
|
display: flex;
|
|
3723
3723
|
gap: 0.75rem;
|
|
3724
3724
|
margin-top: 0.5rem;
|
|
3725
|
-
border-top:
|
|
3725
|
+
border-top: var(--smrt-hairline);
|
|
3726
3726
|
padding-top: 1rem;
|
|
3727
3727
|
}
|
|
3728
3728
|
|
|
@@ -3730,7 +3730,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3730
3730
|
.content-actions a {
|
|
3731
3731
|
flex: 1;
|
|
3732
3732
|
padding: 0.5rem 1rem;
|
|
3733
|
-
border:
|
|
3733
|
+
border: var(--smrt-hairline);
|
|
3734
3734
|
border-radius: 0.375rem;
|
|
3735
3735
|
background: var(--smrt-color-surface-container-low);
|
|
3736
3736
|
color: var(--smrt-color-on-surface);
|
|
@@ -3745,7 +3745,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3745
3745
|
.content-actions :global(.content-action-btn:hover),
|
|
3746
3746
|
.content-actions a:hover {
|
|
3747
3747
|
background: var(--smrt-color-surface-variant);
|
|
3748
|
-
border-color: var(--smrt-color
|
|
3748
|
+
border-color: var(--smrt-hairline-strong-color);
|
|
3749
3749
|
}
|
|
3750
3750
|
|
|
3751
3751
|
.content-actions .view-btn {
|
|
@@ -3773,7 +3773,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3773
3773
|
display: flex;
|
|
3774
3774
|
flex-direction: column;
|
|
3775
3775
|
gap: 0;
|
|
3776
|
-
border-top:
|
|
3776
|
+
border-top: var(--smrt-hairline);
|
|
3777
3777
|
}
|
|
3778
3778
|
|
|
3779
3779
|
.content-row {
|
|
@@ -3782,7 +3782,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3782
3782
|
gap: 1.25rem;
|
|
3783
3783
|
align-items: start;
|
|
3784
3784
|
padding: 1.1rem 0;
|
|
3785
|
-
border-bottom:
|
|
3785
|
+
border-bottom: var(--smrt-hairline);
|
|
3786
3786
|
}
|
|
3787
3787
|
|
|
3788
3788
|
.content-row__select {
|
|
@@ -3831,7 +3831,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3831
3831
|
min-height: 2.4rem;
|
|
3832
3832
|
padding: 0 0.85rem;
|
|
3833
3833
|
border-radius: var(--smrt-radius-full);
|
|
3834
|
-
border:
|
|
3834
|
+
border: var(--smrt-hairline);
|
|
3835
3835
|
background: transparent;
|
|
3836
3836
|
color: var(--smrt-color-on-surface);
|
|
3837
3837
|
font-weight: var(--smrt-typography-weight-semibold, 600);
|
|
@@ -3870,7 +3870,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3870
3870
|
.content-table-wrapper {
|
|
3871
3871
|
background: var(--smrt-color-surface);
|
|
3872
3872
|
border-radius: 0.75rem;
|
|
3873
|
-
border:
|
|
3873
|
+
border: var(--smrt-hairline);
|
|
3874
3874
|
overflow: hidden;
|
|
3875
3875
|
box-shadow: var(--smrt-elevation-1, 0 1px 3px rgba(0,0,0,0.05));
|
|
3876
3876
|
}
|
|
@@ -3913,7 +3913,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3913
3913
|
align-items: center;
|
|
3914
3914
|
gap: 0.75rem;
|
|
3915
3915
|
padding: 0.65rem 0.75rem;
|
|
3916
|
-
border:
|
|
3916
|
+
border: var(--smrt-hairline);
|
|
3917
3917
|
border-radius: 0.5rem;
|
|
3918
3918
|
background: var(--smrt-color-surface-container-low);
|
|
3919
3919
|
color: var(--smrt-color-on-surface-variant);
|
|
@@ -3997,7 +3997,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
3997
3997
|
margin-bottom: 1rem;
|
|
3998
3998
|
padding: 0.75rem 1rem;
|
|
3999
3999
|
border-radius: 0.5rem;
|
|
4000
|
-
border:
|
|
4000
|
+
border: var(--smrt-hairline);
|
|
4001
4001
|
background: var(--smrt-color-surface-container-low);
|
|
4002
4002
|
color: var(--smrt-color-on-surface-variant);
|
|
4003
4003
|
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
@@ -4015,7 +4015,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
4015
4015
|
}
|
|
4016
4016
|
|
|
4017
4017
|
.state-notice :global(.state-notice__dismiss) {
|
|
4018
|
-
border:
|
|
4018
|
+
border: var(--smrt-hairline);
|
|
4019
4019
|
border-radius: 0.375rem;
|
|
4020
4020
|
padding: 0.25rem 0.75rem;
|
|
4021
4021
|
cursor: pointer;
|
|
@@ -4056,7 +4056,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
4056
4056
|
}
|
|
4057
4057
|
|
|
4058
4058
|
.state-panel :global(.retry-button) {
|
|
4059
|
-
border:
|
|
4059
|
+
border: var(--smrt-hairline-strong);
|
|
4060
4060
|
border-radius: 0.5rem;
|
|
4061
4061
|
padding: 0.5rem 1rem;
|
|
4062
4062
|
cursor: pointer;
|
|
@@ -4085,8 +4085,8 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
4085
4085
|
width: 100%;
|
|
4086
4086
|
}
|
|
4087
4087
|
|
|
4088
|
-
.search-filters :global(
|
|
4089
|
-
.search-filters :global(
|
|
4088
|
+
.search-filters :global([data-smrt-component="Input"]),
|
|
4089
|
+
.search-filters :global([data-smrt-component="Select"]),
|
|
4090
4090
|
.add-button {
|
|
4091
4091
|
width: 100%;
|
|
4092
4092
|
}
|