claude-memory-admin 1.5.0 → 1.5.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.
- package/README.md +0 -2
- package/package.json +1 -1
- package/public/app.mjs +234 -286
- package/public/dialog.mjs +84 -0
- package/public/dom.mjs +15 -0
- package/public/index.html +1 -1
- package/public/styles.css +1 -1
- package/public/ui.mjs +5 -6
package/README.md
CHANGED
|
@@ -19,8 +19,6 @@ and this README were written by Claude Code, with a human directing the design
|
|
|
19
19
|
and reviewing what landed. Fitting for a tool about what Claude writes for
|
|
20
20
|
itself, and worth saying out loud.
|
|
21
21
|
|
|
22
|
-
<sub>Brought to you by [BitSpire](https://bitspire.ch/).</sub>
|
|
23
|
-
|
|
24
22
|
---
|
|
25
23
|
|
|
26
24
|
### Prune: see what MEMORY.md actually costs you
|
package/package.json
CHANGED
package/public/app.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { renderGraph } from '/graph.mjs';
|
|
2
2
|
import { renderMarkdown } from '/markdown.mjs';
|
|
3
|
+
import { confirmDialog, isDialogOpen, openDialog } from '/dialog.mjs';
|
|
4
|
+
import { el, node } from '/dom.mjs';
|
|
3
5
|
import * as ui from '/ui.mjs';
|
|
4
6
|
|
|
5
7
|
const state = {
|
|
@@ -25,8 +27,6 @@ const RANK = { ok: 0, warn: 1, bad: 2 };
|
|
|
25
27
|
const worst = (...severities) => severities.reduce((a, b) => (RANK[b] > RANK[a] ? b : a), 'ok');
|
|
26
28
|
const worstSeverity = (items) => (!items.length ? 'ok' : items.some((item) => item.severity === 'bad') ? 'bad' : 'warn');
|
|
27
29
|
|
|
28
|
-
const el = (id) => document.getElementById(id);
|
|
29
|
-
|
|
30
30
|
async function api(path, options) {
|
|
31
31
|
const response = await fetch(path, {
|
|
32
32
|
headers: { 'content-type': 'application/json' },
|
|
@@ -38,32 +38,17 @@ async function api(path, options) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function toast(message, { error = false, action } = {}) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
node.append(document.createTextNode(message));
|
|
41
|
+
const element = node('div', { class: ui.toast(error) });
|
|
42
|
+
element.append(document.createTextNode(message));
|
|
44
43
|
if (action) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
el('toast-root').append(node);
|
|
52
|
-
setTimeout(() => node.remove(), action ? 12000 : 4500);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function node(tag, props = {}, children = []) {
|
|
56
|
-
const element = document.createElement(tag);
|
|
57
|
-
for (const [key, value] of Object.entries(props)) {
|
|
58
|
-
if (key === 'class') element.className = value;
|
|
59
|
-
else if (key === 'text') element.textContent = value;
|
|
60
|
-
else if (key.startsWith('on')) element.addEventListener(key.slice(2).toLowerCase(), value);
|
|
61
|
-
else if (value !== null && value !== undefined) element.setAttribute(key, value);
|
|
62
|
-
}
|
|
63
|
-
for (const child of [].concat(children)) {
|
|
64
|
-
if (child) element.append(child);
|
|
44
|
+
element.append(node('button', {
|
|
45
|
+
class: ui.toastAction,
|
|
46
|
+
text: action.label,
|
|
47
|
+
onclick: () => { element.remove(); action.run(); },
|
|
48
|
+
}));
|
|
65
49
|
}
|
|
66
|
-
|
|
50
|
+
el('toast-root').append(element);
|
|
51
|
+
setTimeout(() => element.remove(), action ? 12000 : 4500);
|
|
67
52
|
}
|
|
68
53
|
|
|
69
54
|
function memoryLookup(project) {
|
|
@@ -667,7 +652,19 @@ function goToTab(id) {
|
|
|
667
652
|
}
|
|
668
653
|
|
|
669
654
|
async function removeIndexLine(lineIndex, expectedText, done) {
|
|
670
|
-
|
|
655
|
+
const go = await confirmDialog({
|
|
656
|
+
title: `Remove line ${lineIndex + 1} from MEMORY.md?`,
|
|
657
|
+
confirmLabel: 'Remove',
|
|
658
|
+
tone: 'danger',
|
|
659
|
+
body: [
|
|
660
|
+
node('div', { class: ui.willBlock }, [
|
|
661
|
+
node('div', { class: ui.willTitle, text: 'Will be removed' }),
|
|
662
|
+
node('div', { class: ui.willItem('remove'), text: expectedText }),
|
|
663
|
+
]),
|
|
664
|
+
node('p', { class: ui.noteTight, text: 'Only this line goes. The memory file it points at is left on disk.' }),
|
|
665
|
+
],
|
|
666
|
+
});
|
|
667
|
+
if (!go) return;
|
|
671
668
|
try {
|
|
672
669
|
await api(`/api/stores/${encodeURIComponent(state.storeId)}/index-line/delete`, {
|
|
673
670
|
method: 'POST',
|
|
@@ -709,7 +706,21 @@ function renderIssue(item, memories) {
|
|
|
709
706
|
action: {
|
|
710
707
|
label: 'Remove link',
|
|
711
708
|
run: async () => {
|
|
712
|
-
|
|
709
|
+
const go = await confirmDialog({
|
|
710
|
+
title: `Remove [[${link.target}]] from ${link.from}?`,
|
|
711
|
+
confirmLabel: 'Remove link',
|
|
712
|
+
tone: 'danger',
|
|
713
|
+
body: [
|
|
714
|
+
node('p', { class: ui.noteTight, text: 'The link markup goes, the words stay.' }),
|
|
715
|
+
node('div', { class: ui.willBlock }, [
|
|
716
|
+
node('div', { class: ui.willTitle, text: 'Will change' }),
|
|
717
|
+
node('div', { class: ui.willItem('remove'), text: `see [[${link.target}]]` }),
|
|
718
|
+
node('div', { class: ui.willItem('keep'), text: `see ${link.target}` }),
|
|
719
|
+
]),
|
|
720
|
+
node('p', { class: ui.noteTight, text: 'A copy of the file is kept in the trash, so this can be undone.' }),
|
|
721
|
+
],
|
|
722
|
+
});
|
|
723
|
+
if (!go) return;
|
|
713
724
|
try {
|
|
714
725
|
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/wikilink/remove`, {
|
|
715
726
|
method: 'POST',
|
|
@@ -1246,7 +1257,7 @@ function openHookEditor(row, lineIndex) {
|
|
|
1246
1257
|
field.select();
|
|
1247
1258
|
}
|
|
1248
1259
|
|
|
1249
|
-
function openMoveDialog(entry) {
|
|
1260
|
+
async function openMoveDialog(entry) {
|
|
1250
1261
|
const current = indexEntryAt(entry.index);
|
|
1251
1262
|
if (!current) return toast('MEMORY.md has changed - reload and try again', { error: true });
|
|
1252
1263
|
|
|
@@ -1256,40 +1267,31 @@ function openMoveDialog(entry) {
|
|
|
1256
1267
|
picker.append(node('option', { value: '', text: 'Top of MEMORY.md' }));
|
|
1257
1268
|
for (const section of sections) picker.append(node('option', { value: section, text: `Start of "${section}"` }));
|
|
1258
1269
|
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
node('
|
|
1263
|
-
node('div', { class: ui.
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
() => 'Entry moved',
|
|
1285
|
-
);
|
|
1286
|
-
},
|
|
1287
|
-
}),
|
|
1288
|
-
]),
|
|
1289
|
-
]);
|
|
1290
|
-
|
|
1291
|
-
const backdrop = node('div', { class: ui.modalBackdrop, onclick: (event) => { if (event.target === backdrop) closeModal(); } }, [modal]);
|
|
1292
|
-
el('modal-root').append(backdrop);
|
|
1270
|
+
const go = await openDialog({
|
|
1271
|
+
title: 'Move this entry above the cutoff',
|
|
1272
|
+
body: [
|
|
1273
|
+
node('p', { class: ui.noteTight, text: `"${current.title}" sits at line ${current.index + 1}, past the cutoff at line ${cutoff ? cutoff.rawLine + 1 : '-'}, so Claude never loads it. Moving it up puts it back inside the loaded part of the index - which pushes whatever is now last past the cutoff instead.` }),
|
|
1274
|
+
node('div', { class: ui.willBlock }, [
|
|
1275
|
+
node('div', { class: ui.willTitle, text: 'Will move' }),
|
|
1276
|
+
node('div', { class: ui.willItem('keep'), text: current.text }),
|
|
1277
|
+
]),
|
|
1278
|
+
node('label', { class: ui.willTitle, text: 'Move to' }),
|
|
1279
|
+
picker,
|
|
1280
|
+
],
|
|
1281
|
+
actions: [
|
|
1282
|
+
{ label: 'Cancel' },
|
|
1283
|
+
{ label: 'Move', tone: 'primary', value: true },
|
|
1284
|
+
],
|
|
1285
|
+
});
|
|
1286
|
+
if (!go) return;
|
|
1287
|
+
|
|
1288
|
+
await runIndexEdit(
|
|
1289
|
+
'index/move',
|
|
1290
|
+
picker.value
|
|
1291
|
+
? { lineIndex: current.index, expectedText: current.text, section: picker.value }
|
|
1292
|
+
: { lineIndex: current.index, expectedText: current.text, top: true },
|
|
1293
|
+
() => 'Entry moved',
|
|
1294
|
+
);
|
|
1293
1295
|
}
|
|
1294
1296
|
|
|
1295
1297
|
async function openAddEntryDialog(file) {
|
|
@@ -1303,8 +1305,8 @@ async function openAddEntryDialog(file) {
|
|
|
1303
1305
|
return toast(err.message, { error: true });
|
|
1304
1306
|
}
|
|
1305
1307
|
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
+
const titleInput = node('input', { type: 'text', class: ui.pathInput, spellcheck: 'false' });
|
|
1309
|
+
titleInput.value = preview.name;
|
|
1308
1310
|
const hook = node('textarea', { class: ui.textArea, spellcheck: 'false' });
|
|
1309
1311
|
hook.value = preview.description;
|
|
1310
1312
|
|
|
@@ -1315,54 +1317,44 @@ async function openAddEntryDialog(file) {
|
|
|
1315
1317
|
|
|
1316
1318
|
const line = node('div', { class: ui.willItem('keep') });
|
|
1317
1319
|
const update = () => {
|
|
1318
|
-
const label =
|
|
1320
|
+
const label = titleInput.value.trim().replace(/[[\]]/g, '') || preview.name;
|
|
1319
1321
|
const text = hook.value.trim();
|
|
1320
1322
|
line.textContent = text ? `- [${label}](${file}) — ${text}` : `- [${label}](${file})`;
|
|
1321
1323
|
};
|
|
1322
|
-
|
|
1324
|
+
titleInput.addEventListener('input', update);
|
|
1323
1325
|
hook.addEventListener('input', update);
|
|
1324
1326
|
update();
|
|
1325
1327
|
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
onclick: async () => {
|
|
1351
|
-
closeModal();
|
|
1352
|
-
await runIndexEdit(
|
|
1353
|
-
'index/add',
|
|
1354
|
-
{ file, section: picker.value || null, title: title.value, hook: hook.value },
|
|
1355
|
-
() => 'Added to MEMORY.md',
|
|
1356
|
-
);
|
|
1357
|
-
},
|
|
1358
|
-
}),
|
|
1359
|
-
]),
|
|
1360
|
-
]);
|
|
1328
|
+
const go = await openDialog({
|
|
1329
|
+
title: `Add ${file} to MEMORY.md`,
|
|
1330
|
+
body: [
|
|
1331
|
+
node('p', { class: ui.noteTight, text: preview.hasIndex
|
|
1332
|
+
? 'MEMORY.md is loaded at the start of every session, so a memory with no bullet here is one Claude never sees. This adds one line and nothing else.'
|
|
1333
|
+
: 'This project has no MEMORY.md yet. Adding this entry creates one.' }),
|
|
1334
|
+
node('label', { class: ui.willTitle, text: 'Title' }),
|
|
1335
|
+
titleInput,
|
|
1336
|
+
node('label', { class: ui.willTitle, text: 'Hook' }),
|
|
1337
|
+
hook,
|
|
1338
|
+
node('label', { class: ui.willTitle, text: 'Section' }),
|
|
1339
|
+
picker,
|
|
1340
|
+
node('div', { class: ui.willBlock }, [
|
|
1341
|
+
node('div', { class: ui.willTitle, text: 'Will be added' }),
|
|
1342
|
+
line,
|
|
1343
|
+
]),
|
|
1344
|
+
],
|
|
1345
|
+
actions: [
|
|
1346
|
+
{ label: 'Cancel' },
|
|
1347
|
+
{ label: 'Add entry', tone: 'primary', value: true },
|
|
1348
|
+
],
|
|
1349
|
+
focus: titleInput,
|
|
1350
|
+
});
|
|
1351
|
+
if (!go) return;
|
|
1361
1352
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1353
|
+
await runIndexEdit(
|
|
1354
|
+
'index/add',
|
|
1355
|
+
{ file, section: picker.value || null, title: titleInput.value, hook: hook.value },
|
|
1356
|
+
() => 'Added to MEMORY.md',
|
|
1357
|
+
);
|
|
1366
1358
|
}
|
|
1367
1359
|
|
|
1368
1360
|
async function openMergeDialog(into, from) {
|
|
@@ -1379,8 +1371,8 @@ async function openMergeDialog(into, from) {
|
|
|
1379
1371
|
const heading = node('input', { type: 'text', class: ui.pathInput, spellcheck: 'false' });
|
|
1380
1372
|
heading.value = preview.heading;
|
|
1381
1373
|
|
|
1382
|
-
const body =
|
|
1383
|
-
body.
|
|
1374
|
+
const body = [];
|
|
1375
|
+
body.push(node('p', { class: ui.noteTight, text: `Everything in "${preview.fromName}" moves into "${preview.intoName}" under a new heading, and "${preview.fromName}" goes to the trash. This rewrites prose, which nothing else in this app does - the whole operation is one undo.` }));
|
|
1384
1376
|
|
|
1385
1377
|
const changes = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: 'Will change' })]);
|
|
1386
1378
|
changes.append(node('div', { class: ui.willItem('keep'), text: `${preview.into} + ${preview.bodyLines} line(s) from ${preview.from}` }));
|
|
@@ -1390,7 +1382,7 @@ async function openMergeDialog(into, from) {
|
|
|
1390
1382
|
for (const link of preview.selfLinks) {
|
|
1391
1383
|
changes.append(node('div', { class: ui.willItem('keep'), text: `${preview.into} [[${link}]] → plain text, to avoid a self-link` }));
|
|
1392
1384
|
}
|
|
1393
|
-
body.
|
|
1385
|
+
body.push(changes);
|
|
1394
1386
|
|
|
1395
1387
|
const removals = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: 'Will be removed' })]);
|
|
1396
1388
|
removals.append(node('div', { class: ui.willItem('remove'), text: `memory/${preview.from} → memory/.trash/` }));
|
|
@@ -1400,7 +1392,7 @@ async function openMergeDialog(into, from) {
|
|
|
1400
1392
|
if (!preview.indexLines.length) {
|
|
1401
1393
|
removals.append(node('div', { class: ui.willItem(), text: 'MEMORY.md has no index bullet for the source - nothing to remove there.' }));
|
|
1402
1394
|
}
|
|
1403
|
-
body.
|
|
1395
|
+
body.push(removals);
|
|
1404
1396
|
|
|
1405
1397
|
if (preview.inlineRefs.length) {
|
|
1406
1398
|
const kept = node('div', { class: ui.willBlock }, [
|
|
@@ -1409,45 +1401,35 @@ async function openMergeDialog(into, from) {
|
|
|
1409
1401
|
for (const ref of preview.inlineRefs) {
|
|
1410
1402
|
kept.append(node('div', { class: ui.willItem('keep'), text: `MEMORY.md line ${ref.index + 1}: ${ref.text}` }));
|
|
1411
1403
|
}
|
|
1412
|
-
body.
|
|
1404
|
+
body.push(kept);
|
|
1413
1405
|
}
|
|
1414
1406
|
|
|
1415
|
-
body.
|
|
1407
|
+
body.push(node('label', { class: ui.willTitle, text: 'Heading for the merged section' }), heading);
|
|
1416
1408
|
|
|
1417
|
-
const
|
|
1418
|
-
|
|
1419
|
-
node('h3', { class: ui.modalTitle, text: `Merge "${preview.fromName}" into "${preview.intoName}"?` }),
|
|
1420
|
-
]),
|
|
1409
|
+
const go = await openDialog({
|
|
1410
|
+
title: `Merge "${preview.fromName}" into "${preview.intoName}"?`,
|
|
1421
1411
|
body,
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
try {
|
|
1430
|
-
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/merge`, {
|
|
1431
|
-
method: 'POST',
|
|
1432
|
-
body: JSON.stringify({ into, from, heading: heading.value }),
|
|
1433
|
-
});
|
|
1434
|
-
if (state.selected === from) state.selected = into;
|
|
1435
|
-
await openStore(state.storeId, { keepTab: true });
|
|
1436
|
-
toast(`Merged into ${preview.intoName}`, {
|
|
1437
|
-
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1438
|
-
});
|
|
1439
|
-
} catch (err) {
|
|
1440
|
-
toast(err.message, { error: true });
|
|
1441
|
-
}
|
|
1442
|
-
},
|
|
1443
|
-
}),
|
|
1444
|
-
]),
|
|
1445
|
-
]);
|
|
1412
|
+
actions: [
|
|
1413
|
+
{ label: 'Cancel' },
|
|
1414
|
+
{ label: 'Merge', tone: 'primary', value: true },
|
|
1415
|
+
],
|
|
1416
|
+
focus: heading,
|
|
1417
|
+
});
|
|
1418
|
+
if (!go) return;
|
|
1446
1419
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1420
|
+
try {
|
|
1421
|
+
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/merge`, {
|
|
1422
|
+
method: 'POST',
|
|
1423
|
+
body: JSON.stringify({ into, from, heading: heading.value }),
|
|
1424
|
+
});
|
|
1425
|
+
if (state.selected === from) state.selected = into;
|
|
1426
|
+
await openStore(state.storeId, { keepTab: true });
|
|
1427
|
+
toast(`Merged into ${preview.intoName}`, {
|
|
1428
|
+
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1429
|
+
});
|
|
1430
|
+
} catch (err) {
|
|
1431
|
+
toast(err.message, { error: true });
|
|
1432
|
+
}
|
|
1451
1433
|
}
|
|
1452
1434
|
|
|
1453
1435
|
async function restoreFromTrash(id) {
|
|
@@ -1498,10 +1480,6 @@ function renderTrash(container) {
|
|
|
1498
1480
|
}
|
|
1499
1481
|
}
|
|
1500
1482
|
|
|
1501
|
-
function closeModal() {
|
|
1502
|
-
el('modal-root').textContent = '';
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
1483
|
async function openDeleteDialog(file) {
|
|
1506
1484
|
let preview;
|
|
1507
1485
|
try {
|
|
@@ -1513,7 +1491,7 @@ async function openDeleteDialog(file) {
|
|
|
1513
1491
|
return toast(err.message, { error: true });
|
|
1514
1492
|
}
|
|
1515
1493
|
|
|
1516
|
-
const body =
|
|
1494
|
+
const body = [];
|
|
1517
1495
|
|
|
1518
1496
|
const removals = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: 'Will be removed' })]);
|
|
1519
1497
|
removals.append(node('div', { class: ui.willItem('remove'), text: `memory/${preview.file} → memory/.trash/` }));
|
|
@@ -1523,14 +1501,14 @@ async function openDeleteDialog(file) {
|
|
|
1523
1501
|
if (!preview.indexLines.length && preview.hasIndex) {
|
|
1524
1502
|
removals.append(node('div', { class: ui.willItem(), text: 'MEMORY.md has no index bullet for this file - nothing to unlink there.' }));
|
|
1525
1503
|
}
|
|
1526
|
-
body.
|
|
1504
|
+
body.push(removals);
|
|
1527
1505
|
|
|
1528
1506
|
if (preview.inlineRefs.length) {
|
|
1529
1507
|
const kept = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: 'Left untouched - mentioned inside prose, so you may want to fix these by hand' })]);
|
|
1530
1508
|
for (const ref of preview.inlineRefs) {
|
|
1531
1509
|
kept.append(node('div', { class: ui.willItem('keep'), text: `MEMORY.md line ${ref.index + 1}: ${ref.text}` }));
|
|
1532
1510
|
}
|
|
1533
|
-
body.
|
|
1511
|
+
body.push(kept);
|
|
1534
1512
|
}
|
|
1535
1513
|
|
|
1536
1514
|
const cascade = new Set();
|
|
@@ -1566,7 +1544,7 @@ async function openDeleteDialog(file) {
|
|
|
1566
1544
|
}
|
|
1567
1545
|
block.append(list);
|
|
1568
1546
|
block.append(node('p', { class: ui.noteTight, text: 'Tick any you also want deleted - they go to the trash together and restore as one step.' }));
|
|
1569
|
-
body.
|
|
1547
|
+
body.push(block);
|
|
1570
1548
|
|
|
1571
1549
|
selectAll.onclick = (event) => {
|
|
1572
1550
|
event.preventDefault();
|
|
@@ -1578,52 +1556,39 @@ async function openDeleteDialog(file) {
|
|
|
1578
1556
|
};
|
|
1579
1557
|
}
|
|
1580
1558
|
|
|
1581
|
-
body.
|
|
1582
|
-
|
|
1583
|
-
const confirmButton = node('button', {
|
|
1584
|
-
class: ui.button({ tone: 'danger' }),
|
|
1585
|
-
text: 'Delete',
|
|
1586
|
-
onclick: async () => {
|
|
1587
|
-
closeModal();
|
|
1588
|
-
try {
|
|
1589
|
-
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/delete`, {
|
|
1590
|
-
method: 'POST',
|
|
1591
|
-
body: JSON.stringify({ file, alsoDelete: [...cascade] }),
|
|
1592
|
-
});
|
|
1593
|
-
if (state.selected === file || cascade.has(state.selected)) state.selected = null;
|
|
1594
|
-
await openStore(state.storeId, { keepTab: true });
|
|
1595
|
-
const count = result.record.files.length;
|
|
1596
|
-
toast(count > 1 ? `Deleted ${count} memories` : `Deleted "${result.record.label || file}"`, {
|
|
1597
|
-
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1598
|
-
});
|
|
1599
|
-
} catch (err) {
|
|
1600
|
-
toast(err.message, { error: true });
|
|
1601
|
-
}
|
|
1602
|
-
},
|
|
1603
|
-
});
|
|
1559
|
+
body.push(node('p', { class: ui.noteTight, text: 'The file moves to memory/.trash/ with a restore record, so this can be undone.' }));
|
|
1604
1560
|
|
|
1605
|
-
const
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
]),
|
|
1561
|
+
const remove = { label: 'Delete', tone: 'danger', value: true };
|
|
1562
|
+
const answer = openDialog({
|
|
1563
|
+
title: `Delete "${preview.name || preview.file}"?`,
|
|
1564
|
+
subtitle: preview.description || '',
|
|
1610
1565
|
body,
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
confirmButton,
|
|
1614
|
-
]),
|
|
1615
|
-
]);
|
|
1616
|
-
|
|
1617
|
-
const backdrop = node('div', { class: ui.modalBackdrop, onclick: (event) => { if (event.target === backdrop) closeModal(); } }, [modal]);
|
|
1618
|
-
el('modal-root').append(backdrop);
|
|
1566
|
+
actions: [{ label: 'Cancel' }, remove],
|
|
1567
|
+
});
|
|
1619
1568
|
updateButton();
|
|
1569
|
+
if (!await answer) return;
|
|
1570
|
+
|
|
1571
|
+
try {
|
|
1572
|
+
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/delete`, {
|
|
1573
|
+
method: 'POST',
|
|
1574
|
+
body: JSON.stringify({ file, alsoDelete: [...cascade] }),
|
|
1575
|
+
});
|
|
1576
|
+
if (state.selected === file || cascade.has(state.selected)) state.selected = null;
|
|
1577
|
+
await openStore(state.storeId, { keepTab: true });
|
|
1578
|
+
const count = result.record.files.length;
|
|
1579
|
+
toast(count > 1 ? `Deleted ${count} memories` : `Deleted "${result.record.label || file}"`, {
|
|
1580
|
+
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1581
|
+
});
|
|
1582
|
+
} catch (err) {
|
|
1583
|
+
toast(err.message, { error: true });
|
|
1584
|
+
}
|
|
1620
1585
|
|
|
1621
1586
|
function updateButton() {
|
|
1622
|
-
|
|
1587
|
+
remove.el.textContent = cascade.size ? `Delete ${cascade.size + 1} memories` : 'Delete';
|
|
1623
1588
|
}
|
|
1624
1589
|
}
|
|
1625
1590
|
|
|
1626
|
-
function openRememberPathDialog() {
|
|
1591
|
+
async function openRememberPathDialog() {
|
|
1627
1592
|
const store = state.store;
|
|
1628
1593
|
const input = node('input', {
|
|
1629
1594
|
type: 'text',
|
|
@@ -1633,44 +1598,42 @@ function openRememberPathDialog() {
|
|
|
1633
1598
|
spellcheck: 'false',
|
|
1634
1599
|
});
|
|
1635
1600
|
|
|
1636
|
-
const
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
onclick: async () => {
|
|
1601
|
+
const remembered = await openDialog({
|
|
1602
|
+
title: 'Remember this project\u2019s path',
|
|
1603
|
+
body: [
|
|
1604
|
+
node('p', { class: ui.note, text: `The folder on disk is "${store.slug}", and its name is a lossy encoding of a path. No session transcript remains to recover the real one from, so tell it once and it will be used from now on.` }),
|
|
1605
|
+
input,
|
|
1606
|
+
node('p', { class: ui.noteTight, text: 'Saved to ~/.claude-memory-admin/paths.json. That file records slugs and folder paths only, never memory content, and is the one thing this app writes outside a memory/ directory.' }),
|
|
1607
|
+
],
|
|
1608
|
+
actions: [
|
|
1609
|
+
{ label: 'Cancel' },
|
|
1610
|
+
{
|
|
1611
|
+
label: 'Remember',
|
|
1612
|
+
tone: 'primary',
|
|
1613
|
+
value: true,
|
|
1614
|
+
guard: async () => {
|
|
1651
1615
|
const value = input.value.trim();
|
|
1652
|
-
if (!value) return;
|
|
1616
|
+
if (!value) return false;
|
|
1653
1617
|
try {
|
|
1654
1618
|
await api(`/api/stores/${encodeURIComponent(state.storeId)}/path/remember`, {
|
|
1655
1619
|
method: 'POST',
|
|
1656
1620
|
body: JSON.stringify({ path: value }),
|
|
1657
1621
|
});
|
|
1658
1622
|
} catch (err) {
|
|
1659
|
-
|
|
1623
|
+
toast(err.message, { error: true });
|
|
1624
|
+
return false;
|
|
1660
1625
|
}
|
|
1661
|
-
|
|
1662
|
-
await reloadStores();
|
|
1663
|
-
await openStore(state.storeId, { keepTab: true });
|
|
1664
|
-
toast(`Remembered ${value}`);
|
|
1626
|
+
return true;
|
|
1665
1627
|
},
|
|
1666
|
-
}
|
|
1667
|
-
]
|
|
1668
|
-
|
|
1628
|
+
},
|
|
1629
|
+
],
|
|
1630
|
+
focus: input,
|
|
1631
|
+
});
|
|
1632
|
+
if (!remembered) return;
|
|
1669
1633
|
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
input.
|
|
1673
|
-
input.select();
|
|
1634
|
+
await reloadStores();
|
|
1635
|
+
await openStore(state.storeId, { keepTab: true });
|
|
1636
|
+
toast(`Remembered ${input.value.trim()}`);
|
|
1674
1637
|
}
|
|
1675
1638
|
|
|
1676
1639
|
async function forgetProjectPath() {
|
|
@@ -1696,7 +1659,7 @@ async function openStoreDeleteDialog() {
|
|
|
1696
1659
|
return toast('This store has no memory to delete');
|
|
1697
1660
|
}
|
|
1698
1661
|
|
|
1699
|
-
const body =
|
|
1662
|
+
const body = [];
|
|
1700
1663
|
const removals = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: 'Will be removed' })]);
|
|
1701
1664
|
if (preview.hasIndex) {
|
|
1702
1665
|
removals.append(node('div', { class: ui.willItem('remove'), text: `MEMORY.md (${preview.indexLines} lines) → memory/.trash/` }));
|
|
@@ -1704,51 +1667,42 @@ async function openStoreDeleteDialog() {
|
|
|
1704
1667
|
for (const entry of preview.files) {
|
|
1705
1668
|
removals.append(node('div', { class: ui.willItem('remove'), text: `${entry.file} → memory/.trash/` }));
|
|
1706
1669
|
}
|
|
1707
|
-
body.
|
|
1670
|
+
body.push(removals);
|
|
1708
1671
|
|
|
1709
|
-
body.
|
|
1672
|
+
body.push(node('div', { class: ui.willBlock }, [
|
|
1710
1673
|
node('div', { class: ui.willTitle, text: 'Will be kept' }),
|
|
1711
1674
|
node('div', { class: ui.willItem('keep'), text: state.store.kind === 'auto'
|
|
1712
1675
|
? 'Session transcripts (*.jsonl) and the project folder itself'
|
|
1713
1676
|
: 'The agent-memory folder itself, and every other agent\u2019s memory' }),
|
|
1714
1677
|
]));
|
|
1715
1678
|
|
|
1716
|
-
body.
|
|
1679
|
+
body.push(node('p', { class: ui.noteTight, text: 'Everything moves to .trash/ inside the store as one restore point, so it can be put back in a single step from the Trash tab.' }));
|
|
1717
1680
|
|
|
1718
1681
|
if (state.store.kind === 'agent-project') {
|
|
1719
|
-
body.
|
|
1682
|
+
body.push(node('p', { class: ui.subWarn, text: 'This store is checked into the repository. Deleting from it changes tracked files, and will show up in git status.' }));
|
|
1720
1683
|
}
|
|
1721
1684
|
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
node('p', { class: ui.note, text: `${preview.files.length} memories${preview.hasIndex ? ' + MEMORY.md' : ''}` }),
|
|
1726
|
-
]),
|
|
1685
|
+
const go = await openDialog({
|
|
1686
|
+
title: `Delete all memory for ${state.store.label}?`,
|
|
1687
|
+
subtitle: `${preview.files.length} memories${preview.hasIndex ? ' + MEMORY.md' : ''}`,
|
|
1727
1688
|
body,
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
closeModal();
|
|
1735
|
-
try {
|
|
1736
|
-
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/project/delete`, { method: 'POST' });
|
|
1737
|
-
state.selected = null;
|
|
1738
|
-
await openStore(state.storeId, { keepTab: true });
|
|
1739
|
-
toast(`Cleared ${state.store.label}`, {
|
|
1740
|
-
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1741
|
-
});
|
|
1742
|
-
} catch (err) {
|
|
1743
|
-
toast(err.message, { error: true });
|
|
1744
|
-
}
|
|
1745
|
-
},
|
|
1746
|
-
}),
|
|
1747
|
-
]),
|
|
1748
|
-
]);
|
|
1689
|
+
actions: [
|
|
1690
|
+
{ label: 'Cancel' },
|
|
1691
|
+
{ label: `Delete ${preview.files.length + (preview.hasIndex ? 1 : 0)} files`, tone: 'danger', value: true },
|
|
1692
|
+
],
|
|
1693
|
+
});
|
|
1694
|
+
if (!go) return;
|
|
1749
1695
|
|
|
1750
|
-
|
|
1751
|
-
|
|
1696
|
+
try {
|
|
1697
|
+
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/project/delete`, { method: 'POST' });
|
|
1698
|
+
state.selected = null;
|
|
1699
|
+
await openStore(state.storeId, { keepTab: true });
|
|
1700
|
+
toast(`Cleared ${state.store.label}`, {
|
|
1701
|
+
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1702
|
+
});
|
|
1703
|
+
} catch (err) {
|
|
1704
|
+
toast(err.message, { error: true });
|
|
1705
|
+
}
|
|
1752
1706
|
}
|
|
1753
1707
|
|
|
1754
1708
|
function highlight(text, terms) {
|
|
@@ -1958,12 +1912,12 @@ async function openBulkDeleteDialog(files) {
|
|
|
1958
1912
|
if (!files.length) return;
|
|
1959
1913
|
const memories = files.map((file) => state.store.memories.find((m) => m.file === file)).filter(Boolean);
|
|
1960
1914
|
|
|
1961
|
-
const body =
|
|
1915
|
+
const body = [];
|
|
1962
1916
|
const removals = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: `${memories.length} memories will be trashed` })]);
|
|
1963
1917
|
for (const memory of memories) {
|
|
1964
1918
|
removals.append(node('div', { class: ui.willItem('remove'), text: `${memory.file}${memory.entry ? ` · MEMORY.md line ${memory.entry.index + 1}` : ' · not in the index'}` }));
|
|
1965
1919
|
}
|
|
1966
|
-
body.
|
|
1920
|
+
body.push(removals);
|
|
1967
1921
|
|
|
1968
1922
|
const doomed = new Set(files);
|
|
1969
1923
|
const breaking = [];
|
|
@@ -1975,41 +1929,35 @@ async function openBulkDeleteDialog(files) {
|
|
|
1975
1929
|
if (breaking.length) {
|
|
1976
1930
|
const block = node('div', { class: ui.willBlock }, [node('div', { class: ui.willTitle, text: `${breaking.length} link(s) from memories you are keeping will break` })]);
|
|
1977
1931
|
for (const link of breaking) block.append(node('div', { class: ui.willItem('keep'), text: `${link.from} → [[${link.target}]]` }));
|
|
1978
|
-
body.
|
|
1932
|
+
body.push(block);
|
|
1979
1933
|
}
|
|
1980
1934
|
|
|
1981
|
-
body.
|
|
1935
|
+
body.push(node('p', { class: ui.noteTight, text: 'All of them go to memory/.trash/ as one restore point.' }));
|
|
1982
1936
|
|
|
1983
|
-
const
|
|
1984
|
-
|
|
1937
|
+
const go = await openDialog({
|
|
1938
|
+
title: `Delete ${memories.length} memories?`,
|
|
1985
1939
|
body,
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
},
|
|
2008
|
-
}),
|
|
2009
|
-
]),
|
|
2010
|
-
]);
|
|
2011
|
-
const backdrop = node('div', { class: ui.modalBackdrop, onclick: (event) => { if (event.target === backdrop) closeModal(); } }, [modal]);
|
|
2012
|
-
el('modal-root').append(backdrop);
|
|
1940
|
+
actions: [
|
|
1941
|
+
{ label: 'Cancel' },
|
|
1942
|
+
{ label: `Delete ${memories.length}`, tone: 'danger', value: true },
|
|
1943
|
+
],
|
|
1944
|
+
});
|
|
1945
|
+
if (!go) return;
|
|
1946
|
+
|
|
1947
|
+
try {
|
|
1948
|
+
const result = await api(`/api/stores/${encodeURIComponent(state.storeId)}/delete-many`, {
|
|
1949
|
+
method: 'POST',
|
|
1950
|
+
body: JSON.stringify({ files, label: `${memories.length} pruned memories` }),
|
|
1951
|
+
});
|
|
1952
|
+
state.pruneSelection.clear();
|
|
1953
|
+
if (doomed.has(state.selected)) state.selected = null;
|
|
1954
|
+
await openStore(state.storeId, { keepTab: true });
|
|
1955
|
+
toast(`Deleted ${memories.length} memories`, {
|
|
1956
|
+
action: { label: 'Undo', run: () => restoreFromTrash(result.record.id) },
|
|
1957
|
+
});
|
|
1958
|
+
} catch (err) {
|
|
1959
|
+
toast(err.message, { error: true });
|
|
1960
|
+
}
|
|
2013
1961
|
}
|
|
2014
1962
|
|
|
2015
1963
|
let searchTimer = null;
|
|
@@ -2393,6 +2341,7 @@ async function init() {
|
|
|
2393
2341
|
paintTheme();
|
|
2394
2342
|
});
|
|
2395
2343
|
document.addEventListener('keydown', (event) => {
|
|
2344
|
+
if (isDialogOpen()) return;
|
|
2396
2345
|
const typing = /^(INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName);
|
|
2397
2346
|
if (event.key === '/' && !typing) {
|
|
2398
2347
|
event.preventDefault();
|
|
@@ -2407,8 +2356,7 @@ async function init() {
|
|
|
2407
2356
|
return;
|
|
2408
2357
|
}
|
|
2409
2358
|
if (event.key === 'Escape') {
|
|
2410
|
-
if (
|
|
2411
|
-
else if (state.search !== null) clearSearch();
|
|
2359
|
+
if (state.search !== null) clearSearch();
|
|
2412
2360
|
else if (!state.collapsed) setCollapsed(true);
|
|
2413
2361
|
}
|
|
2414
2362
|
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as ui from '/ui.mjs';
|
|
2
|
+
import { el, node } from '/dom.mjs';
|
|
3
|
+
|
|
4
|
+
const root = () => el('dialog-root');
|
|
5
|
+
|
|
6
|
+
const TEXT_ENTRY = /^(text|search|url|email|tel|number|password)$/;
|
|
7
|
+
|
|
8
|
+
export const isDialogOpen = () => Boolean(root().firstElementChild);
|
|
9
|
+
|
|
10
|
+
export function openDialog({ title, subtitle, body, actions, focus }) {
|
|
11
|
+
const previous = root().firstElementChild;
|
|
12
|
+
if (previous) {
|
|
13
|
+
previous.close();
|
|
14
|
+
previous.remove();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const dialog = node('dialog', { class: ui.dialog, 'aria-labelledby': 'dialog-title' });
|
|
18
|
+
const primary = actions[actions.length - 1];
|
|
19
|
+
let outcome = null;
|
|
20
|
+
|
|
21
|
+
const buttons = actions.map((action) => {
|
|
22
|
+
const button = node('button', {
|
|
23
|
+
class: ui.button({ tone: action.tone }),
|
|
24
|
+
text: action.label,
|
|
25
|
+
onclick: async () => {
|
|
26
|
+
if (action.guard) {
|
|
27
|
+
for (const other of actions) other.el.disabled = true;
|
|
28
|
+
const passed = await action.guard();
|
|
29
|
+
for (const other of actions) other.el.disabled = false;
|
|
30
|
+
if (!passed) return;
|
|
31
|
+
}
|
|
32
|
+
outcome = action.value ?? null;
|
|
33
|
+
dialog.close();
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
action.el = button;
|
|
37
|
+
return button;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
dialog.append(
|
|
41
|
+
node('header', { class: ui.dialogHead }, [
|
|
42
|
+
node('h3', { id: 'dialog-title', class: ui.dialogTitle, text: title }),
|
|
43
|
+
subtitle ? node('p', { class: ui.note, text: subtitle }) : null,
|
|
44
|
+
]),
|
|
45
|
+
node('div', { class: ui.dialogBody }, [].concat(body)),
|
|
46
|
+
node('footer', { class: ui.dialogFoot }, buttons),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
dialog.addEventListener('click', (event) => {
|
|
50
|
+
if (event.target === dialog) dialog.close();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
dialog.addEventListener('keydown', (event) => {
|
|
54
|
+
if (event.key === 'Enter' && TEXT_ENTRY.test(event.target.type || '')) {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
primary.el.click();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
dialog.addEventListener('close', () => {
|
|
62
|
+
dialog.remove();
|
|
63
|
+
resolve(outcome);
|
|
64
|
+
});
|
|
65
|
+
root().append(dialog);
|
|
66
|
+
dialog.showModal();
|
|
67
|
+
if (focus) {
|
|
68
|
+
focus.focus();
|
|
69
|
+
focus.select?.();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function confirmDialog({ title, subtitle, body, confirmLabel = 'Confirm', tone = 'primary' }) {
|
|
75
|
+
return openDialog({
|
|
76
|
+
title,
|
|
77
|
+
subtitle,
|
|
78
|
+
body,
|
|
79
|
+
actions: [
|
|
80
|
+
{ label: 'Cancel' },
|
|
81
|
+
{ label: confirmLabel, tone, value: true },
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
}
|
package/public/dom.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const el = (id) => document.getElementById(id);
|
|
2
|
+
|
|
3
|
+
export function node(tag, props = {}, children = []) {
|
|
4
|
+
const element = document.createElement(tag);
|
|
5
|
+
for (const [key, value] of Object.entries(props)) {
|
|
6
|
+
if (key === 'class') element.className = value;
|
|
7
|
+
else if (key === 'text') element.textContent = value;
|
|
8
|
+
else if (key.startsWith('on')) element.addEventListener(key.slice(2).toLowerCase(), value);
|
|
9
|
+
else if (value !== null && value !== undefined) element.setAttribute(key, value);
|
|
10
|
+
}
|
|
11
|
+
for (const child of [].concat(children)) {
|
|
12
|
+
if (child) element.append(child);
|
|
13
|
+
}
|
|
14
|
+
return element;
|
|
15
|
+
}
|
package/public/index.html
CHANGED
package/public/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-content:"";--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;--font-mono:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--color-red-50:oklch(97.1% .013 17.4);--color-red-300:oklch(80.8% .114 19.6);--color-red-400:oklch(70.4% .16 22.2);--color-red-500:oklch(63.7% .208 25.3);--color-red-600:oklch(57.7% .215 27.3);--color-red-950:oklch(25.8% .092 26);--color-amber-50:oklch(97.7% .021 84.6);--color-amber-300:oklch(87.9% .153 91.6);--color-amber-400:oklch(82.8% .171 84.4);--color-amber-600:oklch(66.6% .15 58.3);--color-amber-700:oklch(55.5% .13 49);--color-amber-950:oklch(27.9% .077 45.6);--color-green-50:oklch(98.2% .018 155.8);--color-green-300:oklch(87.1% .12 154.4);--color-green-400:oklch(79.2% .15 151.7);--color-green-600:oklch(58.5% .145 149.2);--color-green-700:oklch(52.7% .132 150.1);--color-green-950:oklch(26.6% .065 152.9);--color-blue-50:oklch(97% .014 253.3);--color-blue-200:oklch(88% .06 253.3);--color-blue-300:oklch(78.4% .124 239.1);--color-blue-400:oklch(75.2% .138 243.7);--color-blue-600:oklch(56.5% .163 253.3);--color-blue-700:oklch(48.5% .15 253.3);--color-blue-800:oklch(41% .125 253.3);--color-blue-950:oklch(24% .07 253.3);--color-violet-50:oklch(96.9% .016 300);--color-violet-300:oklch(82.7% .104 300);--color-violet-700:oklch(49.6% .19 300);--color-violet-950:oklch(28.3% .109 300);--color-slate-50:oklch(98.4% .003 253.3);--color-slate-100:oklch(96.4% .005 253.3);--color-slate-200:oklch(92.6% .009 253.3);--color-slate-300:oklch(86.6% .014 253.3);--color-slate-400:oklch(70.4% .021 253.3);--color-slate-500:oklch(55.6% .026 253.3);--color-slate-600:oklch(44.8% .028 253.3);--color-slate-700:oklch(36.8% .028 253.3);--color-slate-800:oklch(26.4% .026 253.3);--color-slate-900:oklch(20.4% .024 253.3);--color-slate-950:oklch(14.2% .022 253.3);--spacing:.25rem;--container-2xl:42rem;--text-xs:.6875rem;--text-xs--line-height:1.45;--text-sm:.8125rem;--text-sm--line-height:1.5;--text-base:.875rem;--text-base--line-height:1.6;--text-lg:1rem;--text-lg--line-height:1.5;--text-xl:1.25rem;--text-xl--line-height:1.3;--text-2xl:1.5rem;--text-2xl--line-height:1.2;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-widest:.12em;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--default-transition-duration:.12s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-slate-0:oklch(100% 0 253.3);--spacing-control-x-sm:calc(var(--spacing) * 2);--spacing-control-y-sm:calc(var(--spacing) * 1);--spacing-control-x-md:calc(var(--spacing) * 3);--spacing-control-y-md:calc(var(--spacing) * 2);--spacing-control-x-lg:calc(var(--spacing) * 3.5);--spacing-control-y-lg:calc(var(--spacing) * 2.5);--spacing-control-h-sm:calc(var(--spacing) * 6.5);--spacing-control-h-md:calc(var(--spacing) * 9.5);--spacing-control-h-lg:calc(var(--spacing) * 9.5);--text-2xs:.625rem;--text-2xs--line-height:1.4;--tracking-tightest:-.03em}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{color-scheme:light}:root[data-theme=dark]{color-scheme:dark}html,body{height:100%}body{background-color:var(--ui-canvas);color:var(--ui-fg);font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--text-base--line-height)}::selection{background-color:var(--ui-accent-surface);color:var(--ui-accent)}:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}}@layer components{.prose{overflow-wrap:anywhere}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}.prose h1,.prose h2,.prose h3,.prose h4{margin:calc(var(--spacing) * 6) 0 calc(var(--spacing) * 2);letter-spacing:var(--tracking-tightest);font-weight:650;line-height:1.25}.prose h1{font-size:var(--text-lg)}.prose h2{font-size:var(--text-base);padding-bottom:calc(var(--spacing) * 1.5);border-bottom:1px solid var(--ui-line)}.prose h3,.prose h4{font-size:var(--text-base);color:var(--ui-fg-muted)}.prose p{margin:calc(var(--spacing) * 3) 0}.prose ul,.prose ol{margin:calc(var(--spacing) * 3) 0;padding-left:calc(var(--spacing) * 5)}.prose ul{list-style-type:"– "}.prose ol{list-style-type:decimal}.prose li{margin:calc(var(--spacing) * 1) 0}.prose li::marker{color:var(--ui-accent);font-family:var(--font-mono)}.prose li>ul,.prose li>ol{margin:calc(var(--spacing) * 1) 0}.prose a{color:var(--ui-accent);text-underline-offset:2px;text-decoration:underline}.prose a:hover{color:var(--ui-accent-hover)}.prose strong{color:var(--ui-fg);font-weight:650}.prose pre{margin:calc(var(--spacing) * 3) 0;padding:calc(var(--spacing) * 3);border:1px solid var(--ui-line);border-radius:var(--radius-md);background-color:var(--ui-surface-sunken);font-size:var(--text-xs);line-height:1.6;overflow-x:auto}.prose code{font-family:var(--font-mono);font-size:.9em}.prose :not(pre)>code{border:1px solid var(--ui-line);border-radius:var(--radius-sm);background-color:var(--ui-surface-sunken);color:var(--ui-accent);padding:1px 4px}.prose blockquote{margin:calc(var(--spacing) * 3) 0;padding-left:calc(var(--spacing) * 3);border-left:2px solid var(--ui-accent-line);color:var(--ui-fg-muted)}.prose hr{margin:calc(var(--spacing) * 5) 0;border:0;border-top:1px dashed var(--ui-line-strong)}.prose table{margin:calc(var(--spacing) * 3) 0;border-collapse:collapse;font-size:var(--text-sm);display:block;overflow-x:auto}.prose th,.prose td{padding:calc(var(--spacing) * 1.5) calc(var(--spacing) * 2.5);border:1px solid var(--ui-line);text-align:left}.prose th{background-color:var(--ui-surface-sunken);font-weight:600}.graph svg{cursor:grab;width:100%;display:block}.graph .node circle{cursor:pointer;stroke-width:1.5px}.graph .node circle.hit{fill:#0000;stroke:none}.graph .node text{fill:var(--ui-fg-muted);font-family:var(--font-mono);pointer-events:none;font-size:9px}.graph .node.hi circle{stroke:var(--ui-accent);stroke-width:2.5px}.graph .node.hi text{fill:var(--ui-fg);font-weight:600}.graph .node.dim{opacity:.18}.graph .node.dim text{display:none}.graph .edge{stroke:var(--ui-line-strong)}.graph .edge.dim{opacity:.05}}@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-y-0{inset-block:0}.top-0{top:0}.top-2{top:calc(var(--spacing) * 2)}.top-3{top:calc(var(--spacing) * 3)}.top-3\.5{top:calc(var(--spacing) * 3.5)}.right-3\.5{right:calc(var(--spacing) * 3.5)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-5{bottom:calc(var(--spacing) * 5)}.left-0{left:0}.left-1\/2{left:50%}.left-3\.5{left:calc(var(--spacing) * 3.5)}.z-10{z-index:10}.z-20{z-index:20}.z-100{z-index:100}.z-200{z-index:200}.float-right{float:right}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.my-1{margin-block:var(--spacing)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.mt-0{margin-top:0}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-3\.5{margin-bottom:calc(var(--spacing) * 3.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.h-2{height:calc(var(--spacing) * 2)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[28rem\]{max-height:28rem}.max-h-\[82vh\]{max-height:82vh}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-control-h-lg{min-height:var(--spacing-control-h-lg)}.min-h-control-h-md{min-height:var(--spacing-control-h-md)}.min-h-control-h-sm{min-height:var(--spacing-control-h-sm)}.w-0\.5{width:calc(var(--spacing) * .5)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.min-w-0{min-width:0}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-control-h-sm{min-width:var(--spacing-control-h-sm)}.flex-1{flex:1}.flex-none{flex:none}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-default{cursor:default}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[3rem_1fr\]{grid-template-columns:3rem 1fr}.grid-cols-\[280px_1fr\]{grid-template-columns:280px 1fr}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-px{gap:1px}.gap-x-3\.5{column-gap:calc(var(--spacing) * 3.5)}.gap-y-1{row-gap:var(--spacing)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-accent{border-color:var(--ui-accent)}.border-accent-line{border-color:var(--ui-accent-line)}.border-current{border-color:currentColor}.border-danger{border-color:var(--ui-danger)}.border-danger-line{border-color:var(--ui-danger-line)}.border-line{border-color:var(--ui-line)}.border-transparent{border-color:#0000}.border-l-danger{border-left-color:var(--ui-danger)}.border-l-warn{border-left-color:var(--ui-warn)}.bg-accent{background-color:var(--ui-accent)}.bg-accent-surface{background-color:var(--ui-accent-surface)}.bg-canvas{background-color:var(--ui-canvas)}.bg-danger{background-color:var(--ui-danger)}.bg-danger-surface{background-color:var(--ui-danger-surface)}.bg-fg{background-color:var(--ui-fg)}.bg-line-strong{background-color:var(--ui-line-strong)}.bg-ok{background-color:var(--ui-ok)}.bg-ok-surface{background-color:var(--ui-ok-surface)}.bg-scope-local-surface{background-color:var(--ui-scope-local-surface)}.bg-scope-managed-surface{background-color:var(--ui-scope-managed-surface)}.bg-scope-project-surface{background-color:var(--ui-scope-project-surface)}.bg-scope-user-surface{background-color:var(--ui-scope-user-surface)}.bg-scrim{background-color:var(--ui-scrim)}.bg-surface{background-color:var(--ui-surface)}.bg-surface-sunken{background-color:var(--ui-surface-sunken)}.bg-transparent{background-color:#0000}.bg-type-feedback-surface{background-color:var(--ui-type-feedback-surface)}.bg-type-project-surface{background-color:var(--ui-type-project-surface)}.bg-type-reference-surface{background-color:var(--ui-type-reference-surface)}.bg-type-user-surface{background-color:var(--ui-type-user-surface)}.bg-warn{background-color:var(--ui-warn)}.bg-warn-surface{background-color:var(--ui-warn-surface)}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-10{padding-inline:calc(var(--spacing) * 10)}.px-control-x-lg{padding-inline:var(--spacing-control-x-lg)}.px-control-x-md{padding-inline:var(--spacing-control-x-md)}.px-control-x-sm{padding-inline:var(--spacing-control-x-sm)}.px-px{padding-inline:1px}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-\[15vh\]{padding-block:15vh}.py-control-y-lg{padding-block:var(--spacing-control-y-lg)}.py-control-y-md{padding-block:var(--spacing-control-y-md)}.py-control-y-sm{padding-block:var(--spacing-control-y-sm)}.py-px{padding-block:1px}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-3\.5{padding-top:calc(var(--spacing) * 3.5)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pb-1{padding-bottom:var(--spacing)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-3\.5{padding-bottom:calc(var(--spacing) * 3.5)}.pb-4\.5{padding-bottom:calc(var(--spacing) * 4.5)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-2xs{font-size:var(--text-2xs);line-height:var(--tw-leading,var(--text-2xs--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tightest{--tw-tracking:var(--tracking-tightest);letter-spacing:var(--tracking-tightest)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--ui-accent)}.text-canvas{color:var(--ui-canvas)}.text-danger{color:var(--ui-danger)}.text-fg{color:var(--ui-fg)}.text-fg-muted{color:var(--ui-fg-muted)}.text-fg-subtle{color:var(--ui-fg-subtle)}.text-ok{color:var(--ui-ok)}.text-on-accent{color:var(--ui-on-accent)}.text-scope-local{color:var(--ui-scope-local)}.text-scope-managed{color:var(--ui-scope-managed)}.text-scope-project{color:var(--ui-scope-project)}.text-scope-user{color:var(--ui-scope-user)}.text-type-feedback{color:var(--ui-type-feedback)}.text-type-project{color:var(--ui-type-project)}.text-type-reference{color:var(--ui-type-reference)}.text-type-user{color:var(--ui-type-user)}.text-warn{color:var(--ui-warn)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-danger{-webkit-text-decoration-color:var(--ui-danger);-webkit-text-decoration-color:var(--ui-danger);text-decoration-color:var(--ui-danger)}.decoration-line-strong{-webkit-text-decoration-color:var(--ui-line-strong);-webkit-text-decoration-color:var(--ui-line-strong);text-decoration-color:var(--ui-line-strong)}.accent-accent{accent-color:var(--ui-accent)}.opacity-45{opacity:.45}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.shadow-card{--tw-shadow:var(--ui-shadow-card);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-pop{--tw-shadow:var(--ui-shadow-pop);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.placeholder\:text-fg-subtle::placeholder{color:var(--ui-fg-subtle)}.before\:flex-1:before{content:var(--tw-content);flex:1}.before\:border-t:before{content:var(--tw-content);border-top-style:var(--tw-border-style);border-top-width:1px}.before\:border-dashed:before{content:var(--tw-content);--tw-border-style:dashed;border-style:dashed}.before\:border-danger:before{content:var(--tw-content);border-color:var(--ui-danger)}.after\:flex-1:after{content:var(--tw-content);flex:1}.after\:border-t:after{content:var(--tw-content);border-top-style:var(--tw-border-style);border-top-width:1px}.after\:border-dashed:after{content:var(--tw-content);--tw-border-style:dashed;border-style:dashed}.after\:border-danger:after{content:var(--tw-content);border-color:var(--ui-danger)}.first\:mt-0:first-child{margin-top:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:border-accent:hover{border-color:var(--ui-accent)}.hover\:border-accent-hover:hover{border-color:var(--ui-accent-hover)}.hover\:border-accent-line:hover{border-color:var(--ui-accent-line)}.hover\:border-line-strong:hover{border-color:var(--ui-line-strong)}.hover\:bg-accent-hover:hover{background-color:var(--ui-accent-hover)}.hover\:bg-danger:hover{background-color:var(--ui-danger)}.hover\:bg-surface-sunken:hover{background-color:var(--ui-surface-sunken)}.hover\:text-accent-hover:hover{color:var(--ui-accent-hover)}.hover\:text-fg:hover{color:var(--ui-fg)}.hover\:text-on-accent:hover{color:var(--ui-on-accent)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-accent:focus{border-color:var(--ui-accent)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-45:disabled{opacity:.45}@media (min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:80rem){.xl\:sticky{position:sticky}.xl\:top-4{top:calc(var(--spacing) * 4)}.xl\:max-h-\[calc\(100vh-9rem\)\]{max-height:calc(100vh - 9rem)}.xl\:grid-cols-\[minmax\(280px\,380px\)_1fr\]{grid-template-columns:minmax(280px,380px) 1fr}.xl\:overflow-y-auto{overflow-y:auto}}.dark\:invert:where([data-theme=dark],[data-theme=dark] *){--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.\[\&\>span\]\:block>span{display:block}}:root{--ui-canvas:var(--color-slate-50);--ui-surface:var(--color-slate-0);--ui-surface-sunken:var(--color-slate-100);--ui-surface-raised:var(--color-slate-0);--ui-line:var(--color-slate-200);--ui-line-strong:var(--color-slate-300);--ui-fg:var(--color-slate-900);--ui-fg-muted:var(--color-slate-500);--ui-fg-subtle:var(--color-slate-400);--ui-accent:var(--color-blue-600);--ui-accent-hover:var(--color-blue-700);--ui-accent-surface:var(--color-blue-50);--ui-accent-line:var(--color-blue-200);--ui-on-accent:var(--color-slate-0);--ui-danger:var(--color-red-600);--ui-danger-surface:var(--color-red-50);--ui-danger-line:var(--color-red-300);--ui-warn:var(--color-amber-700);--ui-warn-surface:var(--color-amber-50);--ui-warn-line:var(--color-amber-300);--ui-ok:var(--color-green-600);--ui-ok-surface:var(--color-green-50);--ui-ok-line:var(--color-green-300);--ui-type-project:var(--color-blue-700);--ui-type-project-surface:var(--color-blue-50);--ui-type-feedback:var(--color-amber-700);--ui-type-feedback-surface:var(--color-amber-50);--ui-type-user:var(--color-violet-700);--ui-type-user-surface:var(--color-violet-50);--ui-type-reference:var(--color-green-700);--ui-type-reference-surface:var(--color-green-50);--ui-scope-managed:var(--color-red-600);--ui-scope-managed-surface:var(--color-red-50);--ui-scope-user:var(--color-blue-700);--ui-scope-user-surface:var(--color-blue-50);--ui-scope-project:var(--color-amber-700);--ui-scope-project-surface:var(--color-amber-50);--ui-scope-local:var(--color-slate-600);--ui-scope-local-surface:var(--color-slate-100);--ui-shadow-card:0 1px 2px #0000000d;--ui-shadow-pop:0 1px 2px #0000000f, 0 12px 32px #0000001a;--ui-scrim:#0f172a73}:root[data-theme=dark]{--ui-canvas:var(--color-slate-950);--ui-surface:var(--color-slate-900);--ui-surface-sunken:var(--color-slate-950);--ui-surface-raised:var(--color-slate-800);--ui-line:var(--color-slate-800);--ui-line-strong:var(--color-slate-700);--ui-fg:var(--color-slate-100);--ui-fg-muted:var(--color-slate-400);--ui-fg-subtle:var(--color-slate-500);--ui-accent:var(--color-blue-400);--ui-accent-hover:var(--color-blue-300);--ui-accent-surface:var(--color-blue-950);--ui-accent-line:var(--color-blue-800);--ui-on-accent:var(--color-slate-950);--ui-danger:var(--color-red-400);--ui-danger-surface:var(--color-red-950);--ui-danger-line:var(--color-red-500);--ui-warn:var(--color-amber-400);--ui-warn-surface:var(--color-amber-950);--ui-warn-line:var(--color-amber-600);--ui-ok:var(--color-green-400);--ui-ok-surface:var(--color-green-950);--ui-ok-line:var(--color-green-600);--ui-type-project:var(--color-blue-300);--ui-type-project-surface:var(--color-blue-950);--ui-type-feedback:var(--color-amber-300);--ui-type-feedback-surface:var(--color-amber-950);--ui-type-user:var(--color-violet-300);--ui-type-user-surface:var(--color-violet-950);--ui-type-reference:var(--color-green-300);--ui-type-reference-surface:var(--color-green-950);--ui-scope-managed:var(--color-red-400);--ui-scope-managed-surface:var(--color-red-950);--ui-scope-user:var(--color-blue-300);--ui-scope-user-surface:var(--color-blue-950);--ui-scope-project:var(--color-amber-300);--ui-scope-project-surface:var(--color-amber-950);--ui-scope-local:var(--color-slate-400);--ui-scope-local-surface:var(--color-slate-800);--ui-shadow-card:0 1px 2px #0006;--ui-shadow-pop:0 1px 2px #00000080, 0 12px 32px #00000073;--ui-scrim:#020610b3}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-content:"";--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;--font-mono:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--color-red-50:oklch(97.1% .013 17.4);--color-red-300:oklch(80.8% .114 19.6);--color-red-400:oklch(70.4% .16 22.2);--color-red-500:oklch(63.7% .208 25.3);--color-red-600:oklch(57.7% .215 27.3);--color-red-950:oklch(25.8% .092 26);--color-amber-50:oklch(97.7% .021 84.6);--color-amber-300:oklch(87.9% .153 91.6);--color-amber-400:oklch(82.8% .171 84.4);--color-amber-600:oklch(66.6% .15 58.3);--color-amber-700:oklch(55.5% .13 49);--color-amber-950:oklch(27.9% .077 45.6);--color-green-50:oklch(98.2% .018 155.8);--color-green-300:oklch(87.1% .12 154.4);--color-green-400:oklch(79.2% .15 151.7);--color-green-600:oklch(58.5% .145 149.2);--color-green-700:oklch(52.7% .132 150.1);--color-green-950:oklch(26.6% .065 152.9);--color-blue-50:oklch(97% .014 253.3);--color-blue-200:oklch(88% .06 253.3);--color-blue-300:oklch(78.4% .124 239.1);--color-blue-400:oklch(75.2% .138 243.7);--color-blue-600:oklch(56.5% .163 253.3);--color-blue-700:oklch(48.5% .15 253.3);--color-blue-800:oklch(41% .125 253.3);--color-blue-950:oklch(24% .07 253.3);--color-violet-50:oklch(96.9% .016 300);--color-violet-300:oklch(82.7% .104 300);--color-violet-700:oklch(49.6% .19 300);--color-violet-950:oklch(28.3% .109 300);--color-slate-50:oklch(98.4% .003 253.3);--color-slate-100:oklch(96.4% .005 253.3);--color-slate-200:oklch(92.6% .009 253.3);--color-slate-300:oklch(86.6% .014 253.3);--color-slate-400:oklch(70.4% .021 253.3);--color-slate-500:oklch(55.6% .026 253.3);--color-slate-600:oklch(44.8% .028 253.3);--color-slate-700:oklch(36.8% .028 253.3);--color-slate-800:oklch(26.4% .026 253.3);--color-slate-900:oklch(20.4% .024 253.3);--color-slate-950:oklch(14.2% .022 253.3);--spacing:.25rem;--container-2xl:42rem;--text-xs:.6875rem;--text-xs--line-height:1.45;--text-sm:.8125rem;--text-sm--line-height:1.5;--text-base:.875rem;--text-base--line-height:1.6;--text-lg:1rem;--text-lg--line-height:1.5;--text-xl:1.25rem;--text-xl--line-height:1.3;--text-2xl:1.5rem;--text-2xl--line-height:1.2;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-widest:.12em;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--default-transition-duration:.12s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-slate-0:oklch(100% 0 253.3);--spacing-control-x-sm:calc(var(--spacing) * 2);--spacing-control-y-sm:calc(var(--spacing) * 1);--spacing-control-x-md:calc(var(--spacing) * 3);--spacing-control-y-md:calc(var(--spacing) * 2);--spacing-control-x-lg:calc(var(--spacing) * 3.5);--spacing-control-y-lg:calc(var(--spacing) * 2.5);--spacing-control-h-sm:calc(var(--spacing) * 6.5);--spacing-control-h-md:calc(var(--spacing) * 9.5);--spacing-control-h-lg:calc(var(--spacing) * 9.5);--text-2xs:.625rem;--text-2xs--line-height:1.4;--tracking-tightest:-.03em}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{color-scheme:light}:root[data-theme=dark]{color-scheme:dark}html,body{height:100%}body{background-color:var(--ui-canvas);color:var(--ui-fg);font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--text-base--line-height)}::selection{background-color:var(--ui-accent-surface);color:var(--ui-accent)}:focus-visible{outline:2px solid var(--ui-accent);outline-offset:1px}}@layer components{.prose{overflow-wrap:anywhere}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}.prose h1,.prose h2,.prose h3,.prose h4{margin:calc(var(--spacing) * 6) 0 calc(var(--spacing) * 2);letter-spacing:var(--tracking-tightest);font-weight:650;line-height:1.25}.prose h1{font-size:var(--text-lg)}.prose h2{font-size:var(--text-base);padding-bottom:calc(var(--spacing) * 1.5);border-bottom:1px solid var(--ui-line)}.prose h3,.prose h4{font-size:var(--text-base);color:var(--ui-fg-muted)}.prose p{margin:calc(var(--spacing) * 3) 0}.prose ul,.prose ol{margin:calc(var(--spacing) * 3) 0;padding-left:calc(var(--spacing) * 5)}.prose ul{list-style-type:"– "}.prose ol{list-style-type:decimal}.prose li{margin:calc(var(--spacing) * 1) 0}.prose li::marker{color:var(--ui-accent);font-family:var(--font-mono)}.prose li>ul,.prose li>ol{margin:calc(var(--spacing) * 1) 0}.prose a{color:var(--ui-accent);text-underline-offset:2px;text-decoration:underline}.prose a:hover{color:var(--ui-accent-hover)}.prose strong{color:var(--ui-fg);font-weight:650}.prose pre{margin:calc(var(--spacing) * 3) 0;padding:calc(var(--spacing) * 3);border:1px solid var(--ui-line);border-radius:var(--radius-md);background-color:var(--ui-surface-sunken);font-size:var(--text-xs);line-height:1.6;overflow-x:auto}.prose code{font-family:var(--font-mono);font-size:.9em}.prose :not(pre)>code{border:1px solid var(--ui-line);border-radius:var(--radius-sm);background-color:var(--ui-surface-sunken);color:var(--ui-accent);padding:1px 4px}.prose blockquote{margin:calc(var(--spacing) * 3) 0;padding-left:calc(var(--spacing) * 3);border-left:2px solid var(--ui-accent-line);color:var(--ui-fg-muted)}.prose hr{margin:calc(var(--spacing) * 5) 0;border:0;border-top:1px dashed var(--ui-line-strong)}.prose table{margin:calc(var(--spacing) * 3) 0;border-collapse:collapse;font-size:var(--text-sm);display:block;overflow-x:auto}.prose th,.prose td{padding:calc(var(--spacing) * 1.5) calc(var(--spacing) * 2.5);border:1px solid var(--ui-line);text-align:left}.prose th{background-color:var(--ui-surface-sunken);font-weight:600}.graph svg{cursor:grab;width:100%;display:block}.graph .node circle{cursor:pointer;stroke-width:1.5px}.graph .node circle.hit{fill:#0000;stroke:none}.graph .node text{fill:var(--ui-fg-muted);font-family:var(--font-mono);pointer-events:none;font-size:9px}.graph .node.hi circle{stroke:var(--ui-accent);stroke-width:2.5px}.graph .node.hi text{fill:var(--ui-fg);font-weight:600}.graph .node.dim{opacity:.18}.graph .node.dim text{display:none}.graph .edge{stroke:var(--ui-line-strong)}.graph .edge.dim{opacity:.05}}@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-y-0{inset-block:0}.top-0{top:0}.top-2{top:calc(var(--spacing) * 2)}.top-3{top:calc(var(--spacing) * 3)}.top-3\.5{top:calc(var(--spacing) * 3.5)}.right-3\.5{right:calc(var(--spacing) * 3.5)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-5{bottom:calc(var(--spacing) * 5)}.left-0{left:0}.left-1\/2{left:50%}.left-3\.5{left:calc(var(--spacing) * 3.5)}.z-10{z-index:10}.z-20{z-index:20}.z-200{z-index:200}.float-right{float:right}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.m-auto{margin:auto}.my-1{margin-block:var(--spacing)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.mt-0{margin-top:0}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-3\.5{margin-bottom:calc(var(--spacing) * 3.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.h-2{height:calc(var(--spacing) * 2)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[28rem\]{max-height:28rem}.max-h-\[82vh\]{max-height:82vh}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-control-h-lg{min-height:var(--spacing-control-h-lg)}.min-h-control-h-md{min-height:var(--spacing-control-h-md)}.min-h-control-h-sm{min-height:var(--spacing-control-h-sm)}.w-0\.5{width:calc(var(--spacing) * .5)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-\[calc\(100\%-3rem\)\]{width:calc(100% - 3rem)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.min-w-0{min-width:0}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-control-h-sm{min-width:var(--spacing-control-h-sm)}.flex-1{flex:1}.flex-none{flex:none}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-default{cursor:default}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[3rem_1fr\]{grid-template-columns:3rem 1fr}.grid-cols-\[280px_1fr\]{grid-template-columns:280px 1fr}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-px{gap:1px}.gap-x-3\.5{column-gap:calc(var(--spacing) * 3.5)}.gap-y-1{row-gap:var(--spacing)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-accent{border-color:var(--ui-accent)}.border-accent-line{border-color:var(--ui-accent-line)}.border-current{border-color:currentColor}.border-danger{border-color:var(--ui-danger)}.border-danger-line{border-color:var(--ui-danger-line)}.border-line{border-color:var(--ui-line)}.border-transparent{border-color:#0000}.border-l-danger{border-left-color:var(--ui-danger)}.border-l-warn{border-left-color:var(--ui-warn)}.bg-accent{background-color:var(--ui-accent)}.bg-accent-surface{background-color:var(--ui-accent-surface)}.bg-canvas{background-color:var(--ui-canvas)}.bg-danger{background-color:var(--ui-danger)}.bg-danger-surface{background-color:var(--ui-danger-surface)}.bg-fg{background-color:var(--ui-fg)}.bg-line-strong{background-color:var(--ui-line-strong)}.bg-ok{background-color:var(--ui-ok)}.bg-ok-surface{background-color:var(--ui-ok-surface)}.bg-scope-local-surface{background-color:var(--ui-scope-local-surface)}.bg-scope-managed-surface{background-color:var(--ui-scope-managed-surface)}.bg-scope-project-surface{background-color:var(--ui-scope-project-surface)}.bg-scope-user-surface{background-color:var(--ui-scope-user-surface)}.bg-surface{background-color:var(--ui-surface)}.bg-surface-sunken{background-color:var(--ui-surface-sunken)}.bg-transparent{background-color:#0000}.bg-type-feedback-surface{background-color:var(--ui-type-feedback-surface)}.bg-type-project-surface{background-color:var(--ui-type-project-surface)}.bg-type-reference-surface{background-color:var(--ui-type-reference-surface)}.bg-type-user-surface{background-color:var(--ui-type-user-surface)}.bg-warn{background-color:var(--ui-warn)}.bg-warn-surface{background-color:var(--ui-warn-surface)}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-10{padding-inline:calc(var(--spacing) * 10)}.px-control-x-lg{padding-inline:var(--spacing-control-x-lg)}.px-control-x-md{padding-inline:var(--spacing-control-x-md)}.px-control-x-sm{padding-inline:var(--spacing-control-x-sm)}.px-px{padding-inline:1px}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-\[15vh\]{padding-block:15vh}.py-control-y-lg{padding-block:var(--spacing-control-y-lg)}.py-control-y-md{padding-block:var(--spacing-control-y-md)}.py-control-y-sm{padding-block:var(--spacing-control-y-sm)}.py-px{padding-block:1px}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-3\.5{padding-top:calc(var(--spacing) * 3.5)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pb-1{padding-bottom:var(--spacing)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-3\.5{padding-bottom:calc(var(--spacing) * 3.5)}.pb-4\.5{padding-bottom:calc(var(--spacing) * 4.5)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-2xs{font-size:var(--text-2xs);line-height:var(--tw-leading,var(--text-2xs--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tightest{--tw-tracking:var(--tracking-tightest);letter-spacing:var(--tracking-tightest)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--ui-accent)}.text-canvas{color:var(--ui-canvas)}.text-danger{color:var(--ui-danger)}.text-fg{color:var(--ui-fg)}.text-fg-muted{color:var(--ui-fg-muted)}.text-fg-subtle{color:var(--ui-fg-subtle)}.text-ok{color:var(--ui-ok)}.text-on-accent{color:var(--ui-on-accent)}.text-scope-local{color:var(--ui-scope-local)}.text-scope-managed{color:var(--ui-scope-managed)}.text-scope-project{color:var(--ui-scope-project)}.text-scope-user{color:var(--ui-scope-user)}.text-type-feedback{color:var(--ui-type-feedback)}.text-type-project{color:var(--ui-type-project)}.text-type-reference{color:var(--ui-type-reference)}.text-type-user{color:var(--ui-type-user)}.text-warn{color:var(--ui-warn)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-danger{-webkit-text-decoration-color:var(--ui-danger);-webkit-text-decoration-color:var(--ui-danger);text-decoration-color:var(--ui-danger)}.decoration-line-strong{-webkit-text-decoration-color:var(--ui-line-strong);-webkit-text-decoration-color:var(--ui-line-strong);text-decoration-color:var(--ui-line-strong)}.accent-accent{accent-color:var(--ui-accent)}.opacity-45{opacity:.45}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.shadow-card{--tw-shadow:var(--ui-shadow-card);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-pop{--tw-shadow:var(--ui-shadow-pop);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.placeholder\:text-fg-subtle::placeholder{color:var(--ui-fg-subtle)}.backdrop\:bg-scrim::backdrop{background-color:var(--ui-scrim)}.before\:flex-1:before{content:var(--tw-content);flex:1}.before\:border-t:before{content:var(--tw-content);border-top-style:var(--tw-border-style);border-top-width:1px}.before\:border-dashed:before{content:var(--tw-content);--tw-border-style:dashed;border-style:dashed}.before\:border-danger:before{content:var(--tw-content);border-color:var(--ui-danger)}.after\:flex-1:after{content:var(--tw-content);flex:1}.after\:border-t:after{content:var(--tw-content);border-top-style:var(--tw-border-style);border-top-width:1px}.after\:border-dashed:after{content:var(--tw-content);--tw-border-style:dashed;border-style:dashed}.after\:border-danger:after{content:var(--tw-content);border-color:var(--ui-danger)}.first\:mt-0:first-child{margin-top:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.open\:flex:is([open],:popover-open,:open){display:flex}@media (hover:hover){.hover\:border-accent:hover{border-color:var(--ui-accent)}.hover\:border-accent-hover:hover{border-color:var(--ui-accent-hover)}.hover\:border-accent-line:hover{border-color:var(--ui-accent-line)}.hover\:border-line-strong:hover{border-color:var(--ui-line-strong)}.hover\:bg-accent-hover:hover{background-color:var(--ui-accent-hover)}.hover\:bg-danger:hover{background-color:var(--ui-danger)}.hover\:bg-surface-sunken:hover{background-color:var(--ui-surface-sunken)}.hover\:text-accent-hover:hover{color:var(--ui-accent-hover)}.hover\:text-fg:hover{color:var(--ui-fg)}.hover\:text-on-accent:hover{color:var(--ui-on-accent)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-accent:focus{border-color:var(--ui-accent)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-45:disabled{opacity:.45}@media (min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:80rem){.xl\:sticky{position:sticky}.xl\:top-4{top:calc(var(--spacing) * 4)}.xl\:max-h-\[calc\(100vh-9rem\)\]{max-height:calc(100vh - 9rem)}.xl\:grid-cols-\[minmax\(280px\,380px\)_1fr\]{grid-template-columns:minmax(280px,380px) 1fr}.xl\:overflow-y-auto{overflow-y:auto}}.dark\:invert:where([data-theme=dark],[data-theme=dark] *){--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.\[\&\>span\]\:block>span{display:block}}:root{--ui-canvas:var(--color-slate-50);--ui-surface:var(--color-slate-0);--ui-surface-sunken:var(--color-slate-100);--ui-surface-raised:var(--color-slate-0);--ui-line:var(--color-slate-200);--ui-line-strong:var(--color-slate-300);--ui-fg:var(--color-slate-900);--ui-fg-muted:var(--color-slate-500);--ui-fg-subtle:var(--color-slate-400);--ui-accent:var(--color-blue-600);--ui-accent-hover:var(--color-blue-700);--ui-accent-surface:var(--color-blue-50);--ui-accent-line:var(--color-blue-200);--ui-on-accent:var(--color-slate-0);--ui-danger:var(--color-red-600);--ui-danger-surface:var(--color-red-50);--ui-danger-line:var(--color-red-300);--ui-warn:var(--color-amber-700);--ui-warn-surface:var(--color-amber-50);--ui-warn-line:var(--color-amber-300);--ui-ok:var(--color-green-600);--ui-ok-surface:var(--color-green-50);--ui-ok-line:var(--color-green-300);--ui-type-project:var(--color-blue-700);--ui-type-project-surface:var(--color-blue-50);--ui-type-feedback:var(--color-amber-700);--ui-type-feedback-surface:var(--color-amber-50);--ui-type-user:var(--color-violet-700);--ui-type-user-surface:var(--color-violet-50);--ui-type-reference:var(--color-green-700);--ui-type-reference-surface:var(--color-green-50);--ui-scope-managed:var(--color-red-600);--ui-scope-managed-surface:var(--color-red-50);--ui-scope-user:var(--color-blue-700);--ui-scope-user-surface:var(--color-blue-50);--ui-scope-project:var(--color-amber-700);--ui-scope-project-surface:var(--color-amber-50);--ui-scope-local:var(--color-slate-600);--ui-scope-local-surface:var(--color-slate-100);--ui-shadow-card:0 1px 2px #0000000d;--ui-shadow-pop:0 1px 2px #0000000f, 0 12px 32px #0000001a;--ui-scrim:#0f172a73}:root[data-theme=dark]{--ui-canvas:var(--color-slate-950);--ui-surface:var(--color-slate-900);--ui-surface-sunken:var(--color-slate-950);--ui-surface-raised:var(--color-slate-800);--ui-line:var(--color-slate-800);--ui-line-strong:var(--color-slate-700);--ui-fg:var(--color-slate-100);--ui-fg-muted:var(--color-slate-400);--ui-fg-subtle:var(--color-slate-500);--ui-accent:var(--color-blue-400);--ui-accent-hover:var(--color-blue-300);--ui-accent-surface:var(--color-blue-950);--ui-accent-line:var(--color-blue-800);--ui-on-accent:var(--color-slate-950);--ui-danger:var(--color-red-400);--ui-danger-surface:var(--color-red-950);--ui-danger-line:var(--color-red-500);--ui-warn:var(--color-amber-400);--ui-warn-surface:var(--color-amber-950);--ui-warn-line:var(--color-amber-600);--ui-ok:var(--color-green-400);--ui-ok-surface:var(--color-green-950);--ui-ok-line:var(--color-green-600);--ui-type-project:var(--color-blue-300);--ui-type-project-surface:var(--color-blue-950);--ui-type-feedback:var(--color-amber-300);--ui-type-feedback-surface:var(--color-amber-950);--ui-type-user:var(--color-violet-300);--ui-type-user-surface:var(--color-violet-950);--ui-type-reference:var(--color-green-300);--ui-type-reference-surface:var(--color-green-950);--ui-scope-managed:var(--color-red-400);--ui-scope-managed-surface:var(--color-red-950);--ui-scope-user:var(--color-blue-300);--ui-scope-user-surface:var(--color-blue-950);--ui-scope-project:var(--color-amber-300);--ui-scope-project-surface:var(--color-amber-950);--ui-scope-local:var(--color-slate-400);--ui-scope-local-surface:var(--color-slate-800);--ui-shadow-card:0 1px 2px #0006;--ui-shadow-pop:0 1px 2px #00000080, 0 12px 32px #00000073;--ui-scrim:#020610b3}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
package/public/ui.mjs
CHANGED
|
@@ -260,12 +260,11 @@ export const graphLegend = 'absolute bottom-3 left-3.5 flex flex-wrap gap-3 roun
|
|
|
260
260
|
export const graphLegendItem = 'flex items-center gap-1.5';
|
|
261
261
|
export const graphLegendSwatch = 'inline-block size-2 rounded-full';
|
|
262
262
|
|
|
263
|
-
export const
|
|
264
|
-
export const
|
|
265
|
-
export const
|
|
266
|
-
export const
|
|
267
|
-
export const
|
|
268
|
-
export const modalFoot = 'flex justify-end gap-2 border-t border-line px-6 pt-3.5 pb-4.5';
|
|
263
|
+
export const dialog = 'backdrop:bg-scrim m-auto open:flex max-h-[82vh] w-[calc(100%-3rem)] max-w-2xl flex-col rounded-xl border border-line bg-surface shadow-pop';
|
|
264
|
+
export const dialogHead = 'px-6 pt-5';
|
|
265
|
+
export const dialogTitle = 'mb-1 text-lg font-semibold tracking-tightest text-fg';
|
|
266
|
+
export const dialogBody = 'overflow-y-auto px-6 py-3.5';
|
|
267
|
+
export const dialogFoot = 'flex justify-end gap-2 border-t border-line px-6 pt-3.5 pb-4.5';
|
|
269
268
|
|
|
270
269
|
export const willBlock = 'mb-3.5';
|
|
271
270
|
export const willTitle = 'mb-1.5 font-mono text-2xs font-semibold uppercase tracking-widest text-fg-subtle';
|