@caretcms/core 0.1.2 → 0.3.0
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.md +109 -13
- package/dist/contracts.d.ts +1 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +1 -0
- package/dist/contracts.js.map +1 -1
- package/dist/index.d.ts +31 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -30
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +17 -6
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +57 -14
- package/dist/loader.js.map +1 -1
- package/dist/markdown/block-context.d.ts +21 -0
- package/dist/markdown/block-context.d.ts.map +1 -0
- package/dist/markdown/block-context.js +27 -0
- package/dist/markdown/block-context.js.map +1 -0
- package/dist/markdown/canonical-body.d.ts +30 -0
- package/dist/markdown/canonical-body.d.ts.map +1 -0
- package/dist/markdown/canonical-body.js +54 -0
- package/dist/markdown/canonical-body.js.map +1 -0
- package/dist/markdown/contracts.d.ts +66 -0
- package/dist/markdown/contracts.d.ts.map +1 -0
- package/dist/markdown/contracts.js +102 -0
- package/dist/markdown/contracts.js.map +1 -0
- package/dist/markdown/html-to-snodes.d.ts +26 -0
- package/dist/markdown/html-to-snodes.d.ts.map +1 -0
- package/dist/markdown/html-to-snodes.js +118 -0
- package/dist/markdown/html-to-snodes.js.map +1 -0
- package/dist/markdown/remark.d.ts +35 -0
- package/dist/markdown/remark.d.ts.map +1 -0
- package/dist/markdown/remark.js +66 -0
- package/dist/markdown/remark.js.map +1 -0
- package/dist/markdown/satteri.d.ts +19 -0
- package/dist/markdown/satteri.d.ts.map +1 -0
- package/dist/markdown/satteri.js +144 -0
- package/dist/markdown/satteri.js.map +1 -0
- package/dist/markdown/serialize.d.ts +60 -0
- package/dist/markdown/serialize.d.ts.map +1 -0
- package/dist/markdown/serialize.js +264 -0
- package/dist/markdown/serialize.js.map +1 -0
- package/dist/markdown/splice.d.ts +32 -0
- package/dist/markdown/splice.d.ts.map +1 -0
- package/dist/markdown/splice.js +44 -0
- package/dist/markdown/splice.js.map +1 -0
- package/dist/markdown/stamp.d.ts +68 -0
- package/dist/markdown/stamp.d.ts.map +1 -0
- package/dist/markdown/stamp.js +131 -0
- package/dist/markdown/stamp.js.map +1 -0
- package/dist/runtime/auth/rate-limiter.d.ts.map +1 -1
- package/dist/runtime/auth/rate-limiter.js +5 -0
- package/dist/runtime/auth/rate-limiter.js.map +1 -1
- package/dist/runtime/auth/session.d.ts +3 -3
- package/dist/runtime/auth/session.d.ts.map +1 -1
- package/dist/runtime/auth/session.js +68 -21
- package/dist/runtime/auth/session.js.map +1 -1
- package/dist/runtime/config.d.ts +3 -0
- package/dist/runtime/config.d.ts.map +1 -1
- package/dist/runtime/config.js +4 -1
- package/dist/runtime/config.js.map +1 -1
- package/dist/runtime/content.d.ts.map +1 -1
- package/dist/runtime/content.js +4 -2
- package/dist/runtime/content.js.map +1 -1
- package/dist/runtime/i18n.d.ts +86 -0
- package/dist/runtime/i18n.d.ts.map +1 -0
- package/dist/runtime/i18n.js +168 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/middleware.d.ts.map +1 -1
- package/dist/runtime/middleware.js +61 -6
- package/dist/runtime/middleware.js.map +1 -1
- package/dist/runtime/mutations/contracts.d.ts +28 -1
- package/dist/runtime/mutations/contracts.d.ts.map +1 -1
- package/dist/runtime/mutations/contracts.js +76 -0
- package/dist/runtime/mutations/contracts.js.map +1 -1
- package/dist/runtime/mutations/engine.d.ts +6 -1
- package/dist/runtime/mutations/engine.d.ts.map +1 -1
- package/dist/runtime/mutations/engine.js +271 -51
- package/dist/runtime/mutations/engine.js.map +1 -1
- package/dist/runtime/providers.d.ts +2 -1
- package/dist/runtime/providers.d.ts.map +1 -1
- package/dist/runtime/providers.js +7 -1
- package/dist/runtime/providers.js.map +1 -1
- package/dist/runtime/publish.d.ts +13 -1
- package/dist/runtime/publish.d.ts.map +1 -1
- package/dist/runtime/publish.js +80 -4
- package/dist/runtime/publish.js.map +1 -1
- package/dist/runtime/request-context.d.ts +14 -2
- package/dist/runtime/request-context.d.ts.map +1 -1
- package/dist/runtime/request-context.js +7 -1
- package/dist/runtime/request-context.js.map +1 -1
- package/dist/runtime/rewrite.d.ts.map +1 -1
- package/dist/runtime/rewrite.js +109 -3
- package/dist/runtime/rewrite.js.map +1 -1
- package/dist/runtime/rich-allowlist.d.ts.map +1 -1
- package/dist/runtime/rich-allowlist.js +5 -1
- package/dist/runtime/rich-allowlist.js.map +1 -1
- package/dist/runtime/routes/admin-entry.d.ts.map +1 -1
- package/dist/runtime/routes/admin-entry.js +114 -18
- package/dist/runtime/routes/admin-entry.js.map +1 -1
- package/dist/runtime/routes/admin.d.ts.map +1 -1
- package/dist/runtime/routes/admin.js +33 -15
- package/dist/runtime/routes/admin.js.map +1 -1
- package/dist/runtime/routes/auth-login.d.ts.map +1 -1
- package/dist/runtime/routes/auth-login.js +4 -0
- package/dist/runtime/routes/auth-login.js.map +1 -1
- package/dist/runtime/routes/auth-logout.d.ts.map +1 -1
- package/dist/runtime/routes/auth-logout.js +7 -2
- package/dist/runtime/routes/auth-logout.js.map +1 -1
- package/dist/runtime/routes/auth-session.d.ts.map +1 -1
- package/dist/runtime/routes/auth-session.js +4 -2
- package/dist/runtime/routes/auth-session.js.map +1 -1
- package/dist/runtime/routes/collection-list.d.ts.map +1 -1
- package/dist/runtime/routes/collection-list.js +64 -41
- package/dist/runtime/routes/collection-list.js.map +1 -1
- package/dist/runtime/routes/entries.d.ts.map +1 -1
- package/dist/runtime/routes/entries.js +16 -6
- package/dist/runtime/routes/entries.js.map +1 -1
- package/dist/runtime/routes/history.d.ts.map +1 -1
- package/dist/runtime/routes/history.js +50 -22
- package/dist/runtime/routes/history.js.map +1 -1
- package/dist/runtime/routes/mutate.d.ts.map +1 -1
- package/dist/runtime/routes/mutate.js +40 -6
- package/dist/runtime/routes/mutate.js.map +1 -1
- package/dist/runtime/routes/publish.d.ts.map +1 -1
- package/dist/runtime/routes/publish.js +5 -2
- package/dist/runtime/routes/publish.js.map +1 -1
- package/dist/runtime/routes/schema.d.ts.map +1 -1
- package/dist/runtime/routes/schema.js +11 -3
- package/dist/runtime/routes/schema.js.map +1 -1
- package/dist/runtime/routes/studio-home.d.ts.map +1 -1
- package/dist/runtime/routes/studio-home.js +38 -19
- package/dist/runtime/routes/studio-home.js.map +1 -1
- package/dist/runtime/routes/theme-stylesheet.d.ts.map +1 -1
- package/dist/runtime/routes/theme-stylesheet.js +11 -1
- package/dist/runtime/routes/theme-stylesheet.js.map +1 -1
- package/dist/runtime/schema-registry.d.ts +8 -1
- package/dist/runtime/schema-registry.d.ts.map +1 -1
- package/dist/runtime/schema-registry.js +47 -3
- package/dist/runtime/schema-registry.js.map +1 -1
- package/dist/runtime/storage/atomic-write.d.ts.map +1 -1
- package/dist/runtime/storage/atomic-write.js +8 -3
- package/dist/runtime/storage/atomic-write.js.map +1 -1
- package/dist/runtime/storage/markdown-adapter.d.ts +19 -0
- package/dist/runtime/storage/markdown-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/markdown-adapter.js +41 -0
- package/dist/runtime/storage/markdown-adapter.js.map +1 -1
- package/dist/runtime/storage/session-overlay-adapter.d.ts +8 -0
- package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -1
- package/dist/runtime/storage/session-overlay-adapter.js +24 -2
- package/dist/runtime/storage/session-overlay-adapter.js.map +1 -1
- package/dist/runtime/themes/preset-tokens.js +4 -4
- package/dist/runtime/themes/preset-tokens.js.map +1 -1
- package/dist/runtime/utils.d.ts +10 -0
- package/dist/runtime/utils.d.ts.map +1 -1
- package/dist/runtime/utils.js +16 -0
- package/dist/runtime/utils.js.map +1 -1
- package/dist/runtime/views/studio-layout.d.ts +3 -0
- package/dist/runtime/views/studio-layout.d.ts.map +1 -1
- package/dist/runtime/views/studio-layout.js +36 -13
- package/dist/runtime/views/studio-layout.js.map +1 -1
- package/dist/schema-utils.d.ts +7 -0
- package/dist/schema-utils.d.ts.map +1 -1
- package/dist/schema-utils.js +143 -0
- package/dist/schema-utils.js.map +1 -1
- package/dist/types.d.ts +83 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/static/cms/admin-entry.css +135 -13
- package/static/cms/admin-entry.js +509 -86
- package/static/cms/editor/guards.js +1 -1
- package/static/cms/editor/image-edit.js +42 -11
- package/static/cms/editor/image.css +7 -1
- package/static/cms/editor/md-block-edit.js +176 -0
- package/static/cms/editor/md-serialize.js +301 -0
- package/static/cms/editor/panel.css +69 -25
- package/static/cms/editor/panel.js +58 -1
- package/static/cms/editor/rich-toolbar.js +4 -3
- package/static/cms/editor/sanitize.js +2 -1
- package/static/cms/editor/sync.js +277 -56
- package/static/cms/editor/text-edit.js +68 -17
- package/static/cms/editor/text-link-interactions.js +4 -4
- package/static/cms/editor/toast.css +114 -2
- package/static/cms/editor/toast.js +121 -22
- package/static/cms/editor/tokens-and-text.css +73 -3
- package/static/cms/editor/toolbar.css +19 -6
- package/static/cms/editor/toolbar.js +64 -23
- package/static/cms/editor.css +1 -1
- package/static/cms/editor.js +14 -3
- package/static/cms/studio-tokens.css +4 -4
- package/static/cms/studio.css +24 -0
|
@@ -50,18 +50,26 @@ function getToolbarNavLinks(pagePath) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function renderDraftControls(staticDelivery) {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
// Static delivery is always drafting, so the controls stay visible. Server
|
|
54
|
+
// delivery saves field edits straight to the site, but inline body-block
|
|
55
|
+
// edits are ALWAYS drafts (they splice into source files only at publish), so
|
|
56
|
+
// the controls render here too — hidden until at least one draft is pending
|
|
57
|
+
// (toggled by refreshDraftControls) so the toolbar stays quiet otherwise.
|
|
58
|
+
const publishTitle = staticDelivery
|
|
59
|
+
? 'Publish drafts; static visitors update after rebuild and deploy'
|
|
60
|
+
: 'Publish your body-block drafts into the source files';
|
|
55
61
|
return `
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
<span class="cms-draft-controls"${staticDelivery ? '' : ' hidden'}>
|
|
63
|
+
<button class="cms-publish-btn cms-go-live-btn" type="button" title="${publishTitle}">
|
|
64
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5"/><polyline points="5 12 12 5 19 12"/></svg>
|
|
65
|
+
<span class="cms-go-live-label">Publish</span>
|
|
66
|
+
</button>
|
|
67
|
+
<button class="cms-discard-btn" type="button" title="Discard your draft changes">
|
|
68
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
|
|
69
|
+
Discard
|
|
70
|
+
</button>
|
|
71
|
+
<div class="cms-toolbar-divider"></div>
|
|
72
|
+
</span>`;
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
function renderToolbar(navLinks, staticDelivery) {
|
|
@@ -74,7 +82,7 @@ function renderToolbar(navLinks, staticDelivery) {
|
|
|
74
82
|
|
|
75
83
|
const badgeLabel = staticDelivery ? 'Draft' : 'Live';
|
|
76
84
|
const badgeHint = staticDelivery
|
|
77
|
-
? '
|
|
85
|
+
? 'Draft preview; visitors update after publish, rebuild, and deploy'
|
|
78
86
|
: 'Changes save directly to your site';
|
|
79
87
|
|
|
80
88
|
const toolbar = document.createElement('div');
|
|
@@ -88,8 +96,8 @@ function renderToolbar(navLinks, staticDelivery) {
|
|
|
88
96
|
<span class="cms-toolbar-badge-text">${badgeLabel}</span>
|
|
89
97
|
</div>
|
|
90
98
|
<div class="cms-toolbar-divider"></div>
|
|
91
|
-
<div class="cms-status-group">
|
|
92
|
-
<span class="cms-status-dot cms-status-idle"></span>
|
|
99
|
+
<div class="cms-status-group" role="status" aria-live="polite">
|
|
100
|
+
<span class="cms-status-dot cms-status-idle" aria-hidden="true"></span>
|
|
93
101
|
<span class="cms-status-text">Ready</span>
|
|
94
102
|
</div>
|
|
95
103
|
</div>
|
|
@@ -168,16 +176,30 @@ export function mountToolbar({ showToast, clearDirty, onLogout }) {
|
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
async function publishDrafts() {
|
|
171
|
-
setStatus('saving', '
|
|
179
|
+
setStatus('saving', 'Publishing…');
|
|
172
180
|
try {
|
|
173
181
|
const res = await draftRequest('POST', '/publish');
|
|
174
182
|
if (!res.ok) throw new Error('publish failed');
|
|
175
183
|
const data = await res.json();
|
|
176
184
|
const n = Array.isArray(data.published) ? data.published.length : 0;
|
|
185
|
+
const conflicts = Array.isArray(data.conflicts) ? data.conflicts.length : 0;
|
|
186
|
+
if (conflicts > 0) {
|
|
187
|
+
// Stale body drafts: preserved server-side, NOT published. Reload so
|
|
188
|
+
// fresh stamps arrive and the editor can re-apply them.
|
|
189
|
+
setStatus('error', 'Some drafts conflicted');
|
|
190
|
+
showToast(
|
|
191
|
+
n > 0
|
|
192
|
+
? `Published ${n} change(s); ${conflicts} draft(s) conflicted with newer content — reloading so you can re-apply.`
|
|
193
|
+
: `${conflicts} draft(s) conflicted with newer content — reloading so you can re-apply.`,
|
|
194
|
+
'error',
|
|
195
|
+
);
|
|
196
|
+
window.location.reload();
|
|
197
|
+
return n > 0;
|
|
198
|
+
}
|
|
177
199
|
if (data.rebuild?.triggered && data.rebuild.ok === false) {
|
|
178
|
-
setStatus('error', '
|
|
200
|
+
setStatus('error', 'Published, deploy failed');
|
|
179
201
|
showToast(
|
|
180
|
-
'Changes are
|
|
202
|
+
'Changes are published, but the deploy webhook failed. Check your CI settings.',
|
|
181
203
|
'error',
|
|
182
204
|
);
|
|
183
205
|
return false;
|
|
@@ -185,18 +207,23 @@ export function mountToolbar({ showToast, clearDirty, onLogout }) {
|
|
|
185
207
|
if (data.rebuild?.triggered) {
|
|
186
208
|
showToast(
|
|
187
209
|
n > 0
|
|
188
|
-
? `
|
|
210
|
+
? `Published ${n} change(s) — rebuild started`
|
|
189
211
|
: 'Your site is rebuilding',
|
|
190
212
|
'success',
|
|
191
213
|
);
|
|
192
214
|
} else {
|
|
193
|
-
showToast(
|
|
215
|
+
showToast(
|
|
216
|
+
n > 0
|
|
217
|
+
? `Published ${n} change(s) — rebuild and deploy to update visitors`
|
|
218
|
+
: 'Already up to date',
|
|
219
|
+
'success',
|
|
220
|
+
);
|
|
194
221
|
}
|
|
195
222
|
window.location.reload();
|
|
196
223
|
return true;
|
|
197
224
|
} catch {
|
|
198
|
-
setStatus('error', '
|
|
199
|
-
showToast('
|
|
225
|
+
setStatus('error', 'Publish failed');
|
|
226
|
+
showToast('Publish failed', 'error');
|
|
200
227
|
return false;
|
|
201
228
|
}
|
|
202
229
|
}
|
|
@@ -206,7 +233,7 @@ export function mountToolbar({ showToast, clearDirty, onLogout }) {
|
|
|
206
233
|
const count = await fetchDraftCount();
|
|
207
234
|
if (count > 0) {
|
|
208
235
|
const goLive = window.confirm(
|
|
209
|
-
`You have ${count} unpublished change${count === 1 ? '' : 's'}.
|
|
236
|
+
`You have ${count} unpublished change${count === 1 ? '' : 's'}. Publish before signing out?`,
|
|
210
237
|
);
|
|
211
238
|
if (goLive) {
|
|
212
239
|
await publishDrafts();
|
|
@@ -235,7 +262,7 @@ export function mountToolbar({ showToast, clearDirty, onLogout }) {
|
|
|
235
262
|
if (
|
|
236
263
|
!window.confirm(
|
|
237
264
|
staticDelivery
|
|
238
|
-
? '
|
|
265
|
+
? 'Publish all draft changes? Static visitors update after rebuild and deploy.'
|
|
239
266
|
: 'Publish all your draft changes to the live site?',
|
|
240
267
|
)
|
|
241
268
|
) {
|
|
@@ -256,6 +283,20 @@ export function mountToolbar({ showToast, clearDirty, onLogout }) {
|
|
|
256
283
|
}
|
|
257
284
|
});
|
|
258
285
|
|
|
286
|
+
// Server delivery hides the draft controls until a body draft exists. Field
|
|
287
|
+
// edits save directly (no draft), so the count reflects pending body blocks.
|
|
288
|
+
// Refresh on mount and whenever a body block is drafted; publish/discard
|
|
289
|
+
// reload the page, so mount re-evaluates from scratch.
|
|
290
|
+
const draftControls = toolbar.querySelector('.cms-draft-controls');
|
|
291
|
+
async function refreshDraftControls() {
|
|
292
|
+
if (staticDelivery || !draftControls) return;
|
|
293
|
+
draftControls.hidden = (await fetchDraftCount()) === 0;
|
|
294
|
+
}
|
|
295
|
+
if (!staticDelivery) {
|
|
296
|
+
refreshDraftControls();
|
|
297
|
+
window.addEventListener('cms:draftSaved', refreshDraftControls);
|
|
298
|
+
}
|
|
299
|
+
|
|
259
300
|
const studioButton = toolbar.querySelector('.cms-studio-btn');
|
|
260
301
|
const mapButton = toolbar.querySelector('.cms-map-btn');
|
|
261
302
|
return {
|
package/static/cms/editor.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* ========================================================================
|
|
2
2
|
CMS Editor Styles — only loaded when isEditor = true
|
|
3
3
|
======================================================================== */
|
|
4
|
-
@import "./editor/tokens-and-text.css";
|
|
4
|
+
@import "./editor/tokens-and-text.css?v=studio-upstream-20260819";
|
|
5
5
|
@import "./editor/image.css";
|
|
6
6
|
@import "./editor/section-controls.css";
|
|
7
7
|
@import "./editor/toolbar.css";
|
package/static/cms/editor.js
CHANGED
|
@@ -18,12 +18,13 @@ import { createToast } from './editor/toast.js';
|
|
|
18
18
|
import { mountEditorGuards } from './editor/guards.js';
|
|
19
19
|
import { mountToolbar, normalizePreviewForDelivery } from './editor/toolbar.js';
|
|
20
20
|
import { mountStudioPanel } from './editor/panel.js';
|
|
21
|
-
import { mountStudioSync } from './editor/sync.js';
|
|
21
|
+
import { mountStudioSync } from './editor/sync.js?v=studio-upstream-20260819';
|
|
22
22
|
import { mountTextEditors } from './editor/text-edit.js';
|
|
23
23
|
import { mountImageEditors } from './editor/image-edit.js';
|
|
24
24
|
import { mountSectionControls } from './editor/section-controls.js';
|
|
25
25
|
import { mountContentMap } from './editor/content-map.js';
|
|
26
26
|
import { mountRichToolbar } from './editor/rich-toolbar.js';
|
|
27
|
+
import { mountMdBlockEditors } from './editor/md-block-edit.js';
|
|
27
28
|
import { mountLinkFollowAffordances } from './editor/link-follow.js';
|
|
28
29
|
import { revealAndFade } from './editor/highlight.js';
|
|
29
30
|
import { hydrateStega } from './editor/stega-hydrate.js';
|
|
@@ -36,7 +37,10 @@ function boot() {
|
|
|
36
37
|
if (normalizePreviewForDelivery()) return;
|
|
37
38
|
|
|
38
39
|
const state = {
|
|
39
|
-
|
|
40
|
+
// Every element with unsaved edits. A Set (not a single element) so a save
|
|
41
|
+
// completing on field A can't clear the dirty flag for field B the user has
|
|
42
|
+
// since moved to — that would let the beforeunload guard miss B's edits.
|
|
43
|
+
dirtyEls: new Set(),
|
|
40
44
|
linkPopupEl: null,
|
|
41
45
|
};
|
|
42
46
|
|
|
@@ -52,7 +56,7 @@ function boot() {
|
|
|
52
56
|
const { studioButton, mapButton, setStatus } = mountToolbar({
|
|
53
57
|
showToast,
|
|
54
58
|
clearDirty: () => {
|
|
55
|
-
state.
|
|
59
|
+
state.dirtyEls.clear();
|
|
56
60
|
},
|
|
57
61
|
onLogout: async () => {
|
|
58
62
|
await fetch(buildCmsUrl('/auth/logout'), { method: 'POST' });
|
|
@@ -94,6 +98,13 @@ function boot() {
|
|
|
94
98
|
richToolbarMounted = true;
|
|
95
99
|
}
|
|
96
100
|
|
|
101
|
+
mountMdBlockEditors({
|
|
102
|
+
state,
|
|
103
|
+
flash,
|
|
104
|
+
showToast,
|
|
105
|
+
onUnauthorized: redirectToEditorLogin,
|
|
106
|
+
});
|
|
107
|
+
|
|
97
108
|
mountImageEditors({
|
|
98
109
|
parseCaretAttr,
|
|
99
110
|
flash,
|
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
--color-theme-border: rgba(255, 255, 255, 0.10);
|
|
31
31
|
|
|
32
32
|
/* ─── Semantic: Accent ────────────────────────────────────────────── */
|
|
33
|
-
--color-theme-accent: #
|
|
33
|
+
--color-theme-accent: #60a5fa;
|
|
34
34
|
--color-theme-accent-soft: rgba(59, 130, 246, 0.12);
|
|
35
35
|
--color-theme-accent-strong: rgba(59, 130, 246, 0.24);
|
|
36
|
-
--color-theme-on-accent: #
|
|
36
|
+
--color-theme-on-accent: #07111f;
|
|
37
37
|
|
|
38
38
|
/* ─── Semantic: Text ──────────────────────────────────────────────── */
|
|
39
39
|
--color-theme-text: rgba(255, 255, 255, 0.92);
|
|
40
|
-
--color-theme-text-muted:
|
|
41
|
-
--color-theme-text-dim:
|
|
40
|
+
--color-theme-text-muted: #b6bac3;
|
|
41
|
+
--color-theme-text-dim: #9298a3;
|
|
42
42
|
|
|
43
43
|
/* ─── Semantic: State ─────────────────────────────────────────────── */
|
|
44
44
|
--color-theme-success: #22c55e;
|
package/static/cms/studio.css
CHANGED
|
@@ -29,6 +29,18 @@ html, body {
|
|
|
29
29
|
box-sizing: border-box;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
.studio-sr-only {
|
|
33
|
+
position: absolute;
|
|
34
|
+
width: 1px;
|
|
35
|
+
height: 1px;
|
|
36
|
+
padding: 0;
|
|
37
|
+
margin: -1px;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
clip: rect(0, 0, 0, 0);
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
border: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
32
44
|
a {
|
|
33
45
|
color: inherit;
|
|
34
46
|
text-decoration: none;
|
|
@@ -47,9 +59,11 @@ a {
|
|
|
47
59
|
/* ─── Layout: Shell + Header ────────────────────────────────────────── */
|
|
48
60
|
|
|
49
61
|
.studio-shell {
|
|
62
|
+
height: 100dvh;
|
|
50
63
|
min-height: 100vh;
|
|
51
64
|
display: flex;
|
|
52
65
|
flex-direction: column;
|
|
66
|
+
overflow: hidden;
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
.studio-header {
|
|
@@ -87,6 +101,15 @@ a {
|
|
|
87
101
|
flex-shrink: 0;
|
|
88
102
|
}
|
|
89
103
|
|
|
104
|
+
.studio-editor-identity {
|
|
105
|
+
max-width: 14rem;
|
|
106
|
+
overflow: hidden;
|
|
107
|
+
text-overflow: ellipsis;
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
color: var(--studio-text-muted);
|
|
110
|
+
font-size: 0.72rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
90
113
|
.studio-brand {
|
|
91
114
|
display: flex;
|
|
92
115
|
align-items: center;
|
|
@@ -113,6 +136,7 @@ a {
|
|
|
113
136
|
|
|
114
137
|
.studio-main {
|
|
115
138
|
flex: 1;
|
|
139
|
+
min-height: 0;
|
|
116
140
|
padding: var(--space-theme-xl) var(--space-theme-lg);
|
|
117
141
|
overflow-y: auto;
|
|
118
142
|
}
|