@handamade/psi-react 0.19.0 → 0.21.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/AppShell/AppShell.d.ts +51 -0
- package/dist/AppShell/AppShell.d.ts.map +1 -0
- package/dist/Banner/Banner.d.ts +35 -0
- package/dist/Banner/Banner.d.ts.map +1 -0
- package/dist/Button/Button.d.ts +4 -0
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/CopyButton/CopyButton.d.ts +23 -0
- package/dist/CopyButton/CopyButton.d.ts.map +1 -0
- package/dist/CursorPagination/CursorPagination.d.ts +29 -0
- package/dist/CursorPagination/CursorPagination.d.ts.map +1 -0
- package/dist/Field/Field.d.ts +18 -3
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/useFieldControl.d.ts +40 -0
- package/dist/Field/useFieldControl.d.ts.map +1 -0
- package/dist/InlineAlert/InlineAlert.d.ts +32 -0
- package/dist/InlineAlert/InlineAlert.d.ts.map +1 -0
- package/dist/NavBar/NavBar.d.ts +10 -2
- package/dist/NavBar/NavBar.d.ts.map +1 -1
- package/dist/NavTree/NavGroup.d.ts +22 -0
- package/dist/NavTree/NavGroup.d.ts.map +1 -0
- package/dist/NavTree/NavItem.d.ts +25 -0
- package/dist/NavTree/NavItem.d.ts.map +1 -0
- package/dist/NavTree/NavTree.d.ts +23 -0
- package/dist/NavTree/NavTree.d.ts.map +1 -0
- package/dist/Skeleton/Skeleton.d.ts +22 -0
- package/dist/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/SkipLink/SkipLink.d.ts +25 -0
- package/dist/SkipLink/SkipLink.d.ts.map +1 -0
- package/dist/Table/Table.d.ts +6 -3
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/TableBody.d.ts +7 -4
- package/dist/Table/TableBody.d.ts.map +1 -1
- package/dist/Table/TableCaption.d.ts +21 -0
- package/dist/Table/TableCaption.d.ts.map +1 -0
- package/dist/Table/TableCell.d.ts +15 -5
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableHead.d.ts +5 -3
- package/dist/Table/TableHead.d.ts.map +1 -1
- package/dist/Table/TableHeaderCell.d.ts +5 -3
- package/dist/Table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Table/TableRow.d.ts +5 -3
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Toast/Announcement.d.ts +30 -0
- package/dist/Toast/Announcement.d.ts.map +1 -0
- package/dist/Toast/Toast.d.ts +16 -2
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/ToastProvider.d.ts.map +1 -1
- package/dist/Toast/ToastRegion.d.ts +16 -7
- package/dist/Toast/ToastRegion.d.ts.map +1 -1
- package/dist/Toast/status.d.ts +15 -0
- package/dist/Toast/status.d.ts.map +1 -0
- package/dist/Toast/useToast.d.ts +6 -1
- package/dist/Toast/useToast.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.d.ts +16 -4
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/a11y-meta.d.ts.map +1 -1
- package/dist/icons/IconChevronLeft.d.ts +7 -0
- package/dist/icons/IconChevronLeft.d.ts.map +1 -0
- package/dist/icons/IconLogOut.d.ts +7 -0
- package/dist/icons/IconLogOut.d.ts.map +1 -0
- package/dist/icons/IconMenu.d.ts +7 -0
- package/dist/icons/IconMenu.d.ts.map +1 -0
- package/dist/icons/IconSimCard.d.ts +7 -0
- package/dist/icons/IconSimCard.d.ts.map +1 -0
- package/dist/icons/index.d.ts +4 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/index.d.ts +30 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1373 -1032
- package/dist/manifest.json +1044 -240
- package/dist/patterns.json +671 -3
- package/dist/styles.css +1 -1
- package/docs/Announcement.md +37 -0
- package/docs/AppShell.md +46 -0
- package/docs/AspectRatio.md +1 -1
- package/docs/Banner.md +54 -0
- package/docs/Button.md +2 -1
- package/docs/Card.md +1 -1
- package/docs/Checkbox.md +1 -1
- package/docs/CopyButton.md +51 -0
- package/docs/CursorPagination.md +45 -0
- package/docs/DescriptionItem.md +1 -1
- package/docs/DescriptionList.md +1 -1
- package/docs/Dialog.md +1 -1
- package/docs/Field.md +5 -3
- package/docs/IconButton.md +1 -1
- package/docs/InlineAlert.md +53 -0
- package/docs/Input.md +1 -1
- package/docs/Menu.md +1 -1
- package/docs/MenuItem.md +1 -1
- package/docs/MenuSeparator.md +1 -1
- package/docs/NavBar.md +4 -2
- package/docs/NavGroup.md +40 -0
- package/docs/NavItem.md +40 -0
- package/docs/NavTree.md +39 -0
- package/docs/Pagination.md +1 -1
- package/docs/Panel.md +1 -1
- package/docs/Select.md +1 -1
- package/docs/Skeleton.md +50 -0
- package/docs/SkipLink.md +40 -0
- package/docs/Switch.md +1 -1
- package/docs/Tab.md +1 -1
- package/docs/TabList.md +1 -1
- package/docs/TabPanel.md +1 -1
- package/docs/Table.md +1 -1
- package/docs/TableBody.md +3 -2
- package/docs/TableCaption.md +39 -0
- package/docs/TableCell.md +5 -2
- package/docs/TableHead.md +2 -1
- package/docs/TableHeaderCell.md +2 -1
- package/docs/TableRow.md +2 -1
- package/docs/Tabs.md +1 -1
- package/docs/Tag.md +1 -1
- package/docs/Toast.md +5 -3
- package/docs/ToastProvider.md +1 -1
- package/docs/ToastRegion.md +4 -4
- package/docs/Toolbar.md +5 -3
- package/docs/Tooltip.md +1 -1
- package/llms.txt +39 -9
- package/package.json +2 -2
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)}._list_1lh3q_8{display:flex;flex-direction:column;gap:var(--psi-space-12);margin:var(--psi-space-0)}._list_1lh3q_8[data-gap="8"]{gap:var(--psi-space-8)}._list_1lh3q_8[data-gap="16"]{gap:var(--psi-space-16)}._item_1lh3q_26{display:flex;flex-direction:column;gap:var(--psi-space-4);min-width:0}._list_1lh3q_8[data-layout=inline] ._item_1lh3q_26{display:grid;grid-template-columns:auto 1fr;column-gap:var(--psi-space-16);row-gap:var(--psi-space-0);align-items:start}._term_1lh3q_44{color:var(--psi-description-list-term-fg);font:var(--psi-text-14-20-medium);min-width:0}._value_1lh3q_50{color:var(--psi-description-list-value-fg);font:var(--psi-text-14-20-regular);margin:var(--psi-space-0);min-width:0;overflow-wrap:anywhere}._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_f9su6_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_f9su6_13{opacity:.4;cursor:not-allowed}._indicator_f9su6_26{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_f9su6_42:checked+._indicator_f9su6_26{background:var(--psi-checkbox-box-bg-checked);border-color:var(--psi-checkbox-box-border-checked)}._input_f9su6_42:checked+._indicator_f9su6_26: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_f9su6_42:focus-visible+._indicator_f9su6_26{outline:2px solid var(--psi-checkbox-focus-ring);outline-offset:2px}._text_f9su6_67{color:var(--psi-checkbox-fg)}._label_16roc_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_16roc_13{opacity:.4;cursor:not-allowed}._track_16roc_26{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_16roc_38:checked+._track_16roc_26{background:var(--psi-switch-track-bg-checked)}._input_16roc_38:focus-visible+._track_16roc_26{outline:2px solid var(--psi-switch-focus-ring);outline-offset:2px}._thumb_16roc_50{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_16roc_38:checked+._track_16roc_26 ._thumb_16roc_50{left:18px}._text_16roc_67{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_16192_1{display:flex;flex-wrap:wrap;align-items:center}._gap8_16192_7{gap:var(--psi-space-8)}._gap12_16192_8{gap:var(--psi-space-12)}._gap16_16192_9{gap:var(--psi-space-16)}._toolbar_16192_1>input,._toolbar_16192_1>select{width:var(--psi-toolbar-control-width)}._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_1gxg8_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_1gxg8_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _toast-enter_1gxg8_1{0%{opacity:0;transform:translateY(8px)}}._icon_1gxg8_39{display:inline-flex;align-items:center}._iconNeutral_1gxg8_44{color:var(--psi-toast-icon-fg-neutral)}._iconSuccess_1gxg8_45{color:var(--psi-toast-icon-fg-success)}._iconWarning_1gxg8_46{color:var(--psi-toast-icon-fg-warning)}._iconDanger_1gxg8_47{color:var(--psi-toast-icon-fg-danger)}._body_1gxg8_51{min-width:0}._action_1gxg8_55{display:inline-flex}._region_1gxg8_61{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_1gxg8_61[data-placement=top-start]{top:0;left:0;align-items:flex-start}._region_1gxg8_61[data-placement=top-end]{top:0;right:0;align-items:flex-end}._region_1gxg8_61[data-placement=bottom-start]{bottom:0;left:0;align-items:flex-start}._region_1gxg8_61[data-placement=bottom-end]{bottom:0;right:0;align-items:flex-end}._region_1gxg8_61[data-placement^=bottom] ._live_1gxg8_91{flex-direction:column-reverse}._live_1gxg8_91{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}
|
|
1
|
+
._button_a3yli_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_a3yli_3:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-button-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._button_a3yli_3:disabled{opacity:.4;cursor:not-allowed}._button_a3yli_3._disabled_a3yli_30{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_a3yli_50{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_a3yli_50:has(>svg:first-child){padding-inline-start:var(--psi-button-24-padding-inline-icon)}._size24_a3yli_50:has(>svg:last-child:not(:first-child)){padding-inline-end:var(--psi-button-24-padding-inline-icon)}._size32_a3yli_63{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_a3yli_63:has(>svg:first-child){padding-inline-start:var(--psi-button-32-padding-inline-icon)}._size32_a3yli_63:has(>svg:last-child:not(:first-child)){padding-inline-end:var(--psi-button-32-padding-inline-icon)}._size40_a3yli_76{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_a3yli_76:has(>svg:first-child){padding-inline-start:var(--psi-button-40-padding-inline-icon)}._size40_a3yli_76:has(>svg:last-child:not(:first-child)){padding-inline-end:var(--psi-button-40-padding-inline-icon)}._size48_a3yli_89{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_a3yli_89:has(>svg:first-child){padding-inline-start:var(--psi-button-48-padding-inline-icon)}._size48_a3yli_89:has(>svg:last-child:not(:first-child)){padding-inline-end:var(--psi-button-48-padding-inline-icon)}._accent_a3yli_105{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_a3yli_105:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-accent-bg-hover)}._accent_a3yli_105:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-accent-bg-active)}._accentSubtle_a3yli_117{background:var(--psi-button-accent-subtle-bg);color:var(--psi-button-accent-subtle-fg)}._accentSubtle_a3yli_117:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-accent-subtle-bg-hover)}._accentSubtle_a3yli_117:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-accent-subtle-bg-active)}._neutral_a3yli_129{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_a3yli_129:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-neutral-bg-hover)}._neutral_a3yli_129:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-neutral-bg-active)}._neutralSubtle_a3yli_141{background:var(--psi-button-neutral-subtle-bg);color:var(--psi-button-neutral-subtle-fg)}._neutralSubtle_a3yli_141:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-neutral-subtle-bg-hover)}._neutralSubtle_a3yli_141:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-neutral-subtle-bg-active)}._ghost_a3yli_153{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_a3yli_153:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-ghost-bg-hover)}._ghost_a3yli_153:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-ghost-bg-active)}._danger_a3yli_165{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_a3yli_165:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-danger-bg-hover)}._danger_a3yli_165:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-danger-bg-active)}._dangerSubtle_a3yli_177{background:var(--psi-button-danger-subtle-bg);color:var(--psi-button-danger-subtle-fg)}._dangerSubtle_a3yli_177:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-danger-subtle-bg-hover)}._dangerSubtle_a3yli_177:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-danger-subtle-bg-active)}._outline_a3yli_189{background:var(--psi-button-outline-bg);color:var(--psi-button-outline-fg);border:1px solid var(--psi-button-outline-border)}._outline_a3yli_189:hover:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-outline-bg-hover);color:var(--psi-button-outline-fg-hover);border-color:transparent}._outline_a3yli_189:active:not(:disabled):not(._disabled_a3yli_30){background:var(--psi-button-outline-bg-active)}._iconButton_1q4hx_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_1q4hx_3:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-button-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._iconButton_1q4hx_3:disabled{opacity:.4;cursor:not-allowed}._iconButton_1q4hx_3._disabled_1q4hx_29{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_1q4hx_37{width:var(--psi-button-24-height);height:var(--psi-button-24-height)}._size32_1q4hx_42{width:var(--psi-button-32-height);height:var(--psi-button-32-height)}._size40_1q4hx_47{width:var(--psi-button-40-height);height:var(--psi-button-40-height)}._size48_1q4hx_52{width:var(--psi-button-48-height);height:var(--psi-button-48-height)}._accent_1q4hx_60{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_1q4hx_60:hover:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-accent-bg-hover)}._accent_1q4hx_60:active:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-accent-bg-active)}._neutral_1q4hx_72{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_1q4hx_72:hover:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-neutral-bg-hover)}._neutral_1q4hx_72:active:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-neutral-bg-active)}._ghost_1q4hx_84{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_1q4hx_84:hover:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-ghost-bg-hover)}._ghost_1q4hx_84:active:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-ghost-bg-active)}._danger_1q4hx_96{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_1q4hx_96:hover:not(:disabled):not(._disabled_1q4hx_29){background:var(--psi-button-danger-bg-hover)}._danger_1q4hx_96:active:not(:disabled):not(._disabled_1q4hx_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)}._list_1lh3q_8{display:flex;flex-direction:column;gap:var(--psi-space-12);margin:var(--psi-space-0)}._list_1lh3q_8[data-gap="8"]{gap:var(--psi-space-8)}._list_1lh3q_8[data-gap="16"]{gap:var(--psi-space-16)}._item_1lh3q_26{display:flex;flex-direction:column;gap:var(--psi-space-4);min-width:0}._list_1lh3q_8[data-layout=inline] ._item_1lh3q_26{display:grid;grid-template-columns:auto 1fr;column-gap:var(--psi-space-16);row-gap:var(--psi-space-0);align-items:start}._term_1lh3q_44{color:var(--psi-description-list-term-fg);font:var(--psi-text-14-20-medium);min-width:0}._value_1lh3q_50{color:var(--psi-description-list-value-fg);font:var(--psi-text-14-20-regular);margin:var(--psi-space-0);min-width:0;overflow-wrap:anywhere}._navbar_1w24e_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_1w24e_12{display:flex;align-items:center;gap:var(--psi-space-24);height:var(--psi-navbar-height)}._fluid_1w24e_20{padding-inline:var(--psi-navbar-gutter)}._brand_1w24e_22{display:flex;align-items:center}._links_1w24e_23{display:flex;align-items:center;gap:var(--psi-space-20);margin-inline-start:auto}._links_1w24e_23 a,._brand_1w24e_22 a{text-decoration:none;transition:color var(--psi-duration-150) var(--psi-ease-soft)}._links_1w24e_23 a{color:var(--psi-navbar-link-fg)}._links_1w24e_23 a:hover,._brand_1w24e_22 a{color:var(--psi-navbar-link-fg-hover)}._links_1w24e_23 a:focus-visible,._brand_1w24e_22 a:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-navbar-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._actions_1w24e_53{display:flex;align-items:center;gap:var(--psi-space-8)}._brand_1w24e_22+._actions_1w24e_53,._actions_1w24e_53:first-child{margin-inline-start:auto}._skipLink_1fn0y_4{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}._skipLink_1fn0y_4:focus-visible{position:fixed;inset-block-start:0;inset-inline-start:0;margin:var(--psi-space-8);z-index:var(--psi-z-overlay);display:inline-flex;align-items:center;box-sizing:border-box;width:auto;height:var(--psi-size-32);padding-inline:var(--psi-space-12);overflow:visible;clip:auto;clip-path:none;background:var(--psi-skip-link-bg);color:var(--psi-skip-link-fg);border:1px solid var(--psi-skip-link-border);border-radius:var(--psi-skip-link-radius);font:var(--psi-text-14-20-medium);text-decoration:none;outline:var(--psi-focus-ring-width) solid var(--psi-skip-link-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._navTree_y5m3t_7{display:block}._list_y5m3t_11,._groupList_y5m3t_12{display:flex;flex-direction:column;gap:var(--psi-space-2);margin:0;padding:0;list-style:none}._item_y5m3t_23 a{position:relative;display:flex;align-items:center;box-sizing:border-box;min-height:var(--psi-size-32);padding-block:var(--psi-space-4);padding-inline:var(--psi-space-12);border-radius:var(--psi-nav-tree-radius);color:var(--psi-nav-tree-item-fg);font:var(--psi-text-14-20-regular);text-decoration:none}._item_y5m3t_23 a:hover{background:var(--psi-nav-tree-item-bg-hover)}._item_y5m3t_23 a:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-nav-tree-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._item_y5m3t_23 a[aria-current=page]{background:var(--psi-nav-tree-item-bg-current);color:var(--psi-nav-tree-item-fg-current);font:var(--psi-text-14-20-medium)}._item_y5m3t_23 a[aria-current=page]:before{content:"";position:absolute;inset-block:0;inset-inline-start:0;width:3px;border-radius:var(--psi-nav-tree-radius);background:var(--psi-nav-tree-indicator)}._groupButton_y5m3t_70{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:flex;align-items:center;justify-content:space-between;gap:var(--psi-space-8);box-sizing:border-box;width:100%;min-height:var(--psi-size-32);padding-block:var(--psi-space-4);padding-inline:var(--psi-space-12);border:0;border-radius:var(--psi-nav-tree-radius);background:none;color:var(--psi-nav-tree-group-fg);font:var(--psi-text-14-20-medium);text-align:start;cursor:pointer}._groupButton_y5m3t_70:hover{background:var(--psi-nav-tree-item-bg-hover)}._groupButton_y5m3t_70:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-nav-tree-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._groupLabel_y5m3t_99{min-width:0}._chevron_y5m3t_103{flex:none;transition:transform var(--psi-duration-150) var(--psi-ease-standard)}._groupButton_y5m3t_70[aria-expanded=true] ._chevron_y5m3t_103{transform:rotate(180deg)}._groupList_y5m3t_12{padding-inline-start:var(--psi-space-12);margin-block-start:var(--psi-space-2)}._groupList_y5m3t_12[hidden]{display:none}._appShell_i1tds_10{display:grid;grid-template-rows:auto 1fr;grid-template-columns:var(--psi-app-shell-sidebar-width) minmax(0,1fr);height:100dvh}._sidebarClosed_i1tds_18{grid-template-columns:minmax(0,1fr)}._header_i1tds_22{grid-row:1;grid-column:1 / -1;min-width:0}._sidebar_i1tds_18{grid-row:2;min-height:0;overflow:auto;padding:var(--psi-space-8);background:var(--psi-app-shell-sidebar-bg);color:var(--psi-app-shell-sidebar-fg)}._sidebar_i1tds_18[hidden]{display:none}._main_i1tds_45{grid-row:2;min-width:0;min-height:0;overflow:auto}._main_i1tds_45:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-app-shell-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._frame_et4fc_1{overflow:hidden}._frame_et4fc_1>img,._frame_et4fc_1>video{width:100%;height:100%;object-fit:cover;display:block}._field_1xhfz_1{display:grid;gap:var(--psi-field-gap);border:0;margin:0;padding:0;min-width:0}._label_1xhfz_10{font:var(--psi-text-14-20-medium);color:var(--psi-field-label-fg);padding:0}._marker_1xhfz_16{color:var(--psi-field-marker-fg)}._requiredText_1xhfz_22{font:var(--psi-text-14-20-regular);color:var(--psi-field-required-text-fg)}._message_1xhfz_27{margin:0;font:var(--psi-text-12-16-regular);color:var(--psi-field-message-fg)}._invalid_1xhfz_33 ._message_1xhfz_27{color:var(--psi-field-error-fg)}._dialog_qg38y_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_qg38y_2::backdrop{background:var(--psi-dialog-backdrop)}._dialog_qg38y_2:focus-visible,._panel_qg38y_20:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-dialog-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._dialog_qg38y_2[open]::backdrop{animation:_backdrop-enter_qg38y_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _backdrop-enter_qg38y_1{0%{opacity:0}}._center_qg38y_42[open]{animation:_dialog-enter_qg38y_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _dialog-enter_qg38y_1{0%{opacity:0;transform:scale(.97)}}._inlineStart_qg38y_50,._inlineEnd_qg38y_51{box-sizing:border-box;margin-block:0;height:100dvh;max-height:100dvh;max-width:100vw;border-radius:0}._inlineEnd_qg38y_51{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_qg38y_50{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_qg38y_51[open]{animation:_drawer-enter-end_qg38y_1 var(--psi-duration-200) var(--psi-ease-soft)}._inlineStart_qg38y_50[open]{animation:_drawer-enter-start_qg38y_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _drawer-enter-end_qg38y_1{0%{transform:translate(100%)}}@keyframes _drawer-enter-start_qg38y_1{0%{transform:translate(-100%)}}._w400_qg38y_100{width:400px}._w560_qg38y_101{width:560px}._w720_qg38y_102{width:720px}._panel_qg38y_20{display:grid;gap:var(--psi-space-16);padding:var(--psi-space-24)}._inlineStart_qg38y_50 ._panel_qg38y_20,._inlineEnd_qg38y_51 ._panel_qg38y_20{height:100%;overflow-y:auto;align-content:start}._header_qg38y_124{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--psi-space-12)}._title_qg38y_131{margin:0;font:var(--psi-text-18-28-medium);color:var(--psi-dialog-title-fg)}._footer_qg38y_137{display:flex;justify-content:flex-end;gap:var(--psi-space-8)}._input_pmr7w_3{display:block;box-sizing:border-box;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_pmr7w_3::placeholder{color:var(--psi-input-placeholder)}._input_pmr7w_3:hover:not(:disabled):not(:focus-visible){border-color:var(--psi-input-border-hover)}._input_pmr7w_3:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-input-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset);border-color:transparent}._input_pmr7w_3:disabled{opacity:.4;cursor:not-allowed}._size24_pmr7w_43{height:var(--psi-input-24-height);padding-inline:var(--psi-input-24-padding-inline);font:var(--psi-input-24-font)}._size32_pmr7w_49{height:var(--psi-input-32-height);padding-inline:var(--psi-input-32-padding-inline);font:var(--psi-input-32-font)}._size40_pmr7w_55{height:var(--psi-input-40-height);padding-inline:var(--psi-input-40-padding-inline);font:var(--psi-input-40-font)}._size48_pmr7w_61{height:var(--psi-input-48-height);padding-inline:var(--psi-input-48-padding-inline);font:var(--psi-input-48-font)}._error_pmr7w_69{border-color:var(--psi-input-border-error)}._error_pmr7w_69:hover:not(:disabled):not(:focus-visible){border-color:var(--psi-input-border-error)}._select_1eqz1_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:linear-gradient(45deg,transparent calc(50% - .75px),var(--psi-select-chevron-fg) calc(50% - .75px),var(--psi-select-chevron-fg) calc(50% + .75px),transparent calc(50% + .75px)),linear-gradient(135deg,transparent calc(50% - .75px),var(--psi-select-chevron-fg) calc(50% - .75px),var(--psi-select-chevron-fg) calc(50% + .75px),transparent calc(50% + .75px));background-size:4px 4px;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_1eqz1_3:hover:not(:disabled):not(:focus-visible){border-color:var(--psi-select-border-hover)}._select_1eqz1_3:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-select-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset);border-color:transparent}._select_1eqz1_3:disabled{opacity:.4;cursor:not-allowed}._size24_1eqz1_57{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 calc(var(--psi-select-24-chevron-offset) + 6px) center,right calc(var(--psi-select-24-chevron-offset) + 2px) center;font:var(--psi-select-24-font)}._size32_1eqz1_67{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 calc(var(--psi-select-32-chevron-offset) + 6px) center,right calc(var(--psi-select-32-chevron-offset) + 2px) center;font:var(--psi-select-32-font)}._size40_1eqz1_77{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 calc(var(--psi-select-40-chevron-offset) + 6px) center,right calc(var(--psi-select-40-chevron-offset) + 2px) center;font:var(--psi-select-40-font)}._size48_1eqz1_87{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 calc(var(--psi-select-48-chevron-offset) + 6px) center,right calc(var(--psi-select-48-chevron-offset) + 2px) center;font:var(--psi-select-48-font)}._error_1eqz1_99{border-color:var(--psi-select-border-error)}._error_1eqz1_99:hover:not(:disabled):not(:focus-visible){border-color:var(--psi-select-border-error)}._label_1jm35_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_1jm35_13{opacity:.4;cursor:not-allowed}._indicator_1jm35_26{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_1jm35_42:checked+._indicator_1jm35_26{background:var(--psi-checkbox-box-bg-checked);border-color:var(--psi-checkbox-box-border-checked)}._input_1jm35_42:checked+._indicator_1jm35_26: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_1jm35_42:focus-visible+._indicator_1jm35_26{outline:var(--psi-focus-ring-width) solid var(--psi-checkbox-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._text_1jm35_67{color:var(--psi-checkbox-fg)}._label_yv464_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_yv464_13{opacity:.4;cursor:not-allowed}._track_yv464_26{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_yv464_38:checked+._track_yv464_26{background:var(--psi-switch-track-bg-checked)}._input_yv464_38:focus-visible+._track_yv464_26{outline:var(--psi-focus-ring-width) solid var(--psi-switch-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._thumb_yv464_50{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_yv464_38:checked+._track_yv464_26 ._thumb_yv464_50{left:18px}._text_yv464_67{color:var(--psi-switch-fg)}._tag_1r2xw_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_1r2xw_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_1r2xw_17:hover{opacity:1}._dismiss_1r2xw_17:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-tag-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._neutral_1r2xw_43{background:var(--psi-tag-neutral-bg);color:var(--psi-tag-neutral-fg)}._accent_1r2xw_48{background:var(--psi-tag-accent-bg);color:var(--psi-tag-accent-fg)}._success_1r2xw_53{background:var(--psi-tag-success-bg);color:var(--psi-tag-success-fg)}._warning_1r2xw_58{background:var(--psi-tag-warning-bg);color:var(--psi-tag-warning-fg)}._danger_1r2xw_63{background:var(--psi-tag-danger-bg);color:var(--psi-tag-danger-fg)}._neutralSubtle_1r2xw_70{background:var(--psi-tag-neutral-subtle-bg);color:var(--psi-tag-neutral-subtle-fg)}._accentSubtle_1r2xw_75{background:var(--psi-tag-accent-subtle-bg);color:var(--psi-tag-accent-subtle-fg)}._successSubtle_1r2xw_80{background:var(--psi-tag-success-subtle-bg);color:var(--psi-tag-success-subtle-fg)}._warningSubtle_1r2xw_85{background:var(--psi-tag-warning-subtle-bg);color:var(--psi-tag-warning-subtle-fg)}._dangerSubtle_1r2xw_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_oljum_1{display:flex;flex-wrap:wrap;align-items:center}._gap8_oljum_7{gap:var(--psi-space-8)}._gap12_oljum_8{gap:var(--psi-space-12)}._gap16_oljum_9{gap:var(--psi-space-16)}._alignEnd_oljum_13{align-items:flex-end}._toolbar_oljum_1>input,._toolbar_oljum_1>select{width:var(--psi-toolbar-control-width)}._trigger_uxpyi_4{display:inline-flex;width:fit-content}._menu_uxpyi_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_uxpyi_16:not([data-open]):not(:popover-open){display:none}._item_uxpyi_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_uxpyi_37:hover{background:var(--psi-menu-item-bg-hover)}._item_uxpyi_37:active{background:var(--psi-menu-item-bg-active)}._item_uxpyi_37:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-menu-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._item_uxpyi_37[data-variant=danger]{color:var(--psi-menu-item-fg-danger)}._item_uxpyi_37[aria-disabled=true]{color:var(--psi-menu-item-fg-disabled);cursor:default}._item_uxpyi_37[aria-disabled=true]:hover{background:var(--psi-menu-item-bg)}._separator_uxpyi_82{height:0;margin:var(--psi-space-4) 0;border-top:1px solid var(--psi-menu-separator-border)}@supports (anchor-name: --x){._menu_uxpyi_16{position:fixed;margin:var(--psi-space-4);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}._menu_uxpyi_16[data-placement=bottom-start]{position-area:block-end span-inline-end}._menu_uxpyi_16[data-placement=bottom-end]{position-area:block-end span-inline-start}._menu_uxpyi_16[data-placement=top-start]{position-area:block-start span-inline-end}._menu_uxpyi_16[data-placement=top-end]{position-area:block-start span-inline-start}}._table_1maek_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)}._caption_1maek_19{caption-side:top;text-align:start;padding-block:var(--psi-space-8);color:var(--psi-table-fg);font:var(--psi-text-14-20-medium)}._captionDetail_1maek_27{display:block;color:var(--psi-table-header-fg);font:var(--psi-text-12-16-regular)}._caption_1maek_19:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-table-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._headerCell_1maek_38{color:var(--psi-table-header-fg);font:var(--psi-text-14-20-medium);text-align:start}._cell_1maek_44,._headerCell_1maek_38{border-bottom:1px solid var(--psi-table-cell-border)}._rowHeader_1maek_51{font:var(--psi-text-14-20-medium);text-align:start}._cell_1maek_44[data-numeric],._headerCell_1maek_38[data-numeric]{text-align:end;font-variant-numeric:var(--psi-font-variant-numeric)}._sortButton_1maek_62{display:inline-flex;align-items:center;gap:var(--psi-space-4);padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}._sortButton_1maek_62:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-table-focus-ring);outline-offset:var(--psi-focus-ring-offset)}._sortIndicator_1maek_79{color:var(--psi-table-sort-indicator-fg)}._table_1maek_3[data-size="32"] ._cell_1maek_44,._table_1maek_3[data-size="32"] ._headerCell_1maek_38{height:var(--psi-table-32-row-height);padding-inline:var(--psi-table-32-cell-padding-x)}._table_1maek_3[data-size="32"] ._caption_1maek_19{padding-inline:var(--psi-table-32-cell-padding-x)}._table_1maek_3[data-size="40"] ._cell_1maek_44,._table_1maek_3[data-size="40"] ._headerCell_1maek_38{height:var(--psi-table-40-row-height);padding-inline:var(--psi-table-40-cell-padding-x)}._table_1maek_3[data-size="40"] ._caption_1maek_19{padding-inline:var(--psi-table-40-cell-padding-x)}._table_1maek_3[data-size="48"] ._cell_1maek_44,._table_1maek_3[data-size="48"] ._headerCell_1maek_38{height:var(--psi-table-48-row-height);padding-inline:var(--psi-table-48-cell-padding-x)}._table_1maek_3[data-size="48"] ._caption_1maek_19{padding-inline:var(--psi-table-48-cell-padding-x)}._table_1maek_3[data-size] ._selectCell_1maek_123{width:1%;padding-inline-end:0}._body_1maek_130 ._row_1maek_51:hover{background:var(--psi-table-row-bg-hover)}._body_1maek_130 ._row_1maek_51[data-selected]:hover,._row_1maek_51[data-selected]{background:var(--psi-table-row-bg-selected)}._row_1maek_51{background:var(--psi-table-row-bg)}._sticky_1maek_155 ._headerCell_1maek_38{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)}._nav_jbhk1_5{display:inline-flex;align-items:center;gap:var(--psi-space-8)}._toast_1gxg8_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_1gxg8_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _toast-enter_1gxg8_1{0%{opacity:0;transform:translateY(8px)}}._icon_1gxg8_39{display:inline-flex;align-items:center}._iconNeutral_1gxg8_44{color:var(--psi-toast-icon-fg-neutral)}._iconSuccess_1gxg8_45{color:var(--psi-toast-icon-fg-success)}._iconWarning_1gxg8_46{color:var(--psi-toast-icon-fg-warning)}._iconDanger_1gxg8_47{color:var(--psi-toast-icon-fg-danger)}._body_1gxg8_51{min-width:0}._action_1gxg8_55{display:inline-flex}._region_1gxg8_61{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_1gxg8_61[data-placement=top-start]{top:0;left:0;align-items:flex-start}._region_1gxg8_61[data-placement=top-end]{top:0;right:0;align-items:flex-end}._region_1gxg8_61[data-placement=bottom-start]{bottom:0;left:0;align-items:flex-start}._region_1gxg8_61[data-placement=bottom-end]{bottom:0;right:0;align-items:flex-end}._region_1gxg8_61[data-placement^=bottom] ._live_1gxg8_91{flex-direction:column-reverse}._live_1gxg8_91{display:flex;flex-direction:column;gap:var(--psi-space-8)}._banner_pco49_7{display:grid;grid-template-columns:auto 1fr auto auto;align-items:start;gap:var(--psi-space-12);width:100%;box-sizing:border-box;padding:var(--psi-space-12) var(--psi-space-16);color:var(--psi-banner-fg);font:var(--psi-text-14-20-regular)}._banner_pco49_7[data-variant=neutral]{background:var(--psi-banner-bg-neutral)}._banner_pco49_7[data-variant=success]{background:var(--psi-banner-bg-success)}._banner_pco49_7[data-variant=warning]{background:var(--psi-banner-bg-warning)}._banner_pco49_7[data-variant=danger]{background:var(--psi-banner-bg-danger)}._icon_pco49_26{display:inline-flex;align-items:center}._iconNeutral_pco49_31{color:var(--psi-banner-icon-fg-neutral)}._iconSuccess_pco49_32{color:var(--psi-banner-icon-fg-success)}._iconWarning_pco49_33{color:var(--psi-banner-icon-fg-warning)}._iconDanger_pco49_34{color:var(--psi-banner-icon-fg-danger)}._body_pco49_36{min-width:0}._title_pco49_40{display:block;font:var(--psi-text-14-20-medium)}._action_pco49_45{display:inline-flex}._inlineAlert_1tt2h_7{display:grid;grid-template-columns:auto 1fr auto;align-items:start;gap:var(--psi-space-12);box-sizing:border-box;padding:var(--psi-space-12) var(--psi-space-16);border-radius:var(--psi-inline-alert-radius);color:var(--psi-inline-alert-fg);font:var(--psi-text-14-20-regular)}._inlineAlert_1tt2h_7[data-variant=neutral]{background:var(--psi-inline-alert-bg-neutral);border:1px solid var(--psi-inline-alert-border-neutral)}._inlineAlert_1tt2h_7[data-variant=success]{background:var(--psi-inline-alert-bg-success);border:1px solid var(--psi-inline-alert-border-success)}._inlineAlert_1tt2h_7[data-variant=warning]{background:var(--psi-inline-alert-bg-warning);border:1px solid var(--psi-inline-alert-border-warning)}._inlineAlert_1tt2h_7[data-variant=danger]{background:var(--psi-inline-alert-bg-danger);border:1px solid var(--psi-inline-alert-border-danger)}._icon_1tt2h_38{display:inline-flex;align-items:center}._iconNeutral_1tt2h_43{color:var(--psi-inline-alert-icon-fg-neutral)}._iconSuccess_1tt2h_44{color:var(--psi-inline-alert-icon-fg-success)}._iconWarning_1tt2h_45{color:var(--psi-inline-alert-icon-fg-warning)}._iconDanger_1tt2h_46{color:var(--psi-inline-alert-icon-fg-danger)}._body_1tt2h_48{min-width:0}._title_1tt2h_52{display:block;font:var(--psi-text-14-20-medium)}._action_1tt2h_57{display:inline-flex}@keyframes _skeleton-pulse_1yo7t_1{0%{opacity:1}to{opacity:.45}}._skeleton_1yo7t_12{width:100%;box-sizing:border-box;animation:_skeleton-pulse_1yo7t_1 var(--psi-duration-600) var(--psi-ease-in-out) infinite alternate}._skeleton_1yo7t_12[data-variant=block]{border-radius:var(--psi-skeleton-radius);background:var(--psi-skeleton-bg)}._skeleton_1yo7t_12[data-size="24"]{height:var(--psi-size-24)}._skeleton_1yo7t_12[data-size="32"]{height:var(--psi-size-32)}._skeleton_1yo7t_12[data-size="40"]{height:var(--psi-size-40)}._skeleton_1yo7t_12[data-size="48"]{height:var(--psi-size-48)}._line_1yo7t_28{display:block;padding-block:var(--psi-space-6);margin-block:var(--psi-space-4);border-radius:var(--psi-skeleton-radius);background:var(--psi-skeleton-bg)}._line_1yo7t_28:last-child:not(:first-child){width:60%}@media(prefers-reduced-motion:reduce){._skeleton_1yo7t_12{animation:none}}._tabs_1x9om_8{display:flex;flex-direction:column;gap:var(--psi-space-16)}._tabs_1x9om_8[data-orientation=vertical]{flex-direction:row;gap:var(--psi-space-24)}._list_1x9om_21{display:flex;flex-wrap:wrap;gap:var(--psi-space-4);border-bottom:1px solid var(--psi-tabs-list-border)}._tabs_1x9om_8[data-orientation=vertical] ._list_1x9om_21{flex-direction:column;flex-wrap:nowrap;border-bottom:none;border-inline-start:1px solid var(--psi-tabs-list-border)}._tab_1x9om_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_1x9om_8:hover:not([aria-disabled=true]){background:var(--psi-tabs-bg-hover)}._tab_1x9om_8:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-tabs-focus-ring);outline-offset:var(--psi-focus-ring-offset-inset)}._tab_1x9om_8[aria-disabled=true]{color:var(--psi-tabs-fg-disabled);cursor:default}._tab_1x9om_8[aria-selected=true]{color:var(--psi-tabs-fg-selected)}._tab_1x9om_8[aria-selected=true]:after{content:"";position:absolute;inset-inline:0;bottom:-1px;height:2px;background:var(--psi-tabs-indicator)}._tabs_1x9om_8[data-orientation=vertical] ._tab_1x9om_8{text-align:start}._tabs_1x9om_8[data-orientation=vertical] ._tab_1x9om_8[aria-selected=true]:after{inset-inline:auto;inset-block:0;inset-inline-start:-1px;width:2px;height:auto}._panel_1x9om_99{min-width:0}._panel_1x9om_99:focus-visible{outline:var(--psi-focus-ring-width) solid var(--psi-tabs-focus-ring);outline-offset:var(--psi-focus-ring-offset)}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# Announcement
|
|
3
|
+
|
|
4
|
+
Text for a screen reader only, spoken through ToastRegion (D83). **It is not a live region.** It renders no `role` and no `aria-live`, and outside a ToastRegion it announces nothing — the region's two persistent wrappers are the only live regions, and an Announcement is content for one of them. Do not use it as a second announcer. Use it where an event must be spoken and there is nothing to show: a state change of the object on screen, or field errors the form already displays. `politeness` is not read here. ToastRegion reads it off the element to pick a wrapper, the same way it reads a Toast's. Controlled, like Toast: it holds no state and never removes itself. Remove it once it has been spoken. To announce the same text again, remove it and render it again with a new `key` — a live region speaks changes, and an unchanged node is not one. It takes no `className`: the one thing a class could do to it is make it visible, and then it is a Toast.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `politeness` | `"polite" \| "assertive"` | "polite" | no | Which of ToastRegion's two live wrappers speaks it. |
|
|
11
|
+
| `children` | `ReactNode` | — | yes | The text to announce. |
|
|
12
|
+
|
|
13
|
+
## Keyboard & assistive tech
|
|
14
|
+
|
|
15
|
+
| Keys | Behavior |
|
|
16
|
+
|---|---|
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
Not a live region: it renders no role and no aria-live, and outside a ToastRegion it announces nothing. It is visually hidden text that ToastRegion places in its polite or assertive wrapper, by the politeness prop (default polite) — for an event that must be spoken and has nothing to show. Keep one ToastRegion as the application's only announcer and put every Announcement inside it; never use an Announcement as a second one. Controlled like Toast: it never removes itself, so remove it once it has been spoken. To announce the same text again, remove it and render it again with a new key — a live region speaks changes, and an unchanged node is not one. Not focusable, and it takes no space in the toast stack.
|
|
20
|
+
|
|
21
|
+
## Theming
|
|
22
|
+
|
|
23
|
+
This component has no `--psi-announcement-*` 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.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
|
|
29
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
30
|
+
- danger only for actions with real consequences.
|
|
31
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
32
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
33
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
34
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
35
|
+
- 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.
|
|
36
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
37
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/AppShell.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# AppShell
|
|
3
|
+
|
|
4
|
+
The frame of an application (D88): a header row over a sidebar and a `<main>` that each scroll on their own, filling the viewport (`100dvh`). Because the header has a row of its own and `main` is its own scroller, nothing scrolls under the header, so a focused element is never obscured by it (WCAG 2.2 *Focus Not Obscured*) without `scroll-padding`. `main` carries `id={mainId}` and `tabIndex={-1}`: the target of a `SkipLink`, not a tab stop; focused by the skip link it draws the shared focus ring inside its box. A closed sidebar is `hidden`, not narrowed to icons; there is no responsive drawer and no stored open state, so this is a desktop frame. A page whose document must scroll as a whole does not use `AppShell`. Mount it at the root of the page with no margin or padding around it: it is `100dvh` tall, so anything around it makes the document scroll and slides the frame. Do not place a `ToastRegion` at `top-start` in an app with a skip link: the native top layer paints over the focused link.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `skipLink` | `ReactNode` | — | no | A `SkipLink` (D88), rendered first so it is the first tab stop. Point its `href` at `#` plus `mainId`. |
|
|
11
|
+
| `header` | `ReactNode` | — | no | The header row, usually a `NavBar` (D88). It sits in a row of its own above the sidebar and `main`, so nothing scrolls under it. |
|
|
12
|
+
| `sidebar` | `ReactNode` | — | no | The sidebar's content, usually a `NavTree` (D88). The shell wraps it in a `<div>`, not an `<aside>`: a `NavTree` is already the landmark. |
|
|
13
|
+
| `children` | `ReactNode` | — | no | The page, rendered inside `<main>` (D88). |
|
|
14
|
+
| `sidebarOpen` | `boolean` | true | no | Whether the sidebar is shown. Controlled: wire your Menu toggle's `aria-expanded` and this to one piece of state. Closed, the sidebar is `hidden`, so it leaves the layout and the accessibility tree, and stays in the DOM so the toggle's `aria-controls` keeps naming an element (D88). |
|
|
15
|
+
| `sidebarTheme` | `string` | — | no | A theme name for the sidebar alone, such as `"dark"`: sets `data-psi-theme` on the sidebar element, so every token inside re-resolves under that theme while the rest of the page keeps its own (D88). The sidebar paints `--psi-bg-primary` itself; a theme paints no background. |
|
|
16
|
+
| `sidebarId` | `string` | sidebar | no | `id` of the sidebar element, which a toggle names with `aria-controls` (D88). |
|
|
17
|
+
| `mainId` | `string` | main | no | `id` of `<main>`, which a `SkipLink`'s `href` names (D88). |
|
|
18
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
19
|
+
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the root `<div>`. |
|
|
20
|
+
|
|
21
|
+
## Keyboard & assistive tech
|
|
22
|
+
|
|
23
|
+
| Keys | Behavior |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Tab | The first stop is the skip link (when given), then the header, the sidebar's links and buttons, and the links of main, in document order. The shell adds no stop of its own: main has tabIndex={-1}. |
|
|
26
|
+
| Enter (on the skip link) | Follows the fragment href: focus moves to main, drawing the shared focus ring inside its box, and the next Tab continues from main's first link. |
|
|
27
|
+
|
|
28
|
+
A grid filling the viewport: the header sits in a row of its own and main is its own scroller, so nothing scrolls under the header and a focused element is never obscured by it (WCAG 2.2 Focus Not Obscured) without scroll-padding, which does nothing on a main that is not the document's scroller (D88). main carries id={mainId} and tabIndex={-1}, the skip link's target. A closed sidebar is `hidden`, so it leaves the layout and the accessibility tree while its id stays in the DOM for a toggle's aria-controls; the toggle's aria-expanded and sidebarOpen are wired by the consumer, since the shell is controlled and stores nothing. The sidebar is a div, not an aside: the NavTree inside is already the navigation landmark. sidebarTheme sets data-psi-theme on the sidebar alone, so its tokens re-resolve under that theme in a page that keeps its own; the sidebar paints --psi-bg-primary itself. Desktop frame only: no responsive drawer. Do not place a ToastRegion at top-start in an app with a skip link.
|
|
29
|
+
|
|
30
|
+
## Theming
|
|
31
|
+
|
|
32
|
+
Override `--psi-app-shell-*` custom properties at any scope.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Rules
|
|
37
|
+
|
|
38
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
39
|
+
- danger only for actions with real consequences.
|
|
40
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
41
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
42
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
43
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
44
|
+
- 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.
|
|
45
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
46
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/AspectRatio.md
CHANGED
|
@@ -27,5 +27,5 @@ This component has no `--psi-aspect-ratio-*` tokens — its styling binds scale
|
|
|
27
27
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
28
28
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
29
29
|
- 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.
|
|
30
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
30
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
31
31
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Banner.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# Banner
|
|
3
|
+
|
|
4
|
+
A full-width, page-level status message (D86). It is not a live region: it renders no `role` and no `aria-live`, so mounting one announces nothing, and announcing stays the application's — route the same event through a `ToastRegion` or an `Announcement` if it must be spoken. Controlled and presentational: it holds no state and never removes itself; `onDismiss` reports and the owner disposes. A tinted strip with no radius and no border, it is meant to span the page edge to edge, above the content. For the same message inside content, use `InlineAlert`.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `variant` | `"neutral" \| "success" \| "warning" \| "danger"` | neutral | no | Status variant. |
|
|
11
|
+
| `title` | `ReactNode` | — | no | A short heading, rendered before the body in the medium weight. |
|
|
12
|
+
| `children` | `ReactNode` | — | yes | The message. |
|
|
13
|
+
| `action` | `ReactNode` | — | no | Trailing affordance — a ghost Button (Review, Retry, Learn more). |
|
|
14
|
+
| `onDismiss` | `(() => void)` | — | no | When provided, renders the dismiss button and calls this. Banner does not remove itself; the owner disposes. |
|
|
15
|
+
| `statusLabel` | `string \| null` | — | no | The visually hidden status word (D83). A string replaces the default ("Success:", "Warning:", "Error:") — pass the translated word; `null` drops it. Unset keeps the default, and `neutral` has none. |
|
|
16
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
17
|
+
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the underlying `<div>`. |
|
|
18
|
+
|
|
19
|
+
## Keyboard & assistive tech
|
|
20
|
+
|
|
21
|
+
| Keys | Behavior |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Tab | Reaches the action and the dismiss button, in that order, when present. The banner itself is not focusable. |
|
|
24
|
+
| Enter / Space | Activates the focused action or the dismiss button. |
|
|
25
|
+
|
|
26
|
+
Not a live region: it renders no role and no aria-live, so mounting a Banner announces nothing; announcing stays the application's (route the same event through a ToastRegion or an Announcement if it must be spoken). Presentational and controlled (D86): onDismiss reports and the owner disposes; Banner never removes itself. The variant's meaning is carried by a visually hidden status word ("Success:", "Warning:", "Error:"), never by colour and icon shape alone; the icon is aria-hidden. neutral has no status and gets no word. statusLabel replaces that word with a translated one, or drops it with null (D83). The dismiss button is labelled "Dismiss". Put it first in the page content so it is met before the content it qualifies.
|
|
27
|
+
|
|
28
|
+
## Theming
|
|
29
|
+
|
|
30
|
+
Override `--psi-banner-*` custom properties at any scope.
|
|
31
|
+
|
|
32
|
+
## Variant guidance
|
|
33
|
+
|
|
34
|
+
- **accent** — Primary action, draws attention. Submit, CTA, main action in a group.
|
|
35
|
+
- **accent-subtle** — Accent tone, lower visual weight. Selected state, active filter, soft CTA.
|
|
36
|
+
- **neutral** — Default, structurally present. Secondary actions, toolbar buttons.
|
|
37
|
+
- **neutral-subtle** — Minimal chrome. Inline actions, table row actions.
|
|
38
|
+
- **ghost** — No visible container until hover. Icon-only triggers, compact toolbars.
|
|
39
|
+
- **outline** — Bordered ghost — visible structure, no fill until hover. Marketing CTA, download button; hover fills accent.
|
|
40
|
+
- **danger** — Destructive action. Delete, remove, disconnect.
|
|
41
|
+
- **danger-subtle** — Destructive context, low urgency. Warning badges, soft destructive hints.
|
|
42
|
+
- **success | warning** — Status communication (Tag only). Status badges, labels.
|
|
43
|
+
|
|
44
|
+
## Rules
|
|
45
|
+
|
|
46
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
47
|
+
- danger only for actions with real consequences.
|
|
48
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
49
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
50
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
51
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
52
|
+
- 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.
|
|
53
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
54
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Button.md
CHANGED
|
@@ -10,6 +10,7 @@ Action trigger. With `href` renders an anchor with identical styling (D33); `dis
|
|
|
10
10
|
| `children` | `ReactNode` | — | no | Label content. |
|
|
11
11
|
| `variant` | `"accent" \| "accent-subtle" \| "neutral" \| "neutral-subtle" \| "ghost" \| "danger" \| "danger-subtle" \| "outline"` | neutral | no | Visual variant. |
|
|
12
12
|
| `size` | `24 \| 32 \| 40 \| 48` | 32 | no | Height in px (24 \| 32 \| 40 \| 48). |
|
|
13
|
+
| `type` | `"button" \| "submit" \| "reset"` | — | no | Button type. Declared so the manifest lists it and a pattern can say `submit` (D87). No default is set: the platform's applies — `submit` inside a form, a plain button elsewhere. |
|
|
13
14
|
| `href` | `string` | — | no | Render as an anchor with this href (D33). disabled → aria-disabled, no href attribute, pointer-events: none. |
|
|
14
15
|
| `target` | `string` | — | no | Anchor target; only used with href. |
|
|
15
16
|
| `rel` | `string` | — | no | Anchor rel; only used with href. |
|
|
@@ -50,5 +51,5 @@ Override `--psi-button-*` custom properties at any scope; interactive states der
|
|
|
50
51
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
51
52
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
52
53
|
- 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.
|
|
53
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
54
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
54
55
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Card.md
CHANGED
|
@@ -39,5 +39,5 @@ Override `--psi-card-*` custom properties at any scope.
|
|
|
39
39
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
40
40
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
41
41
|
- 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.
|
|
42
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
42
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
43
43
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Checkbox.md
CHANGED
|
@@ -34,5 +34,5 @@ Override `--psi-checkbox-*` custom properties at any scope.
|
|
|
34
34
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
35
35
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
36
36
|
- 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.
|
|
37
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
37
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
38
38
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# CopyButton
|
|
3
|
+
|
|
4
|
+
Not a live region: it renders no role and no `aria-live`, never changes its label or icon after a copy, and announces nothing. The application speaks the result — route `onCopy` through its announcer or a Toast (D86). Copies `value` to the clipboard when pressed. A `Button` with a leading `IconCopy` and a visible label; the icon only reinforces the word.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `value` | `string` | — | yes | The text written to the clipboard. |
|
|
11
|
+
| `label` | `string` | Copy | no | Visible text of the button. |
|
|
12
|
+
| `size` | `24 \| 32 \| 40 \| 48` | 32 | no | Button height in px. |
|
|
13
|
+
| `variant` | `"accent" \| "accent-subtle" \| "neutral" \| "neutral-subtle" \| "ghost" \| "danger" \| "danger-subtle" \| "outline"` | ghost | no | Button variant. |
|
|
14
|
+
| `onCopy` | `((result: "copied" \| "failed") => void)` | — | no | Called with the outcome once the clipboard write settles. `"failed"` covers a rejected write and an environment with no clipboard API. |
|
|
15
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
16
|
+
|
|
17
|
+
## Keyboard & assistive tech
|
|
18
|
+
|
|
19
|
+
| Keys | Behavior |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Enter / Space | Copies the value to the clipboard. |
|
|
22
|
+
|
|
23
|
+
Not a live region: it renders no role and no aria-live, announces nothing, and does not change its label or icon after a copy, so a screen reader hears the same button before and after. The application speaks the result: onCopy reports "copied" or "failed" (a rejected write, or no clipboard API), and the application routes that through its announcer or a Toast (D86). The label is visible text; the icon is aria-hidden and only reinforces it. Focus stays on the button.
|
|
24
|
+
|
|
25
|
+
## Theming
|
|
26
|
+
|
|
27
|
+
This component has no `--psi-copy-button-*` 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
|
+
## Variant guidance
|
|
30
|
+
|
|
31
|
+
- **accent** — Primary action, draws attention. Submit, CTA, main action in a group.
|
|
32
|
+
- **accent-subtle** — Accent tone, lower visual weight. Selected state, active filter, soft CTA.
|
|
33
|
+
- **neutral** — Default, structurally present. Secondary actions, toolbar buttons.
|
|
34
|
+
- **neutral-subtle** — Minimal chrome. Inline actions, table row actions.
|
|
35
|
+
- **ghost** — No visible container until hover. Icon-only triggers, compact toolbars.
|
|
36
|
+
- **outline** — Bordered ghost — visible structure, no fill until hover. Marketing CTA, download button; hover fills accent.
|
|
37
|
+
- **danger** — Destructive action. Delete, remove, disconnect.
|
|
38
|
+
- **danger-subtle** — Destructive context, low urgency. Warning badges, soft destructive hints.
|
|
39
|
+
- **success | warning** — Status communication (Tag only). Status badges, labels.
|
|
40
|
+
|
|
41
|
+
## Rules
|
|
42
|
+
|
|
43
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
44
|
+
- danger only for actions with real consequences.
|
|
45
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
46
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
47
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
48
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
49
|
+
- 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.
|
|
50
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
51
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# CursorPagination
|
|
3
|
+
|
|
4
|
+
A pager for a list that pages by cursor (D85): a backend that returns a `nextPageToken` and no page count. Two `ghost` Buttons with visible words in a `<nav>`; the chevrons only reinforce them. A direction that is not available is disabled. It holds no state and knows nothing about pages — the consumer holds the tokens and answers `hasPrevious` / `hasNext`. A sibling of `Pagination`, not a mode of it: `Pagination`'s contract is a page count and numbers, and this one has neither.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `hasPrevious` | `boolean` | — | yes | Whether a previous page exists — the consumer knows, from its tokens. |
|
|
11
|
+
| `hasNext` | `boolean` | — | yes | Whether a next page exists. |
|
|
12
|
+
| `onPrevious` | `() => void` | — | yes | Called when the user asks for the previous page. |
|
|
13
|
+
| `onNext` | `() => void` | — | yes | Called when the user asks for the next page. |
|
|
14
|
+
| `previousLabel` | `string` | Previous | no | Visible text of the previous button. |
|
|
15
|
+
| `nextLabel` | `string` | Next | no | Visible text of the next button. |
|
|
16
|
+
| `size` | `32 \| 40` | 32 | no | Button height in px. |
|
|
17
|
+
| `aria-label` | `string` | Pagination | no | Accessible name for the nav landmark. |
|
|
18
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
19
|
+
|
|
20
|
+
## Keyboard & assistive tech
|
|
21
|
+
|
|
22
|
+
| Keys | Behavior |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Tab | Reaches the Previous and Next buttons in order; a disabled direction is skipped. |
|
|
25
|
+
| Enter / Space | Activates the focused button (native button behavior). |
|
|
26
|
+
|
|
27
|
+
A <nav> named "Pagination" (override with aria-label) holding two ghost Buttons with visible words — Previous and Next, translatable through previousLabel/nextLabel — each with a chevron that only reinforces the word (D85). A direction that is unavailable is disabled, not hidden. It holds no state: the consumer holds the page tokens and answers hasPrevious/hasNext. Pair it with a TableCaption whose detail states the range, and move focus there after a page change.
|
|
28
|
+
|
|
29
|
+
## Theming
|
|
30
|
+
|
|
31
|
+
This component has no `--psi-cursor-pagination-*` 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.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Rules
|
|
36
|
+
|
|
37
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
38
|
+
- danger only for actions with real consequences.
|
|
39
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
40
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
41
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
42
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
43
|
+
- 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.
|
|
44
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
45
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/DescriptionItem.md
CHANGED
|
@@ -27,5 +27,5 @@ This component has no `--psi-description-item-*` tokens — its styling binds sc
|
|
|
27
27
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
28
28
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
29
29
|
- 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.
|
|
30
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
30
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
31
31
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/DescriptionList.md
CHANGED
|
@@ -28,5 +28,5 @@ Override `--psi-description-list-*` custom properties at any scope.
|
|
|
28
28
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
29
29
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
30
30
|
- 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.
|
|
31
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
31
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
32
32
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Dialog.md
CHANGED
|
@@ -42,5 +42,5 @@ Override `--psi-dialog-*` custom properties at any scope.
|
|
|
42
42
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
43
43
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
44
44
|
- 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.
|
|
45
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
45
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
46
46
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Field.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
2
|
# Field
|
|
3
3
|
|
|
4
|
-
Labeled form-row wrapper: label above, control, one message line below — description normally, error when set (aria-live). Auto-wires id/aria-describedby/aria-invalid into Input and Select (D49).
|
|
4
|
+
Labeled form-row wrapper: label above, control, one message line below — description normally, error when set (aria-live unless `announce={false}`). Auto-wires id/aria-describedby/aria-invalid into Input and Select (D49).
|
|
5
5
|
|
|
6
6
|
## Props
|
|
7
7
|
|
|
@@ -12,8 +12,10 @@ Labeled form-row wrapper: label above, control, one message line below — descr
|
|
|
12
12
|
| `description` | `ReactNode` | — | no | Helper line under the control; replaced by error when error is set. |
|
|
13
13
|
| `error` | `ReactNode` | — | no | Error content; when truthy it replaces the description and switches the field (and a wrapped Input/Select) into error state. |
|
|
14
14
|
| `required` | `boolean` | false | no | Renders the required marker and flows `required` to the control. |
|
|
15
|
+
| `requiredText` | `string` | — | no | With `required`, the label shows this text — "(Required)", say — instead of the asterisk, so the requirement is stated in words and not by a glyph alone (D84). Visible and aria-hidden: the control carries the programmatic signal (`required` / `aria-required`), and a screen reader that heard both would say it twice. Without `required` it renders nothing. |
|
|
15
16
|
| `group` | `boolean` | false | no | Group mode: fieldset/legend wrapping several self-labeled controls (Checkbox/Switch); the message describes the whole group. |
|
|
16
17
|
| `htmlFor` | `string` | — | no | Override the generated control id (pair it with the same id on the control). |
|
|
18
|
+
| `announce` | `boolean` | true | no | When false, the message line is not a live region: an application that routes every announcement through one announcer of its own sets this and announces field errors itself. The message still describes the control (aria-describedby). |
|
|
17
19
|
| `ref` | `Ref<HTMLDivElement \| HTMLFieldSetElement>` | — | no | Forwarded ref to the root element. |
|
|
18
20
|
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
19
21
|
|
|
@@ -23,7 +25,7 @@ Labeled form-row wrapper: label above, control, one message line below — descr
|
|
|
23
25
|
|---|---|
|
|
24
26
|
| Tab | Focus moves to the wrapped control; the label is announced with it. |
|
|
25
27
|
|
|
26
|
-
Wires label association, aria-describedby and aria-invalid into a wrapped Input/Select automatically; the message line is aria-live=polite. Group mode renders fieldset/legend.
|
|
28
|
+
Wires label association, aria-describedby and aria-invalid into a wrapped Input/Select automatically; the message line is aria-live=polite. Group mode renders fieldset/legend. required marks the label with an aria-hidden asterisk and flows required to the control; requiredText replaces the asterisk with a visible word such as "(Required)", also aria-hidden, because the control's required/aria-required is what assistive tech reads (D84). A control Psi did not write joins the same wiring through useFieldControl(): spread its result — id, aria-labelledby (a label-for names only a labelable element, and a custom control is usually not one), aria-describedby, aria-invalid, aria-required, required, each present only when the Field sets it — onto the element that takes focus (D84).
|
|
27
29
|
|
|
28
30
|
## Theming
|
|
29
31
|
|
|
@@ -40,5 +42,5 @@ Override `--psi-field-*` custom properties at any scope.
|
|
|
40
42
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
41
43
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
42
44
|
- 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.
|
|
43
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
45
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
44
46
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/IconButton.md
CHANGED
|
@@ -50,5 +50,5 @@ Override `--psi-button-*` custom properties at any scope; interactive states der
|
|
|
50
50
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
51
51
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
52
52
|
- 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.
|
|
53
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
53
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
54
54
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!-- Generated by emit-docs.ts — do not edit. -->
|
|
2
|
+
# InlineAlert
|
|
3
|
+
|
|
4
|
+
Not `role="alert"`, despite its name. It is not a live region: it renders no `role` and no `aria-live`, so mounting one announces nothing, and announcing stays the application's — route the same event through a `ToastRegion` or an `Announcement` if it must be spoken. A status message that sits inside content (D86): above a form, in a panel. A tinted surface with a 1px border in the variant's colour and a radius; it fills the width of its container rather than setting its own. Presentational and stateless, with no dismiss button. For a page-wide strip, use `Banner`.
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Prop | Type | Default | Required | Description |
|
|
9
|
+
|---|---|---|---|---|
|
|
10
|
+
| `variant` | `"neutral" \| "success" \| "warning" \| "danger"` | neutral | no | Status variant. |
|
|
11
|
+
| `title` | `ReactNode` | — | no | A short heading, rendered before the body in the medium weight. |
|
|
12
|
+
| `children` | `ReactNode` | — | yes | The message. |
|
|
13
|
+
| `action` | `ReactNode` | — | no | Trailing affordance — a ghost Button (Review, Retry, Learn more). |
|
|
14
|
+
| `statusLabel` | `string \| null` | — | no | The visually hidden status word (D83). A string replaces the default ("Success:", "Warning:", "Error:") — pass the translated word; `null` drops it. Unset keeps the default, and `neutral` has none. |
|
|
15
|
+
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
|
|
16
|
+
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the underlying `<div>`. |
|
|
17
|
+
|
|
18
|
+
## Keyboard & assistive tech
|
|
19
|
+
|
|
20
|
+
| Keys | Behavior |
|
|
21
|
+
|---|---|
|
|
22
|
+
| Tab | Reaches the action when present. The alert itself is not focusable. |
|
|
23
|
+
| Enter / Space | Activates the focused action. |
|
|
24
|
+
|
|
25
|
+
Not a live region, and not role="alert" despite its name: it renders no role and no aria-live, so mounting an InlineAlert announces nothing; announcing stays the application's (route the same event through a ToastRegion or an Announcement if it must be spoken). Presentational (D86): it holds no state and has no dismiss button. The variant's meaning is carried by a visually hidden status word ("Success:", "Warning:", "Error:"), never by colour, border and icon shape alone; the icon is aria-hidden. neutral has no status and gets no word. statusLabel replaces that word with a translated one, or drops it with null (D83). Place it in reading order before the content it qualifies, such as above the form it is about.
|
|
26
|
+
|
|
27
|
+
## Theming
|
|
28
|
+
|
|
29
|
+
Override `--psi-inline-alert-*` custom properties at any scope.
|
|
30
|
+
|
|
31
|
+
## Variant guidance
|
|
32
|
+
|
|
33
|
+
- **accent** — Primary action, draws attention. Submit, CTA, main action in a group.
|
|
34
|
+
- **accent-subtle** — Accent tone, lower visual weight. Selected state, active filter, soft CTA.
|
|
35
|
+
- **neutral** — Default, structurally present. Secondary actions, toolbar buttons.
|
|
36
|
+
- **neutral-subtle** — Minimal chrome. Inline actions, table row actions.
|
|
37
|
+
- **ghost** — No visible container until hover. Icon-only triggers, compact toolbars.
|
|
38
|
+
- **outline** — Bordered ghost — visible structure, no fill until hover. Marketing CTA, download button; hover fills accent.
|
|
39
|
+
- **danger** — Destructive action. Delete, remove, disconnect.
|
|
40
|
+
- **danger-subtle** — Destructive context, low urgency. Warning badges, soft destructive hints.
|
|
41
|
+
- **success | warning** — Status communication (Tag only). Status badges, labels.
|
|
42
|
+
|
|
43
|
+
## Rules
|
|
44
|
+
|
|
45
|
+
- One accent per visual group; everything else neutral or ghost.
|
|
46
|
+
- danger only for actions with real consequences.
|
|
47
|
+
- Sizes are px numbers (24|32|40|48), never S/M/L.
|
|
48
|
+
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
|
|
49
|
+
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
50
|
+
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
51
|
+
- 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.
|
|
52
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
53
|
+
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Input.md
CHANGED
|
@@ -37,5 +37,5 @@ Override `--psi-input-*` custom properties at any scope; interactive states deri
|
|
|
37
37
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
38
38
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
39
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
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
40
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
41
41
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|
package/docs/Menu.md
CHANGED
|
@@ -43,5 +43,5 @@ Override `--psi-menu-*` custom properties at any scope; interactive states deriv
|
|
|
43
43
|
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
|
|
44
44
|
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
|
|
45
45
|
- 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.
|
|
46
|
-
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
|
|
46
|
+
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field). Filters with visible labels submitted together by a Find button are filter-form: a Toolbar as="form" align="end" of Fields (D87).
|
|
47
47
|
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
|