@handamade/psi-react 0.9.1 → 0.10.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.
@@ -467,6 +467,13 @@
467
467
  "default": null,
468
468
  "description": "Label text."
469
469
  },
470
+ {
471
+ "name": "aria-label",
472
+ "type": "string",
473
+ "required": false,
474
+ "default": null,
475
+ "description": "Accessible name when there is no visible label — a table's row-selection\ncheckbox, say. Optional, unlike IconButton's required form (D60): a\nlabelled checkbox is still the common case."
476
+ },
470
477
  {
471
478
  "name": "ref",
472
479
  "type": "Ref<HTMLInputElement>",
@@ -804,6 +811,249 @@
804
811
  "description": "Hairline rule between Menu item groups. No props by design (D53).",
805
812
  "slots": [],
806
813
  "props": []
814
+ },
815
+ {
816
+ "name": "Table",
817
+ "description": "Data table on native table semantics. Holds no state: sorting, selection and pagination are the consumer's (D62, extending D50/D53).",
818
+ "slots": [
819
+ {
820
+ "name": "body",
821
+ "accepts": {
822
+ "components": [
823
+ "TableHead",
824
+ "TableBody"
825
+ ]
826
+ },
827
+ "cardinality": "1..*",
828
+ "order": 1
829
+ }
830
+ ],
831
+ "props": [
832
+ {
833
+ "name": "size",
834
+ "type": "32 | 40 | 48",
835
+ "required": false,
836
+ "default": 40,
837
+ "description": "Row height in px."
838
+ },
839
+ {
840
+ "name": "stickyHeader",
841
+ "type": "boolean",
842
+ "required": false,
843
+ "default": null,
844
+ "description": "Pins the header while the body scrolls."
845
+ },
846
+ {
847
+ "name": "sortable",
848
+ "type": "boolean",
849
+ "required": false,
850
+ "default": false,
851
+ "description": "Enables the sort affordance on header cells that declare a `sortKey`."
852
+ },
853
+ {
854
+ "name": "sort",
855
+ "type": "TableSortState | null",
856
+ "required": false,
857
+ "default": null,
858
+ "description": "Controlled sort state; `null` when nothing is sorted."
859
+ },
860
+ {
861
+ "name": "onSortChange",
862
+ "type": "((sort: TableSortState) => void)",
863
+ "required": false,
864
+ "default": null,
865
+ "description": "Called when a header's sort control is activated. Optional in the type\nbecause `sortable` may be false; a discriminated union expressing the real\ncontract does not survive docgen's flat prop extraction, which would strip\nthese props from the manifest entirely (D62)."
866
+ },
867
+ {
868
+ "name": "selectable",
869
+ "type": "boolean",
870
+ "required": false,
871
+ "default": false,
872
+ "description": "Renders the row-selection checkbox column."
873
+ },
874
+ {
875
+ "name": "selected",
876
+ "type": "ReadonlySet<string>",
877
+ "required": false,
878
+ "default": "new Set<string>()",
879
+ "description": "Controlled selection, keyed by each `TableRow`'s `rowId`."
880
+ },
881
+ {
882
+ "name": "onSelectionChange",
883
+ "type": "((selected: ReadonlySet<string>) => void)",
884
+ "required": false,
885
+ "default": null,
886
+ "description": "Called with the next selection. See `onSortChange` on why it is optional."
887
+ },
888
+ {
889
+ "name": "className",
890
+ "type": "string",
891
+ "required": false,
892
+ "default": null,
893
+ "description": "Additional CSS class name(s) merged onto the component's root element."
894
+ },
895
+ {
896
+ "name": "ref",
897
+ "type": "Ref<HTMLTableElement>",
898
+ "required": false,
899
+ "default": null,
900
+ "description": "Forwarded ref to the underlying `<table>` element."
901
+ }
902
+ ]
903
+ },
904
+ {
905
+ "name": "TableHead",
906
+ "description": "`<thead>`. When the table is selectable, prepends the select-all cell to the FIRST header row so the header's column count matches the body's — the checkbox column is Table's, not the consumer's schema. Clones the row rather than rebuilding it, so the consumer's own props on that `TableRow` survive.",
907
+ "slots": [],
908
+ "props": [
909
+ {
910
+ "name": "className",
911
+ "type": "string",
912
+ "required": false,
913
+ "default": null,
914
+ "description": "Additional CSS class name(s) merged onto the component's root element."
915
+ }
916
+ ]
917
+ },
918
+ {
919
+ "name": "TableBody",
920
+ "description": "`<tbody>` wrapper.",
921
+ "slots": [],
922
+ "props": [
923
+ {
924
+ "name": "className",
925
+ "type": "string",
926
+ "required": false,
927
+ "default": null,
928
+ "description": "Additional CSS class name(s) merged onto the component's root element."
929
+ }
930
+ ]
931
+ },
932
+ {
933
+ "name": "TableRow",
934
+ "description": "`<tr>`. `rowId` is the key the `selected` set holds.",
935
+ "slots": [],
936
+ "props": [
937
+ {
938
+ "name": "rowId",
939
+ "type": "string",
940
+ "required": false,
941
+ "default": null,
942
+ "description": "Stable identity for selection. Required for selectable tables (D62)."
943
+ },
944
+ {
945
+ "name": "selectLabel",
946
+ "type": "string",
947
+ "required": false,
948
+ "default": null,
949
+ "description": "Accessible name for this row's selection checkbox."
950
+ },
951
+ {
952
+ "name": "className",
953
+ "type": "string",
954
+ "required": false,
955
+ "default": null,
956
+ "description": "Additional CSS class name(s) merged onto the component's root element."
957
+ }
958
+ ]
959
+ },
960
+ {
961
+ "name": "TableHeaderCell",
962
+ "description": "`<th scope=\"col\">`. `aria-sort` belongs on the th, never on the inner button — assistive tech reads the sort state from the column header.",
963
+ "slots": [],
964
+ "props": [
965
+ {
966
+ "name": "sortKey",
967
+ "type": "string",
968
+ "required": false,
969
+ "default": null,
970
+ "description": "Sort key this column emits. Enables the sort control when the table is `sortable`."
971
+ },
972
+ {
973
+ "name": "numeric",
974
+ "type": "boolean",
975
+ "required": false,
976
+ "default": null,
977
+ "description": "Right-aligns and renders tabular figures (D62)."
978
+ },
979
+ {
980
+ "name": "className",
981
+ "type": "string",
982
+ "required": false,
983
+ "default": null,
984
+ "description": "Additional CSS class name(s) merged onto the component's root element."
985
+ }
986
+ ]
987
+ },
988
+ {
989
+ "name": "TableCell",
990
+ "description": "`<td>`. `numeric` means right-aligned *and* tabular — a column that aligns but whose digits jitter between rows defeats the purpose.",
991
+ "slots": [],
992
+ "props": [
993
+ {
994
+ "name": "numeric",
995
+ "type": "boolean",
996
+ "required": false,
997
+ "default": null,
998
+ "description": "Right-aligns and renders tabular figures (D62)."
999
+ },
1000
+ {
1001
+ "name": "className",
1002
+ "type": "string",
1003
+ "required": false,
1004
+ "default": null,
1005
+ "description": "Additional CSS class name(s) merged onto the component's root element."
1006
+ }
1007
+ ]
1008
+ },
1009
+ {
1010
+ "name": "Pagination",
1011
+ "description": "Numbered pager with ellipsis truncation (D63). Standalone rather than a Table family member: `table-pagination` composes it as a Toolbar sibling of the page-size Select.",
1012
+ "slots": [],
1013
+ "props": [
1014
+ {
1015
+ "name": "page",
1016
+ "type": "number",
1017
+ "required": true,
1018
+ "default": null,
1019
+ "description": "Current page, 1-based."
1020
+ },
1021
+ {
1022
+ "name": "pageCount",
1023
+ "type": "number",
1024
+ "required": true,
1025
+ "default": null,
1026
+ "description": "Total number of pages."
1027
+ },
1028
+ {
1029
+ "name": "onPageChange",
1030
+ "type": "(page: number) => void",
1031
+ "required": true,
1032
+ "default": null,
1033
+ "description": "Called with the requested page. Required — unlike Table's `onSortChange`/\n`onSelectionChange`, which are optional because `sortable`/`selectable`\ngate whether they're meaningful, `Pagination` has no such gating boolean:\nthe prop is unconditionally meaningful, so a `Pagination` without it is a\ndead control (final review finding, D62)."
1034
+ },
1035
+ {
1036
+ "name": "siblingCount",
1037
+ "type": "number",
1038
+ "required": false,
1039
+ "default": 1,
1040
+ "description": "Pages shown either side of the current one before truncating."
1041
+ },
1042
+ {
1043
+ "name": "aria-label",
1044
+ "type": "string",
1045
+ "required": false,
1046
+ "default": "Pagination",
1047
+ "description": "Accessible name for the nav landmark."
1048
+ },
1049
+ {
1050
+ "name": "className",
1051
+ "type": "string",
1052
+ "required": false,
1053
+ "default": null,
1054
+ "description": "Additional CSS class name(s) merged onto the component's root element."
1055
+ }
1056
+ ]
807
1057
  }
808
1058
  ]
809
1059
  }
@@ -128,24 +128,90 @@
128
128
  "sortable": true
129
129
  },
130
130
  "slots": {
131
- "head": [
132
- "{content:columns-note}"
133
- ],
134
131
  "body": [
135
- "{content:rows-note}"
132
+ {
133
+ "component": "TableHead",
134
+ "slots": {
135
+ "body": [
136
+ {
137
+ "component": "TableRow",
138
+ "slots": {
139
+ "body": [
140
+ {
141
+ "component": "TableHeaderCell",
142
+ "props": {
143
+ "sortKey": "date"
144
+ },
145
+ "content": "date-label"
146
+ },
147
+ {
148
+ "component": "TableHeaderCell",
149
+ "props": {
150
+ "sortKey": "payee"
151
+ },
152
+ "content": "payee-label"
153
+ },
154
+ {
155
+ "component": "TableHeaderCell",
156
+ "props": {
157
+ "sortKey": "amount",
158
+ "numeric": true
159
+ },
160
+ "content": "amount-label"
161
+ }
162
+ ]
163
+ }
164
+ }
165
+ ]
166
+ }
167
+ },
168
+ {
169
+ "component": "TableBody",
170
+ "slots": {
171
+ "body": [
172
+ {
173
+ "component": "TableRow",
174
+ "props": {
175
+ "rowId": "row-id"
176
+ },
177
+ "slots": {
178
+ "body": [
179
+ {
180
+ "component": "TableCell",
181
+ "content": "date-cell"
182
+ },
183
+ {
184
+ "component": "TableCell",
185
+ "content": "payee-cell"
186
+ },
187
+ {
188
+ "component": "TableCell",
189
+ "props": {
190
+ "numeric": true
191
+ },
192
+ "content": "amount-cell"
193
+ }
194
+ ]
195
+ }
196
+ }
197
+ ]
198
+ }
199
+ }
136
200
  ]
137
201
  }
138
202
  },
139
203
  "parameters": [],
140
204
  "content": {
141
- "columns-note": "[one header cell per column; numeric columns align right]",
142
- "rows-note": "[one row per record; put the row-actions menu in the last cell]"
205
+ "date-label": "Date",
206
+ "payee-label": "Payee",
207
+ "amount-label": "Amount",
208
+ "date-cell": "[one row per record]",
209
+ "payee-cell": "[put the row-actions menu in the last cell]",
210
+ "amount-cell": "[numeric columns align right and use tabular figures]"
143
211
  },
144
- "gaps": [
145
- "Table"
146
- ],
147
- "blocked": true,
148
- "preset": null
212
+ "gaps": [],
213
+ "blocked": false,
214
+ "preset": "<Table\n selectable={true}\n sortable={true}\n>\n <TableHead>\n <TableRow>\n <TableHeaderCell sortKey=\"date\">Date</TableHeaderCell>\n <TableHeaderCell sortKey=\"payee\">Payee</TableHeaderCell>\n <TableHeaderCell numeric={true} sortKey=\"amount\">Amount</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n <TableRow\n rowId=\"row-id\"\n >\n <TableCell>[one row per record]</TableCell>\n <TableCell>[put the row-actions menu in the last cell]</TableCell>\n <TableCell numeric={true}>[numeric columns align right and use tabular figures]</TableCell>\n </TableRow>\n </TableBody>\n</Table>\n"
149
215
  },
150
216
  {
151
217
  "id": "date-range-filter",
@@ -646,11 +712,9 @@
646
712
  "content": {
647
713
  "page-size-label": "Rows per page"
648
714
  },
649
- "gaps": [
650
- "Pagination"
651
- ],
652
- "blocked": true,
653
- "preset": null
715
+ "gaps": [],
716
+ "blocked": false,
717
+ "preset": "<Toolbar\n gap={12}\n>\n <Field\n label=\"Rows per page\"\n >\n <Select size={32} />\n </Field>\n <Pagination />\n</Toolbar>\n"
654
718
  }
655
719
  ]
656
720
  }
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- ._button_c94w9_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;font-family:var(--psi-font-sans);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._button_c94w9_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._button_c94w9_3:disabled{opacity:.4;cursor:not-allowed}._button_c94w9_3._disabled_c94w9_30{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_c94w9_44{height:var(--psi-button-24-height);padding-inline:var(--psi-button-24-padding-inline);gap:var(--psi-button-24-gap);font:var(--psi-button-font, var(--psi-button-24-font))}._size24_c94w9_44:has(>svg:first-child){padding-inline-start:var(--psi-button-24-padding-inline-icon)}._size32_c94w9_54{height:var(--psi-button-32-height);padding-inline:var(--psi-button-32-padding-inline);gap:var(--psi-button-32-gap);font:var(--psi-button-font, var(--psi-button-32-font))}._size32_c94w9_54:has(>svg:first-child){padding-inline-start:var(--psi-button-32-padding-inline-icon)}._size40_c94w9_64{height:var(--psi-button-40-height);padding-inline:var(--psi-button-40-padding-inline);gap:var(--psi-button-40-gap);font:var(--psi-button-font, var(--psi-button-40-font))}._size40_c94w9_64:has(>svg:first-child){padding-inline-start:var(--psi-button-40-padding-inline-icon)}._size48_c94w9_74{height:var(--psi-button-48-height);padding-inline:var(--psi-button-48-padding-inline);gap:var(--psi-button-48-gap);font:var(--psi-button-font, var(--psi-button-48-font))}._size48_c94w9_74:has(>svg:first-child){padding-inline-start:var(--psi-button-48-padding-inline-icon)}._accent_c94w9_87{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_c94w9_87:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-hover)}._accent_c94w9_87:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-active)}._accentSubtle_c94w9_99{background:var(--psi-button-accent-subtle-bg);color:var(--psi-button-accent-subtle-fg)}._accentSubtle_c94w9_99:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-hover)}._accentSubtle_c94w9_99:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-active)}._neutral_c94w9_111{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_c94w9_111:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-hover)}._neutral_c94w9_111:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-active)}._neutralSubtle_c94w9_123{background:var(--psi-button-neutral-subtle-bg);color:var(--psi-button-neutral-subtle-fg)}._neutralSubtle_c94w9_123:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-hover)}._neutralSubtle_c94w9_123:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-active)}._ghost_c94w9_135{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_c94w9_135:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-hover)}._ghost_c94w9_135:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-active)}._danger_c94w9_147{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_c94w9_147:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-hover)}._danger_c94w9_147:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-active)}._dangerSubtle_c94w9_159{background:var(--psi-button-danger-subtle-bg);color:var(--psi-button-danger-subtle-fg)}._dangerSubtle_c94w9_159:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-hover)}._dangerSubtle_c94w9_159:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-active)}._outline_c94w9_171{background:var(--psi-button-outline-bg);color:var(--psi-button-outline-fg);border:1px solid var(--psi-button-outline-border)}._outline_c94w9_171:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-hover);color:var(--psi-button-outline-fg-hover);border-color:transparent}._outline_c94w9_171:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-active)}._iconButton_129ca_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;padding:0;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._iconButton_129ca_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._iconButton_129ca_3:disabled{opacity:.4;cursor:not-allowed}._iconButton_129ca_3._disabled_129ca_29{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_129ca_37{width:var(--psi-button-24-height);height:var(--psi-button-24-height)}._size32_129ca_42{width:var(--psi-button-32-height);height:var(--psi-button-32-height)}._size40_129ca_47{width:var(--psi-button-40-height);height:var(--psi-button-40-height)}._size48_129ca_52{width:var(--psi-button-48-height);height:var(--psi-button-48-height)}._accent_129ca_60{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_129ca_60:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-hover)}._accent_129ca_60:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-active)}._neutral_129ca_72{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_129ca_72:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-hover)}._neutral_129ca_72:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-active)}._ghost_129ca_84{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_129ca_84:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-hover)}._ghost_129ca_84:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-active)}._danger_129ca_96{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_129ca_96:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-hover)}._danger_129ca_96:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-active)}._card_1btb3_1{background:var(--psi-card-bg);border:1px solid var(--psi-card-border);border-radius:var(--psi-card-radius);overflow:hidden}._stacked_1btb3_8{display:flex;flex-direction:column;gap:var(--psi-card-gap)}._featured_1btb3_10{display:grid;grid-template-columns:1.6fr 1fr;gap:var(--psi-card-gap);align-items:start}@media(max-width:960px){._featured_1btb3_10{grid-template-columns:1fr}}._media_1btb3_22{min-width:0}._body_1btb3_23{min-width:0;display:flex;flex-direction:column;gap:var(--psi-card-gap);padding:var(--psi-card-gap)}._hoverLift_1btb3_31{transition:transform var(--psi-duration-350) var(--psi-ease-standard)}._hoverLift_1btb3_31:hover{transform:translateY(-6px)}._panel_jn8w4_1{background:var(--psi-panel-bg);border:1px solid var(--psi-panel-border);border-radius:var(--psi-panel-radius);padding:var(--psi-panel-padding)}._padding16_jn8w4_8{padding:var(--psi-space-16)}._navbar_1gyow_1{font:var(--psi-text-14-20-medium);position:sticky;top:0;z-index:var(--psi-z-nav);background:var(--psi-navbar-bg);backdrop-filter:blur(var(--psi-navbar-blur));-webkit-backdrop-filter:blur(var(--psi-navbar-blur));border-bottom:1px solid var(--psi-navbar-border)}._inner_1gyow_12{display:flex;align-items:center;gap:var(--psi-space-24);height:var(--psi-navbar-height)}._brand_1gyow_19{display:flex;align-items:center}._links_1gyow_20{display:flex;align-items:center;gap:var(--psi-space-20);margin-inline-start:auto}._links_1gyow_20 a,._brand_1gyow_19 a{text-decoration:none;transition:color var(--psi-duration-150) var(--psi-ease-soft)}._links_1gyow_20 a{color:var(--psi-navbar-link-fg)}._links_1gyow_20 a:hover,._brand_1gyow_19 a{color:var(--psi-navbar-link-fg-hover)}._links_1gyow_20 a:focus-visible,._brand_1gyow_19 a:focus-visible{outline:2px solid var(--psi-navbar-focus-ring);outline-offset:2px}._actions_1gyow_50{display:flex;align-items:center;gap:var(--psi-space-8)}._frame_et4fc_1{overflow:hidden}._frame_et4fc_1>img,._frame_et4fc_1>video{width:100%;height:100%;object-fit:cover;display:block}._field_lplye_1{display:grid;gap:var(--psi-field-gap);border:0;margin:0;padding:0;min-width:0}._label_lplye_10{font:var(--psi-text-14-20-medium);color:var(--psi-field-label-fg);padding:0}._marker_lplye_16{color:var(--psi-field-marker-fg)}._message_lplye_20{margin:0;font:var(--psi-text-12-16-regular);color:var(--psi-field-message-fg)}._invalid_lplye_26 ._message_lplye_20{color:var(--psi-field-error-fg)}._dialog_l23jf_2{padding:0;border:1px solid var(--psi-dialog-border);border-radius:var(--psi-dialog-radius);background:var(--psi-dialog-bg);color:var(--psi-dialog-fg);max-width:calc(100vw - var(--psi-space-32))}._dialog_l23jf_2::backdrop{background:var(--psi-dialog-backdrop)}._dialog_l23jf_2[open]{animation:_dialog-enter_l23jf_1 var(--psi-duration-200) var(--psi-ease-soft)}._dialog_l23jf_2[open]::backdrop{animation:_backdrop-enter_l23jf_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _dialog-enter_l23jf_1{0%{opacity:0;transform:scale(.97)}}@keyframes _backdrop-enter_l23jf_1{0%{opacity:0}}._w400_l23jf_31{width:400px}._w560_l23jf_32{width:560px}._w720_l23jf_33{width:720px}._panel_l23jf_35{display:grid;gap:var(--psi-space-16);padding:var(--psi-space-24)}._header_l23jf_41{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--psi-space-12)}._title_l23jf_48{margin:0;font:var(--psi-text-18-28-medium);color:var(--psi-dialog-title-fg)}._footer_l23jf_54{display:flex;justify-content:flex-end;gap:var(--psi-space-8)}._input_hpei8_3{display:block;width:100%;border:1px solid var(--psi-input-border);border-radius:var(--psi-input-radius);background:var(--psi-input-bg);color:var(--psi-input-fg);font-family:var(--psi-font-sans);transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._input_hpei8_3::placeholder{color:var(--psi-input-placeholder)}._input_hpei8_3:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-hover)}._input_hpei8_3:focus{outline:2px solid var(--psi-input-focus-ring);outline-offset:-1px;border-color:transparent}._input_hpei8_3:disabled{opacity:.4;cursor:not-allowed}._size24_hpei8_37{height:var(--psi-input-24-height);padding-inline:var(--psi-input-24-padding-inline);font:var(--psi-input-24-font)}._size32_hpei8_43{height:var(--psi-input-32-height);padding-inline:var(--psi-input-32-padding-inline);font:var(--psi-input-32-font)}._size40_hpei8_49{height:var(--psi-input-40-height);padding-inline:var(--psi-input-40-padding-inline);font:var(--psi-input-40-font)}._size48_hpei8_55{height:var(--psi-input-48-height);padding-inline:var(--psi-input-48-padding-inline);font:var(--psi-input-48-font)}._error_hpei8_63{border-color:var(--psi-input-border-error)}._error_hpei8_63:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-error)}._select_4x9ck_3{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid var(--psi-select-border);border-radius:var(--psi-select-radius);background-color:var(--psi-select-bg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;color:var(--psi-select-fg);font-family:var(--psi-font-sans);cursor:pointer;transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._select_4x9ck_3:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-hover)}._select_4x9ck_3:focus{outline:2px solid var(--psi-select-focus-ring);outline-offset:-1px;border-color:transparent}._select_4x9ck_3:disabled{opacity:.4;cursor:not-allowed}._size24_4x9ck_37{height:var(--psi-select-24-height);padding-inline-start:var(--psi-select-24-padding-inline);padding-inline-end:var(--psi-select-24-padding-inline-end);background-position:right var(--psi-select-24-chevron-offset) center;font:var(--psi-select-24-font)}._size32_4x9ck_45{height:var(--psi-select-32-height);padding-inline-start:var(--psi-select-32-padding-inline);padding-inline-end:var(--psi-select-32-padding-inline-end);background-position:right var(--psi-select-32-chevron-offset) center;font:var(--psi-select-32-font)}._size40_4x9ck_53{height:var(--psi-select-40-height);padding-inline-start:var(--psi-select-40-padding-inline);padding-inline-end:var(--psi-select-40-padding-inline-end);background-position:right var(--psi-select-40-chevron-offset) center;font:var(--psi-select-40-font)}._size48_4x9ck_61{height:var(--psi-select-48-height);padding-inline-start:var(--psi-select-48-padding-inline);padding-inline-end:var(--psi-select-48-padding-inline-end);background-position:right var(--psi-select-48-chevron-offset) center;font:var(--psi-select-48-font)}._error_4x9ck_71{border-color:var(--psi-select-border-error)}._error_4x9ck_71:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-error)}._label_1v4vv_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-checkbox-fg)}._disabled_1v4vv_13{opacity:.4;cursor:not-allowed}._input_1v4vv_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._indicator_1v4vv_34{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;border:1px solid var(--psi-checkbox-box-border);border-radius:var(--psi-checkbox-box-radius);background:var(--psi-checkbox-box-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard),border-color var(--psi-duration-150) var(--psi-ease-standard)}._input_1v4vv_20:checked+._indicator_1v4vv_34{background:var(--psi-checkbox-box-bg-checked);border-color:var(--psi-checkbox-box-border-checked)}._input_1v4vv_20:checked+._indicator_1v4vv_34:after{content:"";display:block;width:4px;height:8px;color:var(--psi-checkbox-check-fg);border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translate(-.5px,-.5px)}._input_1v4vv_20:focus-visible+._indicator_1v4vv_34{outline:2px solid var(--psi-checkbox-focus-ring);outline-offset:2px}._text_1v4vv_75{color:var(--psi-checkbox-fg)}._label_jru2c_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-switch-fg)}._disabled_jru2c_13{opacity:.4;cursor:not-allowed}._input_jru2c_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._track_jru2c_34{position:relative;display:inline-flex;align-items:center;width:36px;height:20px;flex-shrink:0;border-radius:var(--psi-radius-full);background:var(--psi-switch-track-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard)}._input_jru2c_20:checked+._track_jru2c_34{background:var(--psi-switch-track-bg-checked)}._input_jru2c_20:focus-visible+._track_jru2c_34{outline:2px solid var(--psi-switch-focus-ring);outline-offset:2px}._thumb_jru2c_58{position:absolute;width:16px;height:16px;border-radius:var(--psi-radius-full);background:var(--psi-switch-thumb-bg);left:2px;transition:left var(--psi-duration-150) var(--psi-ease-standard);box-shadow:0 1px 2px #00000029}._input_jru2c_20:checked+._track_jru2c_34 ._thumb_jru2c_58{left:18px}._text_jru2c_75{color:var(--psi-switch-fg)}._tag_3oysa_3{display:inline-flex;align-items:center;gap:var(--psi-space-4);height:24px;padding-inline:var(--psi-space-8);border-radius:var(--psi-radius-full);font:var(--psi-text-12-16-medium);white-space:nowrap;-webkit-user-select:none;user-select:none}._dismiss_3oysa_17{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:none;color:inherit;cursor:pointer;opacity:.7;margin-inline-start:var(--psi-space-2);margin-inline-end:calc(-1 * var(--psi-space-4));border-radius:var(--psi-radius-full)}._dismiss_3oysa_17:hover{opacity:1}._dismiss_3oysa_17:focus-visible{outline:2px solid var(--psi-tag-focus-ring);outline-offset:2px}._neutral_3oysa_43{background:var(--psi-tag-neutral-bg);color:var(--psi-tag-neutral-fg)}._accent_3oysa_48{background:var(--psi-tag-accent-bg);color:var(--psi-tag-accent-fg)}._success_3oysa_53{background:var(--psi-tag-success-bg);color:var(--psi-tag-success-fg)}._warning_3oysa_58{background:var(--psi-tag-warning-bg);color:var(--psi-tag-warning-fg)}._danger_3oysa_63{background:var(--psi-tag-danger-bg);color:var(--psi-tag-danger-fg)}._neutralSubtle_3oysa_70{background:var(--psi-tag-neutral-subtle-bg);color:var(--psi-tag-neutral-subtle-fg)}._accentSubtle_3oysa_75{background:var(--psi-tag-accent-subtle-bg);color:var(--psi-tag-accent-subtle-fg)}._successSubtle_3oysa_80{background:var(--psi-tag-success-subtle-bg);color:var(--psi-tag-success-subtle-fg)}._warningSubtle_3oysa_85{background:var(--psi-tag-warning-subtle-bg);color:var(--psi-tag-warning-subtle-fg)}._dangerSubtle_3oysa_90{background:var(--psi-tag-danger-subtle-bg);color:var(--psi-tag-danger-subtle-fg)}._wrapper_1eu6z_3{position:relative;display:inline-flex}._tooltip_1eu6z_10{position:absolute;z-index:var(--psi-z-tooltip);padding:var(--psi-space-4) var(--psi-space-8);border-radius:var(--psi-tooltip-radius);background:var(--psi-tooltip-bg);color:var(--psi-tooltip-fg);font:var(--psi-text-12-16-regular);white-space:nowrap;pointer-events:none}._top_1eu6z_24{bottom:100%;left:50%;transform:translate(-50%);margin-bottom:var(--psi-space-4)}._bottom_1eu6z_31{top:100%;left:50%;transform:translate(-50%);margin-top:var(--psi-space-4)}._left_1eu6z_38{right:100%;top:50%;transform:translateY(-50%);margin-right:var(--psi-space-4)}._right_1eu6z_45{left:100%;top:50%;transform:translateY(-50%);margin-left:var(--psi-space-4)}._toolbar_1i848_1{display:flex;flex-wrap:wrap;align-items:center}._gap8_1i848_7{gap:var(--psi-space-8)}._gap12_1i848_8{gap:var(--psi-space-12)}._gap16_1i848_9{gap:var(--psi-space-16)}._trigger_vpa0u_4{display:inline-flex;width:fit-content}._menu_vpa0u_16{min-width:180px;margin:var(--psi-space-4);padding:var(--psi-space-4);border:1px solid var(--psi-menu-border);border-radius:var(--psi-menu-radius);background:var(--psi-menu-bg);color:var(--psi-menu-fg);font:var(--psi-text-14-20-regular)}._menu_vpa0u_16:not([data-open]):not(:popover-open){display:none}._item_vpa0u_37{display:flex;width:100%;align-items:center;padding:var(--psi-space-8) var(--psi-space-12);border:0;border-radius:var(--psi-radius-6);background:var(--psi-menu-item-bg);color:var(--psi-menu-item-fg);font:inherit;text-align:start;cursor:pointer}._item_vpa0u_37:hover{background:var(--psi-menu-item-bg-hover)}._item_vpa0u_37:active{background:var(--psi-menu-item-bg-active)}._item_vpa0u_37[data-variant=danger]{color:var(--psi-menu-item-fg-danger)}._item_vpa0u_37[aria-disabled=true]{color:var(--psi-menu-item-fg-disabled);cursor:default}._item_vpa0u_37[aria-disabled=true]:hover{background:var(--psi-menu-item-bg)}._separator_vpa0u_74{height:0;margin:var(--psi-space-4) 0;border-top:1px solid var(--psi-menu-separator-border)}@supports (anchor-name: --x){._menu_vpa0u_16{position:fixed;margin:var(--psi-space-4);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}._menu_vpa0u_16[data-placement=bottom-start]{position-area:block-end span-inline-end}._menu_vpa0u_16[data-placement=bottom-end]{position-area:block-end span-inline-start}._menu_vpa0u_16[data-placement=top-start]{position-area:block-start span-inline-end}._menu_vpa0u_16[data-placement=top-end]{position-area:block-start span-inline-start}}
1
+ ._button_c94w9_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;font-family:var(--psi-font-sans);white-space:nowrap;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._button_c94w9_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._button_c94w9_3:disabled{opacity:.4;cursor:not-allowed}._button_c94w9_3._disabled_c94w9_30{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_c94w9_44{height:var(--psi-button-24-height);padding-inline:var(--psi-button-24-padding-inline);gap:var(--psi-button-24-gap);font:var(--psi-button-font, var(--psi-button-24-font))}._size24_c94w9_44:has(>svg:first-child){padding-inline-start:var(--psi-button-24-padding-inline-icon)}._size32_c94w9_54{height:var(--psi-button-32-height);padding-inline:var(--psi-button-32-padding-inline);gap:var(--psi-button-32-gap);font:var(--psi-button-font, var(--psi-button-32-font))}._size32_c94w9_54:has(>svg:first-child){padding-inline-start:var(--psi-button-32-padding-inline-icon)}._size40_c94w9_64{height:var(--psi-button-40-height);padding-inline:var(--psi-button-40-padding-inline);gap:var(--psi-button-40-gap);font:var(--psi-button-font, var(--psi-button-40-font))}._size40_c94w9_64:has(>svg:first-child){padding-inline-start:var(--psi-button-40-padding-inline-icon)}._size48_c94w9_74{height:var(--psi-button-48-height);padding-inline:var(--psi-button-48-padding-inline);gap:var(--psi-button-48-gap);font:var(--psi-button-font, var(--psi-button-48-font))}._size48_c94w9_74:has(>svg:first-child){padding-inline-start:var(--psi-button-48-padding-inline-icon)}._accent_c94w9_87{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_c94w9_87:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-hover)}._accent_c94w9_87:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-bg-active)}._accentSubtle_c94w9_99{background:var(--psi-button-accent-subtle-bg);color:var(--psi-button-accent-subtle-fg)}._accentSubtle_c94w9_99:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-hover)}._accentSubtle_c94w9_99:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-accent-subtle-bg-active)}._neutral_c94w9_111{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_c94w9_111:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-hover)}._neutral_c94w9_111:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-bg-active)}._neutralSubtle_c94w9_123{background:var(--psi-button-neutral-subtle-bg);color:var(--psi-button-neutral-subtle-fg)}._neutralSubtle_c94w9_123:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-hover)}._neutralSubtle_c94w9_123:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-neutral-subtle-bg-active)}._ghost_c94w9_135{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_c94w9_135:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-hover)}._ghost_c94w9_135:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-ghost-bg-active)}._danger_c94w9_147{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_c94w9_147:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-hover)}._danger_c94w9_147:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-bg-active)}._dangerSubtle_c94w9_159{background:var(--psi-button-danger-subtle-bg);color:var(--psi-button-danger-subtle-fg)}._dangerSubtle_c94w9_159:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-hover)}._dangerSubtle_c94w9_159:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-danger-subtle-bg-active)}._outline_c94w9_171{background:var(--psi-button-outline-bg);color:var(--psi-button-outline-fg);border:1px solid var(--psi-button-outline-border)}._outline_c94w9_171:hover:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-hover);color:var(--psi-button-outline-fg-hover);border-color:transparent}._outline_c94w9_171:active:not(:disabled):not(._disabled_c94w9_30){background:var(--psi-button-outline-bg-active)}._iconButton_129ca_3{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--psi-button-radius);cursor:pointer;padding:0;text-decoration:none;-webkit-user-select:none;user-select:none;transition:background-color var(--psi-duration-150) var(--psi-ease-standard),color var(--psi-duration-150) var(--psi-ease-standard)}._iconButton_129ca_3:focus-visible{outline:2px solid var(--psi-button-focus-ring);outline-offset:2px}._iconButton_129ca_3:disabled{opacity:.4;cursor:not-allowed}._iconButton_129ca_3._disabled_129ca_29{opacity:.4;cursor:not-allowed;pointer-events:none}._size24_129ca_37{width:var(--psi-button-24-height);height:var(--psi-button-24-height)}._size32_129ca_42{width:var(--psi-button-32-height);height:var(--psi-button-32-height)}._size40_129ca_47{width:var(--psi-button-40-height);height:var(--psi-button-40-height)}._size48_129ca_52{width:var(--psi-button-48-height);height:var(--psi-button-48-height)}._accent_129ca_60{background:var(--psi-button-accent-bg);color:var(--psi-button-accent-fg)}._accent_129ca_60:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-hover)}._accent_129ca_60:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-accent-bg-active)}._neutral_129ca_72{background:var(--psi-button-neutral-bg);color:var(--psi-button-neutral-fg)}._neutral_129ca_72:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-hover)}._neutral_129ca_72:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-neutral-bg-active)}._ghost_129ca_84{background:var(--psi-button-ghost-bg);color:var(--psi-button-ghost-fg)}._ghost_129ca_84:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-hover)}._ghost_129ca_84:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-ghost-bg-active)}._danger_129ca_96{background:var(--psi-button-danger-bg);color:var(--psi-button-danger-fg)}._danger_129ca_96:hover:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-hover)}._danger_129ca_96:active:not(:disabled):not(._disabled_129ca_29){background:var(--psi-button-danger-bg-active)}._card_1btb3_1{background:var(--psi-card-bg);border:1px solid var(--psi-card-border);border-radius:var(--psi-card-radius);overflow:hidden}._stacked_1btb3_8{display:flex;flex-direction:column;gap:var(--psi-card-gap)}._featured_1btb3_10{display:grid;grid-template-columns:1.6fr 1fr;gap:var(--psi-card-gap);align-items:start}@media(max-width:960px){._featured_1btb3_10{grid-template-columns:1fr}}._media_1btb3_22{min-width:0}._body_1btb3_23{min-width:0;display:flex;flex-direction:column;gap:var(--psi-card-gap);padding:var(--psi-card-gap)}._hoverLift_1btb3_31{transition:transform var(--psi-duration-350) var(--psi-ease-standard)}._hoverLift_1btb3_31:hover{transform:translateY(-6px)}._panel_jn8w4_1{background:var(--psi-panel-bg);border:1px solid var(--psi-panel-border);border-radius:var(--psi-panel-radius);padding:var(--psi-panel-padding)}._padding16_jn8w4_8{padding:var(--psi-space-16)}._navbar_1gyow_1{font:var(--psi-text-14-20-medium);position:sticky;top:0;z-index:var(--psi-z-nav);background:var(--psi-navbar-bg);backdrop-filter:blur(var(--psi-navbar-blur));-webkit-backdrop-filter:blur(var(--psi-navbar-blur));border-bottom:1px solid var(--psi-navbar-border)}._inner_1gyow_12{display:flex;align-items:center;gap:var(--psi-space-24);height:var(--psi-navbar-height)}._brand_1gyow_19{display:flex;align-items:center}._links_1gyow_20{display:flex;align-items:center;gap:var(--psi-space-20);margin-inline-start:auto}._links_1gyow_20 a,._brand_1gyow_19 a{text-decoration:none;transition:color var(--psi-duration-150) var(--psi-ease-soft)}._links_1gyow_20 a{color:var(--psi-navbar-link-fg)}._links_1gyow_20 a:hover,._brand_1gyow_19 a{color:var(--psi-navbar-link-fg-hover)}._links_1gyow_20 a:focus-visible,._brand_1gyow_19 a:focus-visible{outline:2px solid var(--psi-navbar-focus-ring);outline-offset:2px}._actions_1gyow_50{display:flex;align-items:center;gap:var(--psi-space-8)}._frame_et4fc_1{overflow:hidden}._frame_et4fc_1>img,._frame_et4fc_1>video{width:100%;height:100%;object-fit:cover;display:block}._field_lplye_1{display:grid;gap:var(--psi-field-gap);border:0;margin:0;padding:0;min-width:0}._label_lplye_10{font:var(--psi-text-14-20-medium);color:var(--psi-field-label-fg);padding:0}._marker_lplye_16{color:var(--psi-field-marker-fg)}._message_lplye_20{margin:0;font:var(--psi-text-12-16-regular);color:var(--psi-field-message-fg)}._invalid_lplye_26 ._message_lplye_20{color:var(--psi-field-error-fg)}._dialog_l23jf_2{padding:0;border:1px solid var(--psi-dialog-border);border-radius:var(--psi-dialog-radius);background:var(--psi-dialog-bg);color:var(--psi-dialog-fg);max-width:calc(100vw - var(--psi-space-32))}._dialog_l23jf_2::backdrop{background:var(--psi-dialog-backdrop)}._dialog_l23jf_2[open]{animation:_dialog-enter_l23jf_1 var(--psi-duration-200) var(--psi-ease-soft)}._dialog_l23jf_2[open]::backdrop{animation:_backdrop-enter_l23jf_1 var(--psi-duration-200) var(--psi-ease-soft)}@keyframes _dialog-enter_l23jf_1{0%{opacity:0;transform:scale(.97)}}@keyframes _backdrop-enter_l23jf_1{0%{opacity:0}}._w400_l23jf_31{width:400px}._w560_l23jf_32{width:560px}._w720_l23jf_33{width:720px}._panel_l23jf_35{display:grid;gap:var(--psi-space-16);padding:var(--psi-space-24)}._header_l23jf_41{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--psi-space-12)}._title_l23jf_48{margin:0;font:var(--psi-text-18-28-medium);color:var(--psi-dialog-title-fg)}._footer_l23jf_54{display:flex;justify-content:flex-end;gap:var(--psi-space-8)}._input_hpei8_3{display:block;width:100%;border:1px solid var(--psi-input-border);border-radius:var(--psi-input-radius);background:var(--psi-input-bg);color:var(--psi-input-fg);font-family:var(--psi-font-sans);transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._input_hpei8_3::placeholder{color:var(--psi-input-placeholder)}._input_hpei8_3:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-hover)}._input_hpei8_3:focus{outline:2px solid var(--psi-input-focus-ring);outline-offset:-1px;border-color:transparent}._input_hpei8_3:disabled{opacity:.4;cursor:not-allowed}._size24_hpei8_37{height:var(--psi-input-24-height);padding-inline:var(--psi-input-24-padding-inline);font:var(--psi-input-24-font)}._size32_hpei8_43{height:var(--psi-input-32-height);padding-inline:var(--psi-input-32-padding-inline);font:var(--psi-input-32-font)}._size40_hpei8_49{height:var(--psi-input-40-height);padding-inline:var(--psi-input-40-padding-inline);font:var(--psi-input-40-font)}._size48_hpei8_55{height:var(--psi-input-48-height);padding-inline:var(--psi-input-48-padding-inline);font:var(--psi-input-48-font)}._error_hpei8_63{border-color:var(--psi-input-border-error)}._error_hpei8_63:hover:not(:disabled):not(:focus){border-color:var(--psi-input-border-error)}._select_4x9ck_3{display:block;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid var(--psi-select-border);border-radius:var(--psi-select-radius);background-color:var(--psi-select-bg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;color:var(--psi-select-fg);font-family:var(--psi-font-sans);cursor:pointer;transition:border-color var(--psi-duration-150) var(--psi-ease-standard),outline var(--psi-duration-150) var(--psi-ease-standard)}._select_4x9ck_3:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-hover)}._select_4x9ck_3:focus{outline:2px solid var(--psi-select-focus-ring);outline-offset:-1px;border-color:transparent}._select_4x9ck_3:disabled{opacity:.4;cursor:not-allowed}._size24_4x9ck_37{height:var(--psi-select-24-height);padding-inline-start:var(--psi-select-24-padding-inline);padding-inline-end:var(--psi-select-24-padding-inline-end);background-position:right var(--psi-select-24-chevron-offset) center;font:var(--psi-select-24-font)}._size32_4x9ck_45{height:var(--psi-select-32-height);padding-inline-start:var(--psi-select-32-padding-inline);padding-inline-end:var(--psi-select-32-padding-inline-end);background-position:right var(--psi-select-32-chevron-offset) center;font:var(--psi-select-32-font)}._size40_4x9ck_53{height:var(--psi-select-40-height);padding-inline-start:var(--psi-select-40-padding-inline);padding-inline-end:var(--psi-select-40-padding-inline-end);background-position:right var(--psi-select-40-chevron-offset) center;font:var(--psi-select-40-font)}._size48_4x9ck_61{height:var(--psi-select-48-height);padding-inline-start:var(--psi-select-48-padding-inline);padding-inline-end:var(--psi-select-48-padding-inline-end);background-position:right var(--psi-select-48-chevron-offset) center;font:var(--psi-select-48-font)}._error_4x9ck_71{border-color:var(--psi-select-border-error)}._error_4x9ck_71:hover:not(:disabled):not(:focus){border-color:var(--psi-select-border-error)}._label_1v4vv_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-checkbox-fg)}._disabled_1v4vv_13{opacity:.4;cursor:not-allowed}._input_1v4vv_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._indicator_1v4vv_34{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;border:1px solid var(--psi-checkbox-box-border);border-radius:var(--psi-checkbox-box-radius);background:var(--psi-checkbox-box-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard),border-color var(--psi-duration-150) var(--psi-ease-standard)}._input_1v4vv_20:checked+._indicator_1v4vv_34{background:var(--psi-checkbox-box-bg-checked);border-color:var(--psi-checkbox-box-border-checked)}._input_1v4vv_20:checked+._indicator_1v4vv_34:after{content:"";display:block;width:4px;height:8px;color:var(--psi-checkbox-check-fg);border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg) translate(-.5px,-.5px)}._input_1v4vv_20:focus-visible+._indicator_1v4vv_34{outline:2px solid var(--psi-checkbox-focus-ring);outline-offset:2px}._text_1v4vv_75{color:var(--psi-checkbox-fg)}._label_jru2c_3{display:inline-flex;align-items:center;gap:var(--psi-space-8);cursor:pointer;-webkit-user-select:none;user-select:none;font:var(--psi-text-14-20-regular);color:var(--psi-switch-fg)}._disabled_jru2c_13{opacity:.4;cursor:not-allowed}._input_jru2c_20{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}._track_jru2c_34{position:relative;display:inline-flex;align-items:center;width:36px;height:20px;flex-shrink:0;border-radius:var(--psi-radius-full);background:var(--psi-switch-track-bg);transition:background-color var(--psi-duration-150) var(--psi-ease-standard)}._input_jru2c_20:checked+._track_jru2c_34{background:var(--psi-switch-track-bg-checked)}._input_jru2c_20:focus-visible+._track_jru2c_34{outline:2px solid var(--psi-switch-focus-ring);outline-offset:2px}._thumb_jru2c_58{position:absolute;width:16px;height:16px;border-radius:var(--psi-radius-full);background:var(--psi-switch-thumb-bg);left:2px;transition:left var(--psi-duration-150) var(--psi-ease-standard);box-shadow:0 1px 2px #00000029}._input_jru2c_20:checked+._track_jru2c_34 ._thumb_jru2c_58{left:18px}._text_jru2c_75{color:var(--psi-switch-fg)}._tag_3oysa_3{display:inline-flex;align-items:center;gap:var(--psi-space-4);height:24px;padding-inline:var(--psi-space-8);border-radius:var(--psi-radius-full);font:var(--psi-text-12-16-medium);white-space:nowrap;-webkit-user-select:none;user-select:none}._dismiss_3oysa_17{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:none;color:inherit;cursor:pointer;opacity:.7;margin-inline-start:var(--psi-space-2);margin-inline-end:calc(-1 * var(--psi-space-4));border-radius:var(--psi-radius-full)}._dismiss_3oysa_17:hover{opacity:1}._dismiss_3oysa_17:focus-visible{outline:2px solid var(--psi-tag-focus-ring);outline-offset:2px}._neutral_3oysa_43{background:var(--psi-tag-neutral-bg);color:var(--psi-tag-neutral-fg)}._accent_3oysa_48{background:var(--psi-tag-accent-bg);color:var(--psi-tag-accent-fg)}._success_3oysa_53{background:var(--psi-tag-success-bg);color:var(--psi-tag-success-fg)}._warning_3oysa_58{background:var(--psi-tag-warning-bg);color:var(--psi-tag-warning-fg)}._danger_3oysa_63{background:var(--psi-tag-danger-bg);color:var(--psi-tag-danger-fg)}._neutralSubtle_3oysa_70{background:var(--psi-tag-neutral-subtle-bg);color:var(--psi-tag-neutral-subtle-fg)}._accentSubtle_3oysa_75{background:var(--psi-tag-accent-subtle-bg);color:var(--psi-tag-accent-subtle-fg)}._successSubtle_3oysa_80{background:var(--psi-tag-success-subtle-bg);color:var(--psi-tag-success-subtle-fg)}._warningSubtle_3oysa_85{background:var(--psi-tag-warning-subtle-bg);color:var(--psi-tag-warning-subtle-fg)}._dangerSubtle_3oysa_90{background:var(--psi-tag-danger-subtle-bg);color:var(--psi-tag-danger-subtle-fg)}._wrapper_1eu6z_3{position:relative;display:inline-flex}._tooltip_1eu6z_10{position:absolute;z-index:var(--psi-z-tooltip);padding:var(--psi-space-4) var(--psi-space-8);border-radius:var(--psi-tooltip-radius);background:var(--psi-tooltip-bg);color:var(--psi-tooltip-fg);font:var(--psi-text-12-16-regular);white-space:nowrap;pointer-events:none}._top_1eu6z_24{bottom:100%;left:50%;transform:translate(-50%);margin-bottom:var(--psi-space-4)}._bottom_1eu6z_31{top:100%;left:50%;transform:translate(-50%);margin-top:var(--psi-space-4)}._left_1eu6z_38{right:100%;top:50%;transform:translateY(-50%);margin-right:var(--psi-space-4)}._right_1eu6z_45{left:100%;top:50%;transform:translateY(-50%);margin-left:var(--psi-space-4)}._toolbar_1i848_1{display:flex;flex-wrap:wrap;align-items:center}._gap8_1i848_7{gap:var(--psi-space-8)}._gap12_1i848_8{gap:var(--psi-space-12)}._gap16_1i848_9{gap:var(--psi-space-16)}._trigger_vpa0u_4{display:inline-flex;width:fit-content}._menu_vpa0u_16{min-width:180px;margin:var(--psi-space-4);padding:var(--psi-space-4);border:1px solid var(--psi-menu-border);border-radius:var(--psi-menu-radius);background:var(--psi-menu-bg);color:var(--psi-menu-fg);font:var(--psi-text-14-20-regular)}._menu_vpa0u_16:not([data-open]):not(:popover-open){display:none}._item_vpa0u_37{display:flex;width:100%;align-items:center;padding:var(--psi-space-8) var(--psi-space-12);border:0;border-radius:var(--psi-radius-6);background:var(--psi-menu-item-bg);color:var(--psi-menu-item-fg);font:inherit;text-align:start;cursor:pointer}._item_vpa0u_37:hover{background:var(--psi-menu-item-bg-hover)}._item_vpa0u_37:active{background:var(--psi-menu-item-bg-active)}._item_vpa0u_37[data-variant=danger]{color:var(--psi-menu-item-fg-danger)}._item_vpa0u_37[aria-disabled=true]{color:var(--psi-menu-item-fg-disabled);cursor:default}._item_vpa0u_37[aria-disabled=true]:hover{background:var(--psi-menu-item-bg)}._separator_vpa0u_74{height:0;margin:var(--psi-space-4) 0;border-top:1px solid var(--psi-menu-separator-border)}@supports (anchor-name: --x){._menu_vpa0u_16{position:fixed;margin:var(--psi-space-4);position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline}._menu_vpa0u_16[data-placement=bottom-start]{position-area:block-end span-inline-end}._menu_vpa0u_16[data-placement=bottom-end]{position-area:block-end span-inline-start}._menu_vpa0u_16[data-placement=top-start]{position-area:block-start span-inline-end}._menu_vpa0u_16[data-placement=top-end]{position-area:block-start span-inline-start}}._table_146hc_3{width:100%;border-collapse:collapse;background:var(--psi-table-bg);color:var(--psi-table-fg);font:var(--psi-text-14-20-regular);border:1px solid var(--psi-table-border);border-radius:var(--psi-table-radius)}._headerCell_146hc_13{color:var(--psi-table-header-fg);font:var(--psi-text-14-20-medium);text-align:start}._cell_146hc_19,._headerCell_146hc_13{border-bottom:1px solid var(--psi-table-cell-border)}._cell_146hc_19[data-numeric],._headerCell_146hc_13[data-numeric]{text-align:end;font-variant-numeric:var(--psi-font-variant-numeric)}._sortButton_146hc_30{display:inline-flex;align-items:center;gap:var(--psi-space-4);padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}._sortButton_146hc_30:focus-visible{outline:2px solid var(--psi-table-focus-ring);outline-offset:2px}._sortIndicator_146hc_47{color:var(--psi-table-sort-indicator-fg)}._table_146hc_3[data-size="32"] ._cell_146hc_19,._table_146hc_3[data-size="32"] ._headerCell_146hc_13{height:var(--psi-table-32-row-height);padding-inline:var(--psi-table-32-cell-padding-x)}._table_146hc_3[data-size="40"] ._cell_146hc_19,._table_146hc_3[data-size="40"] ._headerCell_146hc_13{height:var(--psi-table-40-row-height);padding-inline:var(--psi-table-40-cell-padding-x)}._table_146hc_3[data-size="48"] ._cell_146hc_19,._table_146hc_3[data-size="48"] ._headerCell_146hc_13{height:var(--psi-table-48-row-height);padding-inline:var(--psi-table-48-cell-padding-x)}._table_146hc_3[data-size] ._selectCell_146hc_79{width:1%;padding-inline-end:0}._body_146hc_86 ._row_146hc_89:hover{background:var(--psi-table-row-bg-hover)}._body_146hc_86 ._row_146hc_89[data-selected]:hover,._row_146hc_89[data-selected]{background:var(--psi-table-row-bg-selected)}._row_146hc_89{background:var(--psi-table-row-bg)}._sticky_146hc_111 ._headerCell_146hc_13{position:sticky;inset-block-start:0;z-index:var(--psi-z-sticky);background:var(--psi-table-bg);box-shadow:inset 0 -1px 0 var(--psi-table-cell-border)}._nav_166vs_6{display:flex;align-items:center;gap:var(--psi-space-4)}._ellipsis_166vs_12{padding-inline:var(--psi-space-4)}
package/docs/Checkbox.md CHANGED
@@ -8,6 +8,7 @@ Native checkbox with a built-in label; for independent binary choices.
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
10
  | `children` | `ReactNode` | — | no | Label text. |
11
+ | `aria-label` | `string` | — | no | Accessible name when there is no visible label — a table's row-selection checkbox, say. Optional, unlike IconButton's required form (D60): a labelled checkbox is still the common case. |
11
12
  | `ref` | `Ref<HTMLInputElement>` | — | no | Forwarded ref to the underlying `<input type="checkbox">` element. |
12
13
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
13
14
 
@@ -0,0 +1,32 @@
1
+ <!-- Generated by emit-docs.ts — do not edit. -->
2
+ # Pagination
3
+
4
+ Numbered pager with ellipsis truncation (D63). Standalone rather than a Table family member: `table-pagination` composes it as a Toolbar sibling of the page-size Select.
5
+
6
+ ## Props
7
+
8
+ | Prop | Type | Default | Required | Description |
9
+ |---|---|---|---|---|
10
+ | `page` | `number` | — | yes | Current page, 1-based. |
11
+ | `pageCount` | `number` | — | yes | Total number of pages. |
12
+ | `onPageChange` | `(page: number) => void` | — | yes | Called with the requested page. Required — unlike Table's `onSortChange`/ `onSelectionChange`, which are optional because `sortable`/`selectable` gate whether they're meaningful, `Pagination` has no such gating boolean: the prop is unconditionally meaningful, so a `Pagination` without it is a dead control (final review finding, D62). |
13
+ | `siblingCount` | `number` | 1 | no | Pages shown either side of the current one before truncating. |
14
+ | `aria-label` | `string` | Pagination | no | Accessible name for the nav landmark. |
15
+ | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
16
+
17
+ ## Theming
18
+
19
+ This component has no `--psi-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.
20
+
21
+
22
+
23
+ ## Rules
24
+
25
+ - One accent per visual group; everything else neutral or ghost.
26
+ - danger only for actions with real consequences.
27
+ - Sizes are px numbers (24|32|40|48), never S/M/L.
28
+ - Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
29
+ - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
30
+ - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
31
+ - 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.
32
+ - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Table.md ADDED
@@ -0,0 +1,36 @@
1
+ <!-- Generated by emit-docs.ts — do not edit. -->
2
+ # Table
3
+
4
+ Data table on native table semantics. Holds no state: sorting, selection and pagination are the consumer's (D62, extending D50/D53).
5
+
6
+ ## Props
7
+
8
+ | Prop | Type | Default | Required | Description |
9
+ |---|---|---|---|---|
10
+ | `size` | `32 \| 40 \| 48` | 40 | no | Row height in px. |
11
+ | `stickyHeader` | `boolean` | — | no | Pins the header while the body scrolls. |
12
+ | `sortable` | `boolean` | false | no | Enables the sort affordance on header cells that declare a `sortKey`. |
13
+ | `sort` | `TableSortState \| null` | — | no | Controlled sort state; `null` when nothing is sorted. |
14
+ | `onSortChange` | `((sort: TableSortState) => void)` | — | no | Called when a header's sort control is activated. Optional in the type because `sortable` may be false; a discriminated union expressing the real contract does not survive docgen's flat prop extraction, which would strip these props from the manifest entirely (D62). |
15
+ | `selectable` | `boolean` | false | no | Renders the row-selection checkbox column. |
16
+ | `selected` | `ReadonlySet<string>` | new Set<string>() | no | Controlled selection, keyed by each `TableRow`'s `rowId`. |
17
+ | `onSelectionChange` | `((selected: ReadonlySet<string>) => void)` | — | no | Called with the next selection. See `onSortChange` on why it is optional. |
18
+ | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
19
+ | `ref` | `Ref<HTMLTableElement>` | — | no | Forwarded ref to the underlying `<table>` element. |
20
+
21
+ ## Theming
22
+
23
+ Override `--psi-table-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).
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
+ - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -0,0 +1,27 @@
1
+ <!-- Generated by emit-docs.ts — do not edit. -->
2
+ # TableBody
3
+
4
+ `<tbody>` wrapper.
5
+
6
+ ## Props
7
+
8
+ | Prop | Type | Default | Required | Description |
9
+ |---|---|---|---|---|
10
+ | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
11
+
12
+ ## Theming
13
+
14
+ This component has no `--psi-table-body-*` 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.
15
+
16
+
17
+
18
+ ## Rules
19
+
20
+ - One accent per visual group; everything else neutral or ghost.
21
+ - danger only for actions with real consequences.
22
+ - Sizes are px numbers (24|32|40|48), never S/M/L.
23
+ - Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
24
+ - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
25
+ - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
26
+ - 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.
27
+ - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -0,0 +1,28 @@
1
+ <!-- Generated by emit-docs.ts — do not edit. -->
2
+ # TableCell
3
+
4
+ `<td>`. `numeric` means right-aligned *and* tabular — a column that aligns but whose digits jitter between rows defeats the purpose.
5
+
6
+ ## Props
7
+
8
+ | Prop | Type | Default | Required | Description |
9
+ |---|---|---|---|---|
10
+ | `numeric` | `boolean` | — | no | Right-aligns and renders tabular figures (D62). |
11
+ | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
12
+
13
+ ## Theming
14
+
15
+ This component has no `--psi-table-cell-*` 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.
16
+
17
+
18
+
19
+ ## Rules
20
+
21
+ - One accent per visual group; everything else neutral or ghost.
22
+ - danger only for actions with real consequences.
23
+ - Sizes are px numbers (24|32|40|48), never S/M/L.
24
+ - Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
25
+ - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
26
+ - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
27
+ - 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.
28
+ - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -0,0 +1,27 @@
1
+ <!-- Generated by emit-docs.ts — do not edit. -->
2
+ # TableHead
3
+
4
+ `<thead>`. When the table is selectable, prepends the select-all cell to the FIRST header row so the header's column count matches the body's — the checkbox column is Table's, not the consumer's schema. Clones the row rather than rebuilding it, so the consumer's own props on that `TableRow` survive.
5
+
6
+ ## Props
7
+
8
+ | Prop | Type | Default | Required | Description |
9
+ |---|---|---|---|---|
10
+ | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
11
+
12
+ ## Theming
13
+
14
+ This component has no `--psi-table-head-*` 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.
15
+
16
+
17
+
18
+ ## Rules
19
+
20
+ - One accent per visual group; everything else neutral or ghost.
21
+ - danger only for actions with real consequences.
22
+ - Sizes are px numbers (24|32|40|48), never S/M/L.
23
+ - Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
24
+ - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
25
+ - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
26
+ - 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.
27
+ - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.