pandorga 1.3.10 → 1.4.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +100 -0
- data/_includes/content-runtime/43-blocks.html +52 -16
- data/_layouts/home.html +5 -1
- data/assets/css/ledger/home.css +54 -1
- data/functions/api/studio/[[path]].js +27 -0
- data/functions/api/studio/_lib/github.js +23 -0
- data/lib/pandorga/commands/new.rb +1 -1
- data/lib/pandorga/version.rb +1 -1
- data/scripts/test/render-parity/blocks/project-inventory-row.json +10 -4
- data/scripts/test/render-parity/run-absent-field-checks.mjs +2 -1
- data/scripts/test/test-studio-slug-config.rb +21 -14
- data/studio/assets/index-BQdNT4zp.css +1 -0
- data/studio/assets/index-pL2vB_T0.js +295 -0
- data/studio/index.html +2 -2
- data/studio/schema.yml +7 -7
- data/studio-app/src/api/client.js +5 -0
- data/studio-app/src/lib/schema.js +1 -1
- data/studio-app/src/main.js +406 -177
- data/studio-app/src/media/browser.js +108 -29
- data/studio-app/src/styles/studio.css +478 -251
- data/studio-app/vite.config.js +70 -3
- data/templates/articles/studio.yml +1 -1
- data/templates/bibliography/studio.yml +1 -1
- data/templates/blog/studio.yml +1 -1
- data/templates/cv/studio.yml +2 -2
- data/templates/media/studio.yml +1 -1
- data/templates/portfolio/studio.yml +1 -1
- metadata +3 -3
- data/studio/assets/index-B2os0c1O.css +0 -1
- data/studio/assets/index-dPB8Vpbd.js +0 -285
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 86199f8d6a5f2f50dc1bac4f3f5562ab445cb4aebd90a0f829780854a30d752c
|
|
4
|
+
data.tar.gz: d0f40ad5df354f067345d75fc99d28b1f7d6ab03ba7153da3e1d4ab01a18f36f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e5be625c48f0203ed4172e59f88013347ccf002829154488c6da9c3b454e0f32e6e7021132f64a6ddbe290dedcb7d9e5f4a3e3bb3e1b0eff0dab8c0bb3f2b901
|
|
7
|
+
data.tar.gz: 6e46c2b43d24e8bf1eb30bf9ac850dc4014292f9605f5accfd0d968afc9ff200002168d373dff2a03b37b1c99fe15c643b2d229c36af4beef72c5fadcd6464b0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,105 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.1] — 2026-10-07
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Studio top-bar brand: icon-only on mobile; no gray current-page plate on desktop
|
|
8
|
+
|
|
9
|
+
## [1.4.0] — 2026-10-07
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Studio collection rows: bordered Edit/Delete icon ops with delete confirm
|
|
14
|
+
- Studio media library: bordered Copy/Delete icon ops inside row cards; delete
|
|
15
|
+
commits through the file DELETE API
|
|
16
|
+
- Home project inventory: vertical code / article / site resource badges when
|
|
17
|
+
those fields are present; rack column widened slightly
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Studio chrome: redesigned top bar, theme menu, equal-width action tools,
|
|
22
|
+
title-face wordmark sized to the mark, Media library shell aligned with
|
|
23
|
+
collection lists
|
|
24
|
+
- Studio writing lists (Articles, Rascunhos): remove category filter chips and
|
|
25
|
+
per-row taxonomy column
|
|
26
|
+
- Studio Media library: drop the disclaimer under the title
|
|
27
|
+
- Home project bench: drop ongoing/completed status pills from the specimen strip
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Studio toolbar Theme/Revert/Save/Export share one locked height; disabled
|
|
32
|
+
tools mute color instead of opacity so Revert does not look shorter
|
|
33
|
+
- Studio sidebar keeps scroll position when expanding nav groups
|
|
34
|
+
- Studio brand home no longer swallows the top-bar action cluster
|
|
35
|
+
|
|
36
|
+
## [1.3.31] — 2026-10-07
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Studio toolbar disabled tools no longer use opacity (which made Revert look
|
|
41
|
+
shorter than Theme/Save/Export at the same box height)
|
|
42
|
+
|
|
43
|
+
## [1.3.30] — 2026-10-07
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- Studio top-bar Theme/Revert/Save/Export share one locked height box
|
|
48
|
+
(min/max/height), including the Theme menu wrapper button
|
|
49
|
+
|
|
50
|
+
## [1.3.29] — 2026-10-07
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- Studio top-bar wordmark uses the title face, sized so the first S matches the mark height
|
|
55
|
+
|
|
56
|
+
## [1.3.28] — 2026-10-07
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
- Home project inventory rows widen slightly and show a vertical column of
|
|
61
|
+
square code / article / site badges when those fields are present
|
|
62
|
+
|
|
63
|
+
## [1.3.27] — 2026-10-07
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- Remove category tag pills and taxonomy column from Articles and Rascunhos lists
|
|
68
|
+
|
|
69
|
+
## [1.3.26] — 2026-10-06
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
|
|
73
|
+
- Media library rows are single bordered cards with Copy/Delete inside, matching collection list ops
|
|
74
|
+
|
|
75
|
+
## [1.3.25] — 2026-10-06
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- Drop the Media library disclaimer under the title
|
|
80
|
+
|
|
81
|
+
## [1.3.24] — 2026-10-06
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
|
|
85
|
+
- Studio top-bar tools share one height again: a later `height: 100%` rule on
|
|
86
|
+
direct `.btn-tool` children was overriding the fixed size and growing
|
|
87
|
+
Revert/Save/Export to the brand line while Theme stayed shorter
|
|
88
|
+
|
|
89
|
+
## [1.3.23] — 2026-10-06
|
|
90
|
+
|
|
91
|
+
### Changed
|
|
92
|
+
|
|
93
|
+
- Media library rows use bordered Copy and Delete icon buttons; delete confirms
|
|
94
|
+
then commits removal via the existing Studio file DELETE API
|
|
95
|
+
|
|
96
|
+
## [1.3.11] — 2026-10-06
|
|
97
|
+
|
|
98
|
+
### Fixed
|
|
99
|
+
|
|
100
|
+
- Studio SPA rebuild embeds the real Clerk Frontend API host again (was baking
|
|
101
|
+
`clerk.example.com` into `studio/`); Vite refuses placeholder publishable keys
|
|
102
|
+
|
|
3
103
|
## [1.3.10] — 2026-10-06
|
|
4
104
|
|
|
5
105
|
### Fixed
|
|
@@ -375,9 +375,8 @@
|
|
|
375
375
|
: '',
|
|
376
376
|
fm.label ? escapeHtml(fm.label) : ''
|
|
377
377
|
]);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
html += '<div class="home-project-inventory-code">' + code + status + '</div>';
|
|
378
|
+
if (code) {
|
|
379
|
+
html += '<div class="home-project-inventory-code">' + code + '</div>';
|
|
381
380
|
}
|
|
382
381
|
|
|
383
382
|
if (selectable) {
|
|
@@ -399,13 +398,14 @@
|
|
|
399
398
|
html += '<span class="home-project-inventory-glyph home-project-inventory-glyph--initial" aria-hidden="true">' +
|
|
400
399
|
escapeHtml(initial) + '</span>';
|
|
401
400
|
}
|
|
401
|
+
html += renderProjectResourceBadges(fm);
|
|
402
402
|
|
|
403
403
|
row.innerHTML = html;
|
|
404
404
|
return row;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
/* System card — the project shape. Carries
|
|
408
|
-
*
|
|
407
|
+
/* System card — the project shape. Carries label and outbound links;
|
|
408
|
+
* listing pages pass their own metaParts when they want period/status. */
|
|
409
409
|
function renderSystemCard(item, options) {
|
|
410
410
|
options = options || {};
|
|
411
411
|
var f = blockFields(item);
|
|
@@ -429,11 +429,10 @@
|
|
|
429
429
|
'<span class="material-symbols-outlined projects-plate-glyph">' +
|
|
430
430
|
escapeHtml(fm.icon) + '</span></div>';
|
|
431
431
|
}
|
|
432
|
-
// Callers may supply their own strip parts;
|
|
433
|
-
//
|
|
432
|
+
// Callers may supply their own strip parts; home defaults to label only
|
|
433
|
+
// (ongoing/completed is noise on the bench).
|
|
434
434
|
var parts = options.metaParts || [
|
|
435
|
-
fm.label ? escapeHtml(fm.label) : ''
|
|
436
|
-
fm.status ? '<span class="ledger-status">' + escapeHtml(fm.status) + '</span>' : ''
|
|
435
|
+
fm.label ? escapeHtml(fm.label) : ''
|
|
437
436
|
];
|
|
438
437
|
var head = renderMetaStrip(parts);
|
|
439
438
|
if (head) html += head;
|
|
@@ -473,11 +472,49 @@
|
|
|
473
472
|
return links.join('');
|
|
474
473
|
}
|
|
475
474
|
|
|
475
|
+
/* Square resource marks for the home inventory rack — same fields as
|
|
476
|
+
* renderProjectLinks (github / article_url / external_url), icon-only. */
|
|
477
|
+
function renderProjectResourceBadges(fm) {
|
|
478
|
+
var badges = [];
|
|
479
|
+
if (fm.github) {
|
|
480
|
+
badges.push({
|
|
481
|
+
href: fm.github,
|
|
482
|
+
icon: 'code',
|
|
483
|
+
label: 'Code repository'
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
if (fm.article_url) {
|
|
487
|
+
badges.push({
|
|
488
|
+
href: fm.article_url,
|
|
489
|
+
icon: 'article',
|
|
490
|
+
label: 'Article'
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
if (fm.external_url) {
|
|
494
|
+
badges.push({
|
|
495
|
+
href: fm.external_url,
|
|
496
|
+
icon: 'public',
|
|
497
|
+
label: 'Site'
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
if (!badges.length) return '';
|
|
501
|
+
return '<div class="home-project-inventory-resources" aria-label="Attached resources">' +
|
|
502
|
+
badges.map(function (badge) {
|
|
503
|
+
return '<a class="home-project-inventory-resource" href="' +
|
|
504
|
+
escapeAttr(badge.href) + '" target="_blank" rel="noopener noreferrer" ' +
|
|
505
|
+
'title="' + escapeAttr(badge.label) + '" aria-label="' +
|
|
506
|
+
escapeAttr(badge.label) + '">' +
|
|
507
|
+
'<span class="material-symbols-outlined" aria-hidden="true">' +
|
|
508
|
+
escapeHtml(badge.icon) + '</span></a>';
|
|
509
|
+
}).join('') +
|
|
510
|
+
'</div>';
|
|
511
|
+
}
|
|
512
|
+
|
|
476
513
|
/* Home specimen — the featured project on the portfolio bench. A system
|
|
477
|
-
* card whose strip carries folio, label
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
514
|
+
* card whose strip carries folio, label and start year, with the title
|
|
515
|
+
* below a 16:9 plate: the thumbnail (icon badge on it) or else the icon
|
|
516
|
+
* plate. `openLabel` adds a visual "open" cue; it is not a second link,
|
|
517
|
+
* the stretched title is. */
|
|
481
518
|
function renderProjectSpecimen(item, options) {
|
|
482
519
|
options = options || {};
|
|
483
520
|
var f = blockFields(item);
|
|
@@ -494,11 +531,10 @@
|
|
|
494
531
|
fm.label ? escapeHtml(fm.label) : '',
|
|
495
532
|
year ? '<span>' + escapeHtml(year[0]) + '</span>' : ''
|
|
496
533
|
]);
|
|
497
|
-
var status = fm.status ? '<span class="ledger-status">' + escapeHtml(fm.status) + '</span>' : '';
|
|
498
534
|
|
|
499
535
|
var html = '';
|
|
500
|
-
if (meta
|
|
501
|
-
html += '<div class="home-specimen-strip">' + meta +
|
|
536
|
+
if (meta) {
|
|
537
|
+
html += '<div class="home-specimen-strip">' + meta + '</div>';
|
|
502
538
|
}
|
|
503
539
|
|
|
504
540
|
// The name's initial stands in for a missing icon, so every project
|
data/_layouts/home.html
CHANGED
|
@@ -330,8 +330,12 @@ layout: shell
|
|
|
330
330
|
selected: entry.slug === selectedSlug,
|
|
331
331
|
index: i + 1
|
|
332
332
|
});
|
|
333
|
-
row.addEventListener('click', function () {
|
|
333
|
+
row.addEventListener('click', function (event) {
|
|
334
|
+
if (event.target.closest('.home-project-inventory-resources')) return;
|
|
335
|
+
select(entry.slug);
|
|
336
|
+
});
|
|
334
337
|
row.addEventListener('keydown', function (event) {
|
|
338
|
+
if (event.target.closest('.home-project-inventory-resources')) return;
|
|
335
339
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
336
340
|
event.preventDefault();
|
|
337
341
|
select(entry.slug);
|
data/assets/css/ledger/home.css
CHANGED
|
@@ -1225,6 +1225,10 @@ html[data-theme="light"] .home-hero-plate {
|
|
|
1225
1225
|
display: none;
|
|
1226
1226
|
}
|
|
1227
1227
|
|
|
1228
|
+
.home-project-inventory-resources {
|
|
1229
|
+
display: none;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1228
1232
|
.home-project-inventory-glyph {
|
|
1229
1233
|
display: inline-flex;
|
|
1230
1234
|
align-items: center;
|
|
@@ -1271,7 +1275,7 @@ html[data-theme="light"] .home-hero-plate {
|
|
|
1271
1275
|
.home-projects-bench {
|
|
1272
1276
|
--home-specimen-height: 36rem;
|
|
1273
1277
|
display: grid;
|
|
1274
|
-
grid-template-columns: minmax(0, 50%) minmax(
|
|
1278
|
+
grid-template-columns: minmax(0, 50%) minmax(20rem, 40%);
|
|
1275
1279
|
column-gap: var(--space-xl);
|
|
1276
1280
|
align-items: stretch;
|
|
1277
1281
|
}
|
|
@@ -1370,6 +1374,55 @@ html[data-theme="light"] .home-hero-plate {
|
|
|
1370
1374
|
min-width: 0;
|
|
1371
1375
|
}
|
|
1372
1376
|
|
|
1377
|
+
.home-project-inventory-resources {
|
|
1378
|
+
display: flex;
|
|
1379
|
+
flex-direction: column;
|
|
1380
|
+
justify-content: space-evenly;
|
|
1381
|
+
align-items: center;
|
|
1382
|
+
align-self: stretch;
|
|
1383
|
+
flex: 0 0 auto;
|
|
1384
|
+
gap: 0.2rem;
|
|
1385
|
+
min-height: 0;
|
|
1386
|
+
position: relative;
|
|
1387
|
+
z-index: 1;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
.home-project-inventory-resource {
|
|
1391
|
+
display: inline-flex;
|
|
1392
|
+
align-items: center;
|
|
1393
|
+
justify-content: center;
|
|
1394
|
+
width: 1.55rem;
|
|
1395
|
+
height: 1.55rem;
|
|
1396
|
+
flex: 0 0 auto;
|
|
1397
|
+
background: var(--color-surface-card);
|
|
1398
|
+
color: var(--color-primary);
|
|
1399
|
+
text-decoration: none;
|
|
1400
|
+
border: 1px solid color-mix(in srgb, var(--border-gentle-divider) 80%, transparent);
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
.home-band--contrast .home-project-inventory-resource {
|
|
1404
|
+
background: var(--color-surface-card-contrast);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
.home-project-inventory-row.is-selected .home-project-inventory-resource,
|
|
1408
|
+
.home-band--contrast .home-project-inventory-row.is-selected .home-project-inventory-resource {
|
|
1409
|
+
background: var(--color-surface-card);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
.home-project-inventory-resource .material-symbols-outlined {
|
|
1413
|
+
font-size: 1rem;
|
|
1414
|
+
line-height: 1;
|
|
1415
|
+
font-variation-settings: "FILL" 0, "wght" 500, "GRAD" 0, "opsz" 20;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
.home-project-inventory-resource:hover,
|
|
1419
|
+
.home-project-inventory-resource:focus-visible {
|
|
1420
|
+
color: var(--color-on-primary, var(--color-surface));
|
|
1421
|
+
background: var(--color-primary);
|
|
1422
|
+
border-color: var(--color-primary);
|
|
1423
|
+
outline: none;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1373
1426
|
.home-project-inventory-title {
|
|
1374
1427
|
margin: 0;
|
|
1375
1428
|
font-size: var(--type-label-lg);
|
|
@@ -7,6 +7,7 @@ import { verifyClerkRequest } from "./_lib/auth.js";
|
|
|
7
7
|
import {
|
|
8
8
|
getFile,
|
|
9
9
|
putFile,
|
|
10
|
+
deleteFile,
|
|
10
11
|
putBinaryFile,
|
|
11
12
|
getFileMeta,
|
|
12
13
|
listDir,
|
|
@@ -297,6 +298,32 @@ export async function onRequest(context) {
|
|
|
297
298
|
);
|
|
298
299
|
}
|
|
299
300
|
|
|
301
|
+
if (head === "file" && request.method === "DELETE") {
|
|
302
|
+
const body = await request.json();
|
|
303
|
+
const path = normalizeRepoPath(body.path || "");
|
|
304
|
+
if (!path) return json({ error: "invalid_path" }, 400, request);
|
|
305
|
+
let sha = body.sha || null;
|
|
306
|
+
if (!sha) {
|
|
307
|
+
const existing = await getFileMeta(env, path);
|
|
308
|
+
sha = existing?.sha || null;
|
|
309
|
+
}
|
|
310
|
+
if (!sha) return json({ error: "not_found" }, 404, request);
|
|
311
|
+
const result = await deleteFile(env, {
|
|
312
|
+
path,
|
|
313
|
+
message: body.message,
|
|
314
|
+
sha,
|
|
315
|
+
});
|
|
316
|
+
return json(
|
|
317
|
+
{
|
|
318
|
+
ok: true,
|
|
319
|
+
path,
|
|
320
|
+
commit: result.commit?.sha || null,
|
|
321
|
+
},
|
|
322
|
+
200,
|
|
323
|
+
request
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
300
327
|
if (head === "media" && request.method === "GET") {
|
|
301
328
|
const url = new URL(request.url);
|
|
302
329
|
const rawPath = url.searchParams.get("path") || MEDIA_ROOT;
|
|
@@ -130,6 +130,29 @@ export async function putFile(env, { path, content, message, sha }) {
|
|
|
130
130
|
return res.json();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
/** Delete a file. GitHub Contents DELETE requires the current blob sha. */
|
|
134
|
+
export async function deleteFile(env, { path, message, sha }) {
|
|
135
|
+
if (!sha) {
|
|
136
|
+
const err = new Error("sha required to delete");
|
|
137
|
+
err.status = 400;
|
|
138
|
+
err.code = "sha_required";
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
const res = await gh(env, `/contents/${path}`, {
|
|
142
|
+
method: "DELETE",
|
|
143
|
+
headers: { "Content-Type": "application/json" },
|
|
144
|
+
body: JSON.stringify({
|
|
145
|
+
message: message || `studio: delete ${path}`,
|
|
146
|
+
sha,
|
|
147
|
+
branch: "main",
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
if (!res.ok) {
|
|
151
|
+
throw githubFail("delete", res, await res.text());
|
|
152
|
+
}
|
|
153
|
+
return res.json();
|
|
154
|
+
}
|
|
155
|
+
|
|
133
156
|
/**
|
|
134
157
|
* Put a binary file. `contentBase64` is already base64 of raw bytes
|
|
135
158
|
* (GitHub Contents API create/update limit: 100 MB; Studio caps lower).
|
|
@@ -24,7 +24,7 @@ module Pandorga
|
|
|
24
24
|
|
|
25
25
|
gem "pandorga", "~> 1.3"
|
|
26
26
|
# Local checkout: gem "pandorga", path: "../pandorga"
|
|
27
|
-
# GitHub tag: gem "pandorga", github: "alexandrelheinen/pandorga", tag: "v1.3.
|
|
27
|
+
# GitHub tag: gem "pandorga", github: "alexandrelheinen/pandorga", tag: "v1.3.11"
|
|
28
28
|
gem "csv"
|
|
29
29
|
gem "base64"
|
|
30
30
|
RUBY
|
data/lib/pandorga/version.rb
CHANGED
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
"icon": "route",
|
|
11
11
|
"label": "Simulation",
|
|
12
12
|
"status": "Ongoing",
|
|
13
|
-
"tagline": "A city-scale race replayed from telemetry."
|
|
13
|
+
"tagline": "A city-scale race replayed from telemetry.",
|
|
14
|
+
"github": "https://github.com/example/arco",
|
|
15
|
+
"article_url": "/articles/arco/",
|
|
16
|
+
"external_url": "https://example.com/arco"
|
|
14
17
|
}
|
|
15
18
|
},
|
|
16
19
|
{
|
|
@@ -25,10 +28,11 @@
|
|
|
25
28
|
"div.ledger-poster",
|
|
26
29
|
"div.home-project-inventory-code",
|
|
27
30
|
"span.home-project-inventory-index",
|
|
28
|
-
"span.ledger-status",
|
|
29
31
|
"h3.home-project-inventory-title",
|
|
30
32
|
"p.home-project-inventory-copy",
|
|
31
|
-
"span.home-project-inventory-glyph"
|
|
33
|
+
"span.home-project-inventory-glyph",
|
|
34
|
+
"div.home-project-inventory-resources",
|
|
35
|
+
"a.home-project-inventory-resource"
|
|
32
36
|
],
|
|
33
37
|
"forbidden": [
|
|
34
38
|
"ledger-card-stretch"
|
|
@@ -36,10 +40,12 @@
|
|
|
36
40
|
"contains": [
|
|
37
41
|
">02<",
|
|
38
42
|
">Simulation<",
|
|
39
|
-
">Ongoing<",
|
|
40
43
|
">ARCO<",
|
|
41
44
|
">A city-scale race replayed from telemetry.<",
|
|
42
45
|
">route<",
|
|
46
|
+
">code<",
|
|
47
|
+
">article<",
|
|
48
|
+
">public<",
|
|
43
49
|
"aria-pressed=\"false\"",
|
|
44
50
|
"data-slug=\"arco\""
|
|
45
51
|
]
|
|
@@ -84,10 +84,10 @@ check!(posts["format"].to_s == "yaml-frontmatter",
|
|
|
84
84
|
"posts must use yaml-frontmatter")
|
|
85
85
|
check!(articles["format"].to_s == "yaml-frontmatter",
|
|
86
86
|
"articles must use yaml-frontmatter")
|
|
87
|
-
check!(posts.dig("operations", "delete") ==
|
|
88
|
-
"posts operations.delete must be
|
|
89
|
-
check!(articles.dig("operations", "delete") ==
|
|
90
|
-
"articles operations.delete must be
|
|
87
|
+
check!(posts.dig("operations", "delete") == true,
|
|
88
|
+
"posts operations.delete must be true")
|
|
89
|
+
check!(articles.dig("operations", "delete") == true,
|
|
90
|
+
"articles operations.delete must be true")
|
|
91
91
|
|
|
92
92
|
posts_fields = field_names(posts)
|
|
93
93
|
articles_fields = field_names(articles)
|
|
@@ -128,16 +128,23 @@ check!(products["filename"].to_s.include?("{key}"),
|
|
|
128
128
|
check!(projects["filename"].to_s.include?("{key}"),
|
|
129
129
|
"projects filename must use key (got #{projects['filename'].inspect})")
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
131
|
+
pipeline_path = REPO_ROOT.join(".github/workflows/content-pipeline.yml")
|
|
132
|
+
if pipeline_path.file?
|
|
133
|
+
pipeline = pipeline_path.read
|
|
134
|
+
if pipeline.match?(/^\s*workflow_call:\s*$/m) && !pipeline.match?(/^\s*push:\s*$/m)
|
|
135
|
+
# Reusable workflow — push triggers live on the consuming site.
|
|
136
|
+
else
|
|
137
|
+
on_push = pipeline[/\non:\n push:\n(?: .*\n)*/]
|
|
138
|
+
check!(!on_push.nil? && !on_push.include?("paths:"),
|
|
139
|
+
"content-pipeline.yml on.push must not use paths: (CMS commits must always trigger)")
|
|
140
|
+
check!(!pipeline.include?("MODE=skip"),
|
|
141
|
+
"content-pipeline.yml must not skip empty CMS commits: those still need an R2 publish")
|
|
142
|
+
check!(pipeline.include?("if: github.ref == 'refs/heads/main'"),
|
|
143
|
+
"content-pipeline.yml must publish on main for push and manual run")
|
|
144
|
+
end
|
|
145
|
+
check!(!pipeline.match?(/sveltia/i),
|
|
146
|
+
"content-pipeline.yml must not reference Sveltia")
|
|
147
|
+
end
|
|
141
148
|
|
|
142
149
|
index = REPO_ROOT.join("studio/index.html").read
|
|
143
150
|
check!(!index.include?("app.pagescms.org"),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root,[data-theme=light]{color-scheme:light;--primary: #1c5a7a;--secondary: #287445;--tertiary: #746f30;--background: #ffffff;--panel: #f4f4f4;--surface-high: #ebebeb;--surface-card: #ffffff;--on-surface: #000000;--on-surface-variant: #5e5d59;--outline: #5c5c5c;--outline-variant: #b8b8b8;--error: #ba1a1a;--scrollbar-track: var(--panel);--scrollbar-thumb: color-mix(in srgb, var(--outline-variant) 75%, var(--panel));--scrollbar-thumb-hover: color-mix(in srgb, var(--outline) 70%, var(--panel));--cubist-shard-opacity: 18%;--cubist-shard-opacity-strong: 26%;--shard-alpha: polygon(26% 0, 100% 0, 78% 100%, 0 68%);--shard-beta: polygon(0 0, 74% 18%, 100% 100%, 18% 84%);--font-body: "Newsreader", Georgia, serif;--font-display: "Newsreader", Georgia, serif;--font-title: "Cinzel Decorative", "Times New Roman", serif;--font-label: "Marcellus SC", "Newsreader", Georgia, serif;--font-mono: "Courier Prime", ui-monospace, monospace;--studio-font-size: 18px;--studio-type-display: 1.55rem;--studio-type-title: 1.15rem;--studio-type-body: 1rem;--studio-type-ui: .9rem;--studio-type-meta: .8rem;--studio-type-micro: .72rem;--studio-brand-title: calc(var(--studio-type-title) + 3pt);--studio-nav-label: calc(var(--studio-type-body) - .5pt);--studio-nav-item: var(--studio-type-body);--studio-ledger-title: var(--studio-type-body);--studio-ledger-meta: var(--studio-type-meta);--studio-list-control-height: 2.25rem;--studio-ledger-thumb-w: 4rem;--studio-ledger-thumb-h: 3rem;--studio-space-2xs: .25rem;--studio-space-xs: .4rem;--studio-space-sm: .65rem;--studio-space-md: .95rem;--studio-space-lg: 1.35rem;--studio-pane-pad: 1.15rem 1.35rem;--studio-editor-min-height: max(24rem, calc(100dvh - 7.5rem) )}[data-theme=dark]{color-scheme:dark;--primary: #a4c8da;--secondary: #95c8a6;--tertiary: #ddd8a8;--background: #0c0c0e;--panel: #141418;--surface-high: #26262b;--surface-card: #0c0c0e;--on-surface: #ffffff;--on-surface-variant: #b8b7ae;--outline: #93938d;--outline-variant: #45454c;--error: #ffb4ab;--scrollbar-track: var(--panel);--scrollbar-thumb: color-mix(in srgb, var(--outline-variant) 85%, var(--surface-high));--scrollbar-thumb-hover: color-mix(in srgb, var(--outline) 55%, var(--surface-high));--cubist-shard-opacity: 10%;--cubist-shard-opacity-strong: 14%}*,*:before,*:after{box-sizing:border-box}html,body{margin:0;min-height:100%;height:100%;background-color:var(--background);background-image:linear-gradient(color-mix(in srgb,var(--outline) 4%,transparent) 1px,transparent 1px),linear-gradient(90deg,color-mix(in srgb,var(--outline) 4%,transparent) 1px,transparent 1px);background-size:1.25rem 1.25rem;background-attachment:fixed;color:var(--on-surface);font-family:var(--font-body);font-size:var(--studio-font-size);line-height:1.5;scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track)}*::-webkit-scrollbar{width:10px;height:10px}*::-webkit-scrollbar-track{background:var(--scrollbar-track)}*::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);border:2px solid var(--scrollbar-track);background-clip:padding-box}*::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-thumb-hover);border:2px solid var(--scrollbar-track);background-clip:padding-box}*::-webkit-scrollbar-corner{background:var(--scrollbar-track)}button,input,select,textarea{font:inherit;color:inherit}a{color:var(--primary)}#app{min-height:100vh;height:100%}.studio-shell{display:grid;grid-template-columns:16.5rem minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);min-height:100vh;height:100%;background:transparent}.studio-shell>.studio-toolbar{grid-column:1 / -1}.studio-nav{background:var(--panel);border-right:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);padding:var(--studio-space-md) var(--studio-space-sm);display:flex;flex-direction:column;gap:var(--studio-space-sm);overflow:auto}.studio-nav-bar{display:flex;flex-direction:column;gap:.35rem}.studio-nav-menu-toggle{display:none;width:100%;align-items:center;justify-content:space-between;gap:.5rem;margin:0;padding:.55rem .65rem;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);border-radius:0;background:var(--background);cursor:pointer;color:var(--on-surface);font:inherit;text-align:left}.studio-nav-menu-toggle:hover{background:var(--surface-high)}.studio-nav-menu-toggle .studio-nav-menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-label);font-size:var(--studio-nav-label);letter-spacing:.04em;font-weight:400}.studio-nav-menu-toggle .material-symbols-outlined{flex-shrink:0;font-size:1.25rem;line-height:1}.studio-nav-panel{display:flex;flex-direction:column;gap:var(--studio-space-xs);min-height:0}@media(min-width:961px){.studio-shell{grid-template-columns:16.5rem minmax(0,1fr)}.studio-nav-menu-toggle{display:none}.studio-nav-panel{display:flex}}.studio-brand{display:grid;grid-template-columns:1.35rem minmax(0,1fr);align-items:center;column-gap:var(--studio-space-sm);padding:var(--studio-space-sm) var(--studio-space-xs) var(--studio-space-md);margin-bottom:var(--studio-space-xs);border-bottom:1px solid var(--outline-variant)}.studio-brand-toolbar{flex:0 0 auto;width:auto;height:var(--studio-toolbar-control-h, 2.35rem);min-height:0;padding:0 .55rem;margin:0;border-bottom:0;column-gap:.55rem;--studio-brand-mark: 1.35rem;grid-template-columns:var(--studio-brand-mark) auto;box-sizing:border-box;align-items:center}.studio-brand-toolbar .studio-mark{width:var(--studio-brand-mark);height:var(--studio-brand-mark)}.studio-brand-toolbar .studio-brand-name{font-family:var(--font-title);font-size:calc(var(--studio-brand-mark) / .83);font-weight:400;font-synthesis:none;line-height:1;letter-spacing:.02em;text-transform:none;color:var(--on-surface)}.studio-brand-copy{display:flex;flex-direction:column;justify-content:center;text-align:left;min-width:0}.studio-brand-name{font-family:var(--font-label);font-size:var(--studio-type-ui);font-weight:400;font-synthesis:none;line-height:1.15;letter-spacing:.04em}.studio-brand strong{font-family:var(--font-title);font-size:var(--studio-brand-title);font-weight:400;font-synthesis:none;line-height:1.15;letter-spacing:.02em}button.studio-brand-home{width:100%;margin:0;border:0;border-radius:0;background:transparent;cursor:pointer;text-align:left;color:inherit;font:inherit}button.studio-brand-home.studio-brand-toolbar{width:auto;flex:0 0 auto}button.studio-brand-home:hover,button.studio-brand-home[aria-current=page]{background:var(--surface-high)}button.studio-brand-home.studio-brand-toolbar:hover,button.studio-brand-home.studio-brand-toolbar[aria-current=page]{background:transparent}.studio-brand .studio-mark{display:block;width:1.35rem;height:1.35rem;justify-self:center;transform:translateY(.5px)}.studio-mark-svg{display:block;width:100%;height:100%}:root .studio-mark-primary,[data-theme=light] .studio-mark-primary{fill:#a4c8da}:root .studio-mark-secondary,[data-theme=light] .studio-mark-secondary{fill:#95c8a6}:root .studio-mark-tertiary,[data-theme=light] .studio-mark-tertiary{fill:#ddd8a8}[data-theme=dark] .studio-mark-primary{fill:#1c5a7a}[data-theme=dark] .studio-mark-secondary{fill:#287445}[data-theme=dark] .studio-mark-tertiary{fill:#746f30}.studio-mark-frame{fill:none;stroke:var(--on-surface-variant);stroke-width:1;stroke-linejoin:miter;vector-effect:non-scaling-stroke}.auth-gate .studio-mark{width:2rem;height:2rem}.studio-nav-group{margin-top:var(--studio-space-2xs)}.studio-nav-group-toggle{width:100%;display:flex;align-items:center;gap:var(--studio-space-xs);margin:0;padding:var(--studio-space-sm) var(--studio-space-xs);border:0;border-radius:0;background:transparent;cursor:pointer;color:var(--on-surface-variant);text-align:left;font-family:var(--font-label);font-size:var(--studio-nav-label);text-transform:none;letter-spacing:.04em;font-weight:400}.studio-nav-group-toggle:hover{background:var(--surface-high);color:var(--on-surface)}.studio-nav-group-toggle .material-symbols-outlined{font-size:1.25rem;line-height:1;flex-shrink:0;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.studio-nav-group-toggle .nav-group-label{flex:1;min-width:0;font-family:var(--font-label);font-size:inherit;letter-spacing:inherit;border-bottom:1px solid var(--outline-variant);padding-bottom:.2rem;text-align:left}.studio-nav-group-items{display:flex;flex-direction:column;gap:.15rem;padding:.2rem 0 var(--studio-space-sm)}.studio-nav-group-items[hidden]{display:none}.studio-nav button.nav-item{width:100%;display:flex;align-items:baseline;justify-content:space-between;gap:var(--studio-space-sm);text-align:left;background:transparent;border:0;border-radius:0;padding:.4rem .5rem .4rem 1.7rem;cursor:pointer;color:var(--on-surface);font-family:var(--font-body);font-size:var(--studio-nav-item);line-height:1.35;letter-spacing:.01em}.studio-nav button.nav-item:hover,.studio-nav button.nav-item[aria-current=page]{background:var(--surface-high)}.nav-item-label{min-width:0}.nav-item-count{flex:0 0 auto;font-family:var(--font-body);font-size:var(--studio-type-meta);color:var(--on-surface-variant)}.studio-main{display:grid;grid-template-rows:auto minmax(0,1fr);min-width:0;min-height:0;height:100%;overflow:hidden;background:transparent}.studio-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem .4rem;padding:var(--studio-space-xs) var(--studio-space-md);border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.04em;text-transform:uppercase;color:var(--on-surface-variant);background:var(--background)}.studio-crumb-sep{color:var(--outline-variant)}.studio-crumb.is-current{color:var(--on-surface);text-transform:none;letter-spacing:.02em}.studio-toolbar{--studio-toolbar-control-h: 2.35rem;display:flex;align-items:center;gap:var(--studio-space-sm);min-height:3.25rem;padding:.55rem 1rem;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 60%,transparent);background:var(--panel);box-shadow:inset 0 -1px color-mix(in srgb,var(--outline) 8%,transparent);min-width:0;font-family:var(--font-label);position:relative;z-index:30;flex-wrap:nowrap}.studio-toolbar-brand{display:flex;align-items:center;gap:var(--studio-space-sm);min-width:0;flex:0 1 auto}.studio-toolbar-status{display:none;max-width:18rem;padding:.2rem .55rem;border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:var(--background);color:var(--on-surface-variant);font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.03em;text-transform:uppercase;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-toolbar-status.error{color:var(--error);border-color:color-mix(in srgb,var(--error) 40%,var(--outline-variant));background:color-mix(in srgb,var(--error) 8%,var(--background))}@media(min-width:720px){.studio-toolbar-status{display:inline-block}}.studio-toolbar .spacer{flex:1 1 auto;min-width:.75rem}.studio-toolbar .btn{flex-shrink:0;position:relative;z-index:1}.studio-toolbar>.studio-theme-menu,.studio-toolbar>.btn-tool{flex:0 0 6rem;width:6rem;height:var(--studio-toolbar-control-h);min-height:var(--studio-toolbar-control-h);max-height:var(--studio-toolbar-control-h);box-sizing:border-box;align-self:center}.studio-toolbar>.studio-theme-menu{display:flex;align-items:stretch;position:relative}.studio-toolbar>.studio-theme-menu .btn-tool,.studio-toolbar>.btn-tool{box-sizing:border-box;width:100%;height:var(--studio-toolbar-control-h);min-height:var(--studio-toolbar-control-h);max-height:var(--studio-toolbar-control-h);margin:0;padding:0 .45rem;border-width:1px;border-style:solid;line-height:1;overflow:hidden;display:inline-flex;justify-content:center;align-items:center;gap:.35rem}.studio-toolbar .studio-nav-menu-toggle{display:none;flex:0 0 auto;width:auto;min-width:2.5rem;min-height:2.5rem;margin-left:.15rem;padding:.35rem .45rem;gap:.35rem;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background)}.studio-toolbar .studio-nav-menu-toggle .studio-mark{display:block;width:1.25rem;height:1.25rem;flex-shrink:0}.btn-tool{gap:.35rem;min-height:var(--studio-toolbar-control-h, 2.35rem);padding:0 .55rem;font-family:var(--font-label);border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);box-sizing:border-box;line-height:1}.btn-tool:hover:not(:disabled){background:var(--surface-high)}.btn-tool .btn-label{font-family:var(--font-label);font-size:var(--studio-type-ui);letter-spacing:.05em;line-height:1}.btn-tool .material-symbols-outlined{font-size:1.2rem;line-height:1;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.studio-toolbar>.btn-primary,.studio-toolbar .btn-primary{background:var(--primary);color:#fff;border-color:var(--primary)}[data-theme=dark] .studio-toolbar>.btn-primary,[data-theme=dark] .studio-toolbar .btn-primary{color:#0f1a22}.studio-toolbar>.btn-primary:hover:not(:disabled),.studio-toolbar .btn-primary:hover:not(:disabled){filter:brightness(1.06);background:var(--primary)}.btn-danger{color:var(--error);border-color:color-mix(in srgb,var(--error) 45%,var(--outline-variant))}.btn-danger:hover{background:color-mix(in srgb,var(--error) 12%,var(--background))}.btn-reexport{color:#5c4b00;border-color:color-mix(in srgb,#c9a227 55%,var(--outline-variant));background:color-mix(in srgb,#f5d76e 55%,var(--background))}.btn-reexport:hover{background:color-mix(in srgb,#f5d76e 75%,var(--background))}[data-theme=dark] .btn-reexport{color:#f5e6a3;border-color:color-mix(in srgb,#c9a227 50%,var(--outline-variant));background:color-mix(in srgb,#746f30 45%,var(--panel))}.studio-icon-bar .btn-icon{width:var(--studio-list-control-height);min-width:var(--studio-list-control-height);padding:.2rem;border-radius:0}.studio-icon-bar .btn-icon .material-symbols-outlined{font-size:1.35rem;line-height:1;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.studio-icon-spin{animation:studio-icon-spin .85s linear infinite}@keyframes studio-icon-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.studio-theme-menu{position:relative;flex-shrink:0}.studio-theme-menu-panel{position:absolute;right:0;top:calc(100% + .25rem);min-width:9.5rem;padding:.25rem 0;background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);box-shadow:0 .35rem 1rem color-mix(in srgb,var(--on-surface) 12%,transparent);z-index:20}.studio-theme-menu-panel[hidden]{display:none}.studio-theme-choice{width:100%;display:flex;align-items:center;gap:.55rem;margin:0;padding:.45rem .75rem;border:0;background:transparent;cursor:pointer;color:var(--on-surface-variant);font-family:var(--font-body);font-size:var(--studio-type-ui);text-align:left}.studio-theme-choice:hover,.studio-theme-choice.is-selected,.studio-theme-choice[aria-checked=true]{color:var(--primary);background:var(--surface-high)}.studio-theme-choice .material-symbols-outlined{font-size:1.2rem;line-height:1}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.btn{border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);padding:.25rem .6rem;cursor:pointer;min-height:var(--studio-list-control-height);box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;font-family:var(--font-mono);font-size:var(--studio-type-ui);letter-spacing:.01em}.btn-nav{gap:.15rem}.btn-nav-icon{font-size:1.25rem!important;line-height:1;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.btn:hover{background:var(--surface-high)}.btn-primary{background:var(--primary);color:#fff;border-color:var(--primary)}[data-theme=dark] .btn-primary{color:#0f1a22}.btn-primary:hover{filter:brightness(1.05)}.btn:disabled{opacity:.5;cursor:not-allowed}.studio-toolbar>.btn-tool:disabled,.studio-toolbar>.studio-theme-menu .btn-tool:disabled{opacity:1;color:color-mix(in srgb,var(--on-surface-variant) 70%,transparent);border-color:color-mix(in srgb,var(--outline-variant) 45%,transparent);background:var(--background);cursor:not-allowed}.studio-toolbar>.btn-tool.btn-primary:disabled{color:color-mix(in srgb,#fff 55%,var(--primary));background:color-mix(in srgb,var(--primary) 45%,var(--background));border-color:color-mix(in srgb,var(--primary) 45%,var(--outline-variant))}[data-theme=dark] .studio-toolbar>.btn-tool.btn-primary:disabled{color:color-mix(in srgb,#0f1a22 55%,var(--primary))}.studio-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-height:0;height:100%;overflow:hidden;background:transparent}.studio-body.list-only{grid-template-columns:minmax(0,1fr)}.pane{min-width:0;min-height:0;overflow:auto;padding:var(--studio-pane-pad);display:flex;flex-direction:column;gap:0;background:transparent}.pane-preview{border-left:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:var(--panel);min-height:0}.ledger-list{display:flex;flex-direction:column;gap:0;background:var(--panel);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);padding:var(--studio-space-xs)}.ledger-columns{display:none}.ledger-row{display:grid;grid-template-columns:var(--studio-ledger-thumb-w) minmax(0,1fr);gap:var(--studio-space-md);align-items:start;padding:var(--studio-space-md) var(--studio-space-md);margin:0 0 var(--studio-space-xs);border:1px solid color-mix(in srgb,var(--outline-variant) 60%,transparent);border-radius:0;cursor:pointer;background:var(--surface-card);text-align:left;width:100%;font:inherit;color:inherit}.ledger-row:last-child{margin-bottom:0}.ledger-row--writing{grid-template-columns:var(--studio-ledger-thumb-w) minmax(0,1fr) auto;align-items:center}.ledger-row:hover{background:var(--surface-high)}.ledger-copy{min-width:0;display:flex;flex-direction:column;gap:.4rem;padding-top:.1rem}.ledger-title-row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--studio-space-xs) var(--studio-space-sm);min-width:0}.ledger-title{font-family:var(--font-body);font-size:var(--studio-ledger-title);font-weight:400;line-height:1.3;min-width:0}.ledger-status{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:5.25rem;flex:0 0 5.25rem;padding:.1rem .3rem;border:1px solid transparent;font-family:var(--font-mono);font-size:var(--studio-type-micro);font-weight:600;letter-spacing:.04em;text-transform:uppercase;line-height:1.2;white-space:nowrap}.ledger-lang{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;padding:.1rem .3rem;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--surface-high);font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.04em;text-transform:uppercase;color:var(--on-surface-variant);line-height:1.2}.ledger-ops{display:inline-flex;align-items:center;justify-content:flex-end;gap:.35rem;white-space:nowrap;padding-top:.1rem}.ledger-op-btn{width:2.35rem;min-width:2.35rem;min-height:2.35rem;padding:.3rem;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);color:var(--on-surface)}.ledger-op-btn .material-symbols-outlined{font-size:1.15rem;line-height:1;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.ledger-edit-btn:hover{background:var(--surface-high);border-color:color-mix(in srgb,var(--primary) 40%,var(--outline-variant));color:var(--primary)}.ledger-delete-btn{color:var(--error);border-color:color-mix(in srgb,var(--error) 45%,var(--outline-variant));background:color-mix(in srgb,var(--error) 6%,var(--background))}.ledger-delete-btn:hover{background:color-mix(in srgb,var(--error) 14%,var(--background));border-color:color-mix(in srgb,var(--error) 60%,var(--outline-variant))}.ledger-row--plain{grid-template-columns:var(--studio-ledger-thumb-w) minmax(0,1fr) auto;align-items:center}@media(min-width:720px){.ledger-columns{display:grid;grid-template-columns:var(--studio-ledger-thumb-w) minmax(0,1fr) 6.25rem;gap:var(--studio-space-sm);align-items:end;padding:var(--studio-space-xs) var(--studio-space-md);margin:0 0 var(--studio-space-2xs);font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.05em;text-transform:uppercase;color:var(--on-surface-variant);background:var(--panel);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent)}.ledger-col-ops{text-align:right}.ledger-row--writing{grid-template-columns:var(--studio-ledger-thumb-w) minmax(0,1fr) auto;align-items:center}}.ledger-status--published{color:color-mix(in srgb,#1b6b3a 88%,var(--on-surface));background:color-mix(in srgb,#1b6b3a 14%,transparent);border-color:color-mix(in srgb,#1b6b3a 35%,transparent)}.ledger-status--draft{color:color-mix(in srgb,#a12828 90%,var(--on-surface));background:color-mix(in srgb,#a12828 14%,transparent);border-color:color-mix(in srgb,#a12828 35%,transparent)}.ledger-thumb{width:var(--studio-ledger-thumb-w);height:var(--studio-ledger-thumb-h);object-fit:cover;background:var(--surface-high);display:block;flex-shrink:0}.ledger-thumb.placeholder{display:flex;align-items:center;justify-content:center;color:var(--on-surface-variant);border:1px dashed color-mix(in srgb,var(--outline-variant) 70%,transparent)}.ledger-thumb.placeholder .material-symbols-outlined{font-size:1.5rem;line-height:1;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 24}.ledger-meta{margin-top:0;font-size:var(--studio-ledger-meta);color:var(--on-surface-variant);font-family:var(--font-mono);letter-spacing:.015em;line-height:1.4;word-break:break-word}.list-controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--studio-space-xs);margin:0 0 var(--studio-space-sm);padding:var(--studio-space-sm) var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent)}.list-search-input{flex:1 1 14rem;min-width:10rem;height:var(--studio-list-control-height);box-sizing:border-box;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);padding:0 var(--studio-space-sm);font-family:var(--font-mono);font-size:var(--studio-type-ui);line-height:1.2;letter-spacing:.01em}.list-sort-label{display:flex;align-items:center;gap:var(--studio-space-xs);flex:0 1 auto;margin:0;font-family:var(--font-mono);font-size:var(--studio-type-ui);color:var(--on-surface-variant);text-transform:none;letter-spacing:0}.list-sort-caption{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.06em;font-size:var(--studio-type-micro);font-weight:600;white-space:nowrap}.list-sort-select,.list-page-size-select{height:var(--studio-list-control-height);box-sizing:border-box;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);padding:0 var(--studio-space-sm);font-family:var(--font-mono);font-size:var(--studio-type-ui);min-width:10rem;max-width:100%}.list-page-size-select{min-width:4rem}.list-count{margin:0 0 var(--studio-space-xs);font-family:var(--font-mono);font-size:var(--studio-type-meta);color:var(--on-surface-variant);min-height:1em}.list-pager{display:flex;align-items:center;justify-content:center;gap:var(--studio-space-sm);margin:var(--studio-space-md) 0 var(--studio-space-xs);flex-wrap:wrap}.list-pager-btn:disabled{opacity:.45;cursor:not-allowed}.list-pager-status{font-family:var(--font-mono);font-size:var(--studio-type-meta);color:var(--on-surface-variant);min-width:7rem;text-align:center}.pane-editor>.btn{flex-shrink:0;align-self:flex-start;margin-bottom:var(--studio-space-sm)}.list-register{display:flex;flex-direction:column;gap:var(--studio-space-sm);margin-bottom:var(--studio-space-lg);padding:var(--studio-space-sm) var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent)}.list-register-kicker{display:flex;flex-wrap:wrap;align-items:center;gap:var(--studio-space-xs) var(--studio-space-sm);margin:0;font-family:var(--font-mono);font-size:var(--studio-type-meta);color:var(--on-surface-variant);text-transform:uppercase;letter-spacing:.05em}.list-register-mark{width:5px;height:5px;background:var(--primary);flex:0 0 auto}.list-register-sep{color:var(--outline-variant)}.list-pane-title{font-family:var(--font-display);font-size:var(--studio-type-display);font-weight:600;line-height:1.15;margin:0 0 var(--studio-space-sm)}.list-register .list-pane-title{margin:0}.list-register-title-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--studio-space-xs) var(--studio-space-md);margin-top:var(--studio-space-2xs)}.list-new-btn{margin-left:auto}.list-pane-count{font-family:var(--font-mono);font-size:var(--studio-type-meta);color:var(--on-surface-variant);letter-spacing:.02em}.front-matter{flex:0 0 auto;margin:0 0 var(--studio-space-sm);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:var(--background);max-width:52rem}.front-matter-summary{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--studio-space-xs) var(--studio-space-md);margin:0;padding:.45rem .65rem;cursor:pointer;list-style:none;font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.06em;text-transform:uppercase;color:var(--on-surface-variant);-webkit-user-select:none;user-select:none}.front-matter-summary::-webkit-details-marker{display:none}.front-matter-summary:before{content:"▸";margin-right:.45rem;color:var(--outline-variant)}.front-matter[open]>.front-matter-summary:before{content:"▾"}.front-matter[open]>.front-matter-summary{border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.front-matter-summary-label{color:var(--on-surface);font-weight:600}.front-matter-summary-hint{color:var(--outline-variant);letter-spacing:.04em}.front-matter>.form-grid{padding:.15rem .65rem .75rem;max-width:none}.editor-mast{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:.65rem 1.25rem;margin-bottom:.85rem;padding:var(--studio-space-sm) var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent)}.editor-mast-lead{display:flex;flex-wrap:wrap;align-items:center;gap:.55rem .75rem;min-width:0}.editor-mast-pills{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem}.editor-mast>.btn,.editor-mast-lead>.btn{flex:0 0 auto;align-self:center;margin-bottom:0}.editor-mast-lead>.btn-back{min-width:2.25rem;padding-left:.4rem;padding-right:.4rem;gap:0}.editor-mast-lead>.btn-back .btn-nav-icon{font-size:1.35rem!important}.editor-body-stats{display:flex;flex-wrap:wrap;align-items:center;flex:0 0 auto;gap:var(--studio-space-xs) var(--studio-space-sm);margin-top:var(--studio-space-sm);padding:var(--studio-space-sm) var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.03em;text-transform:uppercase;color:var(--on-surface-variant)}.editor-body-stats-sep{color:var(--outline-variant)}.preview-pane-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--studio-space-xs) var(--studio-space-sm);margin:0 0 var(--studio-space-sm);font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.05em;text-transform:uppercase;color:var(--on-surface-variant)}.preview-pane-label{color:var(--on-surface-variant)}.preview-pane-sep{color:var(--outline-variant)}.preview-pane-meta{text-transform:none;letter-spacing:.02em}.preview-folio{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;padding:.35rem;background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.preview-folio>.preview-frame{flex:1 1 auto;min-height:12rem;border-color:color-mix(in srgb,var(--outline-variant) 40%,transparent)}.loading-msg{margin:1rem 0;padding:var(--studio-space-sm) var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);color:var(--on-surface-variant);font-size:1rem}.list-empty{margin:1rem 0;padding:var(--studio-space-sm) var(--studio-space-md);background:var(--panel);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);color:var(--on-surface-variant)}.list-error{margin:.75rem 0;padding:.85rem .9rem;border:1px solid color-mix(in srgb,var(--error) 45%,transparent);background:color-mix(in srgb,var(--error) 8%,var(--background))}.list-error-title{margin:0 0 .35rem;font-weight:600;color:var(--error)}.list-error-message{margin:0;font-family:var(--font-mono);font-size:.9rem;color:var(--on-surface);word-break:break-word}.list-error-detail{margin:.65rem 0 0;padding:.55rem .65rem;max-height:10rem;overflow:auto;font-family:var(--font-mono);font-size:.78rem;line-height:1.4;color:var(--on-surface-variant);background:var(--panel);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);white-space:pre-wrap}.studio-map{gap:var(--studio-space-lg);max-width:none;position:relative}.studio-shard{content:"";position:absolute;pointer-events:none;z-index:0;clip-path:var(--shard-alpha);opacity:var(--cubist-shard-opacity);background:color-mix(in srgb,var(--primary) 55%,var(--secondary))}.studio-shard--beta{clip-path:var(--shard-beta);background:color-mix(in srgb,var(--tertiary) 50%,var(--primary));opacity:var(--cubist-shard-opacity-strong)}.studio-map>.studio-shard--lead{width:min(18rem,42vw);height:min(14rem,32vw);top:-1rem;right:4%}.studio-map>.studio-shard--trail{width:min(12rem,28vw);height:min(10rem,22vw);bottom:8%;left:2%}@media(max-width:639px){.studio-shard{display:none}}.studio-map-board{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--studio-space-lg) var(--studio-space-md);align-items:start;min-width:0;position:relative;z-index:1}@media(min-width:48rem){.studio-map-board{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:72rem){.studio-map-board{grid-template-columns:repeat(3,minmax(0,1fr))}}.studio-map-group{display:flex;flex-direction:column;gap:var(--studio-space-sm);padding:var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);min-width:0}.studio-map-group-head{display:flex;align-items:baseline;gap:var(--studio-space-sm)}.studio-map-group-icon{position:relative;top:.1rem;color:var(--primary);font-size:1.15rem;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.studio-map-group-label{margin:0;font-family:var(--font-label);font-size:var(--studio-type-title);font-weight:400;letter-spacing:.03em;line-height:1.2}.studio-map-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(12.5rem,1fr));gap:var(--studio-space-sm)}.studio-map-card{display:flex;align-items:flex-start;gap:var(--studio-space-sm);text-align:left;margin:0;padding:var(--studio-space-sm) var(--studio-space-md);border:1px solid color-mix(in srgb,var(--outline-variant) 60%,transparent);background:var(--background);cursor:pointer;color:inherit;font:inherit;min-height:3.5rem}.studio-map-card:hover{background:var(--surface-high);border-color:color-mix(in srgb,var(--primary) 45%,var(--outline-variant))}.studio-map-card-icon{color:var(--on-surface-variant);font-size:1.25rem;line-height:1;margin-top:.1rem;font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 24}.studio-map-card-body{display:flex;flex-direction:column;gap:.25rem;min-width:0}.studio-map-card-title{font-family:var(--font-body);font-weight:600;font-size:var(--studio-type-body);line-height:1.3}.studio-map-card-meta{font-family:var(--font-mono);font-size:var(--studio-type-meta);color:var(--on-surface-variant);word-break:break-word}.form-grid{display:flex;flex-direction:column;gap:var(--studio-space-md);max-width:52rem;flex-shrink:0}.field label,.field .field-heading{display:block;font-family:var(--font-mono);font-size:var(--studio-type-micro);text-transform:uppercase;letter-spacing:.08em;color:var(--on-surface-variant);margin-bottom:var(--studio-space-2xs)}.field--title{padding-bottom:var(--studio-space-md);border-bottom:1px solid var(--outline-variant)}.form-grid .field input:not([type=checkbox]):not([type=radio]),.form-grid .field select,.form-grid .field textarea{font-family:var(--font-mono);font-size:var(--studio-type-ui)}.field input,.field select,.field textarea{width:100%;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);padding:.4rem .55rem}.field--boolean .field-checkbox,.field input.field-checkbox,.field input[type=checkbox]{width:auto;max-width:none;margin:0;padding:0;border:0;background:transparent;flex:0 0 auto;accent-color:var(--primary)}.field--boolean .field-check-row{display:flex;align-items:center;gap:.55rem;margin:0;text-transform:none;letter-spacing:normal;font-size:.92rem;color:var(--on-surface);cursor:pointer;-webkit-user-select:none;user-select:none;line-height:1.35}.field--boolean .field-check-text{line-height:1.35}.field textarea{min-height:6rem;line-height:1.45}.field .hint{margin:var(--studio-space-2xs) 0 0;font-size:var(--studio-type-meta);color:var(--on-surface-variant);line-height:1.35}.body-editor-stack{display:flex;flex-direction:column;flex:1 1 auto;min-height:var(--studio-editor-min-height);margin-top:.35rem;padding:var(--studio-space-sm) var(--studio-space-md);background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent);overflow:hidden}.editor-chrome{display:flex;flex-direction:column;gap:.45rem;margin-bottom:.5rem;flex-shrink:0}.editor-chrome-row{display:flex;flex-wrap:wrap;align-items:center;gap:.55rem}.editor-chrome-actions{display:inline-flex;flex-wrap:wrap;align-items:center;gap:.45rem}.editor-ai-proof{display:inline-flex;flex-wrap:wrap;align-items:center;gap:.35rem}.ai-proof-hint{margin:0;font-family:var(--font-mono);font-size:var(--studio-type-micro);letter-spacing:.02em;color:var(--on-surface-variant)}.ai-proof-hint[hidden]{display:none!important}.editor-mode-tabs{display:inline-flex;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--panel)}.editor-mode-tab{margin:0;border:0;border-radius:0;background:transparent;padding:.4rem .9rem;cursor:pointer;color:var(--on-surface-variant);font:inherit;font-size:.92rem}.editor-mode-tab+.editor-mode-tab{border-left:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent)}.editor-mode-tab[aria-selected=true]{background:var(--background);color:var(--on-surface);font-weight:600}.editor-mode-tab:hover{background:var(--surface-high);color:var(--on-surface)}.editor-insert{position:relative}.editor-insert-btn{display:inline-flex;align-items:center;gap:.3rem}.editor-insert-btn .material-symbols-outlined{font-size:1.1rem;line-height:1}.editor-insert-caret{font-size:1rem!important;opacity:.75}.editor-insert-menu{position:absolute;top:calc(100% + .25rem);left:0;z-index:20;min-width:12rem;max-height:16rem;overflow:auto;display:flex;flex-direction:column;gap:0;padding:.25rem;background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);box-shadow:0 8px 20px color-mix(in srgb,var(--on-surface) 12%,transparent)}.editor-insert-menu[hidden]{display:none!important}.editor-insert-item{display:flex;align-items:center;gap:.55rem;width:100%;margin:0;padding:.45rem .55rem;border:0;background:transparent;cursor:pointer;text-align:left;color:inherit;font:inherit;font-size:.92rem}.editor-insert-item:hover{background:var(--surface-high)}.editor-insert-icon{font-size:1.15rem;color:var(--on-surface-variant);font-variation-settings:"FILL" 0,"wght" 400,"GRAD" 0,"opsz" 24}.editor-format-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:.2rem;padding:.35rem .4rem;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--panel)}.editor-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;margin:0;padding:0 .35rem;border:0;border-radius:0;background:transparent;cursor:pointer;color:var(--on-surface);font:inherit;font-size:.82rem;font-weight:600}.editor-toolbar-btn:hover{background:var(--surface-high)}.editor-toolbar-btn .material-symbols-outlined{font-size:1.15rem;line-height:1;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.editor-toolbar-sep{width:1px;align-self:stretch;margin:.2rem .3rem;background:color-mix(in srgb,var(--outline-variant) 70%,transparent)}.editor-toolbar-select{border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);padding:.25rem .4rem;font-size:.82rem;max-width:8.5rem}.editor-pane-fill{position:relative;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;overflow:hidden}.editor-surface{flex:1 1 auto;width:100%;min-height:0;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);overflow:auto}.tiptap.editor-surface{padding:.85rem}.tiptap .ProseMirror{outline:none;min-height:12rem}.tiptap .ProseMirror p{margin:.4rem 0}textarea.body-source.editor-surface{display:block;resize:none;padding:.85rem;font-family:var(--font-mono);font-size:.8759rem;line-height:1.5;color:inherit;box-sizing:border-box;min-height:0;flex:1 1 auto;width:100%;overflow:auto}.editor-surface[hidden]{display:none!important}.liquid-block{border:1px dashed color-mix(in srgb,var(--outline) 50%,transparent);background:var(--panel);padding:.5rem .65rem;margin:.5rem 0;font-family:var(--font-mono);font-size:.86rem}.liquid-block--inline{display:inline;margin:0;padding:.05rem .35rem;white-space:normal}.liquid-block strong{font-family:var(--font-body);text-transform:uppercase;letter-spacing:.05em;font-size:.78rem;color:var(--on-surface-variant)}.preview-frame{background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);padding:1rem;min-height:12rem;flex:1;overflow:auto;font-family:var(--font-body);font-size:.95rem;line-height:1.6;color:var(--on-surface)}.preview-frame figure{margin:1rem auto;text-align:center}.preview-frame img,.preview-frame video,.preview-frame iframe{max-width:100%}.preview-frame .studio-embed-placeholder{width:100%}.preview-frame .studio-embed-placeholder__box{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:100%;min-height:inherit;height:100%;padding:1rem 1.1rem;border:1px dashed color-mix(in srgb,var(--outline) 55%,transparent);background:color-mix(in srgb,var(--surface-high) 88%,transparent);color:var(--on-surface-variant)}.preview-frame .studio-embed-placeholder__label{font-family:var(--font-mono);font-size:.8759rem;line-height:1.35;word-break:break-word;background:transparent;border:0;padding:0}.preview-frame .studio-mermaid,.preview-frame .mermaid{margin:1rem 0;overflow-x:auto}.preview-frame .studio-mermaid-fallback{margin:1rem 0}.preview-frame .studio-mermaid-fallback__pre{margin:0;white-space:pre-wrap;word-break:break-word;font-family:var(--font-mono);font-size:.8019rem;padding:.65rem .75rem;border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:color-mix(in srgb,var(--surface-high) 90%,transparent);color:var(--on-surface-variant)}.preview-frame pre,.preview-frame pre code,.preview-frame :not(pre)>code{font-size:.8019rem}.preview-frame pre{overflow-x:auto;padding:.65rem .75rem;background:color-mix(in srgb,var(--surface-high) 90%,transparent);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.preview-frame pre code{font-size:inherit;background:transparent;border:0;padding:0}.preview-frame :not(pre)>code{font-family:var(--font-mono);padding:.05em .3em;background:color-mix(in srgb,var(--surface-high) 90%,transparent);border:1px solid color-mix(in srgb,var(--outline-variant) 45%,transparent)}.preview-frame .studio-ref-pill{display:inline-flex;align-items:center;vertical-align:middle;max-width:100%;margin:0 .12em;padding:.05em .4em;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);border-radius:0;background:color-mix(in srgb,var(--surface-high) 85%,transparent);color:var(--on-surface-variant);font-family:var(--font-mono);font-size:.85em;line-height:1.2;white-space:nowrap;box-sizing:border-box;transition:color .12s ease,background .12s ease,border-color .12s ease}.preview-frame .studio-ref-pill--ok{color:color-mix(in srgb,#1b6b3a 88%,var(--on-surface));background:color-mix(in srgb,#1b6b3a 14%,transparent);border-color:color-mix(in srgb,#1b6b3a 40%,transparent)}.preview-frame .studio-ref-pill--missing{color:color-mix(in srgb,#a12828 90%,var(--on-surface));background:color-mix(in srgb,#a12828 14%,transparent);border-color:color-mix(in srgb,#a12828 40%,transparent)}.preview-frame .studio-ref-pill--latex{color:var(--on-surface);background:color-mix(in srgb,var(--surface-high) 90%,transparent);border-color:color-mix(in srgb,var(--outline-variant) 65%,transparent);white-space:pre-wrap;word-break:break-word}.preview-frame .studio-ref-pill--display{display:flex;margin:.75rem auto;padding:.55rem .75rem;overflow-x:auto;white-space:pre-wrap;word-break:break-word}.preview-frame .article-note{background:color-mix(in srgb,var(--surface-high) 88%,transparent);border-left:3px solid color-mix(in srgb,var(--outline-variant) 80%,transparent);padding:.85rem 1.1rem;margin:1.1rem 0;font-size:.9em}.preview-frame .article-note>:first-child{margin-top:0}.preview-frame .article-note>:last-child{margin-bottom:0}.preview-frame :is(.sov-tweet,.article-tweet){max-width:34rem;margin:1rem 0 1.25rem;padding:.85rem 1rem;border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:color-mix(in srgb,var(--surface-high) 70%,transparent)}.preview-frame :is(.sov-tweet,.article-tweet) p{margin:0}.preview-frame :is(.sov-tweet__head,.article-tweet__head){display:flex;align-items:center;gap:.5rem;margin-bottom:.7rem}.preview-frame :is(.sov-tweet__avatar,.article-tweet__avatar){width:2rem;height:2rem;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--outline-variant) 35%,transparent);font-size:1.1rem}.preview-frame :is(.sov-tweet__id,.article-tweet__id){display:flex;flex-direction:column;line-height:1.2}.preview-frame :is(.sov-tweet__name,.article-tweet__name){font-weight:700;font-size:.92rem}.preview-frame :is(.sov-tweet__handle,.article-tweet__handle){font-size:.8rem;opacity:.75}.preview-frame :is(.sov-tweet__body,.article-tweet__body){margin:0 0 .45rem!important;line-height:1.55}.preview-frame :is(.sov-tweet__cite,.article-tweet__cite){margin:0 0 .45rem!important;font-size:.8rem;opacity:.8}.preview-frame :is(.sov-tweet__note,.article-tweet__note){margin:0!important;font-size:.85rem;opacity:.9}.preview-frame .studio-unknown-include{display:none}.preview-frame table{width:100%;border-collapse:collapse;margin:1rem 0 1.25rem;font-size:.9em;line-height:1.45;overflow-x:auto;display:block;max-width:100%}.preview-frame thead,.preview-frame tbody,.preview-frame tr{display:table;width:100%;table-layout:auto}.preview-frame th,.preview-frame td{border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);padding:.4rem .55rem;text-align:left;vertical-align:top}.preview-frame th{font-weight:600;background:color-mix(in srgb,var(--surface-high) 88%,transparent)}.preview-frame .sov-grid{display:grid;grid-template-columns:1fr;gap:.85rem;margin:1rem 0 1.35rem}@media(min-width:720px){.preview-frame .sov-grid{grid-template-columns:1fr 1fr}}.preview-frame .sov-card{border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);border-left:3px solid var(--sov-accent, var(--primary));background:color-mix(in srgb,var(--surface-high) 70%,transparent);padding:.65rem .8rem .75rem;display:flex;flex-direction:column;gap:.45rem;min-width:0}.preview-frame .sov-card p{margin:0}.preview-frame .sov-card__head{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.preview-frame .sov-card__flag{display:inline-flex;align-items:center;justify-content:center;height:1.5rem;padding:0 .35rem;border:1px solid color-mix(in srgb,var(--outline-variant) 65%,transparent);line-height:1}.preview-frame .sov-card__flag .fi{font-size:1rem}.preview-frame .sov-card__meta{font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;opacity:.8;font-weight:600}.preview-frame .sov-card__lemma{font-style:italic;font-size:1.02rem;color:var(--on-surface)}.preview-frame .sov-card__def{margin:0;padding:.45rem .6rem;border-left:2px solid color-mix(in srgb,var(--sov-accent, var(--primary)) 55%,transparent);background:color-mix(in srgb,var(--sov-accent, var(--primary)) 8%,transparent);font-size:.86rem;line-height:1.6}.preview-frame .sov-card__note{font-size:.82rem;line-height:1.5;opacity:.9}.preview-frame .sov-card__cite{font-size:.76rem;line-height:1.45;opacity:.75}.preview-frame .sov-card__cite a{color:inherit;text-decoration:underline;text-underline-offset:2px}.preview-frame .sov-card--us{--sov-accent: #003494}.preview-frame .sov-card--gb{--sov-accent: #797300}.preview-frame .sov-card--br{--sov-accent: #118826}.preview-frame .sov-card--fr{--sov-accent: #9f020a}.editor-mode-tab--preview{display:none}.auth-gate{max-width:28rem;margin:4rem auto;padding:1.5rem;border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:var(--background)}.auth-gate h1{font-family:var(--font-display);font-size:1.6rem;margin:0 0 .5rem}.auth-gate--pending .pending-copy{font-family:var(--font-body);line-height:1.55;color:var(--on-surface);margin:0 0 1rem}.auth-gate--pending .pending-copy strong{font-weight:600}.auth-gate--pending .pending-signoff{font-family:var(--font-body);margin:0 0 1.25rem;color:var(--on-surface-variant)}.status-pill{font-family:var(--font-mono);font-size:var(--studio-type-meta);color:var(--on-surface-variant)}.status-pill.error{color:var(--error)}.studio-error-banner{display:flex;flex-direction:column;align-items:flex-start;gap:.55rem;padding:.75rem var(--studio-space-md);border-bottom:1px solid color-mix(in srgb,var(--error) 45%,transparent);background:color-mix(in srgb,var(--error) 8%,var(--background))}.studio-error-message{margin:0;color:var(--on-surface);font-size:var(--studio-type-body);line-height:1.45;white-space:normal;overflow-wrap:anywhere}.studio-error-actions{display:flex;flex-wrap:wrap;gap:.45rem}@media(max-width:719px){.ledger-row--writing .ledger-title-row{flex-direction:column;align-items:flex-start;gap:.2rem}.ledger-row--writing .ledger-status{width:auto;flex:0 0 auto}.ledger-row--writing .ledger-ops{display:inline-flex;grid-column:1 / -1;justify-content:flex-end;padding-top:.45rem;margin-top:.15rem;border-top:1px solid color-mix(in srgb,var(--outline-variant) 35%,transparent)}}@media(max-width:960px){.studio-shell{grid-template-columns:1fr;grid-template-rows:auto auto minmax(0,1fr);height:auto;min-height:100vh;padding-top:3.25rem}.ledger-row{align-items:start}.studio-shell>.studio-toolbar{position:fixed;top:0;left:0;right:0;z-index:40;min-height:3.25rem;padding:.45rem .7rem;gap:.45rem;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:color-mix(in srgb,var(--panel) 94%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.studio-toolbar .spacer:before{display:none}.studio-toolbar>.studio-theme-menu,.studio-toolbar>.btn-tool{flex:0 0 var(--studio-toolbar-control-h);width:var(--studio-toolbar-control-h);height:var(--studio-toolbar-control-h);min-height:var(--studio-toolbar-control-h);max-height:var(--studio-toolbar-control-h)}.studio-toolbar .btn-tool .btn-label{display:none}.studio-toolbar>.studio-theme-menu .btn-tool,.studio-toolbar>.btn-tool{width:100%;min-width:0;padding:0}.studio-toolbar-status{display:none}.studio-toolbar .studio-nav-menu-toggle{display:inline-flex;align-items:center;justify-content:center}.studio-toolbar .studio-brand-toolbar{width:var(--studio-toolbar-control-h);min-width:var(--studio-toolbar-control-h);padding:0;column-gap:0;grid-template-columns:var(--studio-brand-mark);justify-items:center}.studio-toolbar .studio-brand-toolbar .studio-brand-copy,.studio-toolbar .studio-brand-toolbar .studio-brand-name{display:none}.studio-nav{border-right:0;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);overflow:visible;gap:.35rem;padding:.65rem .75rem}.studio-nav:not(.is-open){display:none}.studio-nav-bar{display:none}.studio-nav-panel{display:none;margin-top:0;padding-top:.35rem;border-top:0;max-height:min(70vh,28rem);overflow:auto}.studio-nav.is-open .studio-nav-panel{display:flex}.studio-main{height:auto;overflow:visible}.studio-body{grid-template-columns:1fr;height:auto;overflow:visible}.editor-mode-tab--preview{display:inline-flex}.studio-body.view-preview .pane-editor>.btn,.studio-body.view-preview .pane-editor .editor-mast,.studio-body.view-preview .pane-editor .front-matter,.studio-body.view-preview .pane-editor .form-grid,.studio-body.view-preview .pane-editor .editor-pane-fill,.studio-body.view-preview .pane-editor .editor-format-toolbar,.studio-body.view-preview .pane-editor .editor-chrome-row>:not(.editor-mode-tabs),.studio-body.view-preview .pane-editor .body-editor-stack>label{display:none}.studio-body.view-preview .pane-editor{padding-bottom:.35rem;overflow:visible;flex:0 0 auto}.studio-body.view-preview .pane-editor .editor-chrome{margin-bottom:0}.studio-body:not(.view-preview) .pane-preview{display:none}.studio-body.view-preview .pane-preview{display:flex;border-left:0;border-top:0;flex:1 1 auto}.pane-preview{border-left:0;border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}}.pane-yaml .yaml-editor-header{margin:.65rem 0 .35rem}.yaml-editor-title{margin:0;font-family:var(--font-display);font-size:1.35rem;font-weight:500;color:var(--on-surface)}.yaml-editor-path{margin:.2rem 0 0;font-size:.82rem;color:var(--on-surface-variant);word-break:break-word}.yaml-chrome{margin-bottom:.65rem}.yaml-chrome-hint{margin:.45rem 0 0;font-size:.82rem;color:var(--on-surface-variant)}.yaml-editor-body{display:flex;flex-direction:column;gap:.85rem;flex:1 1 auto;min-height:0}.yaml-list,.yaml-object-list{display:flex;flex-direction:column;gap:.85rem}.yaml-list-item{border:1px solid color-mix(in srgb,var(--outline-variant) 65%,transparent);background:var(--panel);padding:.75rem .85rem}.yaml-list-item-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-bottom:.65rem}.yaml-list-item-index{font-size:.82rem;text-transform:uppercase;letter-spacing:.06em;color:var(--on-surface-variant);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yaml-list-item-actions{display:flex;flex-wrap:wrap;gap:.35rem;flex-shrink:0}.yaml-list-btn{padding:.25rem .45rem;font-size:.78rem}.yaml-list-item-fields{max-width:none}.yaml-empty{margin:0;color:var(--on-surface-variant);font-size:.92rem}.yaml-source-stack{display:flex;flex-direction:column;flex:1 1 auto;min-height:var(--studio-editor-min-height)}textarea.yaml-source.editor-surface{display:block;resize:none;padding:.85rem;font-family:var(--font-mono);font-size:.95rem;line-height:1.45;color:inherit;box-sizing:border-box;min-height:var(--studio-editor-min-height);flex:1 1 auto;width:100%;overflow:auto;-moz-tab-size:2;tab-size:2}.yaml-preview-pre{margin:0;padding:.75rem .85rem;font-family:var(--font-mono);font-size:.86rem;line-height:1.45;white-space:pre-wrap;word-break:break-word;background:color-mix(in srgb,var(--surface-high) 70%,transparent);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);overflow:auto}.yaml-preview-error{margin:0;color:var(--error);font-size:.9rem}.media-pane{display:flex;flex-direction:column;gap:.85rem;padding:1rem 1.25rem 1.5rem;overflow:auto;min-height:0}.media-header h1.media-title{margin:0 0 .35rem;font-family:var(--font-display);font-size:1.55rem;font-weight:600}.media-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;font-family:var(--font-mono);font-size:.82rem;color:var(--on-surface-variant)}.media-breadcrumb-sep{opacity:.55}.media-breadcrumb-link{margin:0;padding:.1rem .25rem;border:0;border-radius:0;background:transparent;color:var(--primary);cursor:pointer;font:inherit}.media-breadcrumb-link:hover{background:var(--surface-high)}.media-breadcrumb-current{color:var(--on-surface);font-weight:600}.media-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:.55rem}.media-toolbar .spacer{flex:1}.media-file-input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.media-grid{display:flex;flex-direction:column;gap:.35rem;background:var(--panel);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);padding:var(--studio-space-xs)}.media-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:var(--studio-space-md);align-items:center;padding:var(--studio-space-md) var(--studio-space-md);margin:0 0 var(--studio-space-xs);border:1px solid color-mix(in srgb,var(--outline-variant) 60%,transparent);border-radius:0;cursor:pointer;background:var(--surface-card);text-align:left;width:100%;font:inherit;color:inherit;box-sizing:border-box}.media-row:last-child{margin-bottom:0}.media-row:hover{background:var(--surface-high)}.media-row[aria-disabled=true]{opacity:.55;cursor:not-allowed}.media-row--dir{grid-template-columns:auto minmax(0,1fr)}.media-row--preview{cursor:zoom-in}.media-row--preview:focus-visible{outline:2px solid var(--primary);outline-offset:3px}.media-thumb{width:52px;height:52px;flex-shrink:0;display:grid;place-items:center;background:var(--surface-high);border:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);overflow:hidden}.media-thumb--image{padding:0}.media-thumb-img{width:100%;height:100%;object-fit:cover;display:block}.media-thumb-icon{font-size:1.45rem;color:var(--on-surface-variant)}.media-row-body{display:flex;flex-direction:column;gap:.15rem;min-width:0}.media-row-name{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.media-row-meta{font-family:var(--font-mono);font-size:.78rem;color:var(--on-surface-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.media-ops{display:inline-flex;align-items:center;justify-content:flex-end;gap:.35rem;flex-shrink:0;white-space:nowrap;padding-top:.1rem}.media-op-btn{width:2.35rem;min-width:2.35rem;min-height:2.35rem;padding:.3rem;border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent);background:var(--background);color:var(--on-surface)}.media-op-btn .material-symbols-outlined{font-size:1.15rem;line-height:1;font-variation-settings:"FILL" 0,"wght" 500,"GRAD" 0,"opsz" 24}.media-copy-btn:hover{background:var(--surface-high);border-color:color-mix(in srgb,var(--primary) 40%,var(--outline-variant));color:var(--primary)}.media-delete-btn{color:var(--error);border-color:color-mix(in srgb,var(--error) 45%,var(--outline-variant));background:color-mix(in srgb,var(--error) 6%,var(--background))}.media-delete-btn:hover{background:color-mix(in srgb,var(--error) 14%,var(--background));border-color:color-mix(in srgb,var(--error) 60%,var(--outline-variant))}html.figure-lightbox-open,body.figure-lightbox-open{overflow:hidden}.figure-lightbox{--motion-duration-fast: .15s;--motion-ease-out: ease-out;--motion-ease-default: ease;position:fixed;top:0;right:0;bottom:0;left:0;z-index:80;display:flex;align-items:center;justify-content:center;padding:1.25rem;box-sizing:border-box}.figure-lightbox[hidden]{display:none}.figure-lightbox [hidden]{display:none!important}.figure-lightbox-backdrop{position:absolute;top:0;right:0;bottom:0;left:0;background:#000000d9;cursor:zoom-out;animation:figure-lightbox-fade-in var(--motion-duration-fast) var(--motion-ease-out)}.figure-lightbox-panel{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;max-width:min(92vw,72rem);max-height:92vh;animation:figure-lightbox-scale-in var(--motion-duration-fast) var(--motion-ease-out)}.figure-lightbox-img,.figure-lightbox-video{display:block;max-width:92vw;max-height:85vh;width:auto;height:auto;object-fit:contain;background:var(--background);border:1px solid color-mix(in srgb,var(--outline-variant) 40%,transparent);border-radius:0}.figure-lightbox-video{background:#000}.figure-lightbox-frame{display:block;width:min(92vw,72rem);height:min(78vh,52rem);border:1px solid color-mix(in srgb,var(--outline-variant) 40%,transparent);border-radius:0;background:var(--background)}.figure-lightbox-caption{margin:.75rem 0 0;max-width:min(40rem,90vw);font-family:var(--font-body);font-size:.95rem;line-height:1.45;text-align:center;color:#ffffffeb}.figure-lightbox-close{position:fixed;top:1rem;right:1rem;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:2.75rem;height:2.75rem;padding:0;border:1px solid color-mix(in srgb,var(--outline-variant) 50%,transparent);border-radius:0;background:var(--background);color:var(--on-surface);cursor:pointer;transition:color var(--motion-duration-fast) var(--motion-ease-default),background-color var(--motion-duration-fast) var(--motion-ease-default)}.figure-lightbox-close:hover,.figure-lightbox-close:focus-visible{color:var(--primary);background:var(--surface-high);outline:none}.figure-lightbox-close:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.figure-lightbox-close .material-symbols-outlined{font-size:1.5rem;line-height:1}@keyframes figure-lightbox-fade-in{0%{opacity:0}to{opacity:1}}@keyframes figure-lightbox-scale-in{0%{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){.figure-lightbox-backdrop,.figure-lightbox-panel{animation:none}}
|