@handamade/psi-react 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Dialog/Dialog.d.ts +18 -3
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Tabs/Tab.d.ts +19 -0
- package/dist/Tabs/Tab.d.ts.map +1 -0
- package/dist/Tabs/TabList.d.ts +19 -0
- package/dist/Tabs/TabList.d.ts.map +1 -0
- package/dist/Tabs/TabPanel.d.ts +23 -0
- package/dist/Tabs/TabPanel.d.ts.map +1 -0
- package/dist/Tabs/Tabs.d.ts +45 -0
- package/dist/Tabs/Tabs.d.ts.map +1 -0
- package/dist/Tabs/useTabsKeyboard.d.ts +21 -0
- package/dist/Tabs/useTabsKeyboard.d.ts.map +1 -0
- package/dist/a11y-meta.d.ts.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +722 -571
- package/dist/manifest.json +182 -2
- package/dist/patterns.json +55 -23
- package/dist/styles.css +1 -1
- package/docs/Dialog.md +4 -3
- package/docs/Tab.md +39 -0
- package/docs/TabList.md +40 -0
- package/docs/TabPanel.md +38 -0
- package/docs/Tabs.md +40 -0
- package/llms.txt +13 -1
- package/package.json +2 -2
package/dist/manifest.json
CHANGED
|
@@ -364,7 +364,7 @@
|
|
|
364
364
|
},
|
|
365
365
|
{
|
|
366
366
|
"name": "Dialog",
|
|
367
|
-
"description": "Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus restore come from the platform; title/footer slots, Esc/backdrop/ close-button dismissal via onClose(reason) (D50).",
|
|
367
|
+
"description": "Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus restore come from the platform; title/footer slots, Esc/backdrop/ close-button dismissal via onClose(reason) (D50). `placement` moves the panel and nothing else (D66): an `inline-start` / `inline-end` Dialog is a drawer, pinned full-height to that edge, with the same modality, focus trap, focus restore and dismissal reasons as a centered one. There is deliberately no separate Drawer component — a sibling would have to duplicate or wrap all of that.",
|
|
368
368
|
"slots": [
|
|
369
369
|
{
|
|
370
370
|
"name": "title",
|
|
@@ -430,7 +430,14 @@
|
|
|
430
430
|
"type": "400 | 560 | 720",
|
|
431
431
|
"required": false,
|
|
432
432
|
"default": 560,
|
|
433
|
-
"description": "Panel width in px (400 | 560 | 720)."
|
|
433
|
+
"description": "Panel width in px (400 | 560 | 720). For an `inline-*` placement this is\nthe drawer's width; the height is always the full viewport."
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"name": "placement",
|
|
437
|
+
"type": "\"center\" | \"inline-start\" | \"inline-end\"",
|
|
438
|
+
"required": false,
|
|
439
|
+
"default": "center",
|
|
440
|
+
"description": "Where the panel sits. `inline-start` / `inline-end` pin it full-height to\nthat edge, making it a drawer (D66)."
|
|
434
441
|
},
|
|
435
442
|
{
|
|
436
443
|
"name": "dismissible",
|
|
@@ -1207,6 +1214,179 @@
|
|
|
1207
1214
|
"description": "The subtree that may call `useToast()`. The region is rendered alongside it."
|
|
1208
1215
|
}
|
|
1209
1216
|
]
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"name": "Tabs",
|
|
1220
|
+
"description": "Tab set root (D67) — holds no selection state of its own, following D50, D53 and D62: `value` and `onValueChange` are required and there is no `defaultValue`. Values are strings rather than indices because an index breaks the moment a tab is inserted, and real tab sets map to ids. `Tab` and `TabPanel` pair by value, so their source order need not match. Activation is automatic: arrow keys move focus and selection together. That is the APG default where panel content is already available, and manual activation is deliberately not offered as a mode — a consumer for whom activating a panel is expensive already controls what the panel renders.",
|
|
1221
|
+
"slots": [
|
|
1222
|
+
{
|
|
1223
|
+
"name": "body",
|
|
1224
|
+
"accepts": {
|
|
1225
|
+
"components": [
|
|
1226
|
+
"TabList",
|
|
1227
|
+
"TabPanel"
|
|
1228
|
+
]
|
|
1229
|
+
},
|
|
1230
|
+
"cardinality": "1..*",
|
|
1231
|
+
"order": 1
|
|
1232
|
+
}
|
|
1233
|
+
],
|
|
1234
|
+
"props": [
|
|
1235
|
+
{
|
|
1236
|
+
"name": "value",
|
|
1237
|
+
"type": "string",
|
|
1238
|
+
"required": true,
|
|
1239
|
+
"default": null,
|
|
1240
|
+
"description": "Controlled selected tab, matched against each `Tab`/`TabPanel` value."
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
"name": "onValueChange",
|
|
1244
|
+
"type": "(value: string) => void",
|
|
1245
|
+
"required": true,
|
|
1246
|
+
"default": null,
|
|
1247
|
+
"description": "Fires with the newly selected value; the consumer flips `value`."
|
|
1248
|
+
},
|
|
1249
|
+
{
|
|
1250
|
+
"name": "orientation",
|
|
1251
|
+
"type": "\"horizontal\" | \"vertical\"",
|
|
1252
|
+
"required": false,
|
|
1253
|
+
"default": "horizontal",
|
|
1254
|
+
"description": "Axis of the tab list, which also picks the arrow keys."
|
|
1255
|
+
},
|
|
1256
|
+
{
|
|
1257
|
+
"name": "children",
|
|
1258
|
+
"type": "ReactNode",
|
|
1259
|
+
"required": true,
|
|
1260
|
+
"default": null,
|
|
1261
|
+
"description": "A `TabList` and one `TabPanel` per tab."
|
|
1262
|
+
},
|
|
1263
|
+
{
|
|
1264
|
+
"name": "className",
|
|
1265
|
+
"type": "string",
|
|
1266
|
+
"required": false,
|
|
1267
|
+
"default": null,
|
|
1268
|
+
"description": "Additional CSS class name(s) merged onto the component's root element."
|
|
1269
|
+
},
|
|
1270
|
+
{
|
|
1271
|
+
"name": "ref",
|
|
1272
|
+
"type": "Ref<HTMLDivElement>",
|
|
1273
|
+
"required": false,
|
|
1274
|
+
"default": null,
|
|
1275
|
+
"description": "Forwarded ref to the wrapper `<div>`."
|
|
1276
|
+
}
|
|
1277
|
+
]
|
|
1278
|
+
},
|
|
1279
|
+
{
|
|
1280
|
+
"name": "TabList",
|
|
1281
|
+
"description": "The `role=\"tablist\"` container (D67). Owns the roving tabindex: the whole list is one Tab stop, and the arrow keys move between tabs inside it.",
|
|
1282
|
+
"slots": [],
|
|
1283
|
+
"props": [
|
|
1284
|
+
{
|
|
1285
|
+
"name": "aria-label",
|
|
1286
|
+
"type": "string",
|
|
1287
|
+
"required": false,
|
|
1288
|
+
"default": null,
|
|
1289
|
+
"description": "Accessible name for the tab set. Declared here rather than inherited so\ndocgen keeps it in the manifest (D60) — a tablist without a name is\nannounced as an unlabelled group, and the prop would otherwise be\ninvisible to an agent reading the manifest."
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
"name": "children",
|
|
1293
|
+
"type": "ReactNode",
|
|
1294
|
+
"required": true,
|
|
1295
|
+
"default": null,
|
|
1296
|
+
"description": "One `Tab` per view."
|
|
1297
|
+
},
|
|
1298
|
+
{
|
|
1299
|
+
"name": "className",
|
|
1300
|
+
"type": "string",
|
|
1301
|
+
"required": false,
|
|
1302
|
+
"default": null,
|
|
1303
|
+
"description": "Additional CSS class name(s) merged onto the component's root element."
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
"name": "ref",
|
|
1307
|
+
"type": "Ref<HTMLDivElement>",
|
|
1308
|
+
"required": false,
|
|
1309
|
+
"default": null,
|
|
1310
|
+
"description": "Forwarded ref to the tablist element."
|
|
1311
|
+
}
|
|
1312
|
+
]
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
"name": "Tab",
|
|
1316
|
+
"description": "One `role=\"tab\"` (D67). Renders a real `<button>`. `disabled` sets `aria-disabled` rather than the `disabled` attribute, so the tab stays discoverable to assistive tech while being skipped by roving navigation — the same choice MenuItem made in D53.",
|
|
1317
|
+
"slots": [],
|
|
1318
|
+
"props": [
|
|
1319
|
+
{
|
|
1320
|
+
"name": "value",
|
|
1321
|
+
"type": "string",
|
|
1322
|
+
"required": true,
|
|
1323
|
+
"default": null,
|
|
1324
|
+
"description": "Pairs this tab with the `TabPanel` of the same value."
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
"name": "children",
|
|
1328
|
+
"type": "ReactNode",
|
|
1329
|
+
"required": true,
|
|
1330
|
+
"default": null,
|
|
1331
|
+
"description": "Label — keep it to one or two words."
|
|
1332
|
+
},
|
|
1333
|
+
{
|
|
1334
|
+
"name": "disabled",
|
|
1335
|
+
"type": "boolean",
|
|
1336
|
+
"required": false,
|
|
1337
|
+
"default": false,
|
|
1338
|
+
"description": "Skipped by arrow navigation and not selectable, but still announced."
|
|
1339
|
+
},
|
|
1340
|
+
{
|
|
1341
|
+
"name": "className",
|
|
1342
|
+
"type": "string",
|
|
1343
|
+
"required": false,
|
|
1344
|
+
"default": null,
|
|
1345
|
+
"description": "Additional CSS class name(s) merged onto the component's root element."
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
"name": "ref",
|
|
1349
|
+
"type": "Ref<HTMLButtonElement>",
|
|
1350
|
+
"required": false,
|
|
1351
|
+
"default": null,
|
|
1352
|
+
"description": "Forwarded ref to the underlying `<button>`."
|
|
1353
|
+
}
|
|
1354
|
+
]
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
"name": "TabPanel",
|
|
1358
|
+
"description": "One `role=\"tabpanel\"` (D67). Every panel renders; unselected ones carry `hidden`. Returning null instead would leave `aria-controls` on every unselected tab pointing at an element that does not exist, and would throw away DOM state — a half-filled form in a panel would lose its values on each tab switch. The cost is a heavier DOM when panels are large; the answer to that is rendering less inside the panel, not unmounting it behind the consumer's back. `tabIndex={0}` because a panel whose content has no focusable element would otherwise be unreachable by keyboard.",
|
|
1359
|
+
"slots": [],
|
|
1360
|
+
"props": [
|
|
1361
|
+
{
|
|
1362
|
+
"name": "value",
|
|
1363
|
+
"type": "string",
|
|
1364
|
+
"required": true,
|
|
1365
|
+
"default": null,
|
|
1366
|
+
"description": "Pairs this panel with the `Tab` of the same value."
|
|
1367
|
+
},
|
|
1368
|
+
{
|
|
1369
|
+
"name": "children",
|
|
1370
|
+
"type": "ReactNode",
|
|
1371
|
+
"required": true,
|
|
1372
|
+
"default": null,
|
|
1373
|
+
"description": "The view for this tab. Rendered even when unselected, then `hidden`."
|
|
1374
|
+
},
|
|
1375
|
+
{
|
|
1376
|
+
"name": "className",
|
|
1377
|
+
"type": "string",
|
|
1378
|
+
"required": false,
|
|
1379
|
+
"default": null,
|
|
1380
|
+
"description": "Additional CSS class name(s) merged onto the component's root element."
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
"name": "ref",
|
|
1384
|
+
"type": "Ref<HTMLDivElement>",
|
|
1385
|
+
"required": false,
|
|
1386
|
+
"default": null,
|
|
1387
|
+
"description": "Forwarded ref to the panel element."
|
|
1388
|
+
}
|
|
1389
|
+
]
|
|
1210
1390
|
}
|
|
1211
1391
|
]
|
|
1212
1392
|
}
|
package/dist/patterns.json
CHANGED
|
@@ -345,9 +345,9 @@
|
|
|
345
345
|
"record detail panel"
|
|
346
346
|
],
|
|
347
347
|
"compose": {
|
|
348
|
-
"component": "
|
|
348
|
+
"component": "Dialog",
|
|
349
349
|
"props": {
|
|
350
|
-
"
|
|
350
|
+
"placement": "{param:placement}"
|
|
351
351
|
},
|
|
352
352
|
"slots": {
|
|
353
353
|
"title": [
|
|
@@ -376,13 +376,13 @@
|
|
|
376
376
|
},
|
|
377
377
|
"parameters": [
|
|
378
378
|
{
|
|
379
|
-
"key": "
|
|
379
|
+
"key": "placement",
|
|
380
380
|
"ask": "Which edge should the drawer open from?",
|
|
381
381
|
"options": [
|
|
382
|
-
"end",
|
|
383
|
-
"start"
|
|
382
|
+
"inline-end",
|
|
383
|
+
"inline-start"
|
|
384
384
|
],
|
|
385
|
-
"default": "end"
|
|
385
|
+
"default": "inline-end"
|
|
386
386
|
}
|
|
387
387
|
],
|
|
388
388
|
"content": {
|
|
@@ -391,11 +391,9 @@
|
|
|
391
391
|
"primary-label": "Save",
|
|
392
392
|
"dismiss-label": "Close"
|
|
393
393
|
},
|
|
394
|
-
"gaps": [
|
|
395
|
-
|
|
396
|
-
]
|
|
397
|
-
"blocked": true,
|
|
398
|
-
"preset": null
|
|
394
|
+
"gaps": [],
|
|
395
|
+
"blocked": false,
|
|
396
|
+
"preset": "<Dialog\n footer={<>\n <Button variant=\"accent\">Save</Button>\n <Button variant=\"neutral\">Close</Button>\n </>}\n placement=\"inline-end\"\n title=\"[record title]\"\n>\n [key-value summary of the selected record]\n</Dialog>\n"
|
|
399
397
|
},
|
|
400
398
|
{
|
|
401
399
|
"id": "empty-state",
|
|
@@ -639,11 +637,45 @@
|
|
|
639
637
|
"orientation": "{param:orientation}"
|
|
640
638
|
},
|
|
641
639
|
"slots": {
|
|
642
|
-
"
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
640
|
+
"body": [
|
|
641
|
+
{
|
|
642
|
+
"component": "TabList",
|
|
643
|
+
"props": {
|
|
644
|
+
"aria-label": "Views"
|
|
645
|
+
},
|
|
646
|
+
"slots": {
|
|
647
|
+
"body": [
|
|
648
|
+
{
|
|
649
|
+
"component": "Tab",
|
|
650
|
+
"props": {
|
|
651
|
+
"value": "all"
|
|
652
|
+
},
|
|
653
|
+
"content": "first-label"
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
"component": "Tab",
|
|
657
|
+
"props": {
|
|
658
|
+
"value": "flagged"
|
|
659
|
+
},
|
|
660
|
+
"content": "second-label"
|
|
661
|
+
}
|
|
662
|
+
]
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
"component": "TabPanel",
|
|
667
|
+
"props": {
|
|
668
|
+
"value": "all"
|
|
669
|
+
},
|
|
670
|
+
"content": "first-panel"
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
"component": "TabPanel",
|
|
674
|
+
"props": {
|
|
675
|
+
"value": "flagged"
|
|
676
|
+
},
|
|
677
|
+
"content": "second-panel"
|
|
678
|
+
}
|
|
647
679
|
]
|
|
648
680
|
}
|
|
649
681
|
},
|
|
@@ -659,14 +691,14 @@
|
|
|
659
691
|
}
|
|
660
692
|
],
|
|
661
693
|
"content": {
|
|
662
|
-
"
|
|
663
|
-
"
|
|
694
|
+
"first-label": "All",
|
|
695
|
+
"second-label": "Flagged",
|
|
696
|
+
"first-panel": "[the default view]",
|
|
697
|
+
"second-panel": "[the second view; one panel per tab, paired by value]"
|
|
664
698
|
},
|
|
665
|
-
"gaps": [
|
|
666
|
-
|
|
667
|
-
],
|
|
668
|
-
"blocked": true,
|
|
669
|
-
"preset": null
|
|
699
|
+
"gaps": [],
|
|
700
|
+
"blocked": false,
|
|
701
|
+
"preset": "<Tabs\n orientation=\"horizontal\"\n>\n <TabList\n aria-label=\"Views\"\n >\n <Tab value=\"all\">All</Tab>\n <Tab value=\"flagged\">Flagged</Tab>\n </TabList>\n <TabPanel value=\"all\">[the default view]</TabPanel>\n <TabPanel value=\"flagged\">[the second view; one panel per tab, paired by value]</TabPanel>\n</Tabs>\n"
|
|
670
702
|
},
|
|
671
703
|
{
|
|
672
704
|
"id": "table-pagination",
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
._button_c94w9_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;font-family:var(--psi-font-sans);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._button_c94w9_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._button_c94w9_3:disabled{opacity:.4;cursor:not-allowed}._button_c94w9_3._disabled_c94w9_30{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_c94w9_44{height:var(--psi-button-24-height);padding-inline:var(--psi-button-24-padding-inline);gap:var(--psi-button-24-gap);font:var(--psi-button-font, var(--psi-button-24-font))}._size24_c94w9_44:has(>svg:first-child){padding-inline-start:var(--psi-button-24-padding-inline-icon)}._size32_c94w9_54{height:var(--psi-button-32-height);padding-inline:var(--psi-button-32-padding-inline);gap:var(--psi-button-32-gap);font:var(--psi-button-font, var(--psi-button-32-font))}._size32_c94w9_54:has(>svg:first-child){padding-inline-start:var(--psi-button-32-padding-inline-icon)}._size40_c94w9_64{height:var(--psi-button-40-height);padding-inline:var(--psi-button-40-padding-inline);gap:var(--psi-button-40-gap);font:var(--psi-button-font, var(--psi-button-40-font))}._size40_c94w9_64:has(>svg:first-child){padding-inline-start:var(--psi-button-40-padding-inline-icon)}._size48_c94w9_74{height:var(--psi-button-48-height);padding-inline:var(--psi-button-48-padding-inline);gap:var(--psi-button-48-gap);font:var(--psi-button-font, var(--psi-button-48-font))}._size48_c94w9_74:has(>svg:first-child){padding-inline-start:var(--psi-button-48-padding-inline-icon)}._accent_c94w9_87{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_c94w9_87:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-hover)}._accent_c94w9_87:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-active)}._accentSubtle_c94w9_99{background:var(--psi-button-accent-subtle-bg);color:var(--psi-button-accent-subtle-fg)}._accentSubtle_c94w9_99:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-hover)}._accentSubtle_c94w9_99:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-active)}._neutral_c94w9_111{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_c94w9_111:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-hover)}._neutral_c94w9_111:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-active)}._neutralSubtle_c94w9_123{background:var(--psi-button-neutral-subtle-bg);color:var(--psi-button-neutral-subtle-fg)}._neutralSubtle_c94w9_123:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-hover)}._neutralSubtle_c94w9_123:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-active)}._ghost_c94w9_135{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_c94w9_135:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-hover)}._ghost_c94w9_135:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-active)}._danger_c94w9_147{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_c94w9_147:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-hover)}._danger_c94w9_147:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-active)}._dangerSubtle_c94w9_159{background:var(--psi-button-danger-subtle-bg);color:var(--psi-button-danger-subtle-fg)}._dangerSubtle_c94w9_159:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-hover)}._dangerSubtle_c94w9_159:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-active)}._outline_c94w9_171{background:var(--psi-button-outline-bg);color:var(--psi-button-outline-fg);border:1px solid var(--psi-button-outline-border)}._outline_c94w9_171:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-hover);color:var(--psi-button-outline-fg-hover);border-color:transparent}._outline_c94w9_171:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-active)}._iconButton_129ca_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;padding:0;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._iconButton_129ca_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._iconButton_129ca_3:disabled{opacity:.4;cursor:not-allowed}._iconButton_129ca_3._disabled_129ca_29{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_129ca_37{width:var(--psi-button-24-height);height:var(--psi-button-24-height)}._size32_129ca_42{width:var(--psi-button-32-height);height:var(--psi-button-32-height)}._size40_129ca_47{width:var(--psi-button-40-height);height:var(--psi-button-40-height)}._size48_129ca_52{width:var(--psi-button-48-height);height:var(--psi-button-48-height)}._accent_129ca_60{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_129ca_60:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-hover)}._accent_129ca_60:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-active)}._neutral_129ca_72{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_129ca_72:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-hover)}._neutral_129ca_72:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-active)}._ghost_129ca_84{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_129ca_84:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-hover)}._ghost_129ca_84:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-active)}._danger_129ca_96{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_129ca_96:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-hover)}._danger_129ca_96:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-active)}._card_1btb3_1{background:var(--psi-card-bg);border:1px solid var(--psi-card-border);border-radius:var(--psi-card-radius);overflow:hidden}._stacked_1btb3_8{display:flex;flex-direction:column;gap:var(--psi-card-gap)}._featured_1btb3_10{display:grid;grid-template-columns:1.6fr 1fr;gap:var(--psi-card-gap);align-items:start}@media(max-width:960px){._featured_1btb3_10{grid-template-columns:1fr}}._media_1btb3_22{min-width:0}._body_1btb3_23{min-width:0;display:flex;flex-direction:column;gap:var(--psi-card-gap);padding:var(--psi-card-gap)}._hoverLift_1btb3_31{transition:transform var(--psi-duration-350) var(--psi-ease-standard)}._hoverLift_1btb3_31:hover{transform:translateY(-6px)}._panel_jn8w4_1{background:var(--psi-panel-bg);border:1px solid var(--psi-panel-border);border-radius:var(--psi-panel-radius);padding:var(--psi-panel-padding)}._padding16_jn8w4_8{padding:var(--psi-space-16)}._navbar_1gyow_1{font:var(--psi-text-14-20-medium);position:sticky;top:0;z-index:var(--psi-z-nav);background:var(--psi-navbar-bg);backdrop-filter:blur(var(--psi-navbar-blur));-webkit-backdrop-filter:blur(var(--psi-navbar-blur));border-bottom:1px solid var(--psi-navbar-border)}._inner_1gyow_12{display:flex;align-items:center;gap:var(--psi-space-24);height:var(--psi-navbar-height)}._brand_1gyow_19{display:flex;align-items:center}._links_1gyow_20{display:flex;align-items:center;gap:var(--psi-space-20);margin-inline-start:auto}._links_1gyow_20 a,._brand_1gyow_19 a{text-decoration:none;transition:color var(--psi-duration-150) var(--psi-ease-soft)}._links_1gyow_20 a{color:var(--psi-navbar-link-fg)}._links_1gyow_20 a:hover,._brand_1gyow_19 a{color:var(--psi-navbar-link-fg-hover)}._links_1gyow_20 a:focus-visible,._brand_1gyow_19 a:focus-visible{outline:2px solid var(--psi-navbar-focus-ring);outline-offset:2px}._actions_1gyow_50{display:flex;align-items:center;gap:var(--psi-space-8)}._frame_et4fc_1{overflow:hidden}._frame_et4fc_1>img,._frame_et4fc_1>video{width:100%;height:100%;object-fit:cover;display:block}._field_lplye_1{display:grid;gap:var(--psi-field-gap);border:0;margin:0;padding:0;min-width:0}._label_lplye_10{font:var(--psi-text-14-20-medium);color:var(--psi-field-label-fg);padding:0}._marker_lplye_16{color:var(--psi-field-marker-fg)}._message_lplye_20{margin:0;font:var(--psi-text-12-16-regular);color:var(--psi-field-message-fg)}._invalid_lplye_26 ._message_lplye_20{color:var(--psi-field-error-fg)}._dialog_l23jf_2{padding:0;border:1px solid var(--psi-dialog-border);border-radius:var(--psi-dialog-radius);background:var(--psi-dialog-bg);color:var(--psi-dialog-fg);max-width:calc(100vw - var(--psi-space-32))}._dialog_l23jf_2::backdrop{background:var(--psi-dialog-backdrop)}._dialog_l23jf_2[open]{animation:_dialog-enter_l23jf_1 var(--psi-duration-200) var(--psi-ease-soft)}._dialog_l23jf_2[open]::backdrop{animation:_backdrop-enter_l23jf_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _dialog-enter_l23jf_1{0%{opacity:0;transform:scale(.97)}}@keyframes _backdrop-enter_l23jf_1{0%{opacity:0}}._w400_l23jf_31{width:400px}._w560_l23jf_32{width:560px}._w720_l23jf_33{width:720px}._panel_l23jf_35{display:grid;gap:var(--psi-space-16);padding:var(--psi-space-24)}._header_l23jf_41{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--psi-space-12)}._title_l23jf_48{margin:0;font:var(--psi-text-18-28-medium);color:var(--psi-dialog-title-fg)}._footer_l23jf_54{display:flex;justify-content:flex-end;gap:var(--psi-space-8)}._input_hpei8_3{display:block;width:100%;border:1px solid var(--psi-input-border);border-radius:var(--psi-input-radius);background:var(--psi-input-bg);color:var(--psi-input-fg);font-family:var(--psi-font-sans);transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._input_hpei8_3::placeholder{color:var(--psi-input-placeholder)}._input_hpei8_3:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-hover)}._input_hpei8_3:focus{outline:2px solid var(--psi-input-focus-ring);outline-offset:-1px;border-color:transparent}._input_hpei8_3:disabled{opacity:.4;cursor:not-allowed}._size24_hpei8_37{height:var(--psi-input-24-height);padding-inline:var(--psi-input-24-padding-inline);font:var(--psi-input-24-font)}._size32_hpei8_43{height:var(--psi-input-32-height);padding-inline:var(--psi-input-32-padding-inline);font:var(--psi-input-32-font)}._size40_hpei8_49{height:var(--psi-input-40-height);padding-inline:var(--psi-input-40-padding-inline);font:var(--psi-input-40-font)}._size48_hpei8_55{height:var(--psi-input-48-height);padding-inline:var(--psi-input-48-padding-inline);font:var(--psi-input-48-font)}._error_hpei8_63{border-color:var(--psi-input-border-error)}._error_hpei8_63:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-error)}._select_4x9ck_3{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid var(--psi-select-border);border-radius:var(--psi-select-radius);background-color:var(--psi-select-bg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;color:var(--psi-select-fg);font-family:var(--psi-font-sans);cursor:pointer;transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._select_4x9ck_3:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-hover)}._select_4x9ck_3:focus{outline:2px solid var(--psi-select-focus-ring);outline-offset:-1px;border-color:transparent}._select_4x9ck_3:disabled{opacity:.4;cursor:not-allowed}._size24_4x9ck_37{height:var(--psi-select-24-height);padding-inline-start:var(--psi-select-24-padding-inline);padding-inline-end:var(--psi-select-24-padding-inline-end);background-position:right var(--psi-select-24-chevron-offset) center;font:var(--psi-select-24-font)}._size32_4x9ck_45{height:var(--psi-select-32-height);padding-inline-start:var(--psi-select-32-padding-inline);padding-inline-end:var(--psi-select-32-padding-inline-end);background-position:right var(--psi-select-32-chevron-offset) center;font:var(--psi-select-32-font)}._size40_4x9ck_53{height:var(--psi-select-40-height);padding-inline-start:var(--psi-select-40-padding-inline);padding-inline-end:var(--psi-select-40-padding-inline-end);background-position:right var(--psi-select-40-chevron-offset) center;font:var(--psi-select-40-font)}._size48_4x9ck_61{height:var(--psi-select-48-height);padding-inline-start:var(--psi-select-48-padding-inline);padding-inline-end:var(--psi-select-48-padding-inline-end);background-position:right var(--psi-select-48-chevron-offset) center;font:var(--psi-select-48-font)}._error_4x9ck_71{border-color:var(--psi-select-border-error)}._error_4x9ck_71:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-error)}._label_1v4vv_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-checkbox-fg)}._disabled_1v4vv_13{opacity:.4;cursor:not-allowed}._input_1v4vv_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._indicator_1v4vv_34{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;border:1px solid var(--psi-checkbox-box-border);border-radius:var(--psi-checkbox-box-radius);background:var(--psi-checkbox-box-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard),border-color var(--psi-duration-150) var(--psi-ease-standard)}._input_1v4vv_20:checked+._indicator_1v4vv_34{background:var(--psi-checkbox-box-bg-checked);border-color:var(--psi-checkbox-box-border-checked)}._input_1v4vv_20:checked+._indicator_1v4vv_34:after{content:"";display:block;width:4px;height:8px;color:var(--psi-checkbox-check-fg);border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translate(-.5px,-.5px)}._input_1v4vv_20:focus-visible+._indicator_1v4vv_34{outline:2px solid var(--psi-checkbox-focus-ring);outline-offset:2px}._text_1v4vv_75{color:var(--psi-checkbox-fg)}._label_jru2c_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-switch-fg)}._disabled_jru2c_13{opacity:.4;cursor:not-allowed}._input_jru2c_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._track_jru2c_34{position:relative;display:inline-flex;align-items:center;width:36px;height:20px;flex-shrink:0;border-radius:var(--psi-radius-full);background:var(--psi-switch-track-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard)}._input_jru2c_20:checked+._track_jru2c_34{background:var(--psi-switch-track-bg-checked)}._input_jru2c_20:focus-visible+._track_jru2c_34{outline:2px solid var(--psi-switch-focus-ring);outline-offset:2px}._thumb_jru2c_58{position:absolute;width:16px;height:16px;border-radius:var(--psi-radius-full);background:var(--psi-switch-thumb-bg);left:2px;transition:left var(--psi-duration-150) var(--psi-ease-standard);box-shadow:0 1px 2px #00000029}._input_jru2c_20:checked+._track_jru2c_34 ._thumb_jru2c_58{left:18px}._text_jru2c_75{color:var(--psi-switch-fg)}._tag_3oysa_3{display:inline-flex;align-items:center;gap:var(--psi-space-4);height:24px;padding-inline:var(--psi-space-8);border-radius:var(--psi-radius-full);font:var(--psi-text-12-16-medium);white-space:nowrap;-webkit-user-select:none;user-select:none}._dismiss_3oysa_17{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:none;color:inherit;cursor:pointer;opacity:.7;margin-inline-start:var(--psi-space-2);margin-inline-end:calc(-1 * var(--psi-space-4));border-radius:var(--psi-radius-full)}._dismiss_3oysa_17:hover{opacity:1}._dismiss_3oysa_17:focus-visible{outline:2px solid var(--psi-tag-focus-ring);outline-offset:2px}._neutral_3oysa_43{background:var(--psi-tag-neutral-bg);color:var(--psi-tag-neutral-fg)}._accent_3oysa_48{background:var(--psi-tag-accent-bg);color:var(--psi-tag-accent-fg)}._success_3oysa_53{background:var(--psi-tag-success-bg);color:var(--psi-tag-success-fg)}._warning_3oysa_58{background:var(--psi-tag-warning-bg);color:var(--psi-tag-warning-fg)}._danger_3oysa_63{background:var(--psi-tag-danger-bg);color:var(--psi-tag-danger-fg)}._neutralSubtle_3oysa_70{background:var(--psi-tag-neutral-subtle-bg);color:var(--psi-tag-neutral-subtle-fg)}._accentSubtle_3oysa_75{background:var(--psi-tag-accent-subtle-bg);color:var(--psi-tag-accent-subtle-fg)}._successSubtle_3oysa_80{background:var(--psi-tag-success-subtle-bg);color:var(--psi-tag-success-subtle-fg)}._warningSubtle_3oysa_85{background:var(--psi-tag-warning-subtle-bg);color:var(--psi-tag-warning-subtle-fg)}._dangerSubtle_3oysa_90{background:var(--psi-tag-danger-subtle-bg);color:var(--psi-tag-danger-subtle-fg)}._wrapper_1eu6z_3{position:relative;display:inline-flex}._tooltip_1eu6z_10{position:absolute;z-index:var(--psi-z-tooltip);padding:var(--psi-space-4) var(--psi-space-8);border-radius:var(--psi-tooltip-radius);background:var(--psi-tooltip-bg);color:var(--psi-tooltip-fg);font:var(--psi-text-12-16-regular);white-space:nowrap;pointer-events:none}._top_1eu6z_24{bottom:100%;left:50%;transform:translate(-50%);margin-bottom:var(--psi-space-4)}._bottom_1eu6z_31{top:100%;left:50%;transform:translate(-50%);margin-top:var(--psi-space-4)}._left_1eu6z_38{right:100%;top:50%;transform:translateY(-50%);margin-right:var(--psi-space-4)}._right_1eu6z_45{left:100%;top:50%;transform:translateY(-50%);margin-left:var(--psi-space-4)}._toolbar_1i848_1{display:flex;flex-wrap:wrap;align-items:center}._gap8_1i848_7{gap:var(--psi-space-8)}._gap12_1i848_8{gap:var(--psi-space-12)}._gap16_1i848_9{gap:var(--psi-space-16)}._trigger_vpa0u_4{display:inline-flex;width:fit-content}._menu_vpa0u_16{min-width:180px;margin:var(--psi-space-4);padding:var(--psi-space-4);border:1px solid var(--psi-menu-border);border-radius:var(--psi-menu-radius);background:var(--psi-menu-bg);color:var(--psi-menu-fg);font:var(--psi-text-14-20-regular)}._menu_vpa0u_16:not([data-open]):not(:popover-open){display:none}._item_vpa0u_37{display:flex;width:100%;align-items:center;padding:var(--psi-space-8) var(--psi-space-12);border:0;border-radius:var(--psi-radius-6);background:var(--psi-menu-item-bg);color:var(--psi-menu-item-fg);font:inherit;text-align:start;cursor:pointer}._item_vpa0u_37:hover{background:var(--psi-menu-item-bg-hover)}._item_vpa0u_37:active{background:var(--psi-menu-item-bg-active)}._item_vpa0u_37[data-variant=danger]{color:var(--psi-menu-item-fg-danger)}._item_vpa0u_37[aria-disabled=true]{color:var(--psi-menu-item-fg-disabled);cursor:default}._item_vpa0u_37[aria-disabled=true]:hover{background:var(--psi-menu-item-bg)}._separator_vpa0u_74{height:0;margin:var(--psi-space-4) 0;border-top:1px solid var(--psi-menu-separator-border)}@supports (anchor-name: --x){._menu_vpa0u_16{position:fixed;margin:var(--psi-space-4);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}._menu_vpa0u_16[data-placement=bottom-start]{position-area:block-end span-inline-end}._menu_vpa0u_16[data-placement=bottom-end]{position-area:block-end span-inline-start}._menu_vpa0u_16[data-placement=top-start]{position-area:block-start span-inline-end}._menu_vpa0u_16[data-placement=top-end]{position-area:block-start span-inline-start}}._table_146hc_3{width:100%;border-collapse:collapse;background:var(--psi-table-bg);color:var(--psi-table-fg);font:var(--psi-text-14-20-regular);border:1px solid var(--psi-table-border);border-radius:var(--psi-table-radius)}._headerCell_146hc_13{color:var(--psi-table-header-fg);font:var(--psi-text-14-20-medium);text-align:start}._cell_146hc_19,._headerCell_146hc_13{border-bottom:1px solid var(--psi-table-cell-border)}._cell_146hc_19[data-numeric],._headerCell_146hc_13[data-numeric]{text-align:end;font-variant-numeric:var(--psi-font-variant-numeric)}._sortButton_146hc_30{display:inline-flex;align-items:center;gap:var(--psi-space-4);padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}._sortButton_146hc_30:focus-visible{outline:2px solid var(--psi-table-focus-ring);outline-offset:2px}._sortIndicator_146hc_47{color:var(--psi-table-sort-indicator-fg)}._table_146hc_3[data-size="32"] ._cell_146hc_19,._table_146hc_3[data-size="32"] ._headerCell_146hc_13{height:var(--psi-table-32-row-height);padding-inline:var(--psi-table-32-cell-padding-x)}._table_146hc_3[data-size="40"] ._cell_146hc_19,._table_146hc_3[data-size="40"] ._headerCell_146hc_13{height:var(--psi-table-40-row-height);padding-inline:var(--psi-table-40-cell-padding-x)}._table_146hc_3[data-size="48"] ._cell_146hc_19,._table_146hc_3[data-size="48"] ._headerCell_146hc_13{height:var(--psi-table-48-row-height);padding-inline:var(--psi-table-48-cell-padding-x)}._table_146hc_3[data-size] ._selectCell_146hc_79{width:1%;padding-inline-end:0}._body_146hc_86 ._row_146hc_89:hover{background:var(--psi-table-row-bg-hover)}._body_146hc_86 ._row_146hc_89[data-selected]:hover,._row_146hc_89[data-selected]{background:var(--psi-table-row-bg-selected)}._row_146hc_89{background:var(--psi-table-row-bg)}._sticky_146hc_111 ._headerCell_146hc_13{position:sticky;inset-block-start:0;z-index:var(--psi-z-sticky);background:var(--psi-table-bg);box-shadow:inset 0 -1px 0 var(--psi-table-cell-border)}._nav_166vs_6{display:flex;align-items:center;gap:var(--psi-space-4)}._ellipsis_166vs_12{padding-inline:var(--psi-space-4)}._toast_7toru_10{pointer-events:auto;display:grid;grid-template-columns:auto 1fr auto auto;align-items:center;gap:var(--psi-space-12);min-width:280px;max-width:420px;padding:var(--psi-space-12) var(--psi-space-16);border:1px solid var(--psi-toast-border);border-radius:var(--psi-toast-radius);background:var(--psi-toast-bg);color:var(--psi-toast-fg);font:var(--psi-text-14-20-regular);animation:_toast-enter_7toru_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _toast-enter_7toru_1{0%{opacity:0;transform:translateY(8px)}}._icon_7toru_39{display:inline-flex;align-items:center}._iconNeutral_7toru_44{color:var(--psi-toast-icon-fg-neutral)}._iconSuccess_7toru_45{color:var(--psi-toast-icon-fg-success)}._iconWarning_7toru_46{color:var(--psi-toast-icon-fg-warning)}._iconDanger_7toru_47{color:var(--psi-toast-icon-fg-danger)}._body_7toru_51{min-width:0}._action_7toru_55{display:inline-flex}._srOnly_7toru_60{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._region_7toru_74{position:fixed;inset:auto;margin:0;padding:var(--psi-space-16);border:0;background:none;overflow:visible;pointer-events:none;display:flex;flex-direction:column;gap:var(--psi-space-8);width:max-content;max-width:100%}._region_7toru_74[data-placement=top-start]{top:0;left:0;align-items:flex-start}._region_7toru_74[data-placement=top-end]{top:0;right:0;align-items:flex-end}._region_7toru_74[data-placement=bottom-start]{bottom:0;left:0;align-items:flex-start}._region_7toru_74[data-placement=bottom-end]{bottom:0;right:0;align-items:flex-end}._region_7toru_74[data-placement^=bottom] ._live_7toru_104{flex-direction:column-reverse}._live_7toru_104{display:flex;flex-direction:column;gap:var(--psi-space-8)}
|
|
1
|
+
._button_c94w9_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;font-family:var(--psi-font-sans);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._button_c94w9_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._button_c94w9_3:disabled{opacity:.4;cursor:not-allowed}._button_c94w9_3._disabled_c94w9_30{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_c94w9_44{height:var(--psi-button-24-height);padding-inline:var(--psi-button-24-padding-inline);gap:var(--psi-button-24-gap);font:var(--psi-button-font, var(--psi-button-24-font))}._size24_c94w9_44:has(>svg:first-child){padding-inline-start:var(--psi-button-24-padding-inline-icon)}._size32_c94w9_54{height:var(--psi-button-32-height);padding-inline:var(--psi-button-32-padding-inline);gap:var(--psi-button-32-gap);font:var(--psi-button-font, var(--psi-button-32-font))}._size32_c94w9_54:has(>svg:first-child){padding-inline-start:var(--psi-button-32-padding-inline-icon)}._size40_c94w9_64{height:var(--psi-button-40-height);padding-inline:var(--psi-button-40-padding-inline);gap:var(--psi-button-40-gap);font:var(--psi-button-font, var(--psi-button-40-font))}._size40_c94w9_64:has(>svg:first-child){padding-inline-start:var(--psi-button-40-padding-inline-icon)}._size48_c94w9_74{height:var(--psi-button-48-height);padding-inline:var(--psi-button-48-padding-inline);gap:var(--psi-button-48-gap);font:var(--psi-button-font, var(--psi-button-48-font))}._size48_c94w9_74:has(>svg:first-child){padding-inline-start:var(--psi-button-48-padding-inline-icon)}._accent_c94w9_87{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_c94w9_87:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-hover)}._accent_c94w9_87:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-active)}._accentSubtle_c94w9_99{background:var(--psi-button-accent-subtle-bg);color:var(--psi-button-accent-subtle-fg)}._accentSubtle_c94w9_99:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-hover)}._accentSubtle_c94w9_99:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-active)}._neutral_c94w9_111{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_c94w9_111:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-hover)}._neutral_c94w9_111:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-active)}._neutralSubtle_c94w9_123{background:var(--psi-button-neutral-subtle-bg);color:var(--psi-button-neutral-subtle-fg)}._neutralSubtle_c94w9_123:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-hover)}._neutralSubtle_c94w9_123:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-active)}._ghost_c94w9_135{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_c94w9_135:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-hover)}._ghost_c94w9_135:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-active)}._danger_c94w9_147{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_c94w9_147:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-hover)}._danger_c94w9_147:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-active)}._dangerSubtle_c94w9_159{background:var(--psi-button-danger-subtle-bg);color:var(--psi-button-danger-subtle-fg)}._dangerSubtle_c94w9_159:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-hover)}._dangerSubtle_c94w9_159:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-active)}._outline_c94w9_171{background:var(--psi-button-outline-bg);color:var(--psi-button-outline-fg);border:1px solid var(--psi-button-outline-border)}._outline_c94w9_171:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-hover);color:var(--psi-button-outline-fg-hover);border-color:transparent}._outline_c94w9_171:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-active)}._iconButton_129ca_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;padding:0;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._iconButton_129ca_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._iconButton_129ca_3:disabled{opacity:.4;cursor:not-allowed}._iconButton_129ca_3._disabled_129ca_29{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_129ca_37{width:var(--psi-button-24-height);height:var(--psi-button-24-height)}._size32_129ca_42{width:var(--psi-button-32-height);height:var(--psi-button-32-height)}._size40_129ca_47{width:var(--psi-button-40-height);height:var(--psi-button-40-height)}._size48_129ca_52{width:var(--psi-button-48-height);height:var(--psi-button-48-height)}._accent_129ca_60{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_129ca_60:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-hover)}._accent_129ca_60:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-active)}._neutral_129ca_72{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_129ca_72:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-hover)}._neutral_129ca_72:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-active)}._ghost_129ca_84{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_129ca_84:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-hover)}._ghost_129ca_84:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-active)}._danger_129ca_96{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_129ca_96:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-hover)}._danger_129ca_96:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-active)}._card_1btb3_1{background:var(--psi-card-bg);border:1px solid var(--psi-card-border);border-radius:var(--psi-card-radius);overflow:hidden}._stacked_1btb3_8{display:flex;flex-direction:column;gap:var(--psi-card-gap)}._featured_1btb3_10{display:grid;grid-template-columns:1.6fr 1fr;gap:var(--psi-card-gap);align-items:start}@media(max-width:960px){._featured_1btb3_10{grid-template-columns:1fr}}._media_1btb3_22{min-width:0}._body_1btb3_23{min-width:0;display:flex;flex-direction:column;gap:var(--psi-card-gap);padding:var(--psi-card-gap)}._hoverLift_1btb3_31{transition:transform var(--psi-duration-350) var(--psi-ease-standard)}._hoverLift_1btb3_31:hover{transform:translateY(-6px)}._panel_jn8w4_1{background:var(--psi-panel-bg);border:1px solid var(--psi-panel-border);border-radius:var(--psi-panel-radius);padding:var(--psi-panel-padding)}._padding16_jn8w4_8{padding:var(--psi-space-16)}._navbar_1gyow_1{font:var(--psi-text-14-20-medium);position:sticky;top:0;z-index:var(--psi-z-nav);background:var(--psi-navbar-bg);backdrop-filter:blur(var(--psi-navbar-blur));-webkit-backdrop-filter:blur(var(--psi-navbar-blur));border-bottom:1px solid var(--psi-navbar-border)}._inner_1gyow_12{display:flex;align-items:center;gap:var(--psi-space-24);height:var(--psi-navbar-height)}._brand_1gyow_19{display:flex;align-items:center}._links_1gyow_20{display:flex;align-items:center;gap:var(--psi-space-20);margin-inline-start:auto}._links_1gyow_20 a,._brand_1gyow_19 a{text-decoration:none;transition:color var(--psi-duration-150) var(--psi-ease-soft)}._links_1gyow_20 a{color:var(--psi-navbar-link-fg)}._links_1gyow_20 a:hover,._brand_1gyow_19 a{color:var(--psi-navbar-link-fg-hover)}._links_1gyow_20 a:focus-visible,._brand_1gyow_19 a:focus-visible{outline:2px solid var(--psi-navbar-focus-ring);outline-offset:2px}._actions_1gyow_50{display:flex;align-items:center;gap:var(--psi-space-8)}._frame_et4fc_1{overflow:hidden}._frame_et4fc_1>img,._frame_et4fc_1>video{width:100%;height:100%;object-fit:cover;display:block}._field_lplye_1{display:grid;gap:var(--psi-field-gap);border:0;margin:0;padding:0;min-width:0}._label_lplye_10{font:var(--psi-text-14-20-medium);color:var(--psi-field-label-fg);padding:0}._marker_lplye_16{color:var(--psi-field-marker-fg)}._message_lplye_20{margin:0;font:var(--psi-text-12-16-regular);color:var(--psi-field-message-fg)}._invalid_lplye_26 ._message_lplye_20{color:var(--psi-field-error-fg)}._dialog_h5f0e_2{padding:0;border:1px solid var(--psi-dialog-border);border-radius:var(--psi-dialog-radius);background:var(--psi-dialog-bg);color:var(--psi-dialog-fg);max-width:calc(100vw - var(--psi-space-32))}._dialog_h5f0e_2::backdrop{background:var(--psi-dialog-backdrop)}._dialog_h5f0e_2[open]::backdrop{animation:_backdrop-enter_h5f0e_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _backdrop-enter_h5f0e_1{0%{opacity:0}}._center_h5f0e_32[open]{animation:_dialog-enter_h5f0e_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _dialog-enter_h5f0e_1{0%{opacity:0;transform:scale(.97)}}._inlineStart_h5f0e_40,._inlineEnd_h5f0e_41{box-sizing:border-box;margin-block:0;height:100dvh;max-height:100dvh;max-width:100vw;border-radius:0}._inlineEnd_h5f0e_41{margin-inline-start:auto;margin-inline-end:0;border-start-start-radius:var(--psi-dialog-radius);border-end-start-radius:var(--psi-dialog-radius)}._inlineStart_h5f0e_40{margin-inline-start:0;margin-inline-end:auto;border-start-end-radius:var(--psi-dialog-radius);border-end-end-radius:var(--psi-dialog-radius)}._inlineEnd_h5f0e_41[open]{animation:_drawer-enter-end_h5f0e_1 var(--psi-duration-200) var(--psi-ease-soft)}._inlineStart_h5f0e_40[open]{animation:_drawer-enter-start_h5f0e_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _drawer-enter-end_h5f0e_1{0%{transform:translate(100%)}}@keyframes _drawer-enter-start_h5f0e_1{0%{transform:translate(-100%)}}._w400_h5f0e_90{width:400px}._w560_h5f0e_91{width:560px}._w720_h5f0e_92{width:720px}._panel_h5f0e_94{display:grid;gap:var(--psi-space-16);padding:var(--psi-space-24)}._inlineStart_h5f0e_40 ._panel_h5f0e_94,._inlineEnd_h5f0e_41 ._panel_h5f0e_94{height:100%;overflow-y:auto;align-content:start}._header_h5f0e_114{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--psi-space-12)}._title_h5f0e_121{margin:0;font:var(--psi-text-18-28-medium);color:var(--psi-dialog-title-fg)}._footer_h5f0e_127{display:flex;justify-content:flex-end;gap:var(--psi-space-8)}._input_hpei8_3{display:block;width:100%;border:1px solid var(--psi-input-border);border-radius:var(--psi-input-radius);background:var(--psi-input-bg);color:var(--psi-input-fg);font-family:var(--psi-font-sans);transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._input_hpei8_3::placeholder{color:var(--psi-input-placeholder)}._input_hpei8_3:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-hover)}._input_hpei8_3:focus{outline:2px solid var(--psi-input-focus-ring);outline-offset:-1px;border-color:transparent}._input_hpei8_3:disabled{opacity:.4;cursor:not-allowed}._size24_hpei8_37{height:var(--psi-input-24-height);padding-inline:var(--psi-input-24-padding-inline);font:var(--psi-input-24-font)}._size32_hpei8_43{height:var(--psi-input-32-height);padding-inline:var(--psi-input-32-padding-inline);font:var(--psi-input-32-font)}._size40_hpei8_49{height:var(--psi-input-40-height);padding-inline:var(--psi-input-40-padding-inline);font:var(--psi-input-40-font)}._size48_hpei8_55{height:var(--psi-input-48-height);padding-inline:var(--psi-input-48-padding-inline);font:var(--psi-input-48-font)}._error_hpei8_63{border-color:var(--psi-input-border-error)}._error_hpei8_63:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-error)}._select_4x9ck_3{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid var(--psi-select-border);border-radius:var(--psi-select-radius);background-color:var(--psi-select-bg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;color:var(--psi-select-fg);font-family:var(--psi-font-sans);cursor:pointer;transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._select_4x9ck_3:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-hover)}._select_4x9ck_3:focus{outline:2px solid var(--psi-select-focus-ring);outline-offset:-1px;border-color:transparent}._select_4x9ck_3:disabled{opacity:.4;cursor:not-allowed}._size24_4x9ck_37{height:var(--psi-select-24-height);padding-inline-start:var(--psi-select-24-padding-inline);padding-inline-end:var(--psi-select-24-padding-inline-end);background-position:right var(--psi-select-24-chevron-offset) center;font:var(--psi-select-24-font)}._size32_4x9ck_45{height:var(--psi-select-32-height);padding-inline-start:var(--psi-select-32-padding-inline);padding-inline-end:var(--psi-select-32-padding-inline-end);background-position:right var(--psi-select-32-chevron-offset) center;font:var(--psi-select-32-font)}._size40_4x9ck_53{height:var(--psi-select-40-height);padding-inline-start:var(--psi-select-40-padding-inline);padding-inline-end:var(--psi-select-40-padding-inline-end);background-position:right var(--psi-select-40-chevron-offset) center;font:var(--psi-select-40-font)}._size48_4x9ck_61{height:var(--psi-select-48-height);padding-inline-start:var(--psi-select-48-padding-inline);padding-inline-end:var(--psi-select-48-padding-inline-end);background-position:right var(--psi-select-48-chevron-offset) center;font:var(--psi-select-48-font)}._error_4x9ck_71{border-color:var(--psi-select-border-error)}._error_4x9ck_71:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-error)}._label_1v4vv_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-checkbox-fg)}._disabled_1v4vv_13{opacity:.4;cursor:not-allowed}._input_1v4vv_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._indicator_1v4vv_34{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;border:1px solid var(--psi-checkbox-box-border);border-radius:var(--psi-checkbox-box-radius);background:var(--psi-checkbox-box-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard),border-color var(--psi-duration-150) var(--psi-ease-standard)}._input_1v4vv_20:checked+._indicator_1v4vv_34{background:var(--psi-checkbox-box-bg-checked);border-color:var(--psi-checkbox-box-border-checked)}._input_1v4vv_20:checked+._indicator_1v4vv_34:after{content:"";display:block;width:4px;height:8px;color:var(--psi-checkbox-check-fg);border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translate(-.5px,-.5px)}._input_1v4vv_20:focus-visible+._indicator_1v4vv_34{outline:2px solid var(--psi-checkbox-focus-ring);outline-offset:2px}._text_1v4vv_75{color:var(--psi-checkbox-fg)}._label_jru2c_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-switch-fg)}._disabled_jru2c_13{opacity:.4;cursor:not-allowed}._input_jru2c_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._track_jru2c_34{position:relative;display:inline-flex;align-items:center;width:36px;height:20px;flex-shrink:0;border-radius:var(--psi-radius-full);background:var(--psi-switch-track-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard)}._input_jru2c_20:checked+._track_jru2c_34{background:var(--psi-switch-track-bg-checked)}._input_jru2c_20:focus-visible+._track_jru2c_34{outline:2px solid var(--psi-switch-focus-ring);outline-offset:2px}._thumb_jru2c_58{position:absolute;width:16px;height:16px;border-radius:var(--psi-radius-full);background:var(--psi-switch-thumb-bg);left:2px;transition:left var(--psi-duration-150) var(--psi-ease-standard);box-shadow:0 1px 2px #00000029}._input_jru2c_20:checked+._track_jru2c_34 ._thumb_jru2c_58{left:18px}._text_jru2c_75{color:var(--psi-switch-fg)}._tag_3oysa_3{display:inline-flex;align-items:center;gap:var(--psi-space-4);height:24px;padding-inline:var(--psi-space-8);border-radius:var(--psi-radius-full);font:var(--psi-text-12-16-medium);white-space:nowrap;-webkit-user-select:none;user-select:none}._dismiss_3oysa_17{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:none;color:inherit;cursor:pointer;opacity:.7;margin-inline-start:var(--psi-space-2);margin-inline-end:calc(-1 * var(--psi-space-4));border-radius:var(--psi-radius-full)}._dismiss_3oysa_17:hover{opacity:1}._dismiss_3oysa_17:focus-visible{outline:2px solid var(--psi-tag-focus-ring);outline-offset:2px}._neutral_3oysa_43{background:var(--psi-tag-neutral-bg);color:var(--psi-tag-neutral-fg)}._accent_3oysa_48{background:var(--psi-tag-accent-bg);color:var(--psi-tag-accent-fg)}._success_3oysa_53{background:var(--psi-tag-success-bg);color:var(--psi-tag-success-fg)}._warning_3oysa_58{background:var(--psi-tag-warning-bg);color:var(--psi-tag-warning-fg)}._danger_3oysa_63{background:var(--psi-tag-danger-bg);color:var(--psi-tag-danger-fg)}._neutralSubtle_3oysa_70{background:var(--psi-tag-neutral-subtle-bg);color:var(--psi-tag-neutral-subtle-fg)}._accentSubtle_3oysa_75{background:var(--psi-tag-accent-subtle-bg);color:var(--psi-tag-accent-subtle-fg)}._successSubtle_3oysa_80{background:var(--psi-tag-success-subtle-bg);color:var(--psi-tag-success-subtle-fg)}._warningSubtle_3oysa_85{background:var(--psi-tag-warning-subtle-bg);color:var(--psi-tag-warning-subtle-fg)}._dangerSubtle_3oysa_90{background:var(--psi-tag-danger-subtle-bg);color:var(--psi-tag-danger-subtle-fg)}._wrapper_1eu6z_3{position:relative;display:inline-flex}._tooltip_1eu6z_10{position:absolute;z-index:var(--psi-z-tooltip);padding:var(--psi-space-4) var(--psi-space-8);border-radius:var(--psi-tooltip-radius);background:var(--psi-tooltip-bg);color:var(--psi-tooltip-fg);font:var(--psi-text-12-16-regular);white-space:nowrap;pointer-events:none}._top_1eu6z_24{bottom:100%;left:50%;transform:translate(-50%);margin-bottom:var(--psi-space-4)}._bottom_1eu6z_31{top:100%;left:50%;transform:translate(-50%);margin-top:var(--psi-space-4)}._left_1eu6z_38{right:100%;top:50%;transform:translateY(-50%);margin-right:var(--psi-space-4)}._right_1eu6z_45{left:100%;top:50%;transform:translateY(-50%);margin-left:var(--psi-space-4)}._toolbar_1i848_1{display:flex;flex-wrap:wrap;align-items:center}._gap8_1i848_7{gap:var(--psi-space-8)}._gap12_1i848_8{gap:var(--psi-space-12)}._gap16_1i848_9{gap:var(--psi-space-16)}._trigger_vpa0u_4{display:inline-flex;width:fit-content}._menu_vpa0u_16{min-width:180px;margin:var(--psi-space-4);padding:var(--psi-space-4);border:1px solid var(--psi-menu-border);border-radius:var(--psi-menu-radius);background:var(--psi-menu-bg);color:var(--psi-menu-fg);font:var(--psi-text-14-20-regular)}._menu_vpa0u_16:not([data-open]):not(:popover-open){display:none}._item_vpa0u_37{display:flex;width:100%;align-items:center;padding:var(--psi-space-8) var(--psi-space-12);border:0;border-radius:var(--psi-radius-6);background:var(--psi-menu-item-bg);color:var(--psi-menu-item-fg);font:inherit;text-align:start;cursor:pointer}._item_vpa0u_37:hover{background:var(--psi-menu-item-bg-hover)}._item_vpa0u_37:active{background:var(--psi-menu-item-bg-active)}._item_vpa0u_37[data-variant=danger]{color:var(--psi-menu-item-fg-danger)}._item_vpa0u_37[aria-disabled=true]{color:var(--psi-menu-item-fg-disabled);cursor:default}._item_vpa0u_37[aria-disabled=true]:hover{background:var(--psi-menu-item-bg)}._separator_vpa0u_74{height:0;margin:var(--psi-space-4) 0;border-top:1px solid var(--psi-menu-separator-border)}@supports (anchor-name: --x){._menu_vpa0u_16{position:fixed;margin:var(--psi-space-4);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}._menu_vpa0u_16[data-placement=bottom-start]{position-area:block-end span-inline-end}._menu_vpa0u_16[data-placement=bottom-end]{position-area:block-end span-inline-start}._menu_vpa0u_16[data-placement=top-start]{position-area:block-start span-inline-end}._menu_vpa0u_16[data-placement=top-end]{position-area:block-start span-inline-start}}._table_146hc_3{width:100%;border-collapse:collapse;background:var(--psi-table-bg);color:var(--psi-table-fg);font:var(--psi-text-14-20-regular);border:1px solid var(--psi-table-border);border-radius:var(--psi-table-radius)}._headerCell_146hc_13{color:var(--psi-table-header-fg);font:var(--psi-text-14-20-medium);text-align:start}._cell_146hc_19,._headerCell_146hc_13{border-bottom:1px solid var(--psi-table-cell-border)}._cell_146hc_19[data-numeric],._headerCell_146hc_13[data-numeric]{text-align:end;font-variant-numeric:var(--psi-font-variant-numeric)}._sortButton_146hc_30{display:inline-flex;align-items:center;gap:var(--psi-space-4);padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}._sortButton_146hc_30:focus-visible{outline:2px solid var(--psi-table-focus-ring);outline-offset:2px}._sortIndicator_146hc_47{color:var(--psi-table-sort-indicator-fg)}._table_146hc_3[data-size="32"] ._cell_146hc_19,._table_146hc_3[data-size="32"] ._headerCell_146hc_13{height:var(--psi-table-32-row-height);padding-inline:var(--psi-table-32-cell-padding-x)}._table_146hc_3[data-size="40"] ._cell_146hc_19,._table_146hc_3[data-size="40"] ._headerCell_146hc_13{height:var(--psi-table-40-row-height);padding-inline:var(--psi-table-40-cell-padding-x)}._table_146hc_3[data-size="48"] ._cell_146hc_19,._table_146hc_3[data-size="48"] ._headerCell_146hc_13{height:var(--psi-table-48-row-height);padding-inline:var(--psi-table-48-cell-padding-x)}._table_146hc_3[data-size] ._selectCell_146hc_79{width:1%;padding-inline-end:0}._body_146hc_86 ._row_146hc_89:hover{background:var(--psi-table-row-bg-hover)}._body_146hc_86 ._row_146hc_89[data-selected]:hover,._row_146hc_89[data-selected]{background:var(--psi-table-row-bg-selected)}._row_146hc_89{background:var(--psi-table-row-bg)}._sticky_146hc_111 ._headerCell_146hc_13{position:sticky;inset-block-start:0;z-index:var(--psi-z-sticky);background:var(--psi-table-bg);box-shadow:inset 0 -1px 0 var(--psi-table-cell-border)}._nav_166vs_6{display:flex;align-items:center;gap:var(--psi-space-4)}._ellipsis_166vs_12{padding-inline:var(--psi-space-4)}._toast_7toru_10{pointer-events:auto;display:grid;grid-template-columns:auto 1fr auto auto;align-items:center;gap:var(--psi-space-12);min-width:280px;max-width:420px;padding:var(--psi-space-12) var(--psi-space-16);border:1px solid var(--psi-toast-border);border-radius:var(--psi-toast-radius);background:var(--psi-toast-bg);color:var(--psi-toast-fg);font:var(--psi-text-14-20-regular);animation:_toast-enter_7toru_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _toast-enter_7toru_1{0%{opacity:0;transform:translateY(8px)}}._icon_7toru_39{display:inline-flex;align-items:center}._iconNeutral_7toru_44{color:var(--psi-toast-icon-fg-neutral)}._iconSuccess_7toru_45{color:var(--psi-toast-icon-fg-success)}._iconWarning_7toru_46{color:var(--psi-toast-icon-fg-warning)}._iconDanger_7toru_47{color:var(--psi-toast-icon-fg-danger)}._body_7toru_51{min-width:0}._action_7toru_55{display:inline-flex}._srOnly_7toru_60{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._region_7toru_74{position:fixed;inset:auto;margin:0;padding:var(--psi-space-16);border:0;background:none;overflow:visible;pointer-events:none;display:flex;flex-direction:column;gap:var(--psi-space-8);width:max-content;max-width:100%}._region_7toru_74[data-placement=top-start]{top:0;left:0;align-items:flex-start}._region_7toru_74[data-placement=top-end]{top:0;right:0;align-items:flex-end}._region_7toru_74[data-placement=bottom-start]{bottom:0;left:0;align-items:flex-start}._region_7toru_74[data-placement=bottom-end]{bottom:0;right:0;align-items:flex-end}._region_7toru_74[data-placement^=bottom] ._live_7toru_104{flex-direction:column-reverse}._live_7toru_104{display:flex;flex-direction:column;gap:var(--psi-space-8)}._tabs_17vw6_8{display:flex;flex-direction:column;gap:var(--psi-space-16)}._tabs_17vw6_8[data-orientation=vertical]{flex-direction:row;gap:var(--psi-space-24)}._list_17vw6_21{display:flex;flex-wrap:wrap;gap:var(--psi-space-4);border-bottom:1px solid var(--psi-tabs-list-border)}._tabs_17vw6_8[data-orientation=vertical] ._list_17vw6_21{flex-direction:column;flex-wrap:nowrap;border-bottom:none;border-inline-start:1px solid var(--psi-tabs-list-border)}._tab_17vw6_8{position:relative;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;background:none;cursor:pointer;height:var(--psi-tabs-40-height);padding-inline:var(--psi-tabs-40-padding-x);font:var(--psi-text-14-20-medium);color:var(--psi-tabs-fg);transition:color var(--psi-duration-150) var(--psi-ease-standard)}._tab_17vw6_8:hover:not([aria-disabled=true]){background:var(--psi-tabs-bg-hover)}._tab_17vw6_8:focus-visible{outline:2px solid var(--psi-tabs-focus-ring);outline-offset:-2px}._tab_17vw6_8[aria-disabled=true]{color:var(--psi-tabs-fg-disabled);cursor:default}._tab_17vw6_8[aria-selected=true]{color:var(--psi-tabs-fg-selected)}._tab_17vw6_8[aria-selected=true]:after{content:"";position:absolute;inset-inline:0;bottom:-1px;height:2px;background:var(--psi-tabs-indicator)}._tabs_17vw6_8[data-orientation=vertical] ._tab_17vw6_8{text-align:start}._tabs_17vw6_8[data-orientation=vertical] ._tab_17vw6_8[aria-selected=true]:after{inset-inline:auto;inset-block:0;inset-inline-start:-1px;width:2px;height:auto}._panel_17vw6_97{min-width:0}._panel_17vw6_97:focus-visible{outline:2px solid var(--psi-tabs-focus-ring);outline-offset:2px}
|
package/docs/Dialog.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
2
|
# Dialog
|
|
3
3
|
|
|
4
|
-
Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus restore come from the platform; title/footer slots, Esc/backdrop/ close-button dismissal via onClose(reason) (D50).
|
|
4
|
+
Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus restore come from the platform; title/footer slots, Esc/backdrop/ close-button dismissal via onClose(reason) (D50). `placement` moves the panel and nothing else (D66): an `inline-start` / `inline-end` Dialog is a drawer, pinned full-height to that edge, with the same modality, focus trap, focus restore and dismissal reasons as a centered one. There is deliberately no separate Drawer component — a sibling would have to duplicate or wrap all of that.
|
|
5
5
|
|
|
6
6
|
## Props
|
|
7
7
|
|
|
@@ -11,7 +11,8 @@ Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus
|
|
|
11
11
|
| `onClose` | `(reason: "esc" \| "backdrop" \| "close-button") => void` | — | yes | Called on every dismissal attempt with its source; the consumer flips `open`. |
|
|
12
12
|
| `title` | `ReactNode` | — | no | Heading; renders an <h2> wired to aria-labelledby. Without it, pass aria-label. |
|
|
13
13
|
| `footer` | `ReactNode` | — | no | Action row (Buttons — one accent per group, danger for destructive). |
|
|
14
|
-
| `width` | `400 \| 560 \| 720` | 560 | no | Panel width in px (400 \| 560 \| 720). |
|
|
14
|
+
| `width` | `400 \| 560 \| 720` | 560 | no | Panel width in px (400 \| 560 \| 720). For an `inline-*` placement this is the drawer's width; the height is always the full viewport. |
|
|
15
|
+
| `placement` | `"center" \| "inline-start" \| "inline-end"` | center | no | Where the panel sits. `inline-start` / `inline-end` pin it full-height to that edge, making it a drawer (D66). |
|
|
15
16
|
| `dismissible` | `boolean` | true | no | false = no close button, Esc and backdrop swallowed — footer is the only exit. |
|
|
16
17
|
| `ref` | `Ref<HTMLDialogElement>` | — | no | Forwarded ref to the underlying <dialog> element. |
|
|
17
18
|
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
@@ -23,7 +24,7 @@ Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus
|
|
|
23
24
|
| Esc | Dismisses via onClose('esc') when dismissible; swallowed otherwise. |
|
|
24
25
|
| Tab | Focus is trapped inside by the native <dialog> top layer; restored on close. |
|
|
25
26
|
|
|
26
|
-
Rendered with showModal(): aria-modal, inert background and focus restore come from the platform. title wires aria-labelledby; without title, pass aria-label. Backdrop click dismisses only when dismissible.
|
|
27
|
+
Rendered with showModal(): aria-modal, inert background and focus restore come from the platform. title wires aria-labelledby; without title, pass aria-label. Backdrop click dismisses only when dismissible. placement="inline-start"/"inline-end" pins the panel full-height to that edge — that is Psi's drawer, and it changes nothing about modality, the focus trap, focus restore or the dismissal reasons (D66). A drawer's panel scrolls internally so a dismissible={false} footer stays reachable.
|
|
27
28
|
|
|
28
29
|
## Theming
|
|
29
30
|
|
package/docs/Tab.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# Tab
|
|
3
|
+
|
|
4
|
+
One `role="tab"` (D67). Renders a real `<button>`. `disabled` sets `aria-disabled` rather than the `disabled` attribute, so the tab stays discoverable to assistive tech while being skipped by roving navigation — the same choice MenuItem made in D53.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `value` | `string` | — | yes | Pairs this tab with the `TabPanel` of the same value. |
|
|
11
|
+
| `children` | `ReactNode` | — | yes | Label — keep it to one or two words. |
|
|
12
|
+
| `disabled` | `boolean` | false | no | Skipped by arrow navigation and not selectable, but still announced. |
|
|
13
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
14
|
+
| `ref` | `Ref<HTMLButtonElement>` | — | no | Forwarded ref to the underlying `<button>`. |
|
|
15
|
+
|
|
16
|
+
## Keyboard & assistive tech
|
|
17
|
+
|
|
18
|
+
| Keys | Behavior |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Enter / Space | Activates (native button behavior); arrow keys already select on focus. |
|
|
21
|
+
|
|
22
|
+
Renders a real <button> with role="tab", aria-selected and aria-controls. disabled sets aria-disabled (not the disabled attribute) so the tab stays discoverable to assistive tech while being skipped by roving navigation and refused for selection — the same choice MenuItem made in D53.
|
|
23
|
+
|
|
24
|
+
## Theming
|
|
25
|
+
|
|
26
|
+
This component has no `--psi-tab-*` tokens — its styling binds scale tokens only, so there is nothing component-scoped to override. Theme changes reach it through the semantic tokens of its children and surroundings.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## Rules
|
|
31
|
+
|
|
32
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
33
|
+
- danger only for actions with real consequences.
|
|
34
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
35
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
36
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
37
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
38
|
+
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
|
|
39
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/TabList.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# TabList
|
|
3
|
+
|
|
4
|
+
The `role="tablist"` container (D67). Owns the roving tabindex: the whole list is one Tab stop, and the arrow keys move between tabs inside it.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `aria-label` | `string` | — | no | Accessible name for the tab set. Declared here rather than inherited so docgen keeps it in the manifest (D60) — a tablist without a name is announced as an unlabelled group, and the prop would otherwise be invisible to an agent reading the manifest. |
|
|
11
|
+
| `children` | `ReactNode` | — | yes | One `Tab` per view. |
|
|
12
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
13
|
+
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the tablist element. |
|
|
14
|
+
|
|
15
|
+
## Keyboard & assistive tech
|
|
16
|
+
|
|
17
|
+
| Keys | Behavior |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Arrow Left / Arrow Right | Horizontal orientation: moves to the previous/next enabled tab, wrapping at both ends. Selection follows focus (automatic activation). |
|
|
20
|
+
| Arrow Up / Arrow Down | Vertical orientation: the same, on the block axis. The cross-axis arrows are ignored rather than swallowed. |
|
|
21
|
+
| Home / End | Jumps to the first or last enabled tab. |
|
|
22
|
+
|
|
23
|
+
Renders role="tablist" with aria-orientation. Requires an accessible name — pass aria-label, which is promoted onto its own props interface (D60) so the manifest shows it. Owns the roving tabindex: exactly one tab is in the page tab order at a time.
|
|
24
|
+
|
|
25
|
+
## Theming
|
|
26
|
+
|
|
27
|
+
This component has no `--psi-tab-list-*` tokens — its styling binds scale tokens only, so there is nothing component-scoped to override. Theme changes reach it through the semantic tokens of its children and surroundings.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
34
|
+
- danger only for actions with real consequences.
|
|
35
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
36
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
37
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
38
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
39
|
+
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
|
|
40
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/TabPanel.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# TabPanel
|
|
3
|
+
|
|
4
|
+
One `role="tabpanel"` (D67). Every panel renders; unselected ones carry `hidden`. Returning null instead would leave `aria-controls` on every unselected tab pointing at an element that does not exist, and would throw away DOM state — a half-filled form in a panel would lose its values on each tab switch. The cost is a heavier DOM when panels are large; the answer to that is rendering less inside the panel, not unmounting it behind the consumer's back. `tabIndex={0}` because a panel whose content has no focusable element would otherwise be unreachable by keyboard.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `value` | `string` | — | yes | Pairs this panel with the `Tab` of the same value. |
|
|
11
|
+
| `children` | `ReactNode` | — | yes | The view for this tab. Rendered even when unselected, then `hidden`. |
|
|
12
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
13
|
+
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the panel element. |
|
|
14
|
+
|
|
15
|
+
## Keyboard & assistive tech
|
|
16
|
+
|
|
17
|
+
| Keys | Behavior |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Tab | The panel itself is a tab stop (tabIndex=0), so a panel whose content has no focusable element is still reachable. |
|
|
20
|
+
|
|
21
|
+
Renders role="tabpanel" with aria-labelledby pointing back at its tab. Unselected panels stay in the DOM with `hidden`.
|
|
22
|
+
|
|
23
|
+
## Theming
|
|
24
|
+
|
|
25
|
+
This component has no `--psi-tab-panel-*` tokens — its styling binds scale tokens only, so there is nothing component-scoped to override. Theme changes reach it through the semantic tokens of its children and surroundings.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Rules
|
|
30
|
+
|
|
31
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
32
|
+
- danger only for actions with real consequences.
|
|
33
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
34
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
35
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
36
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
37
|
+
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
|
|
38
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Tabs.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# Tabs
|
|
3
|
+
|
|
4
|
+
Tab set root (D67) — holds no selection state of its own, following D50, D53 and D62: `value` and `onValueChange` are required and there is no `defaultValue`. Values are strings rather than indices because an index breaks the moment a tab is inserted, and real tab sets map to ids. `Tab` and `TabPanel` pair by value, so their source order need not match. Activation is automatic: arrow keys move focus and selection together. That is the APG default where panel content is already available, and manual activation is deliberately not offered as a mode — a consumer for whom activating a panel is expensive already controls what the panel renders.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `value` | `string` | — | yes | Controlled selected tab, matched against each `Tab`/`TabPanel` value. |
|
|
11
|
+
| `onValueChange` | `(value: string) => void` | — | yes | Fires with the newly selected value; the consumer flips `value`. |
|
|
12
|
+
| `orientation` | `"horizontal" \| "vertical"` | horizontal | no | Axis of the tab list, which also picks the arrow keys. |
|
|
13
|
+
| `children` | `ReactNode` | — | yes | A `TabList` and one `TabPanel` per tab. |
|
|
14
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
15
|
+
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the wrapper `<div>`. |
|
|
16
|
+
|
|
17
|
+
## Keyboard & assistive tech
|
|
18
|
+
|
|
19
|
+
| Keys | Behavior |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Tab | Enters the tab list at its selected tab (one stop for the whole list), then moves on to the active panel. |
|
|
22
|
+
|
|
23
|
+
Controlled-only (D67): value and onValueChange are required and Tabs never selects itself. Tab and TabPanel pair by string value, not index, so their source order need not match. Every panel renders and unselected ones carry `hidden`, so aria-controls always resolves and panel DOM state survives a switch.
|
|
24
|
+
|
|
25
|
+
## Theming
|
|
26
|
+
|
|
27
|
+
Override `--psi-tabs-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
34
|
+
- danger only for actions with real consequences.
|
|
35
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
36
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
37
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
38
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
39
|
+
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
|
|
40
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|