@usefragments/ui 1.7.0 → 2.0.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 +54 -66
- package/dist/assets/nav-glyph.cjs +139 -0
- package/dist/assets/nav-glyph.d.ts +28 -0
- package/dist/assets/nav-glyph.d.ts.map +1 -0
- package/dist/assets/nav-glyph.js +139 -0
- package/dist/assets/nav-glyph.module.scss.cjs +71 -0
- package/dist/assets/nav-glyph.module.scss.js +71 -0
- package/dist/assets/ui.css +4975 -4959
- package/dist/blocks/components/StatsCard.d.ts +1 -1
- package/dist/blocks/components/StatsCard.d.ts.map +1 -1
- package/dist/codeblock.cjs +23 -16
- package/dist/codeblock.js +16 -9
- package/dist/colorpicker.cjs +1 -0
- package/dist/colorpicker.js +1 -0
- package/dist/components/Accordion/Accordion.module.scss.cjs +8 -8
- package/dist/components/Accordion/Accordion.module.scss.js +8 -8
- package/dist/components/Alert/Alert.module.scss.cjs +21 -21
- package/dist/components/Alert/Alert.module.scss.js +21 -21
- package/dist/components/Alert/index.cjs +14 -8
- package/dist/components/Alert/index.d.ts +9 -9
- package/dist/components/Alert/index.d.ts.map +1 -1
- package/dist/components/Alert/index.js +14 -8
- package/dist/components/AppShell/AppShell.module.scss.cjs +14 -14
- package/dist/components/AppShell/AppShell.module.scss.js +14 -14
- package/dist/components/AppShell/index.cjs +2 -2
- package/dist/components/AppShell/index.js +2 -2
- package/dist/components/Avatar/Avatar.module.scss.cjs +14 -14
- package/dist/components/Avatar/Avatar.module.scss.js +14 -14
- package/dist/components/Badge/Badge.module.scss.cjs +33 -31
- package/dist/components/Badge/Badge.module.scss.js +33 -31
- package/dist/components/Badge/index.cjs +13 -3
- package/dist/components/Badge/index.d.ts +18 -13
- package/dist/components/Badge/index.d.ts.map +1 -1
- package/dist/components/Badge/index.js +13 -3
- package/dist/components/BentoGrid/BentoGrid.module.scss.cjs +14 -14
- package/dist/components/BentoGrid/BentoGrid.module.scss.js +14 -14
- package/dist/components/Box/Box.module.scss.cjs +152 -152
- package/dist/components/Box/Box.module.scss.js +152 -152
- package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.cjs +11 -8
- package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.js +11 -8
- package/dist/components/Breadcrumbs/index.cjs +1 -1
- package/dist/components/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/components/Breadcrumbs/index.js +1 -1
- package/dist/components/Button/Button.module.scss.cjs +36 -27
- package/dist/components/Button/Button.module.scss.js +36 -27
- package/dist/components/Button/index.cjs +20 -4
- package/dist/components/Button/index.d.ts +18 -10
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +20 -4
- package/dist/components/ButtonGroup/ButtonGroup.module.scss.cjs +15 -15
- package/dist/components/ButtonGroup/ButtonGroup.module.scss.js +15 -15
- package/dist/components/Card/Card.module.scss.cjs +27 -34
- package/dist/components/Card/Card.module.scss.js +27 -34
- package/dist/components/Card/index.cjs +13 -8
- package/dist/components/Card/index.d.ts +23 -25
- package/dist/components/Card/index.d.ts.map +1 -1
- package/dist/components/Card/index.js +13 -8
- package/dist/components/Chart/Chart.module.scss.cjs +15 -15
- package/dist/components/Chart/Chart.module.scss.js +15 -15
- package/dist/components/Checkbox/Checkbox.module.scss.cjs +11 -11
- package/dist/components/Checkbox/Checkbox.module.scss.js +11 -11
- package/dist/components/Checkbox/index.cjs +2 -2
- package/dist/components/Checkbox/index.d.ts +4 -6
- package/dist/components/Checkbox/index.d.ts.map +1 -1
- package/dist/components/Checkbox/index.js +2 -2
- package/dist/components/Chip/Chip.module.scss.cjs +19 -19
- package/dist/components/Chip/Chip.module.scss.js +19 -19
- package/dist/components/Chip/index.cjs +1 -2
- package/dist/components/Chip/index.d.ts +8 -3
- package/dist/components/Chip/index.d.ts.map +1 -1
- package/dist/components/Chip/index.js +1 -2
- package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +22 -22
- package/dist/components/CodeBlock/CodeBlock.module.scss.js +22 -22
- package/dist/components/CodeBlock/index.d.ts +3 -2
- package/dist/components/CodeBlock/index.d.ts.map +1 -1
- package/dist/components/Collapsible/Collapsible.module.scss.cjs +9 -9
- package/dist/components/Collapsible/Collapsible.module.scss.js +9 -9
- package/dist/components/ColorPicker/ColorPicker.module.scss.cjs +14 -14
- package/dist/components/ColorPicker/ColorPicker.module.scss.js +14 -14
- package/dist/components/ColorPicker/index.d.ts.map +1 -1
- package/dist/components/Combobox/Combobox.module.scss.cjs +21 -21
- package/dist/components/Combobox/Combobox.module.scss.js +21 -21
- package/dist/components/Combobox/index.cjs +9 -5
- package/dist/components/Combobox/index.d.ts.map +1 -1
- package/dist/components/Combobox/index.js +9 -5
- package/dist/components/Command/Command.module.scss.cjs +14 -11
- package/dist/components/Command/Command.module.scss.js +14 -11
- package/dist/components/Command/index.cjs +2 -1
- package/dist/components/Command/index.d.ts +6 -1
- package/dist/components/Command/index.d.ts.map +1 -1
- package/dist/components/Command/index.js +2 -1
- package/dist/components/ConversationList/ConversationList.module.scss.cjs +10 -10
- package/dist/components/ConversationList/ConversationList.module.scss.js +10 -10
- package/dist/components/ConversationList/index.cjs +2 -2
- package/dist/components/ConversationList/index.js +2 -2
- package/dist/components/DataTable/DataTable.module.scss.cjs +31 -28
- package/dist/components/DataTable/DataTable.module.scss.js +31 -28
- package/dist/components/DataTable/DataTable.virtual.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.module.scss.cjs +33 -33
- package/dist/components/DatePicker/DatePicker.module.scss.js +33 -33
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/Dialog/Dialog.module.scss.cjs +14 -14
- package/dist/components/Dialog/Dialog.module.scss.js +14 -14
- package/dist/components/Dialog/index.cjs +2 -2
- package/dist/components/Dialog/index.d.ts +5 -4
- package/dist/components/Dialog/index.d.ts.map +1 -1
- package/dist/components/Dialog/index.js +2 -2
- package/dist/components/Drawer/Drawer.module.scss.cjs +39 -39
- package/dist/components/Drawer/Drawer.module.scss.js +40 -40
- package/dist/components/Drawer/index.cjs +2 -2
- package/dist/components/Drawer/index.d.ts +5 -4
- package/dist/components/Drawer/index.d.ts.map +1 -1
- package/dist/components/Drawer/index.js +2 -2
- package/dist/components/Editor/Editor.module.scss.cjs +17 -17
- package/dist/components/Editor/Editor.module.scss.js +17 -17
- package/dist/components/EmptyState/EmptyState.module.scss.cjs +11 -11
- package/dist/components/EmptyState/EmptyState.module.scss.js +11 -11
- package/dist/components/EmptyState/index.cjs +9 -4
- package/dist/components/EmptyState/index.d.ts +8 -5
- package/dist/components/EmptyState/index.d.ts.map +1 -1
- package/dist/components/EmptyState/index.js +9 -4
- package/dist/components/Field/Field.module.scss.cjs +5 -5
- package/dist/components/Field/Field.module.scss.js +5 -5
- package/dist/components/Fieldset/Fieldset.module.scss.cjs +3 -3
- package/dist/components/Fieldset/Fieldset.module.scss.js +3 -3
- package/dist/components/Grid/Grid.module.scss.cjs +54 -54
- package/dist/components/Grid/Grid.module.scss.js +54 -54
- package/dist/components/Header/Header.module.scss.cjs +33 -33
- package/dist/components/Header/Header.module.scss.js +33 -33
- package/dist/components/Icon/Icon.module.scss.cjs +30 -33
- package/dist/components/Icon/Icon.module.scss.js +30 -33
- package/dist/components/Icon/index.cjs +15 -14
- package/dist/components/Icon/index.d.ts +23 -12
- package/dist/components/Icon/index.d.ts.map +1 -1
- package/dist/components/Icon/index.js +15 -14
- package/dist/components/IconButton/IconButton.module.scss.cjs +12 -12
- package/dist/components/IconButton/IconButton.module.scss.js +12 -12
- package/dist/components/IconButton/index.d.ts +4 -4
- package/dist/components/IconButton/index.d.ts.map +1 -1
- package/dist/components/Input/Input.module.scss.cjs +15 -21
- package/dist/components/Input/Input.module.scss.js +15 -21
- package/dist/components/Input/index.cjs +2 -14
- package/dist/components/Input/index.d.ts +0 -2
- package/dist/components/Input/index.d.ts.map +1 -1
- package/dist/components/Input/index.js +2 -14
- package/dist/components/Link/Link.module.scss.cjs +24 -16
- package/dist/components/Link/Link.module.scss.js +24 -16
- package/dist/components/Link/index.cjs +13 -2
- package/dist/components/Link/index.d.ts +10 -3
- package/dist/components/Link/index.d.ts.map +1 -1
- package/dist/components/Link/index.js +13 -2
- package/dist/components/List/List.module.scss.cjs +23 -19
- package/dist/components/List/List.module.scss.js +23 -19
- package/dist/components/List/index.cjs +7 -7
- package/dist/components/List/index.d.ts +10 -7
- package/dist/components/List/index.d.ts.map +1 -1
- package/dist/components/List/index.js +7 -7
- package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
- package/dist/components/Listbox/Listbox.module.scss.js +8 -8
- package/dist/components/Loading/Loading.module.scss.cjs +30 -30
- package/dist/components/Loading/Loading.module.scss.js +30 -30
- package/dist/components/Loading/index.cjs +5 -5
- package/dist/components/Loading/index.d.ts +8 -7
- package/dist/components/Loading/index.d.ts.map +1 -1
- package/dist/components/Loading/index.js +5 -5
- package/dist/components/Markdown/Markdown.module.scss.cjs +1 -1
- package/dist/components/Markdown/Markdown.module.scss.js +1 -1
- package/dist/components/Menu/Menu.module.scss.cjs +14 -14
- package/dist/components/Menu/Menu.module.scss.js +14 -14
- package/dist/components/Message/Message.module.scss.cjs +20 -20
- package/dist/components/Message/Message.module.scss.js +20 -20
- package/dist/components/Message/index.cjs +1 -1
- package/dist/components/Message/index.d.ts +1 -1
- package/dist/components/Message/index.js +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +29 -29
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +29 -29
- package/dist/components/Pagination/Pagination.module.scss.cjs +10 -10
- package/dist/components/Pagination/Pagination.module.scss.js +10 -10
- package/dist/components/Popover/Popover.module.scss.cjs +10 -10
- package/dist/components/Popover/Popover.module.scss.js +10 -10
- package/dist/components/Progress/Progress.module.scss.cjs +28 -25
- package/dist/components/Progress/Progress.module.scss.js +28 -25
- package/dist/components/Progress/index.cjs +21 -12
- package/dist/components/Progress/index.d.ts +10 -6
- package/dist/components/Progress/index.d.ts.map +1 -1
- package/dist/components/Progress/index.js +21 -12
- package/dist/components/Prompt/Prompt.module.scss.cjs +30 -30
- package/dist/components/Prompt/Prompt.module.scss.js +30 -30
- package/dist/components/Prompt/index.cjs +7 -7
- package/dist/components/Prompt/index.d.ts +11 -9
- package/dist/components/Prompt/index.d.ts.map +1 -1
- package/dist/components/Prompt/index.js +7 -7
- package/dist/components/RadioGroup/RadioGroup.module.scss.cjs +20 -17
- package/dist/components/RadioGroup/RadioGroup.module.scss.js +20 -17
- package/dist/components/RadioGroup/index.cjs +10 -5
- package/dist/components/RadioGroup/index.d.ts +11 -7
- package/dist/components/RadioGroup/index.d.ts.map +1 -1
- package/dist/components/RadioGroup/index.js +10 -5
- package/dist/components/ScrollArea/ScrollArea.module.scss.cjs +5 -5
- package/dist/components/ScrollArea/ScrollArea.module.scss.js +5 -5
- package/dist/components/Select/Select.module.scss.cjs +21 -21
- package/dist/components/Select/Select.module.scss.js +21 -21
- package/dist/components/Select/index.cjs +26 -20
- package/dist/components/Select/index.d.ts +5 -5
- package/dist/components/Select/index.d.ts.map +1 -1
- package/dist/components/Select/index.js +26 -20
- package/dist/components/Separator/Separator.module.scss.cjs +25 -19
- package/dist/components/Separator/Separator.module.scss.js +25 -19
- package/dist/components/Separator/index.cjs +10 -8
- package/dist/components/Separator/index.d.ts +4 -2
- package/dist/components/Separator/index.d.ts.map +1 -1
- package/dist/components/Separator/index.js +10 -8
- package/dist/components/Sidebar/Sidebar.module.scss.cjs +43 -43
- package/dist/components/Sidebar/Sidebar.module.scss.js +43 -43
- package/dist/components/Sidebar/index.cjs +3 -3
- package/dist/components/Sidebar/index.js +3 -3
- package/dist/components/Skeleton/Skeleton.module.scss.cjs +46 -46
- package/dist/components/Skeleton/Skeleton.module.scss.js +46 -46
- package/dist/components/Skeleton/index.cjs +7 -7
- package/dist/components/Skeleton/index.d.ts +8 -7
- package/dist/components/Skeleton/index.d.ts.map +1 -1
- package/dist/components/Skeleton/index.js +7 -7
- package/dist/components/Slider/Slider.module.scss.cjs +12 -12
- package/dist/components/Slider/Slider.module.scss.js +12 -12
- package/dist/components/Switch/Switch.module.scss.cjs +9 -9
- package/dist/components/Switch/Switch.module.scss.js +9 -9
- package/dist/components/Table/Table.module.scss.cjs +15 -15
- package/dist/components/Table/Table.module.scss.js +15 -15
- package/dist/components/TableOfContents/TableOfContents.module.scss.cjs +15 -15
- package/dist/components/TableOfContents/TableOfContents.module.scss.js +15 -15
- package/dist/components/TableOfContents/index.cjs +1 -1
- package/dist/components/TableOfContents/index.js +1 -1
- package/dist/components/Tabs/Tabs.module.scss.cjs +18 -18
- package/dist/components/Tabs/Tabs.module.scss.js +18 -18
- package/dist/components/Tabs/index.cjs +5 -6
- package/dist/components/Tabs/index.d.ts +8 -6
- package/dist/components/Tabs/index.d.ts.map +1 -1
- package/dist/components/Tabs/index.js +5 -6
- package/dist/components/Text/Text.module.scss.cjs +105 -105
- package/dist/components/Text/Text.module.scss.js +105 -105
- package/dist/components/Text/index.cjs +5 -9
- package/dist/components/Text/index.d.ts +15 -11
- package/dist/components/Text/index.d.ts.map +1 -1
- package/dist/components/Text/index.js +5 -9
- package/dist/components/Textarea/Textarea.module.scss.cjs +22 -28
- package/dist/components/Textarea/Textarea.module.scss.js +22 -28
- package/dist/components/Textarea/index.cjs +3 -10
- package/dist/components/Textarea/index.d.ts +0 -2
- package/dist/components/Textarea/index.d.ts.map +1 -1
- package/dist/components/Textarea/index.js +3 -10
- package/dist/components/Theme/index.cjs +20 -4
- package/dist/components/Theme/index.d.ts +6 -12
- package/dist/components/Theme/index.d.ts.map +1 -1
- package/dist/components/Theme/index.js +20 -4
- package/dist/components/ThemeToggle/ThemeButton.cjs +51 -0
- package/dist/components/ThemeToggle/ThemeButton.d.ts +16 -0
- package/dist/components/ThemeToggle/ThemeButton.d.ts.map +1 -0
- package/dist/components/ThemeToggle/ThemeButton.js +34 -0
- package/dist/components/ThemeToggle/ThemeToggle.module.scss.cjs +6 -9
- package/dist/components/ThemeToggle/ThemeToggle.module.scss.js +6 -9
- package/dist/components/ThemeToggle/icons.cjs +48 -0
- package/dist/components/ThemeToggle/icons.d.ts +10 -0
- package/dist/components/ThemeToggle/icons.d.ts.map +1 -0
- package/dist/components/ThemeToggle/icons.js +48 -0
- package/dist/components/ThemeToggle/index.cjs +5 -74
- package/dist/components/ThemeToggle/index.d.ts +5 -8
- package/dist/components/ThemeToggle/index.d.ts.map +1 -1
- package/dist/components/ThemeToggle/index.js +3 -72
- package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.cjs +18 -15
- package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.js +18 -15
- package/dist/components/ThinkingIndicator/index.cjs +7 -8
- package/dist/components/ThinkingIndicator/index.d.ts +6 -5
- package/dist/components/ThinkingIndicator/index.d.ts.map +1 -1
- package/dist/components/ThinkingIndicator/index.js +7 -8
- package/dist/components/Toast/Toast.module.scss.cjs +28 -29
- package/dist/components/Toast/Toast.module.scss.js +29 -30
- package/dist/components/Toast/index.cjs +28 -30
- package/dist/components/Toast/index.d.ts +9 -8
- package/dist/components/Toast/index.d.ts.map +1 -1
- package/dist/components/Toast/index.js +28 -30
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.cjs +21 -19
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.js +22 -20
- package/dist/components/ToggleGroup/index.cjs +4 -5
- package/dist/components/ToggleGroup/index.d.ts +7 -6
- package/dist/components/ToggleGroup/index.d.ts.map +1 -1
- package/dist/components/ToggleGroup/index.js +4 -5
- package/dist/components/Tooltip/Tooltip.module.scss.cjs +3 -3
- package/dist/components/Tooltip/Tooltip.module.scss.js +3 -3
- package/dist/components/VisuallyHidden/VisuallyHidden.module.scss.cjs +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.module.scss.js +1 -1
- package/dist/data-table-virtual.cjs +3 -2
- package/dist/data-table-virtual.js +3 -2
- package/dist/data-table.cjs +1 -1
- package/dist/data-table.js +1 -1
- package/dist/datepicker.cjs +23 -11
- package/dist/datepicker.js +23 -11
- package/dist/index.cjs +5 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/measurements/generated.cjs +37 -93
- package/dist/measurements/generated.d.ts +37 -92
- package/dist/measurements/generated.d.ts.map +1 -1
- package/dist/measurements/generated.js +37 -93
- package/dist/measurements/index.d.ts +1 -1
- package/dist/measurements/index.d.ts.map +1 -1
- package/dist/utils/seed-derivation.cjs +0 -1
- package/dist/utils/seed-derivation.d.ts +1 -3
- package/dist/utils/seed-derivation.d.ts.map +1 -1
- package/dist/utils/seed-derivation.js +0 -1
- package/dist/utils/theme-presets.cjs +5 -10
- package/dist/utils/theme-presets.d.ts +1 -2
- package/dist/utils/theme-presets.d.ts.map +1 -1
- package/dist/utils/theme-presets.js +5 -10
- package/fragments.json +1 -1
- package/package.json +5 -8
- package/src/assets/nav-glyph.module.scss +166 -0
- package/src/assets/nav-glyph.tsx +188 -0
- package/src/components/Accordion/Accordion.module.scss +5 -3
- package/src/components/Alert/Alert.contract.json +18 -18
- package/src/components/Alert/Alert.module.scss +50 -64
- package/src/components/Alert/index.tsx +24 -17
- package/src/components/AppShell/AppShell.contract.json +7 -7
- package/src/components/AppShell/AppShell.module.scss +49 -17
- package/src/components/AppShell/index.tsx +2 -2
- package/src/components/Avatar/Avatar.module.scss +0 -1
- package/src/components/Badge/Badge.contract.json +58 -22
- package/src/components/Badge/Badge.module.scss +72 -47
- package/src/components/Badge/index.tsx +34 -17
- package/src/components/BentoGrid/BentoGrid.module.scss +4 -8
- package/src/components/Box/Box.module.scss +7 -6
- package/src/components/Breadcrumbs/Breadcrumbs.module.scss +15 -5
- package/src/components/Breadcrumbs/index.tsx +5 -1
- package/src/components/Button/Button.module.scss +261 -186
- package/src/components/Button/index.tsx +41 -28
- package/src/components/ButtonGroup/ButtonGroup.contract.json +5 -5
- package/src/components/ButtonGroup/ButtonGroup.module.scss +8 -6
- package/src/components/Card/Card.consumer-fixture.module.scss +5 -2
- package/src/components/Card/Card.module.scss +73 -133
- package/src/components/Card/index.tsx +41 -36
- package/src/components/Chart/Chart.module.scss +6 -5
- package/src/components/Checkbox/Checkbox.contract.json +4 -3
- package/src/components/Checkbox/Checkbox.module.scss +16 -32
- package/src/components/Checkbox/index.tsx +6 -8
- package/src/components/Chip/Chip.contract.json +10 -10
- package/src/components/Chip/Chip.module.scss +23 -22
- package/src/components/Chip/index.tsx +10 -6
- package/src/components/CodeBlock/CodeBlock.module.scss +47 -70
- package/src/components/CodeBlock/index.tsx +23 -16
- package/src/components/Collapsible/Collapsible.module.scss +1 -7
- package/src/components/ColorPicker/ColorPicker.module.scss +20 -13
- package/src/components/ColorPicker/index.tsx +1 -0
- package/src/components/Combobox/Combobox.module.scss +16 -19
- package/src/components/Combobox/index.tsx +10 -1
- package/src/components/Command/Command.contract.json +7 -1
- package/src/components/Command/Command.module.scss +19 -21
- package/src/components/Command/index.tsx +7 -1
- package/src/components/ComponentDefaults/ComponentDefaults.contract.json +91 -0
- package/src/components/ConversationList/ConversationList.module.scss +2 -3
- package/src/components/ConversationList/index.tsx +2 -2
- package/src/components/DataTable/DataTable.module.scss +12 -9
- package/src/components/DataTable/DataTable.virtual.tsx +3 -2
- package/src/components/DataTable/index.tsx +1 -1
- package/src/components/DatePicker/DatePicker.module.scss +32 -42
- package/src/components/DatePicker/index.tsx +18 -7
- package/src/components/Dialog/Dialog.module.scss +23 -29
- package/src/components/Dialog/index.tsx +7 -5
- package/src/components/Drawer/Drawer.contract.json +6 -6
- package/src/components/Drawer/Drawer.module.scss +123 -64
- package/src/components/Drawer/index.tsx +7 -5
- package/src/components/Editor/Editor.contract.json +1 -1
- package/src/components/Editor/Editor.module.scss +26 -13
- package/src/components/EmptyState/EmptyState.contract.json +6 -6
- package/src/components/EmptyState/EmptyState.module.scss +31 -23
- package/src/components/EmptyState/index.tsx +17 -9
- package/src/components/Field/Field.module.scss +2 -1
- package/src/components/Fieldset/Fieldset.module.scss +5 -4
- package/src/components/Form/Form.contract.json +4 -4
- package/src/components/Grid/Grid.module.scss +2 -2
- package/src/components/Header/Header.contract.json +2 -2
- package/src/components/Header/Header.module.scss +24 -36
- package/src/components/Icon/Icon.contract.json +19 -23
- package/src/components/Icon/Icon.module.scss +13 -12
- package/src/components/Icon/index.tsx +31 -31
- package/src/components/IconButton/IconButton.contract.json +8 -8
- package/src/components/IconButton/IconButton.module.scss +13 -4
- package/src/components/IconButton/index.tsx +4 -4
- package/src/components/Input/Input.contract.json +0 -13
- package/src/components/Input/Input.module.scss +4 -54
- package/src/components/Input/index.tsx +2 -18
- package/src/components/Link/Link.contract.json +19 -11
- package/src/components/Link/Link.module.scss +24 -10
- package/src/components/Link/index.tsx +26 -5
- package/src/components/List/List.contract.json +11 -11
- package/src/components/List/List.module.scss +10 -5
- package/src/components/List/index.tsx +17 -13
- package/src/components/Listbox/Listbox.module.scss +14 -20
- package/src/components/Loading/Loading.contract.json +6 -6
- package/src/components/Loading/Loading.module.scss +29 -26
- package/src/components/Loading/index.tsx +13 -12
- package/src/components/Markdown/Markdown.module.scss +2 -1
- package/src/components/Menu/Menu.contract.json +5 -5
- package/src/components/Menu/Menu.module.scss +11 -10
- package/src/components/Message/Message.contract.json +5 -5
- package/src/components/Message/Message.module.scss +8 -6
- package/src/components/Message/index.tsx +2 -2
- package/src/components/NavigationMenu/NavigationMenu.module.scss +22 -67
- package/src/components/Pagination/Pagination.module.scss +7 -14
- package/src/components/Popover/Popover.contract.json +4 -4
- package/src/components/Popover/Popover.module.scss +24 -23
- package/src/components/Progress/Progress.contract.json +11 -11
- package/src/components/Progress/Progress.module.scss +13 -8
- package/src/components/Progress/index.tsx +34 -16
- package/src/components/Prompt/Prompt.contract.json +12 -12
- package/src/components/Prompt/Prompt.module.scss +40 -47
- package/src/components/Prompt/index.tsx +17 -15
- package/src/components/RadioGroup/RadioGroup.contract.json +6 -4
- package/src/components/RadioGroup/RadioGroup.module.scss +38 -32
- package/src/components/RadioGroup/index.tsx +23 -10
- package/src/components/ScrollArea/ScrollArea.module.scss +30 -33
- package/src/components/Select/Select.module.scss +19 -18
- package/src/components/Select/index.tsx +26 -24
- package/src/components/Separator/Separator.contract.json +10 -10
- package/src/components/Separator/Separator.module.scss +24 -40
- package/src/components/Separator/index.tsx +16 -11
- package/src/components/Sidebar/Sidebar.contract.json +1 -1
- package/src/components/Sidebar/Sidebar.module.scss +92 -95
- package/src/components/Sidebar/index.tsx +3 -3
- package/src/components/Skeleton/Skeleton.contract.json +9 -9
- package/src/components/Skeleton/Skeleton.module.scss +23 -16
- package/src/components/Skeleton/index.tsx +16 -15
- package/src/components/Slider/Slider.module.scss +6 -19
- package/src/components/Stack/Stack.contract.json +1 -1
- package/src/components/Stack/Stack.module.scss +13 -12
- package/src/components/Switch/Switch.module.scss +44 -35
- package/src/components/Table/Table.module.scss +9 -13
- package/src/components/TableOfContents/TableOfContents.module.scss +12 -18
- package/src/components/TableOfContents/index.tsx +1 -1
- package/src/components/Tabs/Tabs.contract.json +14 -14
- package/src/components/Tabs/Tabs.module.scss +27 -31
- package/src/components/Tabs/index.tsx +15 -12
- package/src/components/Text/Text.contract.json +36 -14
- package/src/components/Text/Text.module.scss +19 -20
- package/src/components/Text/index.tsx +23 -21
- package/src/components/Textarea/Textarea.contract.json +0 -13
- package/src/components/Textarea/Textarea.module.scss +24 -52
- package/src/components/Textarea/index.tsx +3 -14
- package/src/components/Theme/Theme.contract.json +9 -8
- package/src/components/Theme/index.tsx +39 -12
- package/src/components/ThemeToggle/ThemeButton.tsx +49 -0
- package/src/components/ThemeToggle/ThemeToggle.module.scss +21 -44
- package/src/components/ThemeToggle/icons.tsx +46 -0
- package/src/components/ThemeToggle/index.tsx +8 -90
- package/src/components/ThinkingIndicator/ThinkingIndicator.contract.json +11 -10
- package/src/components/ThinkingIndicator/ThinkingIndicator.module.scss +9 -7
- package/src/components/ThinkingIndicator/index.tsx +12 -14
- package/src/components/Toast/Toast.contract.json +29 -13
- package/src/components/Toast/Toast.module.scss +49 -104
- package/src/components/Toast/index.tsx +39 -34
- package/src/components/ToggleGroup/ToggleGroup.contract.json +13 -13
- package/src/components/ToggleGroup/ToggleGroup.module.scss +16 -46
- package/src/components/ToggleGroup/index.tsx +11 -11
- package/src/components/Tooltip/Tooltip.contract.json +3 -3
- package/src/components/Tooltip/Tooltip.module.scss +16 -10
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +4 -14
- package/src/index.ts +14 -10
- package/src/measurements/MeasurementTargets.module.scss +6 -7
- package/src/measurements/generated.ts +38 -96
- package/src/measurements/index.ts +0 -1
- package/src/measurements/measurements.json +37 -116
- package/src/recipes/_action.scss +4 -4
- package/src/recipes/_boolean-range.scss +9 -5
- package/src/recipes/_feedback.scss +17 -16
- package/src/recipes/_field.scss +28 -20
- package/src/recipes/_navigation.scss +84 -29
- package/src/recipes/_overlay.scss +143 -43
- package/src/recipes/_popup.scss +46 -36
- package/src/recipes/_prose.scss +35 -23
- package/src/recipes/_representation.scss +10 -9
- package/src/recipes/_segmented.scss +1 -1
- package/src/recipes/_table-chrome.scss +27 -16
- package/src/recipes/_target.scss +2 -4
- package/src/recipes/_typography.scss +10 -0
- package/src/styles/globals.scss +14 -9
- package/src/tokens/_component-properties.scss +19 -1
- package/src/tokens/_computed.scss +27 -33
- package/src/tokens/_measurements.catalog.generated.css +58 -45
- package/src/tokens/_measurements.generated.scss +107 -250
- package/src/tokens/_mixins.scss +42 -40
- package/src/tokens/_palettes.scss +1 -1
- package/src/tokens/_property-registrations.scss +9 -0
- package/src/tokens/_seeds.scss +1 -12
- package/src/tokens/_variables.scss +71 -59
- package/src/utils/seed-derivation.ts +1 -8
- package/src/utils/theme-presets.ts +5 -12
- package/dist/blocks/AccountSettings.block.d.ts +0 -3
- package/dist/blocks/AccountSettings.block.d.ts.map +0 -1
- package/dist/blocks/ActivityFeedSkeleton.block.d.ts +0 -3
- package/dist/blocks/ActivityFeedSkeleton.block.d.ts.map +0 -1
- package/dist/blocks/BlogEditor.block.d.ts +0 -3
- package/dist/blocks/BlogEditor.block.d.ts.map +0 -1
- package/dist/blocks/ChatInterface.block.d.ts +0 -3
- package/dist/blocks/ChatInterface.block.d.ts.map +0 -1
- package/dist/blocks/ChatMessages.block.d.ts +0 -3
- package/dist/blocks/ChatMessages.block.d.ts.map +0 -1
- package/dist/blocks/CheckoutForm.block.d.ts +0 -3
- package/dist/blocks/CheckoutForm.block.d.ts.map +0 -1
- package/dist/blocks/CommandPalette.block.d.ts +0 -3
- package/dist/blocks/CommandPalette.block.d.ts.map +0 -1
- package/dist/blocks/ContactForm.block.d.ts +0 -3
- package/dist/blocks/ContactForm.block.d.ts.map +0 -1
- package/dist/blocks/DashboardPage.block.d.ts +0 -3
- package/dist/blocks/DashboardPage.block.d.ts.map +0 -1
- package/dist/blocks/DashboardSkeleton.block.d.ts +0 -3
- package/dist/blocks/DashboardSkeleton.block.d.ts.map +0 -1
- package/dist/blocks/DataTable.block.d.ts +0 -3
- package/dist/blocks/DataTable.block.d.ts.map +0 -1
- package/dist/blocks/EmptyState.block.d.ts +0 -3
- package/dist/blocks/EmptyState.block.d.ts.map +0 -1
- package/dist/blocks/FAQSection.block.d.ts +0 -3
- package/dist/blocks/FAQSection.block.d.ts.map +0 -1
- package/dist/blocks/FeatureGrid.block.d.ts +0 -3
- package/dist/blocks/FeatureGrid.block.d.ts.map +0 -1
- package/dist/blocks/HeroSection.block.d.ts +0 -3
- package/dist/blocks/HeroSection.block.d.ts.map +0 -1
- package/dist/blocks/NavigationHeader.block.d.ts +0 -3
- package/dist/blocks/NavigationHeader.block.d.ts.map +0 -1
- package/dist/blocks/PaginatedTable.block.d.ts +0 -3
- package/dist/blocks/PaginatedTable.block.d.ts.map +0 -1
- package/dist/blocks/PricingComparison.block.d.ts +0 -3
- package/dist/blocks/PricingComparison.block.d.ts.map +0 -1
- package/dist/blocks/ProductCard.block.d.ts +0 -3
- package/dist/blocks/ProductCard.block.d.ts.map +0 -1
- package/dist/blocks/RegistrationForm.block.d.ts +0 -3
- package/dist/blocks/RegistrationForm.block.d.ts.map +0 -1
- package/dist/blocks/SettingsDrawer.block.d.ts +0 -3
- package/dist/blocks/SettingsDrawer.block.d.ts.map +0 -1
- package/dist/blocks/SettingsPanel.block.d.ts +0 -3
- package/dist/blocks/SettingsPanel.block.d.ts.map +0 -1
- package/dist/blocks/ShoppingCart.block.d.ts +0 -3
- package/dist/blocks/ShoppingCart.block.d.ts.map +0 -1
- package/dist/blocks/StatsCardSkeleton.block.d.ts +0 -3
- package/dist/blocks/StatsCardSkeleton.block.d.ts.map +0 -1
- package/dist/blocks/TableSkeleton.block.d.ts +0 -3
- package/dist/blocks/TableSkeleton.block.d.ts.map +0 -1
- package/dist/blocks/ThinkingStates.block.d.ts +0 -3
- package/dist/blocks/ThinkingStates.block.d.ts.map +0 -1
- package/dist/components/Toggle/index.d.ts +0 -3
- package/dist/components/Toggle/index.d.ts.map +0 -1
- package/src/components/Toggle/index.ts +0 -7
- package/src/tokens/_density.scss +0 -85
package/fragments.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0.0","generatedAt":"2026-09-03T13:46:03.910Z","generatorVersion":"sha256:deea39c65b3a3a6dc24f36bcd4934c99c5a805d61ac68f207cc41c1029339282","buildInputs":["fragments.config.ts","src/assets/fragments-logo.tsx","src/assets/fragments-wordmark.tsx","src/blocks/AccountSettings.block.ts","src/blocks/ActivityFeed.block.ts","src/blocks/ActivityFeedSkeleton.block.ts","src/blocks/BlogEditor.block.ts","src/blocks/ChatInterface.block.ts","src/blocks/ChatMessages.block.ts","src/blocks/CheckoutForm.block.ts","src/blocks/CommandPalette.block.ts","src/blocks/ContactForm.block.ts","src/blocks/DashboardLayout.block.ts","src/blocks/DashboardPage.block.ts","src/blocks/DashboardSkeleton.block.ts","src/blocks/DataTable.block.ts","src/blocks/EmptyState.block.ts","src/blocks/FAQSection.block.ts","src/blocks/FeatureGrid.block.ts","src/blocks/HeroSection.block.ts","src/blocks/LoginForm.block.ts","src/blocks/NavigationHeader.block.ts","src/blocks/PaginatedTable.block.ts","src/blocks/PricingComparison.block.ts","src/blocks/ProductCard.block.ts","src/blocks/RegistrationForm.block.ts","src/blocks/SettingsDrawer.block.ts","src/blocks/SettingsPanel.block.ts","src/blocks/ShoppingCart.block.ts","src/blocks/StatsCard.block.ts","src/blocks/StatsCardSkeleton.block.ts","src/blocks/TableSkeleton.block.ts","src/blocks/ThinkingStates.block.ts","src/blocks/components/ActivityFeed.tsx","src/blocks/components/DashboardLayout.tsx","src/blocks/components/LoginForm.tsx","src/blocks/components/StatsCard.tsx","src/components/Accordion/Accordion.contract.json","src/components/Accordion/Accordion.module.scss","src/components/Accordion/Accordion.stories.tsx","src/components/Accordion/index.tsx","src/components/Alert/Alert.contract.json","src/components/Alert/Alert.module.scss","src/components/Alert/Alert.stories.tsx","src/components/Alert/index.tsx","src/components/AppShell/AppShell.contract.json","src/components/AppShell/AppShell.module.scss","src/components/AppShell/AppShell.stories.tsx","src/components/AppShell/index.tsx","src/components/Avatar/Avatar.contract.json","src/components/Avatar/Avatar.module.scss","src/components/Avatar/Avatar.stories.tsx","src/components/Avatar/index.tsx","src/components/Badge/Badge.contract.json","src/components/Badge/Badge.module.scss","src/components/Badge/Badge.stories.tsx","src/components/Badge/index.tsx","src/components/BentoGrid/BentoGrid.contract.json","src/components/BentoGrid/BentoGrid.module.scss","src/components/BentoGrid/BentoGrid.stories.tsx","src/components/BentoGrid/index.tsx","src/components/Box/Box.contract.json","src/components/Box/Box.module.scss","src/components/Box/Box.stories.tsx","src/components/Box/index.tsx","src/components/Breadcrumbs/Breadcrumbs.contract.json","src/components/Breadcrumbs/Breadcrumbs.module.scss","src/components/Breadcrumbs/Breadcrumbs.stories.tsx","src/components/Breadcrumbs/index.tsx","src/components/Button/Button.fragment.tsx","src/components/Button/Button.module.scss","src/components/Button/Button.stories.tsx","src/components/Button/index.tsx","src/components/ButtonGroup/ButtonGroup.contract.json","src/components/ButtonGroup/ButtonGroup.module.scss","src/components/ButtonGroup/ButtonGroup.stories.tsx","src/components/ButtonGroup/index.tsx","src/components/Card/Card.consumer-fixture.module.scss","src/components/Card/Card.fragment.tsx","src/components/Card/Card.module.scss","src/components/Card/Card.stories.tsx","src/components/Card/index.tsx","src/components/Chart/Chart.contract.json","src/components/Chart/Chart.module.scss","src/components/Chart/Chart.stories.tsx","src/components/Chart/index.tsx","src/components/Checkbox/Checkbox.contract.json","src/components/Checkbox/Checkbox.module.scss","src/components/Checkbox/Checkbox.stories.tsx","src/components/Checkbox/index.tsx","src/components/Chip/Chip.contract.json","src/components/Chip/Chip.module.scss","src/components/Chip/Chip.stories.tsx","src/components/Chip/index.tsx","src/components/Cloud/CloudGovernanceShell.module.scss","src/components/Cloud/CloudGovernanceShell.stories.tsx","src/components/Cloud/ControlSizing.module.scss","src/components/Cloud/ControlSizing.stories.tsx","src/components/Cloud/DashboardLayoutPrototypes.module.scss","src/components/Cloud/DashboardLayoutPrototypes.shared.tsx","src/components/Cloud/DashboardLayoutPrototypes.shell.tsx","src/components/Cloud/DashboardLayoutPrototypes.stories.tsx","src/components/Cloud/GeometryEvidence.module.scss","src/components/Cloud/GeometryEvidence.stories.tsx","src/components/Cloud/PullRequestsPrototypes.content.tsx","src/components/Cloud/PullRequestsPrototypes.detail-panels.tsx","src/components/Cloud/PullRequestsPrototypes.detail.tsx","src/components/Cloud/PullRequestsPrototypes.id-page.tsx","src/components/Cloud/PullRequestsPrototypes.stories.tsx","src/components/CodeBlock/CodeBlock.contract.json","src/components/CodeBlock/CodeBlock.module.scss","src/components/CodeBlock/CodeBlock.stories.tsx","src/components/CodeBlock/index.tsx","src/components/Collapsible/Collapsible.contract.json","src/components/Collapsible/Collapsible.module.scss","src/components/Collapsible/Collapsible.stories.tsx","src/components/Collapsible/index.tsx","src/components/ColorPicker/ColorPicker.contract.json","src/components/ColorPicker/ColorPicker.module.scss","src/components/ColorPicker/ColorPicker.stories.tsx","src/components/ColorPicker/index.tsx","src/components/Combobox/Combobox.contract.json","src/components/Combobox/Combobox.module.scss","src/components/Combobox/Combobox.stories.tsx","src/components/Combobox/index.tsx","src/components/Command/Command.contract.json","src/components/Command/Command.module.scss","src/components/Command/Command.stories.tsx","src/components/Command/index.tsx","src/components/ComponentDefaults/index.tsx","src/components/ConversationList/ConversationList.contract.json","src/components/ConversationList/ConversationList.module.scss","src/components/ConversationList/ConversationList.stories.tsx","src/components/ConversationList/index.tsx","src/components/DataTable/DataTable.fragment.tsx","src/components/DataTable/DataTable.icons.tsx","src/components/DataTable/DataTable.module.scss","src/components/DataTable/DataTable.stories.tsx","src/components/DataTable/DataTable.support.tsx","src/components/DataTable/DataTable.virtual.tsx","src/components/DataTable/index.tsx","src/components/DatePicker/DatePicker.contract.json","src/components/DatePicker/DatePicker.module.scss","src/components/DatePicker/DatePicker.stories.tsx","src/components/DatePicker/index.tsx","src/components/Dialog/Dialog.fragment.tsx","src/components/Dialog/Dialog.module.scss","src/components/Dialog/Dialog.stories.tsx","src/components/Dialog/index.tsx","src/components/Drawer/Drawer.contract.json","src/components/Drawer/Drawer.module.scss","src/components/Drawer/Drawer.stories.tsx","src/components/Drawer/index.tsx","src/components/Editor/Editor.contract.json","src/components/Editor/Editor.module.scss","src/components/Editor/Editor.stories.tsx","src/components/Editor/index.tsx","src/components/EmptyState/EmptyState.contract.json","src/components/EmptyState/EmptyState.module.scss","src/components/EmptyState/EmptyState.stories.tsx","src/components/EmptyState/index.tsx","src/components/Field/Field.contract.json","src/components/Field/Field.module.scss","src/components/Field/Field.stories.tsx","src/components/Field/index.tsx","src/components/Fieldset/Fieldset.contract.json","src/components/Fieldset/Fieldset.module.scss","src/components/Fieldset/Fieldset.stories.tsx","src/components/Fieldset/index.tsx","src/components/Form/Form.contract.json","src/components/Form/Form.module.scss","src/components/Form/Form.stories.tsx","src/components/Form/index.tsx","src/components/Grid/Grid.contract.json","src/components/Grid/Grid.module.scss","src/components/Grid/Grid.stories.tsx","src/components/Grid/index.tsx","src/components/Header/Header.contract.json","src/components/Header/Header.module.scss","src/components/Header/Header.stories.tsx","src/components/Header/index.tsx","src/components/Icon/Icon.contract.json","src/components/Icon/Icon.module.scss","src/components/Icon/Icon.stories.tsx","src/components/Icon/index.tsx","src/components/IconButton/IconButton.contract.json","src/components/IconButton/IconButton.module.scss","src/components/IconButton/IconButton.stories.tsx","src/components/IconButton/index.tsx","src/components/Image/Image.contract.json","src/components/Image/Image.module.scss","src/components/Image/Image.stories.tsx","src/components/Image/index.tsx","src/components/Input/Input.contract.json","src/components/Input/Input.module.scss","src/components/Input/Input.stories.tsx","src/components/Input/index.tsx","src/components/Link/Link.contract.json","src/components/Link/Link.module.scss","src/components/Link/Link.stories.tsx","src/components/Link/index.tsx","src/components/List/List.contract.json","src/components/List/List.module.scss","src/components/List/List.stories.tsx","src/components/List/index.tsx","src/components/Listbox/Listbox.contract.json","src/components/Listbox/Listbox.module.scss","src/components/Listbox/Listbox.stories.tsx","src/components/Listbox/index.tsx","src/components/Loading/Loading.contract.json","src/components/Loading/Loading.module.scss","src/components/Loading/Loading.stories.tsx","src/components/Loading/index.tsx","src/components/Main/Main.contract.json","src/components/Main/Main.module.scss","src/components/Main/Main.stories.tsx","src/components/Main/index.tsx","src/components/Markdown/Markdown.contract.json","src/components/Markdown/Markdown.module.scss","src/components/Markdown/Markdown.stories.tsx","src/components/Markdown/index.tsx","src/components/Menu/Menu.contract.json","src/components/Menu/Menu.module.scss","src/components/Menu/Menu.stories.tsx","src/components/Menu/index.tsx","src/components/Message/Message.contract.json","src/components/Message/Message.module.scss","src/components/Message/Message.stories.tsx","src/components/Message/index.tsx","src/components/NavigationMenu/NavigationMenu.contract.json","src/components/NavigationMenu/NavigationMenu.module.scss","src/components/NavigationMenu/NavigationMenu.stories.tsx","src/components/NavigationMenu/index.tsx","src/components/Pagination/Pagination.contract.json","src/components/Pagination/Pagination.module.scss","src/components/Pagination/Pagination.stories.tsx","src/components/Pagination/index.tsx","src/components/Popover/Popover.contract.json","src/components/Popover/Popover.module.scss","src/components/Popover/Popover.stories.tsx","src/components/Popover/index.tsx","src/components/Progress/Progress.contract.json","src/components/Progress/Progress.module.scss","src/components/Progress/Progress.stories.tsx","src/components/Progress/index.tsx","src/components/Prompt/Prompt.contract.json","src/components/Prompt/Prompt.module.scss","src/components/Prompt/Prompt.stories.tsx","src/components/Prompt/index.tsx","src/components/RadioGroup/RadioGroup.contract.json","src/components/RadioGroup/RadioGroup.module.scss","src/components/RadioGroup/RadioGroup.stories.tsx","src/components/RadioGroup/index.tsx","src/components/ScrollArea/ScrollArea.contract.json","src/components/ScrollArea/ScrollArea.module.scss","src/components/ScrollArea/ScrollArea.stories.tsx","src/components/ScrollArea/index.tsx","src/components/Select/Select.fragment.tsx","src/components/Select/Select.module.scss","src/components/Select/Select.stories.tsx","src/components/Select/index.tsx","src/components/Separator/Separator.contract.json","src/components/Separator/Separator.module.scss","src/components/Separator/Separator.stories.tsx","src/components/Separator/index.tsx","src/components/Sidebar/Sidebar.contract.json","src/components/Sidebar/Sidebar.module.scss","src/components/Sidebar/Sidebar.stories.tsx","src/components/Sidebar/index.tsx","src/components/Skeleton/Skeleton.contract.json","src/components/Skeleton/Skeleton.module.scss","src/components/Skeleton/Skeleton.stories.tsx","src/components/Skeleton/index.tsx","src/components/Slider/Slider.contract.json","src/components/Slider/Slider.module.scss","src/components/Slider/Slider.stories.tsx","src/components/Slider/index.tsx","src/components/Stack/Stack.contract.json","src/components/Stack/Stack.module.scss","src/components/Stack/Stack.stories.tsx","src/components/Stack/index.tsx","src/components/Switch/Switch.contract.json","src/components/Switch/Switch.module.scss","src/components/Switch/Switch.stories.tsx","src/components/Switch/index.tsx","src/components/Table/Table.contract.json","src/components/Table/Table.module.scss","src/components/Table/Table.stories.tsx","src/components/Table/index.tsx","src/components/TableOfContents/TableOfContents.contract.json","src/components/TableOfContents/TableOfContents.module.scss","src/components/TableOfContents/TableOfContents.stories.tsx","src/components/TableOfContents/index.tsx","src/components/Tabs/Tabs.contract.json","src/components/Tabs/Tabs.module.scss","src/components/Tabs/Tabs.stories.tsx","src/components/Tabs/index.tsx","src/components/Text/Text.contract.json","src/components/Text/Text.module.scss","src/components/Text/Text.stories.tsx","src/components/Text/index.tsx","src/components/Textarea/Textarea.contract.json","src/components/Textarea/Textarea.module.scss","src/components/Textarea/Textarea.stories.tsx","src/components/Textarea/index.tsx","src/components/Theme/Theme.contract.json","src/components/Theme/Theme.stories.tsx","src/components/Theme/index.tsx","src/components/ThemeToggle/ThemeToggle.module.scss","src/components/ThinkingIndicator/ThinkingIndicator.contract.json","src/components/ThinkingIndicator/ThinkingIndicator.module.scss","src/components/ThinkingIndicator/ThinkingIndicator.stories.tsx","src/components/ThinkingIndicator/index.tsx","src/components/Toast/Toast.contract.json","src/components/Toast/Toast.module.scss","src/components/Toast/Toast.stories.tsx","src/components/Toast/index.tsx","src/components/ToggleGroup/ToggleGroup.contract.json","src/components/ToggleGroup/ToggleGroup.module.scss","src/components/ToggleGroup/ToggleGroup.stories.tsx","src/components/ToggleGroup/index.tsx","src/components/Tooltip/Tooltip.contract.json","src/components/Tooltip/Tooltip.module.scss","src/components/Tooltip/Tooltip.stories.tsx","src/components/Tooltip/index.tsx","src/components/VisuallyHidden/VisuallyHidden.contract.json","src/components/VisuallyHidden/VisuallyHidden.module.scss","src/components/VisuallyHidden/VisuallyHidden.stories.tsx","src/components/VisuallyHidden/index.tsx","src/measurements/MeasurementTargets.stories.tsx","src/test/utils.tsx","src/tokens/_component-properties.scss","src/tokens/_measurements.catalog.generated.css","src/tokens/_variables.scss","src/utils/a11y.tsx"],"packageName":"@usefragments/ui","fragments":{"Accordion":{"filePath":"src/components/Accordion/index.tsx","meta":{"name":"Accordion","description":"Stacks sections that expand one at a time, or several at once.","category":"layout","tags":["accordion","collapse","expand","disclosure","faq"],"status":"stable"},"usage":{"when":["Answers most readers skip","Settings grouped by area","Long forms broken into stages","Navigation with nested children"],"whenNot":["Content everyone needs to read","A line or two — just show it","Steps in an order (use Stepper)","Switching between panels (use Tabs)"],"guidelines":["Headers should say what is inside","Single mode when one answer at a time is enough","Multiple mode when sections get compared","Open the section most readers came for","Never nest an accordion inside an accordion"],"accessibility":["Keyboard navigation with Enter/Space to toggle","Uses proper ARIA expanded/controls attributes","Focus is visible on accordion triggers"]},"props":{"type":{"type":"enum","description":"Whether one or multiple items can be open","default":"single","required":false,"values":["single","multiple"]},"value":{"type":"union","description":"Controlled open item(s): string in single mode, string[] in multiple mode","required":false},"defaultValue":{"type":"union","description":"Initially open item(s): string in single mode, string[] in multiple mode","required":false},"onValueChange":{"type":"union","description":"Called when open items change (single: string | undefined, multiple: string[])","required":false},"children":{"type":"node","description":"Accordion items (use Accordion.Item with Accordion.Trigger and Accordion.Content)","required":true},"collapsible":{"type":"boolean","description":"Whether all items can be closed (single mode only)","default":"false","required":false},"headingLevel":{"type":"union","description":"Semantic heading level for accordion triggers","default":"3","required":false,"values":["2","3","4","5","6"]}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for horizontal switching between related views"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for focused content that interrupts the flow"},{"component":"Card","relationship":"complementary","note":"Accordion items can contain Card-like content"}],"variants":[{"name":"Basic","description":"Opening one section closes the last.","code":"import { Accordion } from '@/components/Accordion';\n\n<Accordion type=\"single\" collapsible defaultValue=\"item-1\">\n <Accordion.Item value=\"item-1\">\n <Accordion.Trigger>What is Fragments UI?</Accordion.Trigger>\n <Accordion.Content>\n Fragments UI is a modern React component library built on Base UI primitives, providing accessible and customizable components.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"item-2\">\n <Accordion.Trigger>How do I install it?</Accordion.Trigger>\n <Accordion.Content>\n Install via npm or pnpm: pnpm add @usefragments/ui\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"item-3\">\n <Accordion.Trigger>Is it accessible?</Accordion.Trigger>\n <Accordion.Content>\n Yes! All components follow WAI-ARIA guidelines and support keyboard navigation.\n </Accordion.Content>\n </Accordion.Item>\n</Accordion>"},{"name":"Multiple Open","description":"Sections stay open so answers can be compared.","code":"import { Accordion } from '@/components/Accordion';\n\n<Accordion type=\"multiple\" defaultValue={['features', 'pricing']}>\n <Accordion.Item value=\"features\">\n <Accordion.Trigger>Features</Accordion.Trigger>\n <Accordion.Content>\n Comprehensive component library with theming support, accessibility built-in, and TypeScript-first development.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"pricing\">\n <Accordion.Trigger>Pricing</Accordion.Trigger>\n <Accordion.Content>\n Free and open source. MIT licensed for both personal and commercial use.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"support\">\n <Accordion.Trigger>Support</Accordion.Trigger>\n <Accordion.Content>\n Community support via GitHub issues and discussions.\n </Accordion.Content>\n </Accordion.Item>\n</Accordion>"},{"name":"With Disabled","description":"An unavailable section stays visible but inert.","code":"import { Accordion } from '@/components/Accordion';\n\n<Accordion type=\"single\" collapsible defaultValue=\"available\">\n <Accordion.Item value=\"available\">\n <Accordion.Trigger>Notification preferences</Accordion.Trigger>\n <Accordion.Content>\n Choose which events send you an email and how often digests arrive.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"disabled\" disabled>\n <Accordion.Trigger>Billing history</Accordion.Trigger>\n <Accordion.Content>\n Unavailable until a payment method is on file.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"another\">\n <Accordion.Trigger>Connected accounts</Accordion.Trigger>\n <Accordion.Content>\n Review the services linked to this workspace and revoke the ones you no longer use.\n </Accordion.Content>\n </Accordion.Item>\n</Accordion>"}],"contract":{"propsSummary":["type: single|multiple - controls how many items can be open","value/defaultValue are type-discriminated (single -> string, multiple -> string[])","onValueChange is type-discriminated by mode (single -> string|undefined, multiple -> string[])","collapsible: boolean - allow all closed in single mode","Accordion.Trigger forwards button props and defaults type=\"button\""],"a11yRules":["A11Y_DISCLOSURE_KEYBOARD","A11Y_FOCUS_VISIBLE"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Trigger","Content"],"requiredChildren":["Item"],"commonPatterns":["<Accordion type=\"single\" collapsible><Accordion.Item value=\"item-1\"><Accordion.Trigger>{title}</Accordion.Trigger><Accordion.Content>{content}</Accordion.Content></Accordion.Item></Accordion>"]},"propsSummary":["type: single|multiple (default: single)","value: union","defaultValue: union","onValueChange: union","children: node (required)","collapsible: boolean (default: false)","headingLevel: union (default: 3)"],"sourcePath":"src/components/Accordion/index.tsx","exportName":"Accordion","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:49.840Z"},"performance":{"bundleSize":1558,"rawSize":3499,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Accordion (self)","bytes":2826,"percent":81}]}},"Alert":{"filePath":"src/components/Alert/index.tsx","meta":{"name":"Alert","description":"Tells the user what just happened, or what is about to.","category":"feedback","tags":["notification","message","feedback","banner","toast"],"status":"stable"},"usage":{"when":["Reporting the outcome of something the user did","Flagging a risk before the user hits it","Standing status that must stay on screen"],"whenNot":["A one-word status (use Badge)","A message that should fade away (use Toast)","An invalid field (use the Input error prop)","A decision the user must make first (use Dialog)"],"guidelines":["Match severity to real stakes — an error that is not an error trains people to ignore you","Every error alert says what to do next","Add Alert.Title only when the message needs two lines","One action per alert","Only dismissible when losing the message costs nothing","Alert.Action and Alert.Close default to type=\"button\", so they are safe inside a form","Alert.Close runs your onClick and still respects preventDefault()"],"accessibility":["role=\"alert\" means assistive tech announces it on arrival","Alert.Close needs its own label","Icon plus wording carry the severity — never color alone"]},"props":{"children":{"type":"node","description":"Alert content - use Alert.Icon, Alert.Body, Alert.Title, Alert.Content, Alert.Actions, Alert.Close sub-components","required":true},"severity":{"type":"enum","description":"Visual severity level","default":"info","required":false,"values":["info","success","warning","error"]},"emphasis":{"type":"enum","description":"How much surface the severity claims. `tint` washes the card in the severity colour; `surface` keeps the page background and colours only the hairline and title.","default":"tint","required":false,"values":["tint","surface"]}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for compact, inline status labels"},{"component":"Toast","relationship":"alternative","note":"Use Toast for transient notifications that auto-dismiss"},{"component":"Dialog","relationship":"sibling","note":"Use Dialog for blocking confirmations"}],"variants":[{"name":"Info","description":"Neutral context — nothing went wrong, nothing needs doing.","code":"import { Alert } from '@/components/Alert';\n\n<Alert severity=\"info\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>\n Your session will expire in 15 minutes. Save your work to avoid losing changes.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"Success","description":"Confirms the thing the user just did actually landed.","code":"import { Alert } from '@/components/Alert';\n\n<Alert severity=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Payment processed</Alert.Title>\n <Alert.Content>\n Your order #12345 has been confirmed. You will receive a confirmation email shortly.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"Warning","description":"Nothing is broken yet — act before it is.","code":"import { Alert } from '@/components/Alert';\n\n<Alert severity=\"warning\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Storage almost full</Alert.Title>\n <Alert.Content>\n You have used 90% of your storage quota. Consider deleting unused files.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"Error","description":"Something failed; say what to do about it.","code":"import { Alert } from '@/components/Alert';\n\n<Alert severity=\"error\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Upload failed</Alert.Title>\n <Alert.Content>\n The file could not be uploaded. Check your connection and try again.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"With Action","description":"One button, one job — more than one stalls the reader.","code":"import { Alert } from '@/components/Alert';\n\n<Alert severity=\"warning\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Update available</Alert.Title>\n <Alert.Content>\n A new version is available with important security fixes.\n </Alert.Content>\n <Alert.Actions>\n <Alert.Action onClick={() => {}}>Update now</Alert.Action>\n </Alert.Actions>\n </Alert.Body>\n</Alert>"},{"name":"Dismissible","description":"A close button suits news the user can safely ignore.","code":"import { Alert } from '@/components/Alert';\n\n<Alert severity=\"info\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>\n You can customize your notification preferences in Settings.\n </Alert.Content>\n </Alert.Body>\n <Alert.Close />\n</Alert>"}],"contract":{"propsSummary":["severity: info|success|warning|error - visual severity","Sub-components: Alert.Icon, Alert.Body, Alert.Title, Alert.Content, Alert.Actions, Alert.Action, Alert.Close","Alert.Action / Alert.Close accept button props and default type=\"button\""],"a11yRules":["A11Y_ALERT_ROLE","A11Y_ALERT_DISMISS","A11Y_ALERT_CONTRAST","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Icon","Body","Title","Content","Actions","Action","Close"],"requiredChildren":["Body"],"commonPatterns":["<Alert severity=\"info\"><Alert.Icon /><Alert.Body><Alert.Content>{message}</Alert.Content></Alert.Body></Alert>","<Alert severity=\"warning\"><Alert.Icon /><Alert.Body><Alert.Title>{title}</Alert.Title><Alert.Content>{message}</Alert.Content></Alert.Body></Alert>","<Alert severity=\"error\"><Alert.Icon /><Alert.Body><Alert.Title>{title}</Alert.Title><Alert.Content>{message}</Alert.Content></Alert.Body><Alert.Close /></Alert>"]},"propsSummary":["children: node (required)","severity: info|success|warning|error (default: info)","emphasis: tint|surface (default: tint)"],"sourcePath":"src/components/Alert/index.tsx","exportName":"Alert","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.066Z"},"performance":{"bundleSize":1215,"rawSize":2976,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Alert (self)","bytes":2238,"percent":75}]}},"AppShell":{"filePath":"src/components/AppShell/index.tsx","meta":{"name":"AppShell","description":"Lays out header, sidebar, main, and optional aside as one responsive app frame.","category":"layout","tags":["layout","shell","scaffold","dashboard","app-layout"],"status":"stable"},"usage":{"when":["Dashboards and internal tools","Apps with persistent sidebar navigation","Layouts needing header, sidebar, and main together","Navigation that must collapse to a drawer on mobile"],"whenNot":["Marketing and landing pages","Content-first sites with no app navigation","Single-screen tools with no chrome"],"guidelines":["layout=\"default\" puts the logo in a full-width header","layout=\"sidebar\" puts the logo in a full-height sidebar","variant=\"floating\" is per slot — mix it with any layout","bg overrides one slot's background without touching the rest","AppShell supplies SidebarProvider; do not add your own","Set width and collapse behaviour on AppShell.Sidebar","Main reflows automatically when the sidebar collapses","Aside hides itself on mobile"],"accessibility":["Main content area has id=\"main-content\" for skip links","Use Header.SkipLink for keyboard navigation","Sidebar drawer has proper focus trap on mobile","Keyboard navigation supported throughout"]},"props":{"children":{"type":"node","description":"Layout content (use AppShell.Header, AppShell.Sidebar, AppShell.Main, AppShell.Aside)","required":true},"layout":{"type":"enum","description":"Structural layout for CSS grid areas","default":"default","required":false,"values":["default","sidebar","sidebar-floating","floating"]},"bg":{"type":"string","description":"Background color override for the shell container (accepts any CSS color or token reference like \"var(--fui-bg-secondary)\")","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Theme","relationship":"parent","note":"AppShell should be wrapped in ThemeProvider"},{"component":"Header","relationship":"child","note":"Header is placed inside AppShell.Header"},{"component":"Sidebar","relationship":"child","note":"Sidebar content goes inside AppShell.Sidebar"}],"variants":[{"name":"Default Layout","description":"Header spans the full width above the sidebar.","code":"import { ChartBar, Gear, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"default\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Brand>MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem active>Dashboard</Header.NavItem>\n <Header.NavItem>Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Default Layout</Text>\n <Text as=\"p\" color=\"secondary\">\n Header spans full width. Logo is in the header.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Sidebar Layout","description":"Sidebar runs full height with the header beside it.","code":"import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">\n <Stack direction=\"row\" align=\"center\" gap=\"sm\">\n <Icon icon={MagnifyingGlass} size=\"sm\" variant=\"tertiary\" />\n <Text size=\"sm\" color=\"tertiary\">Search...</Text>\n </Stack>\n </Box>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Sidebar Layout</Text>\n <Text as=\"p\" color=\"secondary\">\n Sidebar is full height. Logo is in the sidebar header.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"With Aside Panel","description":"Adds a right rail for context, filters, or actions.","code":"import { ChartBar, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"default\">\n <AppShell.Header>\n <Header>\n <Header.Brand>App</Header.Brand>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"180px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Stats</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Main Content</Text>\n <Text as=\"p\">Content with aside panel on the right.</Text>\n </Stack>\n </AppShell.Main>\n\n <AppShell.Aside width=\"180px\">\n <Box padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h3\" size=\"sm\" weight=\"semibold\">Aside Panel</Text>\n <Text as=\"p\" size=\"sm\" color=\"secondary\">\n Additional context, filters, or quick actions.\n </Text>\n </Stack>\n </Box>\n </AppShell.Aside>\n </AppShell>\n</Box>"},{"name":"Collapsible Icon Sidebar","description":"Sidebar shrinks to icons on desktop via the footer toggle.","code":"import { ChartBar, Gear, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar collapsible=\"icon\" width=\"200px\" collapsedWidth=\"56px\">\n <Sidebar.Header>\n <Text weight=\"semibold\">App</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Text as=\"p\">\n Click the collapse button in the sidebar footer to toggle between expanded and icon-only modes.\n </Text>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Floating Main","description":"Only the main slot floats — rounded, raised, on its own background.","code":"import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Box background=\"primary\" border rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">\n <Stack direction=\"row\" align=\"center\" gap=\"sm\">\n <Icon icon={MagnifyingGlass} size=\"sm\" variant=\"tertiary\" />\n <Text size=\"sm\" color=\"tertiary\">Search...</Text>\n </Stack>\n </Box>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\" variant=\"floating\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" variant=\"floating\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Floating Main</Text>\n <Text as=\"p\" color=\"secondary\">\n Main content has rounded corners and visual separation from the sidebar.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Floating Main & Aside","description":"Two slots float independently; the sidebar stays flush.","code":"import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Box background=\"primary\" border rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">\n <Stack direction=\"row\" align=\"center\" gap=\"sm\">\n <Icon icon={MagnifyingGlass} size=\"sm\" variant=\"tertiary\" />\n <Text size=\"sm\" color=\"tertiary\">Search...</Text>\n </Stack>\n </Box>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\" variant=\"floating\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" variant=\"floating\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Floating Main & Aside</Text>\n <Text as=\"p\" color=\"secondary\">\n Both main content and aside panel float with rounded corners.\n </Text>\n </Stack>\n </AppShell.Main>\n\n <AppShell.Aside width=\"200px\" variant=\"floating\">\n <Box padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h3\" size=\"sm\" weight=\"semibold\">Aside Panel</Text>\n <Text as=\"p\" size=\"sm\" color=\"secondary\">\n This aside also floats, matching the main content area.\n </Text>\n </Stack>\n </Box>\n </AppShell.Aside>\n </AppShell>\n</Box>"},{"name":"Floating Default Layout","description":"Floating works under any layout, including header-on-top.","code":"import { ChartBar, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"default\">\n <AppShell.Header>\n <Header>\n <Header.Brand>MyApp</Header.Brand>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"180px\" collapsible=\"offcanvas\" variant=\"floating\">\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Stats</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" variant=\"floating\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Floating Default Layout</Text>\n <Text as=\"p\" color=\"secondary\">\n Default structure (header on top) with floating main content. Any slot can float in any layout.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Custom Backgrounds","description":"Each slot takes its own bg, so regions read apart.","code":"import { ChartBar, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\" bg=\"var(--fui-bg-elevated)\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" bg=\"var(--fui-bg-primary)\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Custom Backgrounds</Text>\n <Text as=\"p\" color=\"secondary\">\n Sidebar uses bg-elevated (lighter), main uses bg-primary (darker). Any CSS color or token works.\n </Text>\n </Stack>\n </AppShell.Main>\n\n <AppShell.Aside width=\"200px\" bg=\"var(--fui-bg-elevated)\">\n <Box padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h3\" size=\"sm\" weight=\"semibold\">Aside Panel</Text>\n <Text as=\"p\" size=\"sm\" color=\"secondary\">\n Aside with bg-elevated background matching the sidebar.\n </Text>\n </Stack>\n </Box>\n </AppShell.Aside>\n </AppShell>\n</Box>"}],"contract":{"propsSummary":["children: node (required)","layout: default|sidebar|sidebar-floating|floating (default: default)","bg: string","style: object"]},"ai":{"compositionPattern":"compound","subComponents":["Header","Sidebar","Main","Aside"],"commonPatterns":["<AppShell>\n <AppShell.Header>...</AppShell.Header>\n <AppShell.Sidebar>...</AppShell.Sidebar>\n <AppShell.Main>...</AppShell.Main>\n</AppShell>"],"requiredChildren":["Header","Sidebar","Main"]},"propsSummary":["children: node (required)","layout: default|sidebar|sidebar-floating|floating (default: default)","bg: string","style: object"],"sourcePath":"src/components/AppShell/index.tsx","exportName":"AppShell","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.550Z"},"performance":{"bundleSize":9795,"rawSize":30813,"complexity":"moderate","budgetPercent":64,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Sidebar","bytes":25509,"percent":83},{"path":"AppShell (self)","bytes":4579,"percent":15}]}},"Avatar":{"filePath":"src/components/Avatar/index.tsx","meta":{"name":"Avatar","description":"Shows who someone is — their photo, or their initials when there is none.","category":"display","tags":["user","profile","image","identity"],"status":"stable"},"usage":{"when":["A row, comment, or card needs to say who","Several people belong to one thing — use Avatar.Group"],"whenNot":["The picture is content, not identity (use Image)","A profile hero at display size (build the layout yourself)"],"guidelines":["Pass name even when you pass src — it is the fallback and the label","Hold one size per context; mixed sizes read as a mistake","Avatar.Group max caps the stack and counts the rest","imageProps carries loading, decoding, referrerPolicy"],"accessibility":["alt describes the person, not the word \"avatar\"","Initials come from name, so screen readers get the whole name","Purely decorative? Pass alt=\"\""]},"props":{"src":{"type":"string","description":"Image source URL","required":false},"alt":{"type":"string","description":"Alt text for the image","default":"","required":false},"initials":{"type":"string","description":"Fallback initials (1-2 characters)","required":false},"name":{"type":"string","description":"Full name - used to generate initials","required":false},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["xs","sm","md","lg","xl"]},"customSize":{"type":"union","description":"Custom avatar size (number in px or CSS size string like \"2.25rem\"), overrides size width/height","required":false},"shape":{"type":"enum","description":"Shape variant","default":"circle","required":false,"values":["circle","square"]},"color":{"type":"string","description":"Custom background color for fallback avatar","required":false},"imageStyle":{"type":"object","description":"Inline style object applied to the underlying image element","required":false},"imageProps":{"type":"object","description":"Additional props for the underlying img element (except src/alt/className/style)","required":false},"style":{"type":"object","description":"","required":false},"fallback":{"type":"node","description":"Visual fallback rendered after initials/name and before the generic icon","required":false}},"relations":[{"component":"Image","relationship":"alternative","note":"Use Image for content pictures that are not a person or entity"},{"component":"Badge","relationship":"sibling","note":"Pair with Badge to show presence or role beside a name"}],"variants":[{"name":"Default","description":"A photo, cropped to the circle and centred.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar\n src=\"https://i.pravatar.cc/150?u=jane\"\n alt=\"Jane Doe\"\n name=\"Jane Doe\"\n/>"},{"name":"With Initials","description":"No src, so the name collapses to initials.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar name=\"John Smith\" />"},{"name":"Sizes","description":"Five steps, xs through xl — pick one per context and stick to it.","code":"import { Avatar } from '@/components/Avatar';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Avatar name=\"XS\" size=\"xs\" />\n <Avatar name=\"SM\" size=\"sm\" />\n <Avatar name=\"MD\" size=\"md\" />\n <Avatar name=\"LG\" size=\"lg\" />\n <Avatar name=\"XL\" size=\"xl\" />\n</Stack>"},{"name":"Custom Size","description":"customSize takes any number when the scale does not fit.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar name=\"Conan McNicholl\" customSize={36} />"},{"name":"Square Shape","description":"Squares read as products or orgs, circles as people.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar name=\"App\" shape=\"square\" />"},{"name":"Group","description":"Overlapping stack with a count for whoever did not fit.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar.Group max={3} size=\"md\">\n <Avatar name=\"Alice Johnson\" />\n <Avatar name=\"Bob Smith\" />\n <Avatar name=\"Carol Williams\" />\n <Avatar name=\"David Brown\" />\n <Avatar name=\"Eve Davis\" />\n</Avatar.Group>"}],"contract":{"propsSummary":["src: string - image URL","name: string - used for initials fallback","size: xs|sm|md|lg|xl (default: md)","customSize: number|string - custom size override","imageStyle: CSSProperties - inline image styling","imageProps: ImgHTMLAttributes - advanced img attributes","shape: circle|square (default: circle)"],"a11yRules":["A11Y_IMG_ALT"]},"ai":{"compositionPattern":"compound","subComponents":["Group"]},"propsSummary":["src: string","alt: string (default: )","initials: string","name: string","size: xs|sm|md|lg|xl (default: md)","customSize: union","shape: circle|square (default: circle)","color: string","imageStyle: object","imageProps: object","style: object"],"sourcePath":"src/components/Avatar/index.tsx","exportName":"Avatar","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.743Z"},"performance":{"bundleSize":1972,"rawSize":3875,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Avatar (self)","bytes":3286,"percent":85}]}},"Badge":{"filePath":"src/components/Badge/index.tsx","meta":{"name":"Badge","description":"Labels a status, count, or category without pulling focus.","category":"display","tags":["status","label","tag","count","chip"],"status":"stable"},"usage":{"when":["Marking item status: active, pending, archived","Showing a count inline","Tagging or categorising content","Flagging what is new or changed"],"whenNot":["Real errors that need attention — use Alert","Anything longer than a few words — use Alert","Clickable filters — use Chip or ToggleGroup","View switching — use Tabs or links"],"guidelines":["Under 20 characters","dot for live status; add dotPulse only while it is still changing","Semantic variants are borderless pills on shared status tokens","label pairs with dotColor; dim pairs with active for filter chrome","onRemove for user-created tags only, never system labels"],"accessibility":["The text must carry the meaning — colour alone never does","Removable badges need a named dismiss button","Badges are silent to screen readers unless you pass announce","Do not make a badge the only signal that something changed"]},"props":{"children":{"type":"node","description":"Badge label text","required":true},"variant":{"type":"enum","description":"Visual style indicating severity or category. `label` is a hairline-bordered metadata pill (pair with dotColor); `dim` is transparent filter-pill chrome (pair with active).","default":"default","required":false,"values":["default","success","warning","error","info","outline","label","dim"]},"size":{"type":"enum","description":"Badge size","default":"md","required":false,"values":["sm","md","lg"]},"dot":{"type":"boolean","description":"Show a colored dot indicator before the label","default":"false","required":false},"dotPulse":{"type":"boolean","description":"Breathe the status dot, for a state that is still happening rather than one that has settled. Opacity only, and honours prefers-reduced-motion","default":"false","required":false},"dotColor":{"type":"string","description":"Color for the leading status dot. Applies to variant=\"label\" (and the generic dot prop). Accepts any CSS color including CSS custom properties.","required":false},"icon":{"type":"node","description":"Optional icon element before the text","required":false},"active":{"type":"boolean","description":"Marks variant=\"dim\" as the currently selected filter. Has no effect on other variants.","default":"false","required":false},"onRemove":{"type":"function","description":"Makes the badge removable. Called when X is clicked.","required":false},"announce":{"type":"boolean","description":"Opt into role=\"status\" live announcement semantics","default":"false","required":false},"role":{"type":"union","description":"","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for prominent, longer messages with actions"},{"component":"Chip","relationship":"sibling","note":"Chip is interactive (clickable/filterable); Badge is display-only"}],"variants":[{"name":"Status Variants","description":"Neutral through info, on shared status tokens.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge variant=\"default\">Default</Badge>\n <Badge variant=\"success\">Active</Badge>\n <Badge variant=\"warning\">Pending</Badge>\n <Badge variant=\"error\">Failed</Badge>\n <Badge variant=\"info\">New</Badge>\n</Stack>"},{"name":"With Dot","description":"Leading dot for live state; it breathes while still moving.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge variant=\"success\" dot>Online</Badge>\n <Badge variant=\"warning\" dot>Away</Badge>\n <Badge variant=\"error\" dot>Offline</Badge>\n <Badge variant=\"info\" dot dotPulse>Syncing</Badge>\n</Stack>"},{"name":"Label and Filter","description":"Hairline metadata pill, and filter chrome that marks the active one.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge variant=\"label\" dotColor=\"var(--fui-color-accent)\">Design</Badge>\n <Badge variant=\"label\" dotColor=\"var(--fui-color-success)\">Shipped</Badge>\n <Badge variant=\"dim\" active>All</Badge>\n <Badge variant=\"dim\">Archived</Badge>\n</Stack>"},{"name":"Outline","description":"Bordered and transparent, when a fill would shout.","code":"<Badge variant=\"outline\">Outline</Badge>"},{"name":"Sizes","description":"sm for dense tables, lg for reference status pills.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Badge variant=\"success\" size=\"sm\">Small</Badge>\n <Badge variant=\"success\" size=\"md\">Medium</Badge>\n <Badge variant=\"success\" size=\"lg\">Large</Badge>\n</Stack>"},{"name":"Removable","description":"Dismissible tags the user added themselves.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge variant=\"info\" onRemove={() => {}}>React</Badge>\n <Badge variant=\"info\" onRemove={() => {}}>TypeScript</Badge>\n <Badge variant=\"info\" onRemove={() => {}}>CSS</Badge>\n</Stack>"},{"name":"Announced Status","description":"Looks the same, but screen readers now hear the change.","code":"<Badge variant=\"success\" announce>Saved</Badge>"}],"contract":{"propsSummary":["children: ReactNode - badge label (required)","variant: default|success|warning|error|info|outline|label|dim - visual style","size: sm|md|lg - badge size","dot: boolean - show status dot indicator","dotPulse: boolean - breathe the dot for an in-progress state (respects prefers-reduced-motion)","dotColor: string - color for the leading status dot","active: boolean - marks variant=\"dim\" as the selected filter","onRemove: () => void - makes badge removable","announce: boolean - opt into role=\"status\" + auto status aria-label"],"a11yRules":["A11Y_BADGE_CONTRAST","A11Y_BADGE_DISMISS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","variant: default|success|warning|error|info|outline|label|dim (default: default)","size: sm|md|lg (default: md)","dot: boolean (default: false)","dotPulse: boolean (default: false)","dotColor: string","icon: node","active: boolean (default: false)","onRemove: function","announce: boolean (default: false)","role: union"],"sourcePath":"src/components/Badge/index.tsx","exportName":"Badge","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.941Z"},"performance":{"bundleSize":874,"rawSize":1637,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Badge (self)","bytes":1050,"percent":64}]}},"BentoGrid":{"filePath":"src/components/BentoGrid/index.tsx","meta":{"name":"BentoGrid","description":"Asymmetric feature grid where tiles span different widths and heights.","category":"layout","tags":["bento","grid","layout","responsive","feature-grid","asymmetric"],"status":"stable"},"usage":{"when":["Feature grids with one hero tile and supporting tiles","Dashboards where cards carry different weight","Marketing sections with mixed-size blocks"],"whenNot":["Uniform tiles of one size (use Grid)","Labelled form fields (use Grid)","A single column of content (use Stack)"],"guidelines":["colSpan and rowSpan take per-breakpoint objects","A hero tile is usually colSpan 2 and rowSpan 2 from lg up","Tiles carry their own surface — do not wrap them in Card","Columns collapse 3 to 2 below lg, and to 1 below sm","Keep source order equal to visual order for screen readers"],"accessibility":["Grid is purely visual — it does not affect reading order or semantics","Ensure logical source order matches visual order for screen readers","Hover effects are disabled when prefers-reduced-motion is set","Border thickness increases in prefers-contrast: more mode"]},"props":{"children":{"type":"node","description":"BentoGrid.Item children","required":false},"columns":{"type":"union","description":"Number of columns — auto-collapses responsively (3→2→1)","default":"3","required":false,"values":["2","3","4"]},"gap":{"type":"enum","description":"Gap between grid items, mapped to spacing tokens","default":"md","required":false,"values":["none","xs","sm","md","lg","xl"]},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Grid","relationship":"alternative","note":"Use Grid for uniform layouts; BentoGrid for asymmetric spans with built-in surfaces"},{"component":"Card","relationship":"sibling","note":"BentoGrid.Item has built-in surface styling similar to Card"}],"variants":[{"name":"Default","description":"Equal tiles, each on its own surface.","code":"import { BentoGrid } from '@/components/BentoGrid';\nimport { Box } from '@/components/Box';\n\n<Box width=\"100%\">\n <BentoGrid columns={3} gap=\"md\">\n <BentoGrid.Item>Item 1</BentoGrid.Item>\n <BentoGrid.Item>Item 2</BentoGrid.Item>\n <BentoGrid.Item>Item 3</BentoGrid.Item>\n <BentoGrid.Item>Item 4</BentoGrid.Item>\n <BentoGrid.Item>Item 5</BentoGrid.Item>\n <BentoGrid.Item>Item 6</BentoGrid.Item>\n </BentoGrid>\n</Box>"},{"name":"Hero Layout","description":"One tile takes two columns and two rows; the rest fill around it.","code":"import { BentoGrid } from '@/components/BentoGrid';\nimport { Box } from '@/components/Box';\n\n<Box width=\"100%\">\n <BentoGrid columns={3} gap=\"md\">\n <BentoGrid.Item colSpan={{ base: 1, lg: 2 }} rowSpan={{ base: 1, lg: 2 }}>\n Hero content\n </BentoGrid.Item>\n <BentoGrid.Item>Item 2</BentoGrid.Item>\n <BentoGrid.Item>Item 3</BentoGrid.Item>\n <BentoGrid.Item>Item 4</BentoGrid.Item>\n <BentoGrid.Item>Item 5</BentoGrid.Item>\n </BentoGrid>\n</Box>"},{"name":"Two Column","description":"colSpan stretches a tile across the whole row.","code":"import { BentoGrid } from '@/components/BentoGrid';\nimport { Box } from '@/components/Box';\n\n<Box width=\"100%\">\n <BentoGrid columns={2} gap=\"md\">\n <BentoGrid.Item>Item 1</BentoGrid.Item>\n <BentoGrid.Item>Item 2</BentoGrid.Item>\n <BentoGrid.Item colSpan={2}>Wide item</BentoGrid.Item>\n <BentoGrid.Item>Item 4</BentoGrid.Item>\n <BentoGrid.Item>Item 5</BentoGrid.Item>\n </BentoGrid>\n</Box>"}],"contract":{"propsSummary":["columns: 2|3|4 (default: 3) — auto-collapses responsively","gap: none|xs|sm|md|lg|xl (default: md)","BentoGrid.Item colSpan: 1|2|3 | { base, sm, md, lg, xl }","BentoGrid.Item rowSpan: 1|2|3 | { base, sm, md, lg, xl }","BentoGrid and BentoGrid.Item forward div DOM props; Item style is merged with generated span vars"]},"propsSummary":["children: node","columns: union (default: 3)","gap: none|xs|sm|md|lg|xl (default: md)","style: object"],"sourcePath":"src/components/BentoGrid/index.tsx","exportName":"BentoGrid","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.407Z"},"performance":{"bundleSize":882,"rawSize":1730,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"BentoGrid (self)","bytes":1152,"percent":67}]}},"Box":{"filePath":"src/components/Box/index.tsx","meta":{"name":"Box","description":"Applies spacing, background, border, and radius to any element.","category":"layout","tags":["layout","container","spacing","primitive","box"],"status":"stable"},"usage":{"when":["Padding or insetting a section of content","Bordered or elevated containers","Rendering a semantic element with design-system spacing"],"whenNot":["Spacing a row or column of siblings (use Stack)","Two-dimensional layouts (use Grid)","Header/body/footer surfaces (use Card)","Styling text alone (use Text)"],"guidelines":["Use the padding and margin props, never inline styles","Set as=\"section\" or as=\"article\" so the markup stays semantic","Backgrounds come from the token scale — no custom colours","Reach for Stack or Grid before nesting Boxes for layout"],"accessibility":["Choose semantic as prop values for proper document structure","Avoid div-soup; use meaningful elements like section, article","Ensure proper heading hierarchy within Box containers"]},"props":{"children":{"type":"node","description":"Content to render inside the box","required":false},"as":{"type":"enum","description":"HTML element to render","default":"div","required":false,"values":["div","section","article","aside","main","header","footer","nav","span"]},"padding":{"type":"enum","description":"Padding on all sides","required":false,"values":["none","xs","sm","md","lg","xl"]},"paddingX":{"type":"enum","description":"Horizontal padding","required":false,"values":["none","xs","sm","md","lg","xl"]},"paddingY":{"type":"enum","description":"Vertical padding","required":false,"values":["none","xs","sm","md","lg","xl"]},"margin":{"type":"enum","description":"Margin on all sides","required":false,"values":["none","xs","sm","md","lg","xl","auto"]},"marginX":{"type":"enum","description":"Horizontal margin","required":false,"values":["none","xs","sm","md","lg","xl","auto"]},"marginY":{"type":"enum","description":"Vertical margin","required":false,"values":["none","xs","sm","md","lg","xl","auto"]},"background":{"type":"enum","description":"Background color","required":false,"values":["none","primary","secondary","tertiary","elevated"]},"rounded":{"type":"enum","description":"Border radius","required":false,"values":["none","sm","md","lg","full"]},"border":{"type":"boolean","description":"Show border","default":"false","required":false},"borderTop":{"type":"boolean","description":"Show top border only","default":"false","required":false},"borderBottom":{"type":"boolean","description":"Show bottom border only","default":"false","required":false},"borderLeft":{"type":"boolean","description":"Show left border only","default":"false","required":false},"borderRight":{"type":"boolean","description":"Show right border only","default":"false","required":false},"borderColor":{"type":"enum","description":"Border color variant (requires border or directional border)","required":false,"values":["default","strong","accent","danger"]},"shadow":{"type":"enum","description":"Box shadow","required":false,"values":["none","sm","md","lg"]},"overflow":{"type":"enum","description":"Overflow behavior","required":false,"values":["hidden","auto","scroll","visible"]},"color":{"type":"enum","description":"Text color","required":false,"values":["primary","secondary","tertiary","accent","inverse"]},"display":{"type":"enum","description":"Display type","required":false,"values":["none","block","inline","inline-block","flex","inline-flex","grid"]},"width":{"type":"union","description":"Width (CSS value, e.g. \"100%\", \"300px\", or number for px)","required":false},"minWidth":{"type":"union","description":"Min width","required":false},"maxWidth":{"type":"union","description":"Max width","required":false},"height":{"type":"union","description":"Height (CSS value)","required":false},"minHeight":{"type":"union","description":"Min height","required":false},"maxHeight":{"type":"union","description":"Max height","required":false},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false}},"relations":[{"component":"Stack","relationship":"alternative","note":"Use Stack for directional layouts with gap"},{"component":"Grid","relationship":"alternative","note":"Use Grid for column-based layouts"},{"component":"Card","relationship":"alternative","note":"Use Card for content containers with structure"}],"variants":[{"name":"Default","description":"Padding, background, and radius in one element.","code":"<Box padding=\"md\" background=\"secondary\" rounded=\"md\">\n Content with padding and background\n</Box>"},{"name":"With Border","description":"A hairline border instead of a filled background.","code":"<Box padding=\"lg\" border rounded=\"md\">\n Bordered content area\n</Box>"},{"name":"Directional Padding","description":"Horizontal and vertical padding set separately.","code":"<Box paddingX=\"xl\" paddingY=\"sm\" background=\"tertiary\" rounded=\"sm\">\n Wide horizontal padding, short vertical\n</Box>"},{"name":"Centered with Auto Margin","description":"marginX=\"auto\" centres a fixed-width box in a wider parent.","code":"import { Box } from '@/components/Box';\n\n<Box width=\"100%\" border rounded=\"md\" padding=\"md\">\n <Box padding=\"md\" marginX=\"auto\" width=\"240px\" background=\"elevated\" rounded=\"lg\">\n Centred by auto margin\n </Box>\n</Box>"},{"name":"Directional Borders","description":"Border on chosen sides only.","code":"<Box padding=\"md\" borderTop borderBottom>\n Top and bottom borders only\n</Box>"},{"name":"With Shadow","description":"Shadow lifts the surface off the page.","code":"<Box padding=\"lg\" rounded=\"md\" shadow=\"md\" background=\"primary\">\n Elevated content with shadow\n</Box>"},{"name":"Overflow Hidden","description":"Content past the box's height is clipped, not scrolled.","code":"import { Box } from '@/components/Box';\n\n<Box padding=\"md\" overflow=\"hidden\" border rounded=\"md\" width=\"320px\" height=\"72px\">\n This box clips its overflowing content. Lorem ipsum dolor sit amet, consectetur\n adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua, and this final sentence never becomes visible.\n</Box>"},{"name":"Text Colors","description":"Text colour tokens, from strongest to accent.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\">\n <Box color=\"primary\">Primary</Box>\n <Box color=\"secondary\">Secondary</Box>\n <Box color=\"tertiary\">Tertiary</Box>\n <Box color=\"accent\">Accent</Box>\n</Stack>"}],"contract":{"propsSummary":["as: div|section|article|... - HTML element","padding: none|xs|sm|md|lg|xl - all-sides padding","paddingX/paddingY: directional padding overrides","margin: none|xs|sm|md|lg|xl|auto - margin","background: none|primary|secondary|tertiary|elevated","rounded: none|sm|md|lg|full - border radius","border: boolean - show border","borderTop/borderBottom/borderLeft/borderRight: boolean - directional borders","borderColor: default|strong|accent|danger - border color variant","shadow: sm|md|lg|none - box shadow","overflow: hidden|auto|scroll|visible - overflow behavior","color: primary|secondary|tertiary|accent|inverse - text color","width/minWidth/maxWidth: string|number - sizing","height/minHeight/maxHeight: string|number - sizing","All standard HTMLElement props are forwarded to the rendered element"],"a11yRules":["A11Y_SEMANTIC_HTML"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node","as: div|section|article|aside|main|header|footer|nav|span (default: div)","padding: none|xs|sm|md|lg|xl","paddingX: none|xs|sm|md|lg|xl","paddingY: none|xs|sm|md|lg|xl","margin: none|xs|sm|md|lg|xl|auto","marginX: none|xs|sm|md|lg|xl|auto","marginY: none|xs|sm|md|lg|xl|auto","background: none|primary|secondary|tertiary|elevated","rounded: none|sm|md|lg|full","border: boolean","borderTop: boolean","borderBottom: boolean","borderLeft: boolean","borderRight: boolean","borderColor: default|strong|accent|danger","shadow: none|sm|md|lg","overflow: hidden|auto|scroll|visible","color: primary|secondary|tertiary|accent|inverse","display: none|block|inline|inline-block|flex|inline-flex|grid","width: union","minWidth: union","maxWidth: union","height: union","minHeight: union","maxHeight: union","className: string","style: object"],"sourcePath":"src/components/Box/index.tsx","exportName":"Box","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:51.126Z"},"performance":{"bundleSize":967,"rawSize":1876,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Box (self)","bytes":1304,"percent":70}]}},"Breadcrumbs":{"filePath":"src/components/Breadcrumbs/index.tsx","meta":{"name":"Breadcrumbs","description":"Shows where the user is and links back up the hierarchy.","category":"navigation","tags":["breadcrumbs","navigation","hierarchy","wayfinding"],"status":"stable"},"usage":{"when":["Nested content more than two levels deep","Jumping back to a parent in one click","Documentation and catalogue hierarchies"],"whenNot":["Flat structures with no parents (use Tabs or header navigation)","Steps in an order (use Stepper)","Primary navigation (use Sidebar or Header)"],"guidelines":["End on the current page, unlinked","Short labels — the trail is a path, not a summary","Set maxItems to fold long paths, keeping first and last","The separator defaults to a slash and takes any node","Set label to rename the landmark (defaults to \"Breadcrumb\")","Crumbs truncate at 200px so one long title cannot push the rest out"],"accessibility":["Uses <nav aria-label=\"Breadcrumb\"> for landmark navigation","Current page is marked with aria-current=\"page\"","Separators are hidden from screen readers with aria-hidden","Ellipsis button has aria-label for collapsed items"]},"props":{"children":{"type":"node","description":"Breadcrumb items (use Breadcrumbs.Item)","required":true},"separator":{"type":"node","description":"Custom separator between items","default":"/","required":false},"maxItems":{"type":"number","description":"Maximum visible items before collapsing middle items with ellipsis","required":false},"label":{"type":"string","description":"Custom aria-label for the breadcrumb nav landmark","default":"Breadcrumb","required":false}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for flat, non-hierarchical navigation"},{"component":"Sidebar","relationship":"complementary","note":"Breadcrumbs complement sidebar navigation for deep hierarchies"}],"variants":[{"name":"Default","description":"Each ancestor links; the last one does not.","code":"<Breadcrumbs>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Products</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Category</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Current Page</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"With Icons","description":"Glyphs mark what kind of thing each level is.","code":"<Breadcrumbs>\n <Breadcrumbs.Item\n href=\"#\"\n icon={\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M8 1.25l-7 6v7.5c0 .138.112.25.25.25H5.5V10h5v5h4.25a.25.25 0 0 0 .25-.25v-7.5l-7-6z\" />\n </svg>\n }\n >\n Home\n </Breadcrumbs.Item>\n <Breadcrumbs.Item\n href=\"#\"\n icon={\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75z\" />\n </svg>\n }\n >\n Documents\n </Breadcrumbs.Item>\n <Breadcrumbs.Item current>Report.pdf</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"Collapsed","description":"Middle levels fold behind an ellipsis.","code":"<Breadcrumbs maxItems={3}>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Category</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Subcategory</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Section</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Current Page</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"Custom Separator","description":"Any node can replace the slash.","code":"<Breadcrumbs\n separator={\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06z\" />\n </svg>\n }\n>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Settings</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Profile</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"Custom Landmark Label","description":"Renames the landmark screen readers announce.","code":"<Breadcrumbs label=\"Documentation breadcrumbs\">\n <Breadcrumbs.Item href=\"#\">Docs</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Components</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Breadcrumbs</Breadcrumbs.Item>\n</Breadcrumbs>"}],"contract":{"propsSummary":["separator: ReactNode - custom separator (default \"/\")","maxItems: number - collapse middle items with ellipsis","label: string - nav landmark label (default \"Breadcrumb\")","Breadcrumbs.Item href: string - makes item a link","Breadcrumbs.Item current: boolean - marks current page","Breadcrumbs.Item icon: ReactNode - icon before label"],"a11yRules":["A11Y_NAV_LANDMARK","A11Y_ARIA_CURRENT","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Separator"],"requiredChildren":["Item"],"commonPatterns":["<Breadcrumbs><Breadcrumbs.Item href=\"/\">Home</Breadcrumbs.Item><Breadcrumbs.Item href=\"/products\">Products</Breadcrumbs.Item><Breadcrumbs.Item current>Widget</Breadcrumbs.Item></Breadcrumbs>"]},"propsSummary":["children: node (required)","separator: node (default: /)","maxItems: number","label: string (default: Breadcrumb)"],"sourcePath":"src/components/Breadcrumbs/index.tsx","exportName":"Breadcrumbs","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:51.312Z"},"performance":{"bundleSize":1158,"rawSize":2749,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Breadcrumbs (self)","bytes":2088,"percent":76}]}},"Button":{"filePath":"src/components/Button/Button.fragment.tsx","meta":{"name":"Button","description":"Triggers an action — save, submit, delete, open.","category":"actions","status":"stable","tags":["action","button","form","interactive"]},"guidance":{"when":["Running an action: save, submit, delete","Submitting a form","Opening a dialog or menu"],"whenNot":["Plain navigation — use Link","Toggling state — use Switch or Checkbox","Picking an option — use Select or RadioGroup"],"dont":[{"reason":"Do not use a Button for plain navigation.","bad":"<Button href=\"/settings\">Settings</Button>","good":"<Link href=\"/settings\">Settings</Link>"}],"guidelines":["One primary button per form or section","Danger for anything destructive","Loading state must also disable the button","With asChild, put interaction and a11y props on Button — they forward to the child","variant=\"icon\" for icon-only actions; or icon={true} plus another variant"],"accessibility":["Label the action, not the widget","No \"Click here\"","Icon-only buttons need aria-label"]},"usage":{"when":["Running an action: save, submit, delete","Submitting a form","Opening a dialog or menu"],"whenNot":["Plain navigation — use Link","Toggling state — use Switch or Checkbox","Picking an option — use Select or RadioGroup"],"dont":[{"reason":"Do not use a Button for plain navigation.","bad":"<Button href=\"/settings\">Settings</Button>","good":"<Link href=\"/settings\">Settings</Link>"}],"guidelines":["One primary button per form or section","Danger for anything destructive","Loading state must also disable the button","With asChild, put interaction and a11y props on Button — they forward to the child","variant=\"icon\" for icon-only actions; or icon={true} plus another variant"],"accessibility":["Label the action, not the widget","No \"Click here\"","Icon-only buttons need aria-label"]},"props":{"as":{"type":"enum","description":"","required":false,"values":["a","button"]},"asChild":{"type":"boolean","description":"Merge props onto child element instead of rendering a button. Useful for composition with Link components.","required":false},"children":{"type":"node","description":"","required":true},"fullWidth":{"type":"boolean","description":"Make button full width of container","required":false},"icon":{"type":"boolean","description":"Render as icon-only button (square aspect ratio). Prefer `variant=\"icon\"` for the default outlined icon button.","required":false},"size":{"type":"enum","description":"Button size. `\"xs\"` is for inline row-action controls (accept/dismiss, table-row icons) where `\"sm\"` is too tall.","default":"\"md\"","required":false,"values":["xs","sm","md","lg"]},"variant":{"type":"enum","description":"Visual style variant.","default":"\"primary\"","required":false,"values":["primary","secondary","ghost","link","quiet","danger","outlined","outline","icon"]}},"relations":[{"component":"Link","relationship":"alternative","note":"Use Link for navigation without action context"},{"component":"Icon","relationship":"complementary","note":"Use Icon inside Button for icon-leading/trailing or icon-only actions"},{"component":"ButtonGroup","relationship":"parent","note":"Use ButtonGroup for related action sets"}],"variants":[{"name":"Primary","description":"The one action you want people to take here.","code":"<Button variant=\"primary\">Save changes</Button>","canonical":true},{"name":"Secondary","description":"Supporting action that sits beside the main one.","code":"<Button variant=\"secondary\">Cancel</Button>"},{"name":"Ghost","description":"No fill, no border — for dense toolbars and repeated rows.","code":"<Button variant=\"ghost\">Learn more</Button>"},{"name":"Link","description":"Reads like a link, behaves like an action.","code":"<Button variant=\"link\">View all →</Button>"},{"name":"Quiet","description":"No box and no height floor, so it sits inline in meta lines.","code":"<Button variant=\"quiet\" size=\"xs\">\n Manage preferences\n </Button>"},{"name":"Danger","description":"Destructive action people cannot undo.","code":"<Button variant=\"danger\">Delete item</Button>"},{"name":"Outline","description":"Bordered and transparent — reads over any surface.","code":"<Button variant=\"outline\">View details</Button>"},{"name":"Icon","description":"Square icon-only action. Always pass aria-label.","code":"<Button variant=\"icon\" aria-label=\"Add item\">\n <span aria-hidden>+</span>\n </Button>"},{"name":"Sizes","description":"xs for inline row actions, lg for hero calls to action.","code":"<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Button size=\"xs\">Extra small</Button>\n <Button size=\"sm\">Small</Button>\n <Button size=\"md\">Medium</Button>\n <Button size=\"lg\">Large</Button>\n </Stack>"},{"name":"Disabled","description":"Blocks clicks and drops the button out of the tab order.","code":"<Button disabled>Unavailable</Button>"},{"name":"As Child","description":"Paints button styles onto an anchor or router link; props forward to the child.","code":"<Button asChild variant=\"outlined\" aria-label=\"Open billing settings\">\n <a href=\"#billing-settings\">Billing settings</a>\n </Button>"},{"name":"Long Label","description":"Long labels stay on one line; shorten the label or give the button room.","code":"<Button>\n Save the localized account preferences and notify every affected workspace administrator\n </Button>"}],"ai":{"compositionPattern":"compound","subComponents":["Root"]},"contract":{"propsSummary":["variant: primary|secondary|ghost|link|quiet|danger|outlined|outline|icon (default: primary, icon = outlined + icon-only, link = accent transparent, quiet = neutral text button, no box)","size: xs|sm|md|lg (default: md, xs for inline row-action controls)","disabled: boolean - disables interaction","type: button|submit|reset (default: button)","onClick: (event) => void - action handler","asChild: boolean - composes styles/props onto a child element (links/router links)","icon: boolean - icon-only square layout (can be combined with visual variants)"],"a11yRules":["A11Y_BTN_LABEL","A11Y_BTN_FOCUS"]},"matrix":{"axes":{"variant":"auto","size":"auto","theme":["light","dark"]},"forced":["hover","focus","disabled"],"worstCase":{"children":"A long localized action label that wraps without hiding the action"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Button/index.tsx","exportName":"Button","performance":{"bundleSize":1170,"rawSize":2277,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Button (self)","bytes":1324,"percent":58},{"path":"ComponentDefaults","bytes":194,"percent":9},{"path":"src/utils/canonical-stamp.ts","bytes":170,"percent":7}]}},"ButtonGroup":{"filePath":"src/components/ButtonGroup/index.tsx","meta":{"name":"ButtonGroup","description":"Lays out related buttons in a row with one shared gap and alignment.","category":"actions","tags":["button","group","toolbar","actions","layout"],"status":"stable"},"usage":{"when":["Confirm/cancel pairs at the end of a form","Toolbars and action bars","Pagination controls"],"whenNot":["Unrelated buttons — use Stack","Navigation links — use a nav element","A single button"],"guidelines":["Two to four buttons; more belongs in a Menu","Confirming action goes last","One primary button per group","align=\"end\" for form footers","Pass role, aria-label, id and data-* straight through to ButtonGroup"],"accessibility":["Each button stays individually focusable","Add role=\"group\" plus aria-label when the set needs a name","Order buttons the way they read, not the way they look"]},"props":{"children":{"type":"node","description":"Button elements to group together","required":true},"gap":{"type":"enum","description":"Spacing between buttons","default":"sm","required":false,"values":["none","xs","sm","md"]},"wrap":{"type":"boolean","description":"Allow buttons to wrap to next line","default":"false","required":false},"align":{"type":"enum","description":"Alignment of buttons","required":false,"values":["start","center","end"]}},"relations":[{"component":"Button","relationship":"child","note":"ButtonGroup contains Button components"},{"component":"Stack","relationship":"alternative","note":"Use Stack for more general layout needs"}],"variants":[{"name":"Default","description":"Confirming action sits last in the row.","code":"<ButtonGroup>\n <Button variant=\"secondary\">Cancel</Button>\n <Button variant=\"primary\">Save</Button>\n</ButtonGroup>"},{"name":"Spacing","description":"Four gap steps, from touching to airy.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <ButtonGroup gap=\"none\">\n <Button variant=\"secondary\" size=\"sm\">None</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"xs\">\n <Button variant=\"secondary\" size=\"sm\">XS</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"sm\">\n <Button variant=\"secondary\" size=\"sm\">SM</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"md\">\n <Button variant=\"secondary\" size=\"sm\">MD</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n</Stack>"},{"name":"Alignment","description":"Pins the row to the left, centre, or right of its container.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <ButtonGroup align=\"start\">\n <Button variant=\"secondary\" size=\"sm\">Start</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"center\">\n <Button variant=\"secondary\" size=\"sm\">Center</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"end\">\n <Button variant=\"secondary\" size=\"sm\">End</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n</Stack>"},{"name":"Wrapping","description":"Buttons drop to a second line instead of overflowing.","code":"<ButtonGroup wrap>\n <Button variant=\"secondary\" size=\"sm\">Approve</Button>\n <Button variant=\"secondary\" size=\"sm\">Request changes</Button>\n <Button variant=\"secondary\" size=\"sm\">Reassign reviewer</Button>\n <Button variant=\"secondary\" size=\"sm\">Move to backlog</Button>\n <Button variant=\"secondary\" size=\"sm\">Archive</Button>\n</ButtonGroup>"},{"name":"Form Actions","description":"Right-aligned pair, named for screen readers.","code":"<ButtonGroup align=\"end\" role=\"group\" aria-label=\"Form actions\">\n <Button variant=\"ghost\">Cancel</Button>\n <Button variant=\"primary\">Submit</Button>\n</ButtonGroup>"}],"contract":{"propsSummary":["children: ReactNode - buttons to group","gap: none|xs|sm|md - spacing between buttons","wrap: boolean - allow wrapping","align: start|center|end - alignment","Pass-through DOM props supported on root (id, role, aria-*, data-*, handlers)"],"a11yRules":["A11Y_GROUP_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","gap: none|xs|sm|md (default: sm)","wrap: boolean (default: false)","align: start|center|end"],"sourcePath":"src/components/ButtonGroup/index.tsx","exportName":"ButtonGroup","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:51.693Z"},"performance":{"bundleSize":599,"rawSize":1007,"complexity":"lightweight","budgetPercent":4,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"ButtonGroup (self)","bytes":427,"percent":42}]}},"Card":{"filePath":"src/components/Card/Card.fragment.tsx","meta":{"name":"Card","description":"Groups related content onto one bounded surface.","category":"layout","status":"stable","tags":["container","layout","surface"]},"guidance":{"when":["Grouping related content behind one boundary","Previews, summaries, and dashboard tiles","Separating sections that spacing alone cannot"],"whenNot":["Plain text that needs no grouping","Modal surfaces (use Dialog)","Navigation items (use List or Sidebar)"],"dont":[{"reason":"Do not use a Card as a modal surface.","bad":"<Card>Confirm deletion</Card>","good":"<Card variant=\"outlined\">\n <Card.Body>Inline summary</Card.Body>\n </Card>"}],"guidelines":["Keep one variant per context — mixed variants read as noise","Cards sharing a grid row should size uniformly","elevated is for emphasis; use it on one card, not all of them","stat and panel keep dashboard spacing, border, and radius consistent","outline is an alias for outlined — either spelling works","Prefer a Button or Link inside the card over making the whole card clickable"],"accessibility":["Card is a semantic container (article/div/section); onClick adds keyboard and role=\"button\" behavior, but explicit Button or Link actions are preferred","Card titles should be appropriate heading levels"]},"usage":{"when":["Grouping related content behind one boundary","Previews, summaries, and dashboard tiles","Separating sections that spacing alone cannot"],"whenNot":["Plain text that needs no grouping","Modal surfaces (use Dialog)","Navigation items (use List or Sidebar)"],"dont":[{"reason":"Do not use a Card as a modal surface.","bad":"<Card>Confirm deletion</Card>","good":"<Card variant=\"outlined\">\n <Card.Body>Inline summary</Card.Body>\n </Card>"}],"guidelines":["Keep one variant per context — mixed variants read as noise","Cards sharing a grid row should size uniformly","elevated is for emphasis; use it on one card, not all of them","stat and panel keep dashboard spacing, border, and radius consistent","outline is an alias for outlined — either spelling works","Prefer a Button or Link inside the card over making the whole card clickable"],"accessibility":["Card is a semantic container (article/div/section); onClick adds keyboard and role=\"button\" behavior, but explicit Button or Link actions are preferred","Card titles should be appropriate heading levels"]},"props":{"as":{"type":"enum","description":"Root element tag.","default":"article","required":false,"values":["article","div","section"]},"children":{"type":"node","description":"","required":true},"padding":{"type":"enum","description":"Inner padding.","default":"md","required":false,"values":["none","sm","md","lg"]},"style":{"type":"object","description":"","required":false},"tone":{"type":"enum","description":"Semantic tone of the `accent` capsule. The wash and hairline follow the\ntone so the same earned-moment idiom can carry state: `danger` (a merge is\nheld), `warning` (enforcement lapsed), `neutral` (waiting — ink hairline,\nno wash). Ignored for other variants.","default":"accent","required":false,"values":["accent","danger","warning","neutral"]},"variant":{"type":"enum","description":"Visual style variant. `\"outline\"` is an alias for `\"outlined\"`.\n\n- `default` / `outlined` / `elevated`: general-purpose cards.\n- `stat`: compact metric tile for dashboard grids — hairline border,\n panel-subtle surface, tight radius, zero shadow.\n- `panel`: hairline-bordered panel with zero own padding, designed for\n compound use with `Card.Header divided` + `Card.Body` so each region\n manages its own spacing.\n- `accent`: the earned-moment capsule — accent-tinted hairline, radial\n accent wash, soft fixed radius. Reserve for the few surfaces that earn\n emphasis (demo banner, upgrade panel, onboarding resume), never for\n routine content.","default":"default","required":false,"values":["default","outlined","outline","elevated","stat","panel","accent"]}},"relations":[{"component":"Grid","relationship":"parent","note":"Use Grid + Card for responsive card layouts"},{"component":"List","relationship":"alternative","note":"Use List for linear, text-first layouts"}],"variants":[{"name":"Default","description":"Quiet surface with a title and description.","code":"<Card>\n <Card.Header>\n <Card.Title>Card title</Card.Title>\n <Card.Description>A brief description</Card.Description>\n </Card.Header>\n <Card.Body>Related content</Card.Body>\n </Card>","canonical":true},{"name":"Content Only","description":"Body alone, when there is nothing to title.","code":"<Card>\n <Card.Body>Just content, no header or footer.</Card.Body>\n </Card>"},{"name":"With Footer","description":"Footer parks the actions below the content.","code":"<Card>\n <Card.Header>\n <Card.Title>Card with footer</Card.Title>\n <Card.Description>Complete card layout</Card.Description>\n </Card.Header>\n <Card.Body>Main content area.</Card.Body>\n <Card.Footer>Footer actions go here</Card.Footer>\n </Card>"},{"name":"Outlined","description":"Border instead of shadow, for dense layouts.","code":"<Card variant=\"outlined\">\n <Card.Body>Related content</Card.Body>\n </Card>"},{"name":"Elevated","description":"Heavier shadow pulls one surface forward.","code":"<Card variant=\"elevated\">\n <Card.Body>Related content</Card.Body>\n </Card>"},{"name":"Stat","description":"Compact metric tile for dashboard grids.","code":"<Card variant=\"stat\">\n <Card.Body>\n <Text size=\"xl\" weight=\"semibold\">\n 94%\n </Text>\n <Text size=\"sm\" color=\"secondary\">\n Component coverage\n </Text>\n </Card.Body>\n </Card>"},{"name":"Panel","description":"Divided header; the body owns its own spacing.","code":"<Card variant=\"panel\">\n <Card.Header divided>\n <Card.Title>Overview</Card.Title>\n </Card.Header>\n <Card.Body padding=\"md\">Panel content</Card.Body>\n </Card>"},{"name":"Accent","description":"Earned-moment capsule: accent hairline and wash, for the few surfaces that deserve emphasis.","code":"<Card variant=\"accent\" padding=\"lg\">\n <Card.Header>\n <Card.Title>Finish setting up governance</Card.Title>\n <Card.Description>Run the first scan to start tracking drift.</Card.Description>\n </Card.Header>\n </Card>"},{"name":"Interactive","description":"onClick adds keyboard and button behaviour to the whole surface.","code":"<Card as=\"section\" onClick={() => undefined}>\n <Card.Header>\n <Card.Title>Open details</Card.Title>\n <Card.Description>This card is interactive</Card.Description>\n </Card.Header>\n <Card.Body>Activate the card to view more.</Card.Body>\n </Card>"},{"name":"Section Root","description":"The as prop matches the surrounding document semantics.","code":"<Card as=\"section\" aria-labelledby=\"billing-card-title\">\n <Card.Header>\n <Card.Title id=\"billing-card-title\">Billing summary</Card.Title>\n </Card.Header>\n <Card.Body>Section semantics support the surrounding document outline.</Card.Body>\n </Card>"},{"name":"Nested Heading","description":"Pick the heading level the page outline expects.","code":"<Card variant=\"panel\" padding=\"none\">\n <Card.Header divided>\n <Card.Title as=\"h4\">Nested panel</Card.Title>\n </Card.Header>\n <Card.Body padding=\"md\">Panel content</Card.Body>\n </Card>"},{"name":"Long Content","description":"Long titles and dense text wrap without breaking the surface.","code":"<Card>\n <Card.Header>\n <Card.Title>\n A detailed localized account recovery policy for administrators across multiple\n workspaces\n </Card.Title>\n <Card.Description>\n Supporting content remains readable when translated strings take substantially more\n space than the English source.\n </Card.Description>\n </Card.Header>\n <Card.Body>\n Recovery settings apply to every affected administrator and retain an auditable history\n of the notification decision.\n </Card.Body>\n </Card>"}],"ai":{"compositionPattern":"compound","subComponents":["Header","Title","Description","Body","Footer"],"requiredChildren":["Body"],"commonPatterns":["<Card><Card.Body>{content}</Card.Body></Card>","<Card><Card.Header><Card.Title>{title}</Card.Title></Card.Header><Card.Body>{content}</Card.Body></Card>","<Card><Card.Header><Card.Title>{title}</Card.Title><Card.Description>{desc}</Card.Description></Card.Header><Card.Body>{content}</Card.Body><Card.Footer>{actions}</Card.Footer></Card>"]},"contract":{"propsSummary":["variant: default|outlined|outline|elevated|stat|panel|accent (default: default)","padding: none|sm|md|lg (default: md)","as: article|div|section (default: article) - card root element","onClick: (event) => void - click handler on root (adds role/button keyboard behavior)","Sub-components: Card.Header, Card.Title, Card.Description, Card.Body, Card.Footer","Card.Body padding: none|sm|md|lg - use for panel body spacing"],"a11yRules":["A11Y_CARD_HEADING","A11Y_CARD_INTERACTIVE"]},"matrix":{"axes":{"variant":"auto","padding":"auto","theme":["light","dark"]},"forced":["hover","focus"],"worstCase":{"children":"A long localized heading and dense multi-line supporting content"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Card/index.tsx","exportName":"Card","performance":{"bundleSize":1127,"rawSize":2674,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Card (self)","bytes":1992,"percent":74}]}},"Chart":{"filePath":"src/components/Chart/index.tsx","meta":{"name":"Chart","description":"Plots your data with tooltips, legends, and colors that track the theme.","category":"display","tags":["chart","graph","data-visualization","recharts"],"status":"stable","dependencies":[{"name":"recharts","version":">=2.0.0 || >=3.0.0","reason":"Optional — powers Chart.Tooltip and Chart.Legend; both render nothing until it is installed."}]},"usage":{"when":["A trend over time is the point","Categories need comparing side by side","A whole splits into parts worth seeing"],"whenNot":["One number tells the story (use Text or Badge)","Distance to a goal (use Progress)","Readers need exact values (use Table)"],"guidelines":["Wrap every recharts chart in ChartContainer","Map each data key to a label and color in ChartConfig","Colors come from --fui-* variables so both themes stay readable","Pair with ChartTooltip and ChartLegend rather than recharts' own","Give the container a real height — recharts cannot measure zero"],"accessibility":["accessibilityLayer is on by default","ChartConfig labels are what screen readers read","Pass dataTable to offer the same numbers as text"]},"props":{"config":{"type":"object","description":"ChartConfig mapping data keys to labels/colors (optional icon per series)","required":true},"children":{"type":"element","description":"A recharts chart component (LineChart, BarChart, etc.)","required":true},"summary":{"type":"string","description":"Non-visual summary announced to assistive technology users","required":false},"dataTable":{"type":"node","description":"Optional accessible data table or textual fallback","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Card","relationship":"parent","note":"Charts are typically placed inside Cards"},{"component":"Progress","relationship":"alternative","note":"Use Progress for single-value completion"},{"component":"Table","relationship":"sibling","note":"Combine with Table for full data views"}],"variants":[{"name":"Line Chart","description":"Two series share one scale, so the gap between them reads instantly.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n users: { label: 'Users', color: 'var(--fui-color-info)' },\n }}\n >\n <LineChart data={monthlyData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"month\" />\n <YAxis />\n <ChartTooltip />\n <ChartLegend />\n <Line type=\"monotone\" dataKey=\"revenue\" stroke=\"var(--fui-color-accent)\" strokeWidth={2} dot={false} />\n <Line type=\"monotone\" dataKey=\"users\" stroke=\"var(--fui-color-info)\" strokeWidth={2} dot={false} />\n </LineChart>\n </ChartContainer>\n</div>"},{"name":"Bar Chart","description":"Fixed categories, compared by height — the safest default.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n sessions: { label: 'Sessions', color: 'var(--fui-color-accent)' },\n }}\n >\n <BarChart data={deviceData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"device\" />\n <YAxis />\n <ChartTooltip />\n <Bar dataKey=\"sessions\" fill=\"var(--fui-color-accent)\" radius={[4, 4, 0, 0]} />\n </BarChart>\n </ChartContainer>\n</div>"},{"name":"Area Chart","description":"The fill under the line stresses volume, not just direction.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n }}\n >\n <AreaChart data={monthlyData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"month\" />\n <YAxis />\n <ChartTooltip />\n <Area type=\"monotone\" dataKey=\"revenue\" stroke=\"var(--fui-color-accent)\" fill=\"var(--fui-color-accent)\" fillOpacity={0.15} strokeWidth={2} />\n </AreaChart>\n </ChartContainer>\n</div>"},{"name":"Pie Chart","description":"Parts of one whole — keep it under six slices or it stops reading.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n Chrome: { label: 'Chrome', color: 'var(--fui-color-accent)' },\n Firefox: { label: 'Firefox', color: 'var(--fui-color-info)' },\n Safari: { label: 'Safari', color: 'var(--fui-color-success)' },\n Edge: { label: 'Edge', color: 'var(--fui-color-warning)' },\n }}\n >\n <PieChart>\n <ChartTooltip />\n <ChartLegend />\n <Pie\n data={browserData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={60}\n outerRadius={90}\n strokeWidth={2}\n >\n {browserData.map((entry) => (\n <Cell key={entry.name} fill={entry.color} />\n ))}\n </Pie>\n </PieChart>\n </ChartContainer>\n</div>"}],"contract":{"propsSummary":["config: ChartConfig - maps data keys to labels and theme colors","children: ReactElement - recharts chart component","Chart.Tooltip / Chart.Legend support custom content renderers for advanced overlays"],"a11yRules":["A11Y_CHART_LABEL"]},"propsSummary":["config: object (required)","children: element (required)","summary: string","dataTable: node","style: object"],"sourcePath":"src/components/Chart/index.tsx","exportName":"ChartContainer","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.043Z"},"ai":{"subComponents":["Root","Tooltip","TooltipContent","Legend","LegendContent","preload"],"compositionPattern":"compound"},"performance":{"bundleSize":1911,"rawSize":4368,"complexity":"lightweight","budgetPercent":12,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Chart (self)","bytes":3545,"percent":81},{"path":"src/utils/aria.ts","bytes":109,"percent":2}]}},"Checkbox":{"filePath":"src/components/Checkbox/index.tsx","meta":{"name":"Checkbox","description":"Selects options that take effect when a form is submitted.","category":"inputs","tags":["checkbox","form","boolean","selection","input"],"status":"stable"},"usage":{"when":["Choices that apply only once the form is submitted","Picking several items from a list","Accepting terms","Filter and preference lists"],"whenNot":["Settings that apply instantly (use Switch)","One choice from a few (use RadioGroup)","Many options (use Select)"],"guidelines":["Always show a label","Add helperText when the consequence is not obvious","Keep related boxes together","Use indeterminate for a parent whose children are partly checked"],"accessibility":["Label is tied to the box","Space toggles it","Focus ring stays visible","Indeterminate is announced as mixed"]},"props":{"checked":{"type":"boolean","description":"Controlled checked state","required":false},"defaultChecked":{"type":"boolean","description":"Default checked state (uncontrolled)","required":false},"onCheckedChange":{"type":"function","description":"Called when checked state changes","required":false},"onChange":{"type":"function","description":"Alias for onCheckedChange: (checked: boolean) => void","required":false},"indeterminate":{"type":"boolean","description":"Indeterminate state (partial selection)","default":"false","required":false},"disabled":{"type":"boolean","description":"Disable the checkbox","default":"false","required":false},"required":{"type":"boolean","description":"Whether the checkbox is required","default":"false","required":false},"size":{"type":"enum","description":"Checkbox size","default":"\"md\"","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Visual variant. 'default' is the inline checkbox, 'card' renders as a full-width clickable card with the checkbox tucked inside.","default":"default","required":false,"values":["default","card"]},"label":{"type":"string","description":"Label text","required":false},"helperText":{"type":"string","description":"Helper text shown below the label (preferred)","required":false},"description":{"type":"string","description":"Deprecated alias for helperText","required":false},"name":{"type":"string","description":"Name attribute for form submission","required":false},"value":{"type":"string","description":"Value attribute for form submission","required":false},"id":{"type":"string","description":"ID for the checkbox input","required":false},"controlClassName":{"type":"string","description":"Class name for the checkbox control element (stable styling target)","required":false},"contentClassName":{"type":"string","description":"Class name for the label/description content wrapper","required":false},"aria-label":{"type":"string","description":"Accessible label for icon-only mode","required":false},"aria-labelledby":{"type":"string","description":"Accessible labelled-by relationship for icon-only mode","required":false},"aria-describedby":{"type":"string","description":"Accessible described-by relationship","required":false},"form":{"type":"string","description":"ID of the form that owns the hidden input","required":false},"inputRef":{"type":"union","description":"Ref to the hidden input element","required":false},"parent":{"type":"boolean","description":"Whether this checkbox controls child checkboxes in a checkbox group","required":false},"readOnly":{"type":"boolean","description":"Whether the checkbox cannot be changed by the user","default":"false","required":false},"uncheckedValue":{"type":"string","description":"Value submitted when unchecked","required":false}},"relations":[{"component":"Switch","relationship":"alternative","note":"Use Switch for immediate-effect settings"},{"component":"Input","relationship":"sibling","note":"Checkbox handles boolean; Input handles text"}],"variants":[{"name":"Default","description":"One box, one label, off to start.","code":"<StatefulCheckbox label=\"Accept terms and conditions\" />"},{"name":"With Helper Text","description":"Second line spells out what opting in does.","code":"<StatefulCheckbox\n label=\"Email notifications\"\n helperText=\"Receive email updates about your account activity\"\n/>"},{"name":"Checked","description":"Starts on.","code":"<StatefulCheckbox defaultChecked label=\"Subscribe to newsletter\" />"},{"name":"Indeterminate","description":"A dash on the parent means only some children are on.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox indeterminate label=\"Select all\" />\n <div style={{ marginLeft: '24px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <StatefulCheckbox defaultChecked label=\"Option 1\" />\n <StatefulCheckbox label=\"Option 2\" />\n <StatefulCheckbox defaultChecked label=\"Option 3\" />\n </div>\n</div>"},{"name":"Sizes","description":"Three box sizes: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulCheckbox size=\"sm\" label=\"Small checkbox\" />\n <StatefulCheckbox size=\"md\" label=\"Medium checkbox\" />\n <StatefulCheckbox size=\"lg\" label=\"Large checkbox\" />\n</div>"},{"name":"Disabled","description":"Locked in both positions, on and off.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox disabled label=\"Disabled unchecked\" />\n <Checkbox disabled checked label=\"Disabled checked\" />\n</div>"},{"name":"Custom Styling Targets","description":"controlClassName styles the box, contentClassName the text.","code":"<Checkbox\n label=\"Styled checkbox\"\n helperText=\"Control and content wrappers can be targeted independently\"\n controlClassName=\"demo-checkbox-control\"\n contentClassName=\"demo-checkbox-content\"\n/>"}],"contract":{"propsSummary":["checked: boolean - controlled checked state","onCheckedChange: (checked) => void - change handler","onChange: (checked) => void - alias for onCheckedChange","indeterminate: boolean - partial selection state","label: string - checkbox label","helperText: string - helper text (preferred)","description: string - deprecated alias for helperText","controlClassName/contentClassName - explicit styling targets for control and content"],"a11yRules":["A11Y_CHECKBOX_LABEL","A11Y_CHECKBOX_FOCUS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["checked: boolean","defaultChecked: boolean","onCheckedChange: function","onChange: function","indeterminate: boolean (default: false)","disabled: boolean (default: false)","required: boolean (default: false)","size: sm|md|lg (default: md)","label: string","helperText: string","description: string","name: string","value: string","id: string","controlClassName: string","contentClassName: string","aria-label: string","aria-labelledby: string","aria-describedby: string"],"sourcePath":"src/components/Checkbox/index.tsx","exportName":"Checkbox","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.226Z"},"performance":{"bundleSize":1386,"rawSize":3421,"complexity":"lightweight","budgetPercent":9,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Checkbox (self)","bytes":2512,"percent":73},{"path":"ComponentDefaults","bytes":198,"percent":6},{"path":"src/utils/aria.ts","bytes":110,"percent":3}]}},"Chip":{"filePath":"src/components/Chip/index.tsx","meta":{"name":"Chip","description":"Pill control for filtering, multi-select, and removable tags.","category":"inputs","tags":["chip","tag","filter","selection","multi-select","action"],"status":"stable"},"usage":{"when":["Filtering a list by tag or category","Multi-select from a compact set","Showing filters the user can dismiss"],"whenNot":["Read-only status — use Badge","Switching views — use Tabs","On/off state — use Switch","A main call to action — use Button"],"guidelines":["One to three words per chip","Chip.Group when chips share selection state","Keep xs for filters and tags; size up only to match a taller control track","onRemove only when the chip is genuinely dismissible","Pass an explicit value when children are custom JSX"],"accessibility":["Chips are buttons; selection is reported via aria-pressed","Add role and aria-label to Chip.Group when the set needs a name","Remove buttons carry the chip text in their aria-label","Disabled chips are skipped by keyboard and pointer"]},"props":{"children":{"type":"node","description":"Chip label text","required":true},"variant":{"type":"enum","description":"Visual style variant","default":"filled","required":false,"values":["filled","outlined","outline","soft"]},"size":{"type":"enum","description":"Chip size","default":"\"xs\"","required":false,"values":["xs","sm","md","lg"]},"selected":{"type":"boolean","description":"Whether the chip is in a selected state","default":"false","required":false},"icon":{"type":"node","description":"Icon element rendered before the label","required":false},"avatar":{"type":"node","description":"Avatar element rendered before the label","required":false},"onRemove":{"type":"function","description":"Makes chip removable. Called when X is clicked.","required":false},"value":{"type":"string","description":"Value identifier used by Chip.Group for selection tracking","required":false},"disabled":{"type":"boolean","description":"","default":"false","required":false},"onClick":{"type":"function","description":"","required":false}},"relations":[{"component":"Badge","relationship":"sibling","note":"Badge is display-only; Chip is interactive"},{"component":"ToggleGroup","relationship":"alternative","note":"Use ToggleGroup for mutually exclusive options"},{"component":"Button","relationship":"alternative","note":"Use Button for primary actions, Chip for selection/filtering"}],"variants":[{"name":"Variants","description":"Tinted, hairline, and accent-soft chrome.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip variant=\"filled\">Filled</Chip>\n <Chip variant=\"outlined\">Outlined</Chip>\n <Chip variant=\"soft\">Soft</Chip>\n</Stack>"},{"name":"Sizes","description":"xs for filter rows; larger sizes match taller field tracks.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Chip variant=\"outlined\" size=\"xs\">Extra small</Chip>\n <Chip variant=\"outlined\" size=\"sm\">Small</Chip>\n <Chip variant=\"outlined\" size=\"md\">Medium</Chip>\n <Chip variant=\"outlined\" size=\"lg\">Large</Chip>\n</Stack>"},{"name":"Selected","description":"All three variants share one selection treatment.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip selected>Filled</Chip>\n <Chip variant=\"outlined\" selected>Outlined</Chip>\n <Chip variant=\"soft\" selected>Soft</Chip>\n</Stack>"},{"name":"With Avatar","description":"Leading face, for people-shaped selections.","code":"<Chip avatar={<img src=\"https://i.pravatar.cc/32?u=chip\" alt=\"\" />}>\n Jane Doe\n</Chip>"},{"name":"With Remove","description":"Trailing dismiss button clears the tag.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip variant=\"outlined\" onRemove={() => {}}>React</Chip>\n <Chip variant=\"outlined\" selected onRemove={() => {}}>TypeScript</Chip>\n <Chip variant=\"soft\" onRemove={() => {}}>SCSS</Chip>\n</Stack>"},{"name":"Chip Group","description":"Selection state is held by the group, not each chip.","code":"<Chip.Group defaultValue={['react']}>\n <Chip value=\"react\">React</Chip>\n <Chip value=\"vue\">Vue</Chip>\n <Chip value=\"angular\">Angular</Chip>\n <Chip value=\"svelte\">Svelte</Chip>\n</Chip.Group>"},{"name":"Chip Group with Custom Labels","description":"Custom JSX children need an explicit value.","code":"<Chip.Group aria-label=\"Assignees\">\n <Chip value=\"jane\">\n <span>Jane Doe</span>\n </Chip>\n <Chip value=\"sam\">\n <span>Sam Lee</span>\n </Chip>\n</Chip.Group>"},{"name":"Disabled","description":"Dimmed and unreachable, selected or not.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip variant=\"outlined\" disabled>Disabled</Chip>\n <Chip variant=\"outlined\" disabled selected>Disabled selected</Chip>\n</Stack>"}],"contract":{"propsSummary":["children: ReactNode - chip label (required)","variant: filled|outlined|outline|soft - visual style","size: xs|sm|md|lg - chip size (xs by default)","selected: boolean - selection state","icon/avatar: ReactNode - leading visual","onRemove: () => void - makes chip removable","value: string - identifier for Chip.Group","Chip.Group forwards DOM props (id, role, aria-*, data-*, handlers)","Chip.Group: non-string chip labels should set an explicit value"],"a11yRules":["A11Y_CHIP_SELECTION","A11Y_CHIP_DISMISS"]},"ai":{"compositionPattern":"compound","subComponents":["Group"]},"propsSummary":["children: node (required)","variant: filled|outlined|outline|soft (default: filled)","size: xs|sm|md|lg (default: xs)","selected: boolean (default: false)","icon: node","avatar: node","onRemove: function","value: string","disabled: boolean (default: false)","onClick: function"],"sourcePath":"src/components/Chip/index.tsx","exportName":"Chip","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:54.270Z"},"performance":{"bundleSize":1137,"rawSize":2261,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Chip (self)","bytes":1675,"percent":74}]}},"CodeBlock":{"filePath":"src/components/CodeBlock/index.tsx","meta":{"name":"CodeBlock","description":"Shows code with syntax colors, a copy button, and diff or collapse when you need them.","category":"display","tags":["code","syntax","highlighting","documentation","developer","diff"],"status":"stable","dependencies":[{"name":"shiki","version":">=1.0.0","reason":"Optional — provides syntax highlighting; without it code renders unhighlighted."}]},"usage":{"when":["Code examples inside prose or docs","Install and config snippets","Showing what changed, as a diff"],"whenNot":["The user needs to edit it (use an editor)","A couple of words inline (use a code element)"],"guidelines":["Set language every time — wrong highlighting is worse than none","filename for a real file, title for a label, caption for the aside","Line numbers earn their keep once you need to point at a line","highlightLines for emphasis; addedLines and removedLines for diffs","maxHeight or collapsible keeps a long file from swallowing the page","CodeBlock.Tabbed groups the same snippet across languages"],"accessibility":["Renders as semantic pre and code","The copy button is labelled and keyboard reachable","The collapse toggle reports aria-expanded"]},"props":{"code":{"type":"string","description":"The code string to display","required":true},"language":{"type":"enum","description":"Programming language for syntax highlighting","default":"tsx","required":false,"values":["tsx","typescript","ts","javascript","js","jsx","bash","shell","css","scss","sass","json","html","xml","markdown","md","yaml","yml","python","py","ruby","go","rust","java","kotlin","swift","c","cpp","csharp","php","sql","graphql","diff","plaintext","text"]},"theme":{"type":"enum","description":"Syntax highlighting theme. css-variables maps spans onto --fui-code-token-* so both themes stay readable.","default":"css-variables","required":false,"values":["css-variables","synthwave-84","github-dark","github-light","one-dark-pro","dracula","nord","monokai","vitesse-dark","vitesse-light","min-dark","min-light"]},"showCopy":{"type":"boolean","description":"Whether to show the copy button","default":"true","required":false},"title":{"type":"string","description":"Optional title displayed above the code block (external label)","required":false},"filename":{"type":"string","description":"Optional filename shown in header bar inside code block","required":false},"caption":{"type":"string","description":"Optional caption displayed below the code block","required":false},"showLineNumbers":{"type":"boolean","description":"Whether to display line numbers","default":"false","required":false},"startLineNumber":{"type":"number","description":"Starting line number (useful for code excerpts)","default":"1","required":false},"highlightLines":{"type":"array","description":"Lines to highlight (e.g., [1, 3, \"5-7\"])","required":false},"addedLines":{"type":"array","description":"Lines marked as added in diff view (e.g., [2, \"4-6\"])","required":false},"removedLines":{"type":"array","description":"Lines marked as removed in diff view (e.g., [1, 3])","required":false},"wordWrap":{"type":"boolean","description":"Enable word wrapping for long lines","default":"false","required":false},"maxHeight":{"type":"number","description":"Maximum height in pixels (enables scrolling)","required":false},"collapsible":{"type":"boolean","description":"Allow collapsing/expanding the code block","default":"false","required":false},"defaultCollapsed":{"type":"boolean","description":"Initial collapsed state (only applies when collapsible is true)","default":"false","required":false},"collapsedLines":{"type":"number","description":"Number of lines to show when collapsed","default":"5","required":false},"collapseAction":{"type":"enum","description":"Collapse control copy: line-count bar, or a single Expand / Collapse control","default":"lines","required":false,"values":["lines","expand"]},"compact":{"type":"boolean","description":"Compact mode with reduced padding","default":"false","required":false},"persistentCopy":{"type":"boolean","description":"Show a persistent copy button that is always visible","default":"false","required":false},"copyPlacement":{"type":"enum","description":"Where to place the copy button when not using persistentCopy","default":"auto","required":false,"values":["auto","header","overlay"]},"bg":{"type":"string","description":"Custom background color for the code block (useful when the content area is pure black or dark gray)","required":false},"onCopy":{"type":"function","description":"Callback fired when the copy button is clicked and copy succeeds","required":false}},"relations":[{"component":"Card","relationship":"parent","note":"Can be wrapped in Card for additional context"},{"component":"Tabs","relationship":"child","note":"Use in Tabs for showing code in multiple languages"}],"variants":[{"name":"Default","description":"Pass code and language; highlighting and copy come free.","code":"<CodeBlock code={`import { Button } from '@usefragments/ui';\n\nfunction App() {\n return <Button>Click me</Button>;\n}`} language=\"tsx\" />"},{"name":"With Filename","description":"A header bar names the source file and holds the copy button.","code":"<CodeBlock filename=\"app.tsx\" code={`import { Button, Card } from '@usefragments/ui';\n\nfunction App() {\n return (\n <Card>\n <Card.Header>Welcome</Card.Header>\n <Card.Content>\n <Button>Get Started</Button>\n </Card.Content>\n </Card>\n );\n}`} language=\"tsx\" />"},{"name":"With Title","description":"A label above the block, outside the code surface.","code":"<CodeBlock title=\"Installation\" code=\"npm install @usefragments/ui\" language=\"bash\" />"},{"name":"With Caption","description":"A footer line for the aside that does not belong in the code.","code":"<CodeBlock\n code={`const API_URL = process.env.NEXT_PUBLIC_API_URL;`}\n language=\"typescript\"\n caption=\"Environment variables must be prefixed with NEXT_PUBLIC_ to be available in the browser.\"\n/>"},{"name":"With Line Numbers","description":"Turn these on once a snippet is long enough to point at.","code":"<CodeBlock code={`const greeting = \"Hello\";\nconst name = \"World\";\nconsole.log(\\`\\${greeting}, \\${name}!\\`);`} language=\"typescript\" showLineNumbers />"},{"name":"Custom Start Line","description":"Numbering starts where the excerpt actually starts in the file.","code":"<CodeBlock\n code={` return (\n <button onClick={() => setCount(c => c + 1)}>\n Count: {count}\n </button>\n );\n}`}\n language=\"tsx\"\n showLineNumbers\n startLineNumber={15}\n caption=\"Lines 15-20 from Counter.tsx\"\n/>"},{"name":"With Highlighted Lines","description":"Marks the lines the prose is talking about.","code":"<CodeBlock code={`import { useState } from 'react';\n\nfunction Counter() {\n const [count, setCount] = useState(0);\n\n return (\n <button onClick={() => setCount(c => c + 1)}>\n Count: {count}\n </button>\n );\n}`} language=\"tsx\" showLineNumbers highlightLines={[4, '7-9']} />"},{"name":"Diff View","description":"Added and removed lines, side by side with the rest.","code":"<CodeBlock\n code={`import { useState } from 'react';\nimport { useCallback } from 'react';\n\nfunction Counter() {\n const [count, setCount] = useState(0);\n const increment = () => setCount(c => c + 1);\n const increment = useCallback(() => setCount(c => c + 1), []);\n\n return <button onClick={increment}>Count: {count}</button>;\n}`}\n language=\"tsx\"\n showLineNumbers\n removedLines={[6]}\n addedLines={[2, 7]}\n/>"},{"name":"Custom Theme","description":"Any Shiki theme works — pass its name to theme.","code":"<CodeBlock\n code={`async function fetchUser(id: string) {\n const response = await fetch(\\`/api/users/\\${id}\\`);\n return response.json();\n}`}\n language=\"typescript\"\n theme=\"github-dark\"\n/>"},{"name":"Word Wrap","description":"Long lines break instead of scrolling sideways.","code":"<CodeBlock\n code={`const longString = \"This is a very long string that would normally cause horizontal scrolling, but with word wrap enabled it will break to the next line instead.\";`}\n language=\"typescript\"\n wordWrap\n/>"},{"name":"Max Height with Scroll","description":"Caps the height so one snippet cannot own the page.","code":"<CodeBlock\n code={`// This code block has a maximum height\nfunction processItems(items: string[]) {\n const results = [];\n for (const item of items) {\n if (item.startsWith('_')) {\n continue;\n }\n const processed = item.trim().toLowerCase();\n if (processed.length > 0) {\n results.push(processed);\n }\n }\n return results;\n}\n\nexport default processItems;`}\n language=\"typescript\"\n maxHeight={150}\n showLineNumbers\n/>"},{"name":"Collapsible","description":"Shows the opening lines and hides the rest behind a toggle.","code":"<CodeBlock\n code={`import React, { useState, useEffect } from 'react';\n\ninterface User {\n id: string;\n name: string;\n email: string;\n avatar?: string;\n}\n\nexport function UserProfile({ userId }: { userId: string }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n async function fetchUser() {\n try {\n setLoading(true);\n const response = await fetch(\\`/api/users/\\${userId}\\`);\n if (!response.ok) throw new Error('Failed to fetch');\n const data = await response.json();\n setUser(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error');\n } finally {\n setLoading(false);\n }\n }\n fetchUser();\n }, [userId]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div>Error: {error}</div>;\n if (!user) return null;\n\n return (\n <div>\n <h1>{user.name}</h1>\n <p>{user.email}</p>\n </div>\n );\n}`}\n language=\"tsx\"\n showLineNumbers\n collapsible\n defaultCollapsed\n collapsedLines={8}\n/>"},{"name":"JSON","description":"Config files highlight the same way source does.","code":"<CodeBlock title=\"package.json\" code={`{\n \"name\": \"my-app\",\n \"dependencies\": {\n \"@usefragments/ui\": \"^0.3.0\"\n }\n}`} language=\"json\" />"},{"name":"Without Copy Button","description":"Drop the copy button when the snippet is not meant to be reused.","code":"<CodeBlock code=\"const simple = true;\" language=\"typescript\" showCopy={false} />"}],"contract":{"propsSummary":["code: string - required code content","language: tsx|typescript|javascript|jsx|bash|shell|css|scss|sass|json|html|xml|markdown|md|yaml|yml|python|py|ruby|go|rust|java|kotlin|swift|c|cpp|csharp|php|sql|graphql|diff|plaintext","theme: css-variables|synthwave-84|github-dark|github-light|one-dark-pro|dracula|nord|monokai|vitesse-dark|vitesse-light|min-dark|min-light (default: css-variables)","showCopy: boolean (default: true)","copyPlacement: auto|header|overlay (default: auto)","title: string - optional external label","filename: string - optional filename in header bar","caption: string - optional footer caption","showLineNumbers: boolean (default: false)","startLineNumber: number (default: 1)","highlightLines: (number | string)[] - lines to emphasize","addedLines: (number | string)[] - diff added lines","removedLines: (number | string)[] - diff removed lines","wordWrap: boolean (default: false)","maxHeight: number - max height with scrolling","collapsible: boolean (default: false)","defaultCollapsed: boolean (default: false)","collapsedLines: number (default: 5)","CodeBlock.Tabbed: tabs[] plus optional defaultTab/value/onValueChange for multi-language snippets; collapsible/defaultCollapsed/collapsedLines forward to every panel"],"a11yRules":["A11Y_CODE_SEMANTIC","A11Y_BTN_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Tabbed"]},"propsSummary":["code: string (required)","language: tsx|typescript|ts|javascript|js|jsx|bash|shell|css|scss|sass|json|html|xml|markdown|md|yaml|yml|python|py|ruby|go|rust|java|kotlin|swift|c|cpp|csharp|php|sql|graphql|diff|plaintext|text (default: tsx)","theme: css-variables|synthwave-84|github-dark|github-light|one-dark-pro|dracula|nord|monokai|vitesse-dark|vitesse-light|min-dark|min-light (default: css-variables)","showCopy: boolean (default: true)","title: string","filename: string","caption: string","showLineNumbers: boolean (default: false)","startLineNumber: number (default: 1)","highlightLines: array","addedLines: array","removedLines: array","wordWrap: boolean (default: false)","maxHeight: number","collapsible: boolean (default: false)","defaultCollapsed: boolean (default: false)","collapsedLines: number (default: 5)","compact: boolean (default: false)","persistentCopy: boolean (default: false)","copyPlacement: auto|header|overlay (default: auto)","bg: string","onCopy: function"],"sourcePath":"src/components/CodeBlock/index.tsx","exportName":"CodeBlock","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.626Z"},"performance":{"bundleSize":4848,"rawSize":13619,"complexity":"lightweight","budgetPercent":32,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"CodeBlock (self)","bytes":11094,"percent":81},{"path":"Tabs","bytes":1894,"percent":14}]}},"Collapsible":{"filePath":"src/components/Collapsible/index.tsx","meta":{"name":"Collapsible","description":"Shows or hides one region of content behind a trigger.","category":"layout","tags":["collapsible","expandable","accordion","disclosure","toggle"],"status":"stable"},"usage":{"when":["Detail most readers do not need","Optional or advanced settings","Navigation sections that fold away","Building a disclosure the other components do not cover"],"whenNot":["Several sections that should coordinate (use Accordion)","Content that must overlay the page (use Dialog or Popover)","Action lists (use Menu)"],"guidelines":["The trigger should say what opens, not 'click here'","defaultOpen for content most users want on arrival","Keep the trigger to a short phrase","Keep the chevron direction consistent across the page"],"accessibility":["Trigger must have aria-expanded to indicate state","Content region needs aria-labelledby pointing to trigger","Keyboard: Enter/Space toggles open state","Focus should remain on trigger after toggle"]},"props":{"children":{"type":"node","description":"Collapsible.Trigger and Collapsible.Content components","required":true},"defaultOpen":{"type":"boolean","description":"Whether the collapsible is initially open (uncontrolled)","default":"false","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false},"onOpenChange":{"type":"function","description":"Callback when open state changes - (open: boolean) => void","required":false},"disabled":{"type":"boolean","description":"Whether the collapsible is disabled","default":"false","required":false}},"relations":[{"component":"Accordion","relationship":"alternative","note":"Use Accordion for multiple exclusive collapsible sections"},{"component":"Sidebar","relationship":"used-by","note":"Sidebar uses Collapsible for section expand/collapse"},{"component":"Menu","relationship":"alternative","note":"Use Menu for dropdown navigation with actions"}],"variants":[{"name":"Default","description":"Starts closed and opens on click.","code":"<Collapsible>\n <Collapsible.Trigger>Click to expand</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content is hidden by default and revealed when the trigger is clicked.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Default Open","description":"Starts open for content most users want.","code":"<Collapsible defaultOpen>\n <Collapsible.Trigger>Section Title</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content is visible by default. Click the trigger to collapse.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Chevron Start","description":"Marker leads the label instead of trailing it.","code":"<Collapsible>\n <Collapsible.Trigger chevronPosition=\"start\">Navigation</Collapsible.Trigger>\n <Collapsible.Content>\n <ul style={{ margin: 0, paddingLeft: '1.5rem' }}>\n <li>Dashboard</li>\n <li>Settings</li>\n <li>Profile</li>\n </ul>\n </Collapsible.Content>\n</Collapsible>"},{"name":"No Chevron","description":"Bare trigger when the surrounding layout signals enough.","code":"<Collapsible>\n <Collapsible.Trigger showChevron={false}>Show more details</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Hidden details that appear when triggered.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Disabled","description":"Locked shut and skipped by the keyboard.","code":"<Collapsible disabled>\n <Collapsible.Trigger>Cannot toggle (disabled)</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content cannot be shown because the collapsible is disabled.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Multiple Sections","description":"Independent regions that ignore each other.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n <Collapsible defaultOpen>\n <Collapsible.Trigger>Getting Started</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Introduction and setup instructions.</p>\n </Collapsible.Content>\n </Collapsible>\n <Collapsible>\n <Collapsible.Trigger>Advanced Usage</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Advanced configuration options.</p>\n </Collapsible.Content>\n </Collapsible>\n <Collapsible>\n <Collapsible.Trigger>API Reference</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Complete API documentation.</p>\n </Collapsible.Content>\n </Collapsible>\n</div>"}],"contract":{"propsSummary":["defaultOpen: boolean - initial open state (default: false)","open: boolean - controlled open state","onOpenChange: (open: boolean) => void - state change callback","disabled: boolean - prevents interaction"],"a11yRules":["A11Y_EXPANDED_STATE","A11Y_REGION_LABEL","A11Y_KEYBOARD_NAV"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Trigger","Content"],"commonPatterns":["<Collapsible>\n <Collapsible.Trigger>...</Collapsible.Trigger>\n <Collapsible.Content>...</Collapsible.Content>\n</Collapsible>"],"requiredChildren":["Trigger","Content"]},"propsSummary":["children: node (required)","defaultOpen: boolean (default: false)","open: boolean","onOpenChange: function","disabled: boolean (default: false)"],"sourcePath":"src/components/Collapsible/index.tsx","exportName":"Collapsible","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.800Z"},"performance":{"bundleSize":1511,"rawSize":3197,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Collapsible (self)","bytes":2508,"percent":78}]}},"ColorPicker":{"filePath":"src/components/ColorPicker/index.tsx","meta":{"name":"ColorPicker","description":"Selects a color through a visual picker and hexadecimal input.","category":"inputs","tags":["color","picker","input","hex","swatch","theme"],"status":"stable","dependencies":[{"name":"react-colorful","version":">=5.0.0","reason":"Optional — renders the visual picker surface; the swatch and hex input work without it."}]},"usage":{"when":["Theme and brand customisation","Any colour the user must pick freely","Design tool inputs"],"whenNot":["A fixed palette (use RadioGroup with swatches)","Showing a colour without editing it (use a tinted Badge)","Status colour that should come from a token"],"guidelines":["Label says what the colour is for","Use helperText for constraints, such as contrast rules","Offer presets next to the picker for the common choices","Validate the hex as #RRGGBB before accepting it"],"accessibility":["Label is tied to the hex input","The swatch button carries its own aria-label","The picker popup is reachable from the keyboard","Users can type a hex instead of dragging"]},"props":{"label":{"type":"string","description":"Label text above the picker","required":false},"value":{"type":"string","description":"Controlled color value in hex format (#RRGGBB)","required":false},"defaultValue":{"type":"string","description":"Default color for uncontrolled usage","default":"#000000","required":false},"onChange":{"type":"function","description":"Called with new color value when changed","required":false},"onValueChange":{"type":"function","description":"Alias for onChange (Radix convention)","required":false},"helperText":{"type":"string","description":"Helper text below the picker (preferred)","required":false},"description":{"type":"string","description":"Deprecated alias for helperText","required":false},"error":{"type":"boolean","description":"Show error styling","default":"false","required":false},"disabled":{"type":"boolean","description":"Disable the color picker","default":"false","required":false},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["sm","md","lg"]},"showInput":{"type":"boolean","description":"Show the hex input field","default":"true","required":false}},"relations":[{"component":"Input","relationship":"sibling","note":"ColorPicker is a specialized input for colors"},{"component":"RadioGroup","relationship":"alternative","note":"Use RadioGroup for predefined color choices"},{"component":"Field","relationship":"parent","note":"ColorPicker uses Field internally for structure"}],"variants":[{"name":"Default","description":"Swatch opens the picker; the hex field accepts typing.","code":"<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#3b82f6\"\n/>"},{"name":"With Helper Text","description":"Supporting line says where the colour will be used.","code":"<ColorPicker\n label=\"Primary Color\"\n defaultValue=\"#10b981\"\n helperText=\"This color will be used for buttons and links\"\n/>"},{"name":"Controlled","description":"The parent owns the value and sees every change.","code":"<ControlledColorPickerDemo />"},{"name":"Multiple Pickers","description":"A stacked set reads as one palette.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '240px' }}>\n <ColorPicker label=\"Primary\" defaultValue=\"#3b82f6\" />\n <ColorPicker label=\"Success\" defaultValue=\"#22c55e\" />\n <ColorPicker label=\"Warning\" defaultValue=\"#f59e0b\" />\n <ColorPicker label=\"Danger\" defaultValue=\"#ef4444\" />\n</div>"},{"name":"Compact","description":"showInput={false} drops the hex field, leaving a swatch row.","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <ColorPicker defaultValue=\"#ef4444\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#f59e0b\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#22c55e\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#3b82f6\" size=\"sm\" showInput={false} />\n</div>"},{"name":"Sizes","description":"Three swatch sizes: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '240px' }}>\n <ColorPicker label=\"Small\" defaultValue=\"#3b82f6\" size=\"sm\" />\n <ColorPicker label=\"Medium (default)\" defaultValue=\"#3b82f6\" size=\"md\" />\n <ColorPicker label=\"Large\" defaultValue=\"#3b82f6\" size=\"lg\" />\n</div>"},{"name":"Error State","description":"Red border on the hex field, and the reason below it.","code":"<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#7c3aed\"\n error\n helperText=\"This color fails contrast against the page background\"\n/>"},{"name":"Disabled","description":"Swatch will not open and the hex field will not accept typing.","code":"<ColorPicker\n label=\"Locked Color\"\n defaultValue=\"#64748b\"\n helperText=\"This color cannot be changed\"\n disabled\n/>"}],"contract":{"propsSummary":["value: string - controlled hex color (#RRGGBB)","defaultValue: string - initial color for uncontrolled usage","onChange: (color: string) => void - change handler","label: string - field label","helperText: string - helper text (preferred)","description: string - deprecated alias for helperText","error: boolean - error styling","disabled: boolean - disable interaction","size: sm|md|lg - size variant","showInput: boolean - show hex input field"],"a11yRules":["A11Y_LABEL_REQUIRED","A11Y_FOCUS_VISIBLE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root","preload"]},"propsSummary":["label: string","value: string","defaultValue: string (default: #000000)","onChange: function","onValueChange: function","helperText: string","description: string","error: boolean (default: false)","disabled: boolean (default: false)","size: sm|md|lg (default: md)","showInput: boolean (default: true)"],"sourcePath":"src/components/ColorPicker/index.tsx","exportName":"ColorPicker","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.238Z"},"performance":{"bundleSize":8251,"rawSize":23047,"complexity":"moderate","budgetPercent":54,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"react-colorful","bytes":14089,"percent":61},{"path":"Input","bytes":3169,"percent":14},{"path":"src/recipes/popup.ts","bytes":2836,"percent":12},{"path":"ColorPicker (self)","bytes":1998,"percent":9},{"path":"ComponentDefaults","bytes":199,"percent":1}]}},"Combobox":{"filePath":"src/components/Combobox/index.tsx","meta":{"name":"Combobox","description":"Filters a list of options as the user types.","category":"inputs","tags":["combobox","autocomplete","search","select","typeahead","form","multiselect"],"status":"stable"},"usage":{"when":["Lists too long to scan by eye","The user roughly knows the value they want","Autocomplete or typeahead","Multi-select from a searchable list"],"whenNot":["Under five options (use Select or RadioGroup)","Free-form text with no known options (use Input)","Short list nobody needs to search (use Select)","Actions rather than values (use Menu)"],"guidelines":["Placeholder names what is searchable","Set label so the field is announced","helperText for guidance, error for the failure reason","Override the built-in \"No results found\" with Combobox.Empty when you have better wording","Group related options with Combobox.Group in long lists","Filtering keeps wrapper composition, so groups and fragments survive","Keep option text short and searchable","multiple turns selections into removable chips"],"accessibility":["Arrow keys, Enter, and Escape all work","Typing filters the list in place","Correct ARIA combobox roles and attributes","Filtered result counts are announced","Chips can be removed from the keyboard"]},"props":{"multiple":{"type":"boolean","description":"Allow multiple selections with chips","default":"false","required":false},"value":{"type":"union","description":"Controlled selected value (string for single, string[] for multiple)","required":false},"defaultValue":{"type":"union","description":"Default selected value (uncontrolled)","required":false},"onValueChange":{"type":"union","description":"Called when selection changes","required":false},"onChange":{"type":"union","description":"Alias for onValueChange","required":false},"children":{"type":"node","description":"Combobox input and content","required":true},"open":{"type":"boolean","description":"Controlled open state of the dropdown","required":false},"defaultOpen":{"type":"boolean","description":"Initial open state for uncontrolled usage","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when dropdown open state changes","required":false},"required":{"type":"boolean","description":"","required":false},"name":{"type":"string","description":"","required":false},"placeholder":{"type":"string","description":"Placeholder text for the input","required":false},"autoHighlight":{"type":"boolean","description":"Auto-highlight first matching item while filtering","default":"true","required":false},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"className":{"type":"string","description":"Wrapper class name","required":false},"label":{"type":"string","description":"Visible label text above the combobox","required":false},"helperText":{"type":"string","description":"Helper text shown below the combobox","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false},"disabled":{"type":"boolean","description":"Disable the combobox","default":"false","required":false},"autoComplete":{"type":"string","description":"","required":false},"form":{"type":"string","description":"","required":false},"inputRef":{"type":"union","description":"","required":false},"readOnly":{"type":"boolean","description":"","required":false}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select when search/filtering is not needed"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text entry"},{"component":"Listbox","relationship":"sibling","note":"Use Listbox for inline option lists"}],"variants":[{"name":"Default","description":"Type to narrow the list; unmatched queries show a no-results row.","code":"<StatefulCombobox placeholder=\"Select a fruit\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"apple\">Apple</Combobox.Item>\n <Combobox.Item value=\"banana\">Banana</Combobox.Item>\n <Combobox.Item value=\"orange\">Orange</Combobox.Item>\n <Combobox.Item value=\"grape\">Grape</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Multiple Selection","description":"Each pick becomes a removable chip in the field.","code":"<StatefulCombobox multiple placeholder=\"Select fruits...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"apple\">Apple</Combobox.Item>\n <Combobox.Item value=\"banana\">Banana</Combobox.Item>\n <Combobox.Item value=\"orange\">Orange</Combobox.Item>\n <Combobox.Item value=\"grape\">Grape</Combobox.Item>\n <Combobox.Item value=\"mango\">Mango</Combobox.Item>\n <Combobox.Item value=\"kiwi\">Kiwi</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"With Label and Helper Text","description":"Helper text tells the user the field is searchable.","code":"<StatefulCombobox\n label=\"Assignee\"\n placeholder=\"Search assignees...\"\n helperText=\"Type to filter the list of available assignees.\"\n>\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Empty>No matches</Combobox.Empty>\n <Combobox.Item value=\"alice\">Alice Johnson</Combobox.Item>\n <Combobox.Item value=\"bob\">Bob Chen</Combobox.Item>\n <Combobox.Item value=\"carol\">Carol Smith</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Error State","description":"Red border, and the message replaces helper text.","code":"<Combobox\n label=\"Reviewer\"\n placeholder=\"Search reviewers...\"\n error=\"Please select a reviewer\"\n>\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"alice\">Alice</Combobox.Item>\n </Combobox.Content>\n</Combobox>"},{"name":"With Groups","description":"Headed sections stay intact while filtering.","code":"<StatefulCombobox placeholder=\"Search countries...\">\n <Combobox.Input />\n <Combobox.Content>\n <>\n <Combobox.Group>\n <Combobox.GroupLabel>North America</Combobox.GroupLabel>\n <Combobox.Item value=\"us\">United States</Combobox.Item>\n <Combobox.Item value=\"ca\">Canada</Combobox.Item>\n <Combobox.Item value=\"mx\">Mexico</Combobox.Item>\n </Combobox.Group>\n <Combobox.Group>\n <Combobox.GroupLabel>Europe</Combobox.GroupLabel>\n <Combobox.Item value=\"uk\">United Kingdom</Combobox.Item>\n <Combobox.Item value=\"de\">Germany</Combobox.Item>\n <Combobox.Item value=\"fr\">France</Combobox.Item>\n </Combobox.Group>\n <Combobox.Empty>No matching country</Combobox.Empty>\n </>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"With Empty State","description":"Combobox.Empty replaces the default no-results wording.","code":"<StatefulCombobox placeholder=\"Filter languages...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Empty>No language matches that search</Combobox.Empty>\n <Combobox.Item value=\"js\">JavaScript</Combobox.Item>\n <Combobox.Item value=\"ts\">TypeScript</Combobox.Item>\n <Combobox.Item value=\"py\">Python</Combobox.Item>\n <Combobox.Item value=\"rs\">Rust</Combobox.Item>\n <Combobox.Item value=\"go\">Go</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Scrollable List","description":"Caps at four rows and half-shows the fifth as a scroll hint.","code":"<StatefulCombobox placeholder=\"Search languages...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Empty>No results found</Combobox.Empty>\n <Combobox.Item value=\"js\">JavaScript</Combobox.Item>\n <Combobox.Item value=\"ts\">TypeScript</Combobox.Item>\n <Combobox.Item value=\"py\">Python</Combobox.Item>\n <Combobox.Item value=\"rs\">Rust</Combobox.Item>\n <Combobox.Item value=\"go\">Go</Combobox.Item>\n <Combobox.Item value=\"rb\">Ruby</Combobox.Item>\n <Combobox.Item value=\"java\">Java</Combobox.Item>\n <Combobox.Item value=\"swift\">Swift</Combobox.Item>\n <Combobox.Item value=\"kt\">Kotlin</Combobox.Item>\n <Combobox.Item value=\"cpp\">C++</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Custom Max Visible Items","description":"maxVisibleItems raises the cap to six rows.","code":"<StatefulCombobox placeholder=\"Search cities...\">\n <Combobox.Input />\n <Combobox.Content maxVisibleItems={6}>\n <Combobox.Empty>No results found</Combobox.Empty>\n <Combobox.Item value=\"nyc\">New York</Combobox.Item>\n <Combobox.Item value=\"lon\">London</Combobox.Item>\n <Combobox.Item value=\"tok\">Tokyo</Combobox.Item>\n <Combobox.Item value=\"par\">Paris</Combobox.Item>\n <Combobox.Item value=\"syd\">Sydney</Combobox.Item>\n <Combobox.Item value=\"ber\">Berlin</Combobox.Item>\n <Combobox.Item value=\"tor\">Toronto</Combobox.Item>\n <Combobox.Item value=\"sin\">Singapore</Combobox.Item>\n <Combobox.Item value=\"dub\">Dubai</Combobox.Item>\n <Combobox.Item value=\"sao\">São Paulo</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Disabled","description":"Dimmed and unfocusable.","code":"<Combobox disabled placeholder=\"Search...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"1\">Option 1</Combobox.Item>\n </Combobox.Content>\n</Combobox>"},{"name":"Explicit Trigger","description":"showTrigger={false} hands the open control to your own Combobox.Trigger.","code":"<StatefulCombobox placeholder=\"Search assignees...\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n <Combobox.Input showTrigger={false} />\n <Combobox.Trigger aria-label=\"Open assignee list\" />\n </div>\n <Combobox.Content>\n <Combobox.Item value=\"alice\">Alice</Combobox.Item>\n <Combobox.Item value=\"bob\">Bob</Combobox.Item>\n <Combobox.Item value=\"carol\">Carol</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"}],"contract":{"propsSummary":["value: string | string[] - controlled selected value","onValueChange: (value) => void - selection handler","onChange: (value) => void - alias for onValueChange","multiple: boolean - enable multi-select with chips","When multiple=true, value/defaultValue must be string[] (single mode uses string|null)","placeholder: string - input placeholder text","label: string - visible label text","helperText: string - helper text below field","error: boolean | string - error styling and message","disabled: boolean - disable combobox","size: sm|md|lg (default: md)","autoHighlight: boolean - auto-highlight first match","Combobox.Input showTrigger: boolean - hide built-in trigger when using Combobox.Trigger explicitly","maxVisibleItems: number - max visible options before scrolling (default 4)"],"a11yRules":["A11Y_COMBOBOX_KEYBOARD","A11Y_COMBOBOX_LABEL","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Input","Trigger","Content","Item","ItemIndicator","Empty","Group","GroupLabel"],"requiredChildren":["Input","Content"],"commonPatterns":["<Combobox placeholder=\"Search...\"><Combobox.Input /><Combobox.Content><Combobox.Item value=\"opt1\">{label1}</Combobox.Item><Combobox.Item value=\"opt2\">{label2}</Combobox.Item></Combobox.Content></Combobox>","<Combobox multiple placeholder=\"Select items...\"><Combobox.Input /><Combobox.Content><Combobox.Item value=\"opt1\">{label1}</Combobox.Item><Combobox.Item value=\"opt2\">{label2}</Combobox.Item></Combobox.Content></Combobox>","<Combobox placeholder=\"Search...\"><Combobox.Input showTrigger={false} /><Combobox.Trigger aria-label=\"Open\" /><Combobox.Content>...</Combobox.Content></Combobox>"]},"propsSummary":["multiple: boolean (default: false)","value: union","defaultValue: union","onValueChange: union","onChange: union","children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","required: boolean","name: string","placeholder: string","autoHighlight: boolean (default: true)","size: sm|md|lg (default: md)","className: string","label: string","helperText: string","error: union","disabled: boolean"],"sourcePath":"src/components/Combobox/index.tsx","exportName":"Combobox","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.524Z"},"performance":{"bundleSize":4261,"rawSize":11955,"complexity":"lightweight","budgetPercent":28,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Combobox (self)","bytes":7616,"percent":64},{"path":"src/recipes/popup.ts","bytes":2931,"percent":25},{"path":"src/utils/aria.ts","bytes":436,"percent":4},{"path":"ComponentDefaults","bytes":199,"percent":2}]}},"Command":{"filePath":"src/components/Command/index.tsx","meta":{"name":"Command","description":"Filters a list of actions as the user types.","category":"navigation","tags":["command","palette","search","spotlight","quick-actions","cmdk"],"status":"stable"},"usage":{"when":["A keyboard shortcut that jumps anywhere","Action lists too long to scan","Inline lists that need filtering","Search across everything the app can do"],"whenNot":["A handful of actions (use Menu)","Picking a value for a form (use Select or Combobox)","Fixed navigation (use Sidebar or Tabs)"],"guidelines":["Wrap in Dialog for the summon-anywhere palette","Group by category once the list gets long","Always supply Command.Empty","Add keywords so aliases and synonyms match","Label rows with a verb"],"accessibility":["Uses combobox + listbox ARIA pattern","Keyboard navigation with ArrowUp/ArrowDown, Enter to select","Home/End jump to first/last item","aria-activedescendant tracks focused item"]},"props":{"children":{"type":"node","description":"Command.Input, Command.List, and other sub-components","required":true},"search":{"type":"string","description":"Controlled search value","required":false},"defaultSearch":{"type":"string","description":"Default search value (uncontrolled)","default":"","required":false},"onSearchChange":{"type":"function","description":"Called when search input changes","required":false},"filter":{"type":"function","description":"Custom filter function. Return 0 to hide, >0 to show.","required":false},"loop":{"type":"boolean","description":"Whether to loop keyboard navigation","default":"true","required":false}},"relations":[{"component":"Dialog","relationship":"sibling","note":"Compose inside Dialog for modal command palette"},{"component":"Listbox","relationship":"sibling","note":"Command uses Listbox-like keyboard navigation internally"},{"component":"Combobox","relationship":"alternative","note":"Use Combobox for form field selection with search"}],"variants":[{"name":"Default","description":"Search field over a flat list.","code":"<div style={{ maxWidth: '400px', width: '100%' }}>\n <Command>\n <Command.Input placeholder=\"Type a command...\" />\n <Command.List>\n <Command.Item onItemSelect={() => {}}>Open File</Command.Item>\n <Command.Item onItemSelect={() => {}}>Save Document</Command.Item>\n <Command.Item onItemSelect={() => {}}>Print</Command.Item>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n</div>"},{"name":"Dialog Command Palette","description":"The same list summoned over the page.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"secondary\">Open Command Palette</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"sm\">\n <Command>\n <Command.Input placeholder=\"Search commands...\" />\n <Command.List>\n <Command.Group heading=\"Actions\">\n <Command.Item onItemSelect={() => {}}>New File</Command.Item>\n <Command.Item onItemSelect={() => {}}>Open Recent</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Settings\">\n <Command.Item onItemSelect={() => {}}>Preferences</Command.Item>\n <Command.Item onItemSelect={() => {}}>Keyboard Shortcuts</Command.Item>\n </Command.Group>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n </Dialog.Content>\n</Dialog>"},{"name":"With Groups","description":"Category labels survive filtering.","code":"<div style={{ maxWidth: '400px', width: '100%' }}>\n <Command>\n <Command.Input placeholder=\"Search...\" />\n <Command.List>\n <Command.Group heading=\"Suggestions\">\n <Command.Item onItemSelect={() => {}}>Calendar</Command.Item>\n <Command.Item onItemSelect={() => {}}>Calculator</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Settings\">\n <Command.Item onItemSelect={() => {}}>Profile</Command.Item>\n <Command.Item onItemSelect={() => {}}>Billing</Command.Item>\n <Command.Item disabled onItemSelect={() => {}}>\n Team (coming soon)\n </Command.Item>\n </Command.Group>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n</div>"},{"name":"With Icons","description":"Leading glyphs speed up scanning.","code":"<div style={{ maxWidth: '400px', width: '100%' }}>\n <Command>\n <Command.Input placeholder=\"What do you need?\" />\n <Command.List>\n <Command.Item onItemSelect={() => {}}>\n <span style={{ marginRight: '0.5rem', fontSize: '1rem' }}>+</span> New Document\n </Command.Item>\n <Command.Item onItemSelect={() => {}}>\n <span style={{ marginRight: '0.5rem', fontSize: '1rem' }}>{'>'}</span> Open Folder\n </Command.Item>\n <Command.Item onItemSelect={() => {}}>\n <span style={{ marginRight: '0.5rem', fontSize: '1rem' }}>?</span> Search\n </Command.Item>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n</div>"}],"contract":{"propsSummary":["search: string - controlled search value","onSearchChange: (search) => void - search change handler","filter: (value, search, keywords?) => number - custom filter","loop: boolean - loop keyboard navigation (default: true)","Command.Item value: string - filter match value","Command.Item keywords: string[] - extra filter terms","Command.Item onItemSelect: (value, event) => void - selection handler"],"a11yRules":["A11Y_COMBOBOX_ROLE","A11Y_LISTBOX_ROLE","A11Y_ACTIVE_DESCENDANT"]},"ai":{"compositionPattern":"compound","subComponents":["Input","List","Item","Group","Empty","Separator"],"requiredChildren":["Input","List"],"commonPatterns":["<Dialog><Dialog.Trigger><Button>Open Palette</Button></Dialog.Trigger><Dialog.Content size=\"sm\"><Command><Command.Input placeholder=\"Search...\" /><Command.List><Command.Group heading=\"Actions\"><Command.Item onItemSelect={() => {}}>Action 1</Command.Item></Command.Group><Command.Empty>No results.</Command.Empty></Command.List></Command></Dialog.Content></Dialog>"]},"propsSummary":["children: node (required)","search: string","defaultSearch: string (default: )","onSearchChange: function","filter: function","loop: boolean (default: true)"],"sourcePath":"src/components/Command/index.tsx","exportName":"Command","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.723Z"},"performance":{"bundleSize":2632,"rawSize":6103,"complexity":"lightweight","budgetPercent":17,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Command (self)","bytes":5385,"percent":88}]}},"ConversationList":{"filePath":"src/components/ConversationList/index.tsx","meta":{"name":"ConversationList","description":"Stacks chat messages in a scroller that follows new arrivals.","category":"ai","tags":["conversation","chat","messages","scroll","ai","list"],"status":"stable"},"usage":{"when":["Chat interfaces holding many messages","Transcripts that should follow new arrivals","Paging back through older message history","Runs of messages grouped day by day"],"whenNot":["Plain item lists with no chat context (use List)","A single message (use Message directly)","Layouts that never scroll"],"guidelines":["autoScroll=\"smart\" follows only when the reader is already near the bottom","showAvatars={false} drops the avatar gutter and the inset that goes with it","Chrome stays on neutral surfaces; reserve accent for actions and semantic state","Implement onScrollTop to page in older messages","Your onScroll handler composes with the internal auto-scroll and history logic","Give new conversations an emptyState","Put a DateSeparator between messages from different days"],"accessibility":["Uses proper ARIA roles for separators","Typing indicator uses a status role with an aria-label","Smooth scroll respects reduced motion preferences","Keyboard navigation works within scrollable container"]},"props":{"children":{"type":"node","description":"Message components","required":true},"showAvatars":{"type":"boolean","description":"Show avatars for messages and typing indicators in this conversation","default":"true","required":false},"autoScroll":{"type":"union","description":"Auto-scroll behavior: true (always), false (never), or \"smart\" (only when near bottom)","default":"smart","required":false},"onScrollTop":{"type":"function","description":"Callback when user scrolls to top (for loading history). Receives the scroll event.","required":false},"loadingHistory":{"type":"boolean","description":"Show loading spinner at top when loading history","default":"false","required":false},"emptyState":{"type":"node","description":"Content to show when conversation is empty","required":false},"scrollTopThreshold":{"type":"number","description":"Pixels from top to trigger onScrollTop","default":"50","required":false},"scrollBottomThreshold":{"type":"number","description":"Pixels from bottom for smart auto-scroll","default":"100","required":false}},"relations":[{"component":"Message","relationship":"child","note":"ConversationList contains Message components"},{"component":"ThinkingIndicator","relationship":"child","note":"Show ThinkingIndicator at bottom while awaiting response"},{"component":"Prompt","relationship":"sibling","note":"Typically paired with Prompt for input"}],"variants":[{"name":"Basic","description":"Three turns stacked in reading order.","code":"<ConversationList>\n <Message role=\"user\">\n <Message.Content>Hello!</Message.Content>\n </Message>\n <Message role=\"assistant\">\n <Message.Content>Hi there! How can I help you today?</Message.Content>\n </Message>\n <Message role=\"user\">\n <Message.Content>Can you explain React hooks?</Message.Content>\n </Message>\n</ConversationList>"},{"name":"With Date Separators","description":"A labelled rule marks where one day ends.","code":"<ConversationList>\n <ConversationList.DateSeparator date={new Date(Date.now() - 86400000)} />\n <Message role=\"user\">\n <Message.Content>A message from yesterday</Message.Content>\n </Message>\n <ConversationList.DateSeparator date={new Date()} />\n <Message role=\"assistant\">\n <Message.Content>And a message from today!</Message.Content>\n </Message>\n</ConversationList>"},{"name":"Without Avatars","description":"Turns sit flush when nothing needs an avatar gutter.","code":"<ConversationList showAvatars={false}>\n <Message role=\"user\">\n <Message.Content>Hello!</Message.Content>\n </Message>\n <Message role=\"assistant\">\n <Message.Content>How can I help?</Message.Content>\n </Message>\n</ConversationList>"},{"name":"With Typing Indicator","description":"Animated dots hold the reply's place before it lands.","code":"<ConversationList>\n <Message role=\"user\">\n <Message.Content>What is TypeScript?</Message.Content>\n </Message>\n <ConversationList.TypingIndicator name=\"Assistant\" />\n</ConversationList>"},{"name":"Loading History","description":"A spinner pins to the top while older turns load.","code":"<ConversationList loadingHistory>\n <Message role=\"user\">\n <Message.Content>This is the latest message</Message.Content>\n </Message>\n</ConversationList>"},{"name":"Empty","description":"A fresh conversation shows its placeholder instead of blank space.","code":"<ConversationList\n emptyState={\n <EmptyState>\n <EmptyState.Title>No messages yet</EmptyState.Title>\n <EmptyState.Description>\n Ask a question to get started.\n </EmptyState.Description>\n </EmptyState>\n }\n/>"}],"contract":{"propsSummary":["children: ReactNode - Message components","showAvatars: boolean - show message and typing-indicator avatars (default: true)","autoScroll: boolean | \"smart\" - scroll behavior (default: \"smart\")","onScrollTop: (event?) => void - callback for loading history (receives scroll event)","loadingHistory: boolean - show history loading spinner","emptyState: ReactNode - empty conversation content"],"a11yRules":["A11Y_ARIA_ROLES","A11Y_MOTION_PREFERENCE"]},"propsSummary":["children: node (required)","showAvatars: boolean (default: true)","autoScroll: union (default: smart)","onScrollTop: function","loadingHistory: boolean (default: false)","emptyState: node","scrollTopThreshold: number (default: 50)","scrollBottomThreshold: number (default: 100)"],"sourcePath":"src/components/ConversationList/index.tsx","exportName":"ConversationList","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.889Z"},"ai":{"subComponents":["DateSeparator","TypingIndicator"],"compositionPattern":"compound"},"performance":{"bundleSize":2123,"rawSize":5495,"complexity":"lightweight","budgetPercent":14,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"ConversationList (self)","bytes":2734,"percent":50},{"path":"Loading","bytes":2035,"percent":37}]}},"DataTable":{"filePath":"src/components/DataTable/DataTable.fragment.tsx","meta":{"name":"DataTable","description":"Interactive table — sort, select, expand, and click through rows of data.","category":"display","status":"stable","tags":["table","data","grid","list","sorting","tanstack"],"dependencies":[{"name":"@tanstack/react-table","version":">=8.0.0","reason":"Optional — powers sorting, selection, and expansion; without it DataTable renders a static, non-interactive table."}]},"guidance":{"when":["Rows need sorting, selection, or expansion","Users scan and compare several attributes per row","A row click opens the record behind it"],"whenNot":["The data is read-only and static (use Table)","Each item is a single line (use List)","Narrow screens where a card list reads better"],"dont":[{"reason":"Do not use DataTable for a simple static comparison.","bad":"<DataTable />","good":"<Table aria-label=\"Plan comparison\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Starter</Table.Cell>\n <Table.Cell>$0</Table.Cell>\n </Table.Row>\n </Table.Body>\n </Table>"}],"guidelines":["Cap visible columns near 5–7; push the rest behind a row click","Right-align numbers, left-align text","Always set emptyMessage — a bare grid reads as broken","Clickable rows need getRowProps for a role and an accessible name","Reach for density, not the deprecated size prop"],"accessibility":["Headers stay real th elements with scope","Sortable headers are buttons — reachable by keyboard","Selection checkboxes carry their own labels","Expand toggles report aria-expanded"]},"usage":{"when":["Rows need sorting, selection, or expansion","Users scan and compare several attributes per row","A row click opens the record behind it"],"whenNot":["The data is read-only and static (use Table)","Each item is a single line (use List)","Narrow screens where a card list reads better"],"dont":[{"reason":"Do not use DataTable for a simple static comparison.","bad":"<DataTable />","good":"<Table aria-label=\"Plan comparison\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Starter</Table.Cell>\n <Table.Cell>$0</Table.Cell>\n </Table.Row>\n </Table.Body>\n </Table>"}],"guidelines":["Cap visible columns near 5–7; push the rest behind a row click","Right-align numbers, left-align text","Always set emptyMessage — a bare grid reads as broken","Clickable rows need getRowProps for a role and an accessible name","Reach for density, not the deprecated size prop"],"accessibility":["Headers stay real th elements with scope","Sortable headers are buttons — reachable by keyboard","Selection checkboxes carry their own labels","Expand toggles report aria-expanded"]},"props":{"bordered":{"type":"boolean","description":"Wrap table in a bordered container","required":false},"caption":{"type":"string","description":"Visible caption for the table (recommended for accessibility)","required":false},"captionHidden":{"type":"boolean","description":"Hide the caption visually but keep it for screen readers","required":false},"columns":{"type":"array","description":"Column definitions","required":true},"data":{"type":"array","description":"Data array","required":true},"density":{"type":"enum","description":"Canonical row density. `condensed` is a deprecated alias for `compact`.","required":false,"values":["compact","regular","relaxed","condensed"]},"emptyMessage":{"type":"string","description":"Empty state message (plain text). Ignored if `emptyState` is set.","required":false},"emptyState":{"type":"node","description":"Rich empty-state slot (icon + copy + CTA) rendered when there's no data.","required":false},"expanded":{"type":"union","description":"Controlled expanded state","required":false},"getRowId":{"type":"function","description":"Unique key extractor for each row","required":false},"getRowProps":{"type":"function","description":"Props applied to each rendered data row. Use this for row-level ARIA labels, roles, and data attributes.","required":false},"getSubRows":{"type":"function","description":"Extract sub-rows from a row for expandable tree tables","required":false},"hideHeader":{"type":"boolean","description":"Hide the column header row (e.g. stacked per-group tables share one).","required":false},"loading":{"type":"boolean","description":"When true, render skeleton placeholder rows instead of data.","required":false},"onExpandedChange":{"type":"function","description":"Expanded state change handler","required":false},"onRowClick":{"type":"function","description":"Row click handler","required":false},"onRowSelectionChange":{"type":"function","description":"Selection change handler","required":false},"onSortingChange":{"type":"function","description":"Sorting change handler","required":false},"rowSelection":{"type":"object","description":"Controlled selection state","required":false},"selectable":{"type":"boolean","description":"Enable row selection","required":false},"showCheckbox":{"type":"boolean","description":"Show checkbox column for row selection","required":false},"size":{"type":"enum","description":"","required":false,"values":["sm","md"]},"skeletonRows":{"type":"number","description":"Number of skeleton rows to show while loading (default 6).","required":false},"sortable":{"type":"boolean","description":"Enable sorting","required":false},"sorting":{"type":"array","description":"Controlled sorting state","required":false},"striped":{"type":"boolean","description":"Show alternating row backgrounds","required":false},"wrapperClassName":{"type":"string","description":"Additional class name for the outer wrapper div","required":false},"wrapperProps":{"type":"object","description":"Props forwarded to the outer wrapper div","required":false}},"relations":[{"component":"Table","relationship":"alternative","note":"Use Table for simple semantic HTML tables"},{"component":"EmptyState","relationship":"sibling","note":"Use EmptyState for empty table states"},{"component":"Badge","relationship":"sibling","note":"Use Badge for status columns"},{"component":"Menu","relationship":"sibling","note":"Use Menu for filter dropdowns"},{"component":"Checkbox","relationship":"sibling","note":"Built-in checkbox selection via showCheckbox"}],"variants":[{"name":"Default","description":"Columns and data are the only required props; everything else is opt-in.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[\n { name: \"Ada Lovelace\", status: \"Active\" },\n { name: \"Grace Hopper\", status: \"Pending\" },\n ]}\n aria-label=\"Team members\"\n />","canonical":true},{"name":"Loading","description":"Skeleton rows hold the table's height so the page never jumps.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[]}\n loading\n skeletonRows={3}\n aria-label=\"Loading team members\"\n />"},{"name":"Rich Cells","description":"A cell renderer drops any component — avatar, badge — straight into the column.","code":"<DataTable\n columns={[\n {\n accessorKey: \"name\",\n header: \"Name\",\n cell: ({ row }) => (\n <Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <Avatar name={row.original.name} size=\"sm\" />\n <span>{row.original.name}</span>\n </Stack>\n ),\n },\n { accessorKey: \"role\", header: \"Role\" },\n {\n accessorKey: \"status\",\n header: \"Status\",\n cell: ({ row }) => (\n <Badge variant={row.original.status === \"Active\" ? \"success\" : \"warning\"}>\n {row.original.status}\n </Badge>\n ),\n },\n ]}\n data={[\n { name: \"Ada Lovelace\", role: \"Engineer\", status: \"Active\" },\n { name: \"Grace Hopper\", role: \"Admiral\", status: \"Pending\" },\n ]}\n bordered\n aria-label=\"Team members\"\n />"},{"name":"Sortable","description":"Click a header to sort; click it again to reverse.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"amount\", header: \"Amount\" },\n ]}\n data={[\n { name: \"Subscription\", amount: \"$24.00\" },\n { name: \"Usage\", amount: \"$12.00\" },\n ]}\n sortable\n bordered\n caption=\"Recent transactions\"\n captionHidden\n aria-label=\"Transactions\"\n />"},{"name":"Checkbox Selection","description":"The header checkbox toggles every row at once.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[\n { id: \"ada\", name: \"Ada Lovelace\", status: \"Active\" },\n { id: \"grace\", name: \"Grace Hopper\", status: \"Pending\" },\n ]}\n getRowId={(row) => row.id}\n selectable\n showCheckbox\n bordered\n aria-label=\"Team members\"\n />"},{"name":"Expandable Rows","description":"Children fold away under their parent, like a file tree.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"type\", header: \"Type\" },\n ]}\n data={[\n {\n id: \"src\",\n name: \"src\",\n type: \"folder\",\n subRows: [{ id: \"components\", name: \"components\", type: \"folder\", subRows: [] }],\n },\n { id: \"package\", name: \"package.json\", type: \"file\", subRows: [] },\n ]}\n getRowId={(row) => row.id}\n getSubRows={(row) => row.subRows}\n bordered\n density=\"compact\"\n aria-label=\"File tree\"\n />"},{"name":"With Filters","description":"Filter controls sit outside the table; you own the filtering.","code":"<Stack gap=\"sm\">\n <Input aria-label=\"Search users\" placeholder=\"Search...\" withFieldWrapper={false} />\n <DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[{ name: \"Ada Lovelace\", status: \"Active\" }]}\n sortable\n bordered\n emptyMessage=\"No users match the current filters\"\n aria-label=\"Filtered team members\"\n />\n </Stack>"},{"name":"Clickable Rows","description":"Mouse or keyboard opens the row; getRowProps supplies its name.","code":"<DataTable\n columns={[\n { accessorKey: \"method\", header: \"Method\" },\n { accessorKey: \"path\", header: \"Path\" },\n ]}\n data={[{ method: \"GET\", path: \"/v1/components\" }]}\n getRowProps={(row) => ({\n role: \"button\",\n \"aria-label\": `Open ${row.method} ${row.path}`,\n })}\n onRowClick={() => undefined}\n density=\"compact\"\n aria-label=\"API endpoints\"\n />"},{"name":"Striped","description":"Row tint alternates so tightly packed rows stay readable.","code":"<DataTable\n columns={[\n { accessorKey: \"method\", header: \"Method\" },\n { accessorKey: \"path\", header: \"Path\" },\n ]}\n data={[\n { method: \"GET\", path: \"/v1/components\" },\n { method: \"POST\", path: \"/v1/fragments\" },\n ]}\n striped\n density=\"compact\"\n sortable\n aria-label=\"API endpoints\"\n />"},{"name":"Empty State","description":"emptyMessage replaces the rows and keeps the headers in place.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[]}\n emptyMessage=\"No users match your search criteria\"\n aria-label=\"Search results\"\n />"},{"name":"Long Cell Content","description":"Oversized values scroll inside the table instead of stretching the page.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Administrator\" },\n { accessorKey: \"status\", header: \"Recovery policy\" },\n ]}\n data={[\n {\n name: \"A very long localized administrator identity that remains distinguishable\",\n status:\n \"Pending confirmation of the detailed workspace recovery policy and notification workflow\",\n },\n ]}\n bordered\n aria-label=\"Long localized team member data\"\n />"}],"ai":{"compositionPattern":"simple","subComponents":["Root","Columns","preload"],"commonPatterns":["<DataTable columns={createColumns([{key:\"name\",header:\"Name\"},{key:\"status\",header:\"Status\"}])} data={[{name:\"Item 1\",status:\"Active\"}]} />"]},"contract":{"propsSummary":["columns: ColumnDef[] - column definitions","data: T[] - row data array","sortable: boolean - enable sorting","selectable: boolean - enable row selection","showCheckbox: boolean - add checkbox column","getSubRows: (row) => T[] - enable expandable rows","onRowClick: (row, event) => void - row activation handler with event access","getRowProps: (row) => HTMLAttributes<HTMLTableRowElement> - row-level ARIA, role, data, class, and event props","density: compact|regular|relaxed - row density (size is deprecated)","striped: boolean - alternating row backgrounds","bordered: boolean - bordered container","wrapperClassName / wrapperProps - style and configure the outer wrapper div"],"a11yRules":["A11Y_TABLE_HEADERS","A11Y_TABLE_SORT"]},"matrix":{"axes":{"size":"auto","theme":["light","dark"]},"forced":["loading","empty","focus"],"worstCase":{"data":"Long localized cell values and enough rows to require horizontal and vertical overflow handling"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/DataTable/index.tsx","exportName":"DataTable","performance":{"bundleSize":6098,"rawSize":17916,"complexity":"moderate","budgetPercent":40,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"DataTable (self)","bytes":11347,"percent":63},{"path":"src/recipes/table-chrome.ts","bytes":3086,"percent":17},{"path":"Checkbox","bytes":2854,"percent":16}]}},"DatePicker":{"filePath":"src/components/DatePicker/index.tsx","meta":{"name":"DatePicker","description":"Selects a date or date range from a calendar.","category":"inputs","tags":["date","picker","calendar","range","form","input"],"status":"stable","dependencies":[{"name":"react-day-picker","version":">=9.0.0","reason":"Optional — renders the calendar popup; the trigger and form field work without it."}]},"usage":{"when":["A date the user picks off a calendar","A start and end date together","Filtering by date"],"whenNot":["Time on its own (use a dedicated TimePicker)","A handful of known dates (use Select)","Typed date entry (use Input with a date mask)"],"guidelines":["Pair range mode with numberOfMonths={2} so both ends are visible","size=\"sm\" lines the trigger up with other dense toolbar controls","Offer presets for the common ranges: Today, Last 7 days, Last 30 days","disabledDates blocks past or unavailable days before the user tries","Placeholder names the date, not the action","DatePicker.Trigger defaults to type=\"button\", so it is safe inside a form"],"accessibility":["The calendar grid is fully keyboard navigable","Arrow keys move between days","Escape closes the calendar","Focus returns to the trigger on close"]},"props":{"children":{"type":"node","description":"DatePicker trigger and content","required":true},"className":{"type":"string","description":"Wrapper class name","required":false},"mode":{"type":"enum","description":"Selection mode","default":"single","required":false,"values":["single","range"]},"selected":{"type":"object","description":"Controlled date (single mode). Type: Date | null","required":false},"selectedRange":{"type":"object","description":"Controlled range (range mode). Type: DateRange | null","required":false},"onSelect":{"type":"function","description":"Called when a single date is selected","required":false},"onChange":{"type":"function","description":"Alias for onSelect (consistent with Input/Select onChange convention)","required":false},"onRangeSelect":{"type":"function","description":"Called when a date range is selected","required":false},"numberOfMonths":{"type":"number","description":"Number of months displayed side-by-side","default":"1","required":false},"disabled":{"type":"boolean","description":"Disable the picker","default":"false","required":false},"size":{"type":"enum","description":"Trigger size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"disabledDates":{"type":"union","description":"Dates to disable (react-day-picker Matcher | Matcher[])","required":false},"placeholder":{"type":"string","description":"Trigger placeholder text","required":false},"locale":{"type":"object","description":"date-fns locale for i18n","required":false},"fixedWeeks":{"type":"boolean","description":"Always show 6 rows","default":"false","required":false},"formatDate":{"type":"function","description":"Custom trigger date formatter","required":false},"formatRange":{"type":"function","description":"Custom trigger range formatter","required":false},"open":{"type":"boolean","description":"Controlled popover open state","required":false},"onOpenChange":{"type":"function","description":"Popover open state change callback","required":false},"name":{"type":"string","description":"Hidden input name for forms","required":false},"label":{"type":"string","description":"Visible label text above the date picker","required":false},"helperText":{"type":"string","description":"Helper text shown below the date picker","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for choosing from a list of options"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text date entry"},{"component":"Popover","relationship":"composition","note":"DatePicker uses Popover for the calendar dropdown"}],"variants":[{"name":"Default","description":"Trigger opens one month; today is outlined.","code":"<StatefulDatePicker placeholder=\"Pick a date\">\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Small Trigger","description":"Matches the height of other sm toolbar controls.","code":"<StatefulDatePicker size=\"sm\" placeholder=\"Last scanned\">\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Date Range","description":"Two months side by side so both ends of the range are visible.","code":"<StatefulRangePicker placeholder=\"Select date range\" numberOfMonths={2}>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulRangePicker>"},{"name":"Multi-Month","description":"Three months at once, for dates far from today.","code":"<StatefulDatePicker placeholder=\"Pick a date\" numberOfMonths={3}>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Disabled Dates","description":"Everything before today is greyed out and unclickable.","code":"<StatefulDatePicker\n placeholder=\"Select a future date\"\n disabledDates={{ before: new Date() }}\n>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"With Presets","description":"Shortcut buttons beside the calendar skip the common ranges.","code":"<StatefulRangePicker placeholder=\"Select date range\" numberOfMonths={2}>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <div style={{ display: 'flex', gap: '1rem' }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', minWidth: '8rem' }}>\n <DatePicker.Preset range={{ from: today, to: today }}>Today</DatePicker.Preset>\n <DatePicker.Preset range={{ from: subDays(today, 7), to: today }}>Last 7 days</DatePicker.Preset>\n <DatePicker.Preset range={{ from: subDays(today, 30), to: today }}>Last 30 days</DatePicker.Preset>\n <DatePicker.Preset range={{ from: subDays(today, 90), to: today }}>Last 90 days</DatePicker.Preset>\n </div>\n <DatePicker.Calendar />\n </div>\n </DatePicker.Content>\n</StatefulRangePicker>"},{"name":"With Label and Helper Text","description":"Label above the trigger, supporting text below it.","code":"<StatefulDatePicker\n label=\"Renewal date\"\n placeholder=\"Pick a date\"\n helperText=\"Billing restarts on this day each month.\"\n>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Error State","description":"Red border on the trigger, and the reason below it.","code":"<DatePicker\n label=\"Start Date\"\n placeholder=\"Pick a date\"\n error=\"Please select a start date\"\n>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</DatePicker>"},{"name":"Disabled","description":"Dimmed; the calendar will not open.","code":"<StatefulDatePicker placeholder=\"Pick a date\" disabled>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"}],"contract":{"propsSummary":["mode: \"single\" | \"range\" - selection mode","selected: Date - controlled date (single)","selectedRange: DateRange - controlled range","onSelect: (date) => void - single selection handler","onRangeSelect: (range) => void - range selection handler","numberOfMonths: number - months visible (default 1)","size: \"sm\" | \"md\" | \"lg\" - trigger size variant (default md)","label: string - visible label text","helperText: string - helper text below field","error: boolean | string - error styling and message","disabled: boolean - disable picker","disabledDates: Matcher - dates to disable","DatePicker.Trigger: button props supported (type defaults to \"button\")"],"a11yRules":["A11Y_DATEPICKER_KEYBOARD","A11Y_DATEPICKER_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Calendar","Preset","preload"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<DatePicker size=\"sm\" selected={date} onSelect={setDate}><DatePicker.Trigger placeholder=\"Pick a date\" /><DatePicker.Content><DatePicker.Calendar /></DatePicker.Content></DatePicker>","<DatePicker selected={date} onSelect={setDate}><DatePicker.Trigger placeholder=\"Pick a date\" /><DatePicker.Content><DatePicker.Calendar /></DatePicker.Content></DatePicker>"]},"propsSummary":["children: node (required)","className: string","mode: single|range (default: single)","selected: object","selectedRange: object","onSelect: function","onChange: function","onRangeSelect: function","numberOfMonths: number (default: 1)","disabled: boolean (default: false)","size: sm|md|lg (default: md)","disabledDates: union","placeholder: string","locale: object","fixedWeeks: boolean (default: false)","formatDate: function","formatRange: function","open: boolean","onOpenChange: function","name: string","label: string","helperText: string","error: union"],"sourcePath":"src/components/DatePicker/index.tsx","exportName":"DatePicker","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:54.712Z"},"performance":{"bundleSize":4099,"rawSize":11008,"complexity":"lightweight","budgetPercent":27,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"DatePicker (self)","bytes":6899,"percent":63},{"path":"src/recipes/popup.ts","bytes":2832,"percent":26},{"path":"src/utils/aria.ts","bytes":351,"percent":3},{"path":"ComponentDefaults","bytes":199,"percent":2}]}},"Dialog":{"filePath":"src/components/Dialog/Dialog.fragment.tsx","meta":{"name":"Dialog","description":"Blocks the page with one focused task the user must finish or dismiss.","category":"overlays","status":"stable","tags":["modal","dialog","overlay","popup","confirmation"]},"guidance":{"when":["Confirming something irreversible","Collecting input the user must finish in one pass","Content that needs acknowledgment before continuing","Isolating a step in a longer workflow"],"whenNot":["A short hint (use Tooltip)","A list of actions (use Menu)","Contextual content that should not block (use Popover)","Feedback the user does not act on (use Toast or Alert)"],"dont":[{"reason":"Do not use a Dialog for a non-blocking notification.","bad":"<Dialog>Saved</Dialog>","good":"<Alert severity=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Changes saved</Alert.Title>\n <Alert.Content>Your settings are up to date.</Alert.Content>\n </Alert.Body>\n </Alert>"},{"reason":"Do not omit an accessible title and explicit close action from a Dialog.","bad":"<Dialog><Dialog.Content>Focused task</Dialog.Content></Dialog>","good":"<Dialog defaultOpen>\n <Dialog.Content>\n <Dialog.Title>Account settings</Dialog.Title>\n <Dialog.Body>Update your workspace preferences.</Dialog.Body>\n <Dialog.Close>Close</Dialog.Close>\n </Dialog.Content>\n </Dialog>"}],"guidelines":["One task per dialog","Title states the task; body states the consequence","Pair the primary action with an explicit cancel","Leave backdrop and Escape dismissal on unless the choice is destructive","Wrap the trigger with asChild around a real control — the bare trigger ships unstyled"],"accessibility":["Traps focus while open","Escape closes","Focus returns to the trigger on close","role=\"dialog\" with title and description wired to aria attributes"]},"usage":{"when":["Confirming something irreversible","Collecting input the user must finish in one pass","Content that needs acknowledgment before continuing","Isolating a step in a longer workflow"],"whenNot":["A short hint (use Tooltip)","A list of actions (use Menu)","Contextual content that should not block (use Popover)","Feedback the user does not act on (use Toast or Alert)"],"dont":[{"reason":"Do not use a Dialog for a non-blocking notification.","bad":"<Dialog>Saved</Dialog>","good":"<Alert severity=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Changes saved</Alert.Title>\n <Alert.Content>Your settings are up to date.</Alert.Content>\n </Alert.Body>\n </Alert>"},{"reason":"Do not omit an accessible title and explicit close action from a Dialog.","bad":"<Dialog><Dialog.Content>Focused task</Dialog.Content></Dialog>","good":"<Dialog defaultOpen>\n <Dialog.Content>\n <Dialog.Title>Account settings</Dialog.Title>\n <Dialog.Body>Update your workspace preferences.</Dialog.Body>\n <Dialog.Close>Close</Dialog.Close>\n </Dialog.Content>\n </Dialog>"}],"guidelines":["One task per dialog","Title states the task; body states the consequence","Pair the primary action with an explicit cancel","Leave backdrop and Escape dismissal on unless the choice is destructive","Wrap the trigger with asChild around a real control — the bare trigger ships unstyled"],"accessibility":["Traps focus while open","Escape closes","Focus returns to the trigger on close","role=\"dialog\" with title and description wired to aria attributes"]},"props":{"children":{"type":"node","description":"","required":true},"defaultOpen":{"type":"boolean","description":"Default open state","required":false},"modal":{"type":"boolean","description":"Whether the dialog blocks interaction with the rest of the page.","default":"true","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for non-modal contextual content"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Alert","relationship":"sibling","note":"Use Alert for inline notifications"}],"variants":[{"name":"Default","description":"Header, body, and footer in the standard layout.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Dialog title</Dialog.Title>\n <Dialog.Description>Focused supporting content.</Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>Dialog body</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>","canonical":true},{"name":"Confirmation","description":"Names the consequence before an irreversible action.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"danger\">Delete item</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Delete item?</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>This action cannot be undone.</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Dialog.Close>\n <Dialog.Close asChild>\n <Button variant=\"danger\">Delete</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Large","description":"Wider surface for denser content.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open large dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"lg\">\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Detailed settings</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>Complex content</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"No Initial Focus","description":"Skips autofocus when you place focus yourself.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"secondary\">Open settings</Button>\n </Dialog.Trigger>\n <Dialog.Content initialFocus={false}>\n <Dialog.Header>\n <Dialog.Title>Settings</Dialog.Title>\n <Dialog.Description>Choose a settings area to edit.</Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>Settings content</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Long Title","description":"A wrapping title keeps the close control reachable.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open long title dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>\n Confirm the localized account recovery policy for every workspace administrator\n </Dialog.Title>\n <Dialog.Description>\n The title wraps while the close affordance and recovery action remain reachable.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"secondary\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","Header","Title","Description","Body","Footer"],"requiredChildren":["Content"],"commonPatterns":["<Dialog><Dialog.Trigger asChild><Button>Open</Button></Dialog.Trigger><Dialog.Content><Dialog.Header><Dialog.Title>{title}</Dialog.Title></Dialog.Header><Dialog.Body>{content}</Dialog.Body><Dialog.Footer><Dialog.Close asChild><Button variant=\"secondary\">Cancel</Button></Dialog.Close><Button>Confirm</Button></Dialog.Footer></Dialog.Content></Dialog>","<Dialog><Dialog.Trigger asChild><Button variant=\"secondary\">Open settings</Button></Dialog.Trigger><Dialog.Content initialFocus={false}>...</Dialog.Content></Dialog>"]},"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - open state handler","modal: boolean - blocks page interaction (default: true)","Dialog.Content initialFocus?: boolean - control auto-focus on open (default: true)","Dialog.Content size: sm|md|lg|xl|full - dialog width"],"a11yRules":["A11Y_DIALOG_FOCUS","A11Y_DIALOG_ESCAPE","A11Y_DIALOG_LABEL"]},"matrix":{"axes":{"size":"auto","modal":["true","false"],"theme":["light","dark"]},"forced":["open","focus","reduced-motion"],"worstCase":{"title":"A long localized dialog title that wraps while the close affordance remains reachable"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Dialog/index.tsx","exportName":"Dialog","performance":{"bundleSize":1127,"rawSize":3004,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Dialog (self)","bytes":2253,"percent":75}]}},"Drawer":{"filePath":"src/components/Drawer/index.tsx","meta":{"name":"Drawer","description":"Slides a panel in from a screen edge and dims the page behind it.","category":"overlays","tags":["drawer","sheet","panel","sidebar","slide-over"],"status":"stable"},"usage":{"when":["Editing or creating alongside the page behind it","Touch-reachable action sheets","Navigation that slides in and back out","Detail views that overlay rather than replace"],"whenNot":["A centred task (use Dialog)","Navigation that stays on screen (use Sidebar)","A short list of actions (use Menu or Popover)","Feedback the user does not act on (use Toast)"],"guidelines":["Right for editing, left for navigation, bottom for touch","Always give the user a visible way out","One task per drawer","asChild on Trigger and Close needs a single element child","Set initialFocus={false} when you place focus yourself"],"accessibility":["Automatically traps focus within the drawer","Closes on Escape key press","Returns focus to trigger element on close","Uses role=\"dialog\" with proper aria attributes"]},"props":{"children":{"type":"node","description":"Drawer content (use Drawer.Content, Drawer.Header, etc.)","required":true},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"modal":{"type":"union","description":"Whether to render as modal (blocks interaction with rest of page)","default":"true","required":false},"disablePointerDismissal":{"type":"boolean","description":"Disable outside-click dismissal","required":false},"onOpenChangeComplete":{"type":"function","description":"Called after open/close animation completes","required":false},"snapPoints":{"type":"array","description":"Preset snap-point heights for bottom-sheet drawers","required":false},"swipeDirection":{"type":"enum","description":"Swipe direction to dismiss.","default":"derived from `side` prop on Content","required":false,"values":["up","down","left","right"]}},"relations":[{"component":"Dialog","relationship":"sibling","note":"Use Dialog for centered modal overlays"},{"component":"Sidebar","relationship":"alternative","note":"Use Sidebar for permanent side navigation"},{"component":"Popover","relationship":"alternative","note":"Use Popover for small contextual content"}],"variants":[{"name":"Default","description":"Enters from the right, the default for editing and forms.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button>Open Drawer</Button>\n </Drawer.Trigger>\n <Drawer.Content>\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Drawer Title</Drawer.Title>\n <Drawer.Description>\n A panel sliding in from the right.\n </Drawer.Description>\n </Drawer.Header>\n <Drawer.Body>\n <p>Drawer content goes here.</p>\n </Drawer.Body>\n <Drawer.Footer>\n <Drawer.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Drawer.Close>\n <Button variant=\"primary\">Save</Button>\n </Drawer.Footer>\n </Drawer.Content>\n</Drawer>"},{"name":"Left Side","description":"Enters from the left, where navigation belongs.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button variant=\"secondary\">Open Left</Button>\n </Drawer.Trigger>\n <Drawer.Content side=\"left\">\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Navigation</Drawer.Title>\n </Drawer.Header>\n <Drawer.Body>\n <p>Left-side drawer for navigation or filters.</p>\n </Drawer.Body>\n </Drawer.Content>\n</Drawer>"},{"name":"Bottom Sheet","description":"Rises from the bottom for touch-reachable actions.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button variant=\"secondary\">Open Bottom Sheet</Button>\n </Drawer.Trigger>\n <Drawer.Content side=\"bottom\" size=\"sm\">\n <Drawer.Header>\n <Drawer.Title>Actions</Drawer.Title>\n </Drawer.Header>\n <Drawer.Body>\n <p>Bottom sheet for mobile-style actions.</p>\n </Drawer.Body>\n </Drawer.Content>\n</Drawer>"},{"name":"With Form","description":"Fields in the body, submit and cancel pinned to the footer.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button>Edit Settings</Button>\n </Drawer.Trigger>\n <Drawer.Content size=\"md\">\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Settings</Drawer.Title>\n <Drawer.Description>Update your preferences.</Drawer.Description>\n </Drawer.Header>\n <Drawer.Body>\n <Stack gap=\"md\">\n <Input label=\"Display Name\" placeholder=\"Enter name\" />\n <Input label=\"Email\" type=\"email\" placeholder=\"you@example.com\" />\n </Stack>\n </Drawer.Body>\n <Drawer.Footer>\n <Drawer.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Drawer.Close>\n <Button variant=\"primary\">Save Changes</Button>\n </Drawer.Footer>\n </Drawer.Content>\n</Drawer>"}],"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - open state handler","modal: boolean - blocks page interaction (default: true)","Drawer.Content side: left|right|top|bottom - slide direction (default: right)","Drawer.Content size: sm|md|lg|xl|full - panel size","Drawer.Content initialFocus: boolean - auto-focus popup on open (default: true)"],"a11yRules":["A11Y_DIALOG_FOCUS","A11Y_DIALOG_ESCAPE","A11Y_DIALOG_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","SwipeArea","Header","Title","Description","Body","Footer"],"requiredChildren":["Content"],"commonPatterns":["<Drawer><Drawer.Trigger><Button>Open</Button></Drawer.Trigger><Drawer.Content><Drawer.Close /><Drawer.Header><Drawer.Title>{title}</Drawer.Title></Drawer.Header><Drawer.Body>{content}</Drawer.Body><Drawer.Footer><Drawer.Close asChild><Button variant=\"secondary\">Cancel</Button></Drawer.Close><Button>Save</Button></Drawer.Footer></Drawer.Content></Drawer>"]},"propsSummary":["children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","modal: boolean (default: true)"],"sourcePath":"src/components/Drawer/index.tsx","exportName":"Drawer","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:55.637Z"},"performance":{"bundleSize":1520,"rawSize":4046,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Drawer (self)","bytes":3274,"percent":81}]}},"Editor":{"filePath":"src/components/Editor/index.tsx","meta":{"name":"Editor","description":"Edits rich text with formatting, autosave, and a word count.","category":"inputs","tags":["editor","rich-text","markdown","toolbar","writing","blog","content"],"status":"stable","dependencies":[{"name":"@tiptap/react","version":">=2.0.0","reason":"Optional — enables rich-text mode; without TipTap the editor falls back to a markdown textarea."},{"name":"@tiptap/starter-kit","version":">=2.0.0","reason":"Optional — TipTap extension bundle used by rich-text mode."},{"name":"@tiptap/extension-link","version":">=2.0.0","reason":"Optional — link formatting in rich-text mode."}]},"usage":{"when":["Blog posts and long-form articles","Text that needs formatting controls beside it","Drafts that autosave and report a word count","Markdown or WYSIWYG authoring"],"whenNot":["Single-line text (use Input)","Multi-line with no formatting (use Textarea)","Chat or AI prompt input (use Prompt)","Code editing (use CodeBlock)"],"guidelines":["Compose Editor.Toolbar and Editor.Content to control toolbar layout","Rich text needs @tiptap/react, @tiptap/starter-kit, and @tiptap/extension-link","Without TipTap it falls back to a markdown-aware textarea","onAutoSave may return a Promise; save status updates once it settles","size sets the minimum body height: sm 120px, md 200px, lg 400px","maxLength drives the counter's warning and over-limit states","Headings, blockquote, orderedList, undo, and redo are opt-in via formats","toolbarIcons swaps glyphs without changing labels or keyboard behavior"],"accessibility":["Toolbar has role=\"toolbar\" with aria-label","Format buttons use aria-pressed to indicate active state","Action buttons (undo/redo) omit aria-pressed since they are not toggles","Status indicator uses aria-live=\"polite\" for save status announcements","Keyboard shortcuts match standard text editor conventions (Ctrl+B, Ctrl+I, etc.)","Global shortcuts (e.g., Sidebar Ctrl+B) automatically yield when focus is inside the Editor","Focus ring appears on the editor container when any child element is focused"]},"props":{"children":{"type":"node","description":"","required":false},"value":{"type":"string","description":"Controlled editor value","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","default":"","required":false},"onValueChange":{"type":"function","description":"Called when content changes","required":false},"placeholder":{"type":"string","description":"Placeholder text shown when empty","default":"Start typing...","required":false},"disabled":{"type":"boolean","description":"Disable the editor","default":"false","required":false},"readOnly":{"type":"boolean","description":"Make the editor read-only","default":"false","required":false},"formats":{"type":"array","description":"Which format buttons to show in the toolbar","default":"[\"bold\", \"italic\", \"strikethrough\", \"link\", \"code\", \"bulletList\"]","required":false},"toolbar":{"type":"boolean","description":"Show default toolbar","default":"true","required":false},"statusBar":{"type":"boolean","description":"Show default status bar with word/character counts","default":"true","required":false},"onAutoSave":{"type":"function","description":"Auto-save callback, called at autoSaveInterval (may be async)","required":false},"autoSaveInterval":{"type":"number","description":"Auto-save interval in milliseconds","default":"30000","required":false},"size":{"type":"enum","description":"Editor size preset: \"sm\" (120px), \"md\" (200px), or \"lg\" (400px)","default":"md","required":false,"values":["sm","md","lg"]},"maxLength":{"type":"number","description":"Maximum character count. Shows counter in status bar with warning (90%) and error (over limit) states","required":false},"toolbarIcons":{"type":"object","description":"Optional toolbar icon overrides keyed by format/action (e.g. bold, italic, undo). Values can be React nodes or render functions.","required":false}},"relations":[{"component":"Prompt","relationship":"sibling","note":"Prompt is for AI/chat input; Editor is for long-form content editing"},{"component":"Textarea","relationship":"alternative","note":"Use Textarea for simple multi-line input without formatting toolbar"},{"component":"Input","relationship":"alternative","note":"Use Input for single-line text input"}],"variants":[{"name":"Default","description":"Toolbar and status bar you get with no configuration.","code":"<Editor placeholder=\"Start typing your masterpiece here...\" />"},{"name":"With Auto-Save and Publish","description":"Save state sits next to the primary action in the toolbar.","code":"<Editor\n placeholder=\"Start typing your masterpiece here...\"\n onValueChange={(v) => console.log(v)}\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n <Editor.ToolbarButton format=\"strikethrough\" />\n <Editor.ToolbarButton format=\"link\" />\n <Editor.ToolbarButton format=\"code\" />\n <Editor.ToolbarButton format=\"bulletList\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Actions\">\n <Editor.StatusIndicator status=\"saved\" />\n <Button variant=\"accent\" size=\"sm\">\n Publish\n </Button>\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"Save Failed","description":"A failed autosave turns the status text red.","code":"<Editor defaultValue=\"This draft could not be saved.\">\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Status\">\n <Editor.StatusIndicator status=\"error\" />\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"Disabled","description":"Dimmed and inert, but the text stays readable.","code":"<Editor\n defaultValue=\"This content cannot be edited.\"\n disabled\n/>"},{"name":"Read Only","description":"Text can be selected and copied, but never changed.","code":"<Editor\n defaultValue=\"This content is read-only. You can select and copy text but cannot modify it.\"\n readOnly\n/>"},{"name":"Custom Toolbar","description":"Separators split the controls into labelled clusters.","code":"<Editor\n placeholder=\"Write your blog post...\"\n onValueChange={(v) => console.log(v)}\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Basic formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Advanced formatting\">\n <Editor.ToolbarButton format=\"link\" />\n <Editor.ToolbarButton format=\"code\" />\n <Editor.ToolbarButton format=\"bulletList\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Status\">\n <Editor.StatusIndicator status=\"saving\" />\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"Full Formatting","description":"Every opt-in format switched on, at the tallest preset.","code":"<Editor\n placeholder=\"Write an article...\"\n size=\"lg\"\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"History\">\n <Editor.ToolbarButton format=\"undo\" />\n <Editor.ToolbarButton format=\"redo\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Headings\">\n <Editor.ToolbarButton format=\"heading1\" />\n <Editor.ToolbarButton format=\"heading2\" />\n <Editor.ToolbarButton format=\"heading3\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n <Editor.ToolbarButton format=\"strikethrough\" />\n <Editor.ToolbarButton format=\"code\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Block formatting\">\n <Editor.ToolbarButton format=\"bulletList\" />\n <Editor.ToolbarButton format=\"orderedList\" />\n <Editor.ToolbarButton format=\"blockquote\" />\n <Editor.ToolbarButton format=\"link\" />\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"With Character Limit","description":"The counter warns near 280 characters and turns red past it.","code":"<Editor\n placeholder=\"Write a tweet-sized message...\"\n maxLength={280}\n size=\"sm\"\n formats={['bold', 'italic', 'link']}\n/>"},{"name":"Small Size","description":"A 120px body with a trimmed toolbar, for tight spaces.","code":"<Editor\n placeholder=\"Quick note...\"\n size=\"sm\"\n formats={['bold', 'italic', 'code']}\n/>"}],"contract":{"propsSummary":["value: string - controlled editor value","onValueChange: (value: string) => void - change callback","placeholder: string - hint text (default: \"Start typing...\")","disabled: boolean - disables interaction","readOnly: boolean - prevents editing","formats: EditorFormat[] - toolbar buttons (default: all 6)","toolbar: boolean - show default toolbar (default: true)","statusBar: boolean - show word/char counts (default: true)","onAutoSave: (value: string) => void | Promise<void> - auto-save handler","size: \"sm\" | \"md\" | \"lg\" - editor height preset (default: \"md\")","maxLength: number - character limit with visual indicator","toolbarIcons: Partial<Record<EditorFormat, ReactNode | (state) => ReactNode>> - custom toolbar icons"],"a11yRules":["A11Y_TOOLBAR_ROLE","A11Y_BUTTON_LABEL","A11Y_LIVE_REGION"]},"ai":{"compositionPattern":"compound","subComponents":["Toolbar","ToolbarGroup","ToolbarButton","Separator","StatusIndicator","Content","StatusBar","preload"]},"propsSummary":["children: node","value: string","defaultValue: string (default: )","onValueChange: function","placeholder: string (default: Start typing...)","disabled: boolean (default: false)","readOnly: boolean (default: false)","formats: array","toolbar: boolean (default: true)","statusBar: boolean (default: true)","onAutoSave: function","autoSaveInterval: number (default: 30000)","size: sm|md|lg (default: md)","maxLength: number","toolbarIcons: object"],"sourcePath":"src/components/Editor/index.tsx","exportName":"Editor","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:56.748Z"},"performance":{"bundleSize":138646,"rawSize":442175,"complexity":"heavy","budgetPercent":903,"overBudget":true,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"@tiptap/react","bytes":335208,"percent":76},{"path":"@phosphor-icons/react","bytes":34485,"percent":8},{"path":"@tiptap/starter-kit","bytes":32005,"percent":7},{"path":"@tiptap/extension-link","bytes":25654,"percent":6},{"path":"Editor (self)","bytes":10010,"percent":2},{"path":"src/utils/keyboard-shortcuts.ts","bytes":2656,"percent":1}]}},"EmptyState":{"filePath":"src/components/EmptyState/index.tsx","meta":{"name":"EmptyState","description":"Explains why an area is blank and offers the next step.","category":"feedback","tags":["empty","placeholder","no-data","zero-state","blank-slate"],"status":"stable"},"usage":{"when":["Lists, tables, or search results with nothing to show","First-run screens before any content exists","Filtered views that matched nothing"],"whenNot":["Content still loading (use Skeleton)","Failures that need a retry (use Alert)","Transient confirmations (use Toast)"],"guidelines":["Say why the area is empty, not just that it is","Give one clear action out of the state","Keep to two actions at most, primary first","Match the icon to the cause — search, inbox, folder","Use size=\"sm\" inline and size=\"lg\" for full-page states"],"accessibility":["Empty state content is accessible to screen readers","Action buttons follow button accessibility guidelines"]},"props":{"children":{"type":"node","description":"EmptyState content - use EmptyState.Icon, EmptyState.Title, EmptyState.Description, EmptyState.Actions sub-components","required":true},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Frame style. `outlined` draws a dashed hairline around the reserved region; `plain` leaves framing to the surrounding surface.","default":"plain","required":false,"values":["plain","outlined"]}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for error states with retry"},{"component":"Progress","relationship":"alternative","note":"Use Progress/Spinner for loading states"}],"variants":[{"name":"Default","description":"First-run state: nothing exists yet, so offer the create action.","code":"<EmptyState>\n <EmptyState.Icon><FolderIcon /></EmptyState.Icon>\n <EmptyState.Title>No projects yet</EmptyState.Title>\n <EmptyState.Description>Get started by creating your first project.</EmptyState.Description>\n <EmptyState.Actions>\n <Button>Create Project</Button>\n </EmptyState.Actions>\n</EmptyState>"},{"name":"No Results","description":"A filter or query matched nothing — offer a way back.","code":"<EmptyState>\n <EmptyState.Icon><SearchIcon /></EmptyState.Icon>\n <EmptyState.Title>No results found</EmptyState.Title>\n <EmptyState.Description>Try adjusting your search terms or filters.</EmptyState.Description>\n <EmptyState.Actions>\n <Button variant=\"secondary\">Clear Filters</Button>\n </EmptyState.Actions>\n</EmptyState>"},{"name":"With Secondary Action","description":"One primary action plus a quieter alternative.","code":"<EmptyState>\n <EmptyState.Icon><InboxIcon /></EmptyState.Icon>\n <EmptyState.Title>Inbox is empty</EmptyState.Title>\n <EmptyState.Description>You have no new messages.</EmptyState.Description>\n <EmptyState.Actions>\n <Button>Compose Message</Button>\n <Button variant=\"secondary\">View Archive</Button>\n </EmptyState.Actions>\n</EmptyState>"},{"name":"Small","description":"Compact size for inline panels; no icon, no action.","code":"<EmptyState size=\"sm\">\n <EmptyState.Title>No items</EmptyState.Title>\n <EmptyState.Description>Add items to see them here.</EmptyState.Description>\n</EmptyState>"},{"name":"Large","description":"Full-page size for a workspace or onboarding screen.","code":"<EmptyState size=\"lg\">\n <EmptyState.Icon><FolderIcon /></EmptyState.Icon>\n <EmptyState.Title>Welcome to your workspace</EmptyState.Title>\n <EmptyState.Description>\n This is where your projects will appear. Create your first project to get started.\n </EmptyState.Description>\n <EmptyState.Actions>\n <Button>Create Your First Project</Button>\n </EmptyState.Actions>\n</EmptyState>"}],"contract":{"propsSummary":["size: sm|md|lg (default: md)","Sub-components: EmptyState.Icon, EmptyState.Title, EmptyState.Description, EmptyState.Actions","Compound sub-components forward DOM props to their rendered elements"],"a11yRules":["A11Y_EMPTY_STATE_CONTENT"]},"ai":{"compositionPattern":"compound","subComponents":["Icon","Title","Description","Actions"],"requiredChildren":["Title"],"commonPatterns":["<EmptyState><EmptyState.Title>{title}</EmptyState.Title><EmptyState.Description>{description}</EmptyState.Description></EmptyState>","<EmptyState><EmptyState.Icon>{icon}</EmptyState.Icon><EmptyState.Title>{title}</EmptyState.Title><EmptyState.Description>{description}</EmptyState.Description><EmptyState.Actions><Button>{action}</Button></EmptyState.Actions></EmptyState>"]},"propsSummary":["children: node (required)","size: sm|md|lg (default: md)","variant: plain|outlined (default: plain)"],"sourcePath":"src/components/EmptyState/index.tsx","exportName":"EmptyState","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:56.922Z"},"performance":{"bundleSize":795,"rawSize":1897,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"EmptyState (self)","bytes":1168,"percent":62}]}},"Field":{"filePath":"src/components/Field/index.tsx","meta":{"name":"Field","description":"Composes labels, descriptions, validation, and errors around a form control.","category":"inputs","tags":["form","field","validation","label","error","input","accessible"],"status":"stable"},"usage":{"when":["One error message per failure reason, not one catch-all","A custom control needs a real label and description","Server errors must land on the field that caused them","You need dirty and touched tracking"],"whenNot":["A plain input with a label and helper text (use Input's own props)","A Select or Textarea whose built-in error display is enough"],"guidelines":["Every Field gets a Field.Label","Wrap the control in Field.Control so it joins the field context","Give each Field.Error a match so the message fits the failure","Nest inside Form to route server errors by field name"],"accessibility":["Label links to the control via aria-labelledby","Description links via aria-describedby","Errors are announced when they appear","data-disabled and data-invalid are available for styling"]},"props":{"children":{"type":"node","description":"Field content (Label, Control, Description, Error)","required":true},"name":{"type":"string","description":"Field name, used for error distribution from Form","required":false},"disabled":{"type":"boolean","description":"Disables the field and its control","required":false},"invalid":{"type":"boolean","description":"Marks the field as invalid","required":false},"validate":{"type":"function","description":"Custom validation function returning error string(s) or null","required":false},"validationMode":{"type":"enum","description":"When to trigger validation","required":false,"values":["onSubmit","onBlur","onChange"]},"validationDebounceTime":{"type":"number","description":"Debounce time in ms for onChange validation","required":false},"size":{"type":"enum","description":"","required":false,"values":["sm","md","lg"]}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for simple fields with built-in label/error"},{"component":"Form","relationship":"parent","note":"Wrap in Form for server-side error distribution"},{"component":"Fieldset","relationship":"sibling","note":"Use Fieldset to group related fields"}],"variants":[{"name":"Single field","description":"Label, control and description wired together automatically.","code":"<Field name=\"email\">\n <Field.Label>Email address</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Description>We will never share your email.</Field.Description>\n</Field>"},{"name":"Two-column layout","description":"Grid places two short fields side by side and one full-width.","code":"<Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"typeMismatch\">Enter a valid email address</Field.Error>\n </Field>\n </Grid.Item>\n</Grid>"},{"name":"Invalid","description":"invalid marks the field failed and reveals Field.Error.","code":"<Field name=\"username\" invalid>\n <Field.Label>Username</Field.Label>\n <Field.Control>\n <Input value=\"ada lovelace\" error />\n </Field.Control>\n <Field.Error match>Usernames cannot contain spaces</Field.Error>\n</Field>"},{"name":"Custom validation","description":"validate runs on change and feeds Field.Error.","code":"<Field\n name=\"age\"\n validate={(value) => {\n const num = Number(value);\n if (isNaN(num) || num < 18) return 'Must be 18 or older';\n return null;\n }}\n validationMode=\"onChange\"\n validationDebounceTime={500}\n>\n <Field.Label>Age</Field.Label>\n <Field.Control>\n <Input type=\"number\" placeholder=\"18\" />\n </Field.Control>\n <Field.Description>You must be at least 18 years old.</Field.Description>\n <Field.Error match=\"customError\" />\n</Field>"}],"contract":{"propsSummary":["name: string - field name for error distribution","validate: (value) => string | null - custom validation","validationMode: onSubmit|onBlur|onChange - validation trigger","Field.Control: wraps any form component (Input, Textarea, etc.)","Field.Error match: valueMissing|typeMismatch|customError|... - granular errors"],"a11yRules":["A11Y_FIELD_LABEL","A11Y_FIELD_ERROR","A11Y_FIELD_DESCRIPTION"]},"ai":{"compositionPattern":"compound","subComponents":["Label","Control","Description","Error","Validity","Required"],"commonPatterns":["<Field>\n <Field.Label>...</Field.Label>\n <Field.Control>...</Field.Control>\n <Field.Description>...</Field.Description>\n</Field>"],"requiredChildren":["Label","Control"]},"propsSummary":["children: node (required)","name: string","disabled: boolean","invalid: boolean","validate: function","validationMode: onSubmit|onBlur|onChange","validationDebounceTime: number"],"sourcePath":"src/components/Field/index.tsx","exportName":"Field","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.733Z"},"performance":{"bundleSize":923,"rawSize":2253,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Field (self)","bytes":1348,"percent":60},{"path":"ComponentDefaults","bytes":193,"percent":9}]}},"Fieldset":{"filePath":"src/components/Fieldset/index.tsx","meta":{"name":"Fieldset","description":"Groups related form controls under an accessible legend.","category":"inputs","tags":["form","fieldset","group","legend","accessible"],"status":"stable"},"usage":{"when":["Fields that belong to one subject: address, billing, profile","Locking a whole section at once","Screen readers should hear the group name before each field"],"whenNot":["Grouping for looks alone (use Card)","Wrapping one control (use Field)"],"guidelines":["Every Fieldset gets a Fieldset.Legend","disabled on the Fieldset locks every control inside it","Put a Grid inside for multi-column layouts","Fieldset.Legend forwards DOM props for ids, ARIA, and data hooks"],"accessibility":["Renders a real fieldset element","Legend names the group","Disabled cascades to every child field"]},"props":{"children":{"type":"node","description":"Fieldset content including Fieldset.Legend and form fields","required":true},"disabled":{"type":"boolean","description":"Disables all fields within the fieldset","required":false}},"relations":[{"component":"Field","relationship":"sibling","note":"Contains Field components"},{"component":"Form","relationship":"parent","note":"Used within a Form"},{"component":"Card","relationship":"alternative","note":"Use Card for non-form visual grouping"}],"variants":[{"name":"Two-column layout","description":"A Grid inside the legend box pairs short fields on one row.","code":"<Fieldset>\n <Fieldset.Legend>Personal Information</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n</Fieldset>"},{"name":"Mixed controls","description":"Textarea, select and checkbox share one spacing rhythm.","code":"<Fieldset>\n <Fieldset.Legend>Preferences</Fieldset.Legend>\n <Field name=\"bio\">\n <Field.Label>Bio</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"Tell us about yourself\" rows={3} />\n </Field.Control>\n <Field.Description>Brief description for your profile.</Field.Description>\n </Field>\n <Field name=\"role\">\n <Field.Label>Role</Field.Label>\n <Field.Control>\n <Select placeholder=\"Select a role\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"admin\">Admin</Select.Item>\n <Select.Item value=\"editor\">Editor</Select.Item>\n <Select.Item value=\"viewer\">Viewer</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n <Field name=\"newsletter\">\n <Field.Control>\n <Checkbox label=\"Subscribe to newsletter\" />\n </Field.Control>\n </Field>\n</Fieldset>"},{"name":"With Description","description":"One sentence under the legend covers the whole group.","code":"<Fieldset>\n <Fieldset.Legend>Notification Settings</Fieldset.Legend>\n <Fieldset.Description>Choose how you want to be notified about updates.</Fieldset.Description>\n <Field name=\"emailNotif\">\n <Field.Control>\n <Checkbox label=\"Email notifications\" />\n </Field.Control>\n </Field>\n <Field name=\"smsNotif\">\n <Field.Control>\n <Checkbox label=\"SMS notifications\" />\n </Field.Control>\n </Field>\n</Fieldset>"},{"name":"Disabled","description":"One prop on the wrapper dims and locks every control inside.","code":"<Fieldset disabled>\n <Fieldset.Legend>Locked Section</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"lockedFirst\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input defaultValue=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lockedLast\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input defaultValue=\"Doe\" />\n </Field.Control>\n </Field>\n </Grid>\n <Field name=\"lockedCheck\">\n <Field.Control>\n <Checkbox label=\"Cannot toggle\" defaultChecked />\n </Field.Control>\n </Field>\n</Fieldset>"}],"contract":{"propsSummary":["disabled: boolean - disables all child fields","Fieldset.Legend: accessible group label","Fieldset.Legend forwards DOM props","Fieldset.Description: helper text below the legend"],"a11yRules":["A11Y_FIELDSET_LEGEND"]},"ai":{"compositionPattern":"compound","subComponents":["Legend","Description"],"commonPatterns":["<Fieldset>\n <Fieldset.Legend>...</Fieldset.Legend>\n</Fieldset>"],"requiredChildren":["Legend"]},"propsSummary":["children: node (required)","disabled: boolean"],"sourcePath":"src/components/Fieldset/index.tsx","exportName":"Fieldset","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:57.275Z"},"performance":{"bundleSize":610,"rawSize":1285,"complexity":"lightweight","budgetPercent":4,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Fieldset (self)","bytes":632,"percent":49}]}},"Form":{"filePath":"src/components/Form/index.tsx","meta":{"name":"Form","description":"Distributes server-side validation errors to its Field components.","category":"inputs","tags":["form","validation","errors","submit","server"],"status":"stable"},"usage":{"when":["The server rejects a submission and each reason must reach its own field","Client and server validation live in the same form"],"whenNot":["Client-side validation only (a native form plus Field is enough)","Layout without submission (use Grid or Card)"],"guidelines":["errors is keyed by field name: Record<string, string | string[]>","Clear a field's error in onClearErrors when the user edits it","Use onSubmit; onFormSubmit is a deprecated alias","A Field picks up its error by matching name","Leave Field.Error unmatched so it shows whatever the server sent","Put a Grid inside Form or Fieldset for multi-column layouts","Buttons go in Form.Actions so they stay right-aligned"],"accessibility":["Renders a real form element","Errors link back to their field via aria-describedby"]},"props":{"children":{"type":"node","description":"Form content","required":true},"errors":{"type":"object","description":"Server-side errors keyed by field name","required":false},"onSubmit":{"type":"function","description":"Form submission handler (preferred)","required":false},"onFormSubmit":{"type":"function","description":"Deprecated alias for onSubmit","required":false},"onClearErrors":{"type":"function","description":"Called with field name when errors should be cleared","required":false},"validationMode":{"type":"enum","description":"When field validation should run","required":false,"values":["onSubmit","onBlur","onChange"]}},"relations":[{"component":"Field","relationship":"sibling","note":"Contains Field components for error distribution"},{"component":"Fieldset","relationship":"sibling","note":"Use Fieldset to group fields within a Form"},{"component":"Button","relationship":"sibling","note":"Use Button type=\"submit\" for form submission"}],"variants":[{"name":"Sign up","description":"Paired name fields, then full-width rows and a right-aligned submit.","code":"<Form onSubmit={(e) => { e.preventDefault(); }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"typeMismatch\">Enter a valid email address</Field.Error>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"password\">\n <Field.Label>Password</Field.Label>\n <Field.Control>\n <Input type=\"password\" placeholder=\"At least 8 characters\" />\n </Field.Control>\n <Field.Description>Must be at least 8 characters</Field.Description>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"terms\">\n <Field.Control>\n <Checkbox label=\"I agree to the terms and conditions\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n <Form.Actions>\n <Button type=\"submit\" variant=\"primary\">Create Account</Button>\n </Form.Actions>\n</Form>"},{"name":"Profile settings","description":"Fieldsets split a long form into sections the user can scan.","code":"<Form onSubmit={(e) => { e.preventDefault(); }}>\n <Fieldset>\n <Fieldset.Legend>Profile</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"displayName\">\n <Field.Label>Display Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"How others see you\" />\n </Field.Control>\n </Field>\n <Field name=\"timezone\">\n <Field.Label>Timezone</Field.Label>\n <Field.Control>\n <Select placeholder=\"Select timezone\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"utc\">UTC</Select.Item>\n <Select.Item value=\"est\">Eastern (EST)</Select.Item>\n <Select.Item value=\"pst\">Pacific (PST)</Select.Item>\n <Select.Item value=\"gmt\">GMT</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"bio\">\n <Field.Label>Bio</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"Tell us about yourself\" rows={3} maxLength={280} />\n </Field.Control>\n <Field.Description>Max 280 characters</Field.Description>\n </Field>\n </Grid.Item>\n </Grid>\n </Fieldset>\n <Fieldset>\n <Fieldset.Legend>Notifications</Fieldset.Legend>\n <Field name=\"emailNotifs\">\n <Field.Control>\n <Switch label=\"Email notifications\" />\n </Field.Control>\n </Field>\n <Field name=\"marketingEmails\">\n <Field.Control>\n <Switch label=\"Marketing emails\" />\n </Field.Control>\n </Field>\n <Field name=\"frequency\">\n <Field.Label>Digest frequency</Field.Label>\n <Field.Control>\n <RadioGroup name=\"frequency\" orientation=\"vertical\">\n <RadioGroup.Item value=\"daily\" label=\"Daily\" />\n <RadioGroup.Item value=\"weekly\" label=\"Weekly\" />\n <RadioGroup.Item value=\"monthly\" label=\"Monthly\" />\n </RadioGroup>\n </Field.Control>\n </Field>\n </Fieldset>\n <Form.Actions>\n <Button type=\"submit\" variant=\"primary\">Save Changes</Button>\n </Form.Actions>\n</Form>"},{"name":"Contact form","description":"Mixed control types in one submission flow.","code":"<Form onSubmit={(e) => { e.preventDefault(); }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"name\">\n <Field.Label>Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Your name\" />\n </Field.Control>\n </Field>\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"you@example.com\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"subject\">\n <Field.Label>Subject</Field.Label>\n <Field.Control>\n <Select placeholder=\"What is this about?\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"general\">General Inquiry</Select.Item>\n <Select.Item value=\"support\">Technical Support</Select.Item>\n <Select.Item value=\"billing\">Billing</Select.Item>\n <Select.Item value=\"feedback\">Feedback</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"message\">\n <Field.Label>Message</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"How can we help?\" rows={5} />\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"copy\">\n <Field.Control>\n <Checkbox label=\"Send me a copy\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n <Form.Actions>\n <Button type=\"submit\" variant=\"primary\">Send Message</Button>\n </Form.Actions>\n</Form>"},{"name":"With server errors","description":"Errors from the server land on the fields that caused them.","code":"<Form errors={{ username: 'Username is already taken', email: 'Email is already registered' }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"username\">\n <Field.Label>Username</Field.Label>\n <Field.Control>\n <Input defaultValue=\"janedoe\" />\n </Field.Control>\n <Field.Error />\n </Field>\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" defaultValue=\"jane@example.com\" />\n </Field.Control>\n <Field.Error />\n </Field>\n </Grid>\n <Form.Actions>\n <Button type=\"submit\" variant=\"primary\">Submit</Button>\n </Form.Actions>\n</Form>"}],"contract":{"propsSummary":["errors: Record<string, string | string[]> - server errors by field name","onSubmit: (event) => void - submission handler (preferred)","onFormSubmit: (event) => void - deprecated alias for onSubmit","onClearErrors: (name) => void - clear errors callback"],"a11yRules":["A11Y_FORM_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Actions"],"commonPatterns":["<Form>\n <Form.Actions>...</Form.Actions>\n</Form>"],"requiredChildren":["Actions"]},"propsSummary":["children: node (required)","errors: object","onSubmit: function","onFormSubmit: function","onClearErrors: function","validationMode: onSubmit|onBlur|onChange"],"sourcePath":"src/components/Form/index.tsx","exportName":"Form","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:57.100Z"},"performance":{"bundleSize":619,"rawSize":1139,"complexity":"lightweight","budgetPercent":4,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Form (self)","bytes":553,"percent":49}]}},"Grid":{"filePath":"src/components/Grid/index.tsx","meta":{"name":"Grid","description":"Arranges items into responsive columns with one shared gap.","category":"layout","tags":["grid","layout","columns","responsive"],"status":"stable"},"usage":{"when":["Cards, tiles, or media that reflow across breakpoints","Multi-column form layouts","Dashboard widget layouts"],"whenNot":["One-directional lists (use Stack)","Editorial mosaics with feature tiles (use BentoGrid)","Navigation bars (use Header)"],"guidelines":["columns=\"auto\" with minChildWidth adapts without breakpoints","Pass { base, md, lg } to columns for explicit per-breakpoint control","Numeric gaps (1-8) map to the same spacing scale as the tokens","Wrap a child in Grid.Item to span columns; colSpan=\"full\" spans the row","Keep source order equal to visual order — Grid does not reorder for screen readers"],"accessibility":["Grid is purely visual — it does not affect reading order or semantics","Ensure logical source order matches visual order for screen readers"]},"props":{"children":{"type":"node","description":"Grid items and content","required":false},"columns":{"type":"union","description":"Number of columns: a number (1-12), a responsive object { base, sm, md, lg, xl }, or \"auto\" for auto-fill","default":"1","required":false,"constraints":["Use \"auto\" with minChildWidth for fully fluid layouts","Use responsive object for explicit breakpoint control: { base: 1, md: 2, lg: 3 }"]},"minChildWidth":{"type":"string","description":"Minimum width for auto-fill columns (e.g., \"16rem\", \"250px\")","required":false,"constraints":["Only applies when columns=\"auto\""]},"gap":{"type":"union","description":"Gap between grid items. Accepts string tokens or numbers (1-8) mapped to the spacing scale","default":"md","required":false,"values":["none","xs","sm","md","lg","xl"]},"alignItems":{"type":"enum","description":"Vertical alignment of items within their cells","required":false,"values":["start","center","end","stretch"]},"justifyItems":{"type":"enum","description":"Horizontal alignment of items within their cells","required":false,"values":["start","center","end","stretch"]},"padding":{"type":"enum","description":"Internal padding of the grid container","default":"none","required":false,"values":["none","sm","md","lg"]},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false}},"relations":[{"component":"Card","relationship":"child","note":"Grid commonly contains Card components for dashboard and tile layouts"},{"component":"Separator","relationship":"sibling","note":"Use Separator between grid sections"}],"variants":[{"name":"Default","description":"A fixed count of equal columns.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns={3} gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">One</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Two</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Three</Box>\n </Grid>\n</Box>"},{"name":"Responsive","description":"Column count changes per breakpoint.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns={{ base: 1, md: 2, lg: 3 }} gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 1</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 2</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 3</Box>\n </Grid>\n</Box>"},{"name":"Auto-fill","description":"Columns fit themselves to a minimum child width — no breakpoints needed.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns=\"auto\" minChildWidth=\"10rem\" gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 1</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 2</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 3</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 4</Box>\n </Grid>\n</Box>"},{"name":"With Spanning","description":"Grid.Item stretches a child across columns.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns={4} gap=\"md\">\n <Grid.Item colSpan={2}>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Spans 2 columns</Box>\n </Grid.Item>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">1 col</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">1 col</Box>\n <Grid.Item colSpan=\"full\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Full width</Box>\n </Grid.Item>\n </Grid>\n</Box>"},{"name":"Form Layout","description":"Paired fields with one full-width row.","code":"import { Box } from '@/components/Box';\nimport { Field } from '@/components/Field';\nimport { Grid } from '@/components/Grid';\nimport { Input } from '@/components/Input';\n\n<Box width=\"100%\">\n <Grid columns={{ base: 1, md: 2 }} gap=\"md\">\n <Field>\n <Field.Label>First name</Field.Label>\n <Input placeholder=\"Ada\" />\n </Field>\n <Field>\n <Field.Label>Last name</Field.Label>\n <Input placeholder=\"Lovelace\" />\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field>\n <Field.Label>Email address</Field.Label>\n <Input type=\"email\" placeholder=\"ada@example.com\" />\n </Field>\n </Grid.Item>\n </Grid>\n</Box>"}],"contract":{"propsSummary":["columns: 1-12 | { base, sm, md, lg, xl } | \"auto\" (default: 1)","minChildWidth: string — min width for auto-fill (only with columns=\"auto\")","gap: none|xs|sm|md|lg|xl|number (default: md, number maps to space scale)","alignItems: start|center|end|stretch — vertical alignment","justifyItems: start|center|end|stretch — horizontal alignment","padding: none|sm|md|lg (default: none)","Pass-through DOM props supported on Grid and Grid.Item roots (id, role, aria-*, data-*, handlers)"]},"propsSummary":["children: node","columns: union (default: 1)","minChildWidth: string","gap: union (default: md)","alignItems: start|center|end|stretch","justifyItems: start|center|end|stretch","padding: none|sm|md|lg (default: none)","className: string","style: object"],"sourcePath":"src/components/Grid/index.tsx","exportName":"Grid","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:57.444Z"},"performance":{"bundleSize":2038,"rawSize":4967,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"src/utils/layout-spacing.ts","bytes":2779,"percent":56},{"path":"Grid (self)","bytes":1615,"percent":33}]}},"Header":{"filePath":"src/components/Header/index.tsx","meta":{"name":"Header","description":"Composes brand, navigation, search, and actions into one responsive app bar.","category":"layout","tags":["header","navigation","navbar","brand","layout","dropdown"],"status":"stable"},"usage":{"when":["Top-level navigation for an app or site","Inside AppShell.Header","Anywhere brand, nav, and actions share one row"],"whenNot":["Section headings inside a page (use a heading)","Toolbars scoped to one panel (use Toolbar)","Sidebar-only navigation (use Sidebar)"],"guidelines":["Header.Spacer pushes the actions cluster to the right","Omit Header.Brand when the sidebar already shows the logo","container=\"page\" caps the content at page width for marketing bars","elevatedOnScroll adds a bottom border once the page scrolls","Pair Header.Trigger with Header.MobileNav for small screens","Header.SkipLink should be the first child"],"accessibility":["Include Header.SkipLink for keyboard users","Navigation has aria-label for screen readers","Active nav items use aria-current=\"page\"","Mobile trigger has aria-expanded state","NavMenu dropdown opens with click and is keyboard navigable"]},"props":{"children":{"type":"node","description":"Header content (use Header.Brand, Header.Nav, etc.)","required":true},"height":{"type":"string","description":"Header height","default":"56px","required":false},"position":{"type":"enum","description":"Position behavior (usually controlled by AppShell)","default":"static","required":false,"values":["static","fixed","sticky"]},"elevatedOnScroll":{"type":"union","description":"Apply the elevated header border after scrolling. Object form accepts { threshold?: number }.","default":"false","required":false},"navAlign":{"type":"enum","description":"Navigation alignment inside the header","default":"start","required":false,"values":["start","center"]},"container":{"type":"enum","description":"Header content width","default":"full","required":false,"values":["full","page"]},"icons":{"type":"object","description":"Optional icon overrides for Header.Trigger (menu/close) and Header.NavMenu chevron","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"AppShell","relationship":"parent","note":"Header is typically used inside AppShell.Header"},{"component":"Sidebar","relationship":"sibling","note":"Header.Trigger toggles Sidebar on mobile"},{"component":"Theme","relationship":"child","note":"ThemeToggle is commonly placed in Header.Actions"},{"component":"NavigationMenu","relationship":"child","note":"Use NavigationMenu inside Header for rich dropdown nav with auto mobile drawer"}],"variants":[{"name":"For Default Layout","description":"Brand, nav, and actions for AppShell layout=\"default\".","code":"import { Box } from '@/components/Box';\nimport { Button } from '@/components/Button';\nimport { Header } from '@/components/Header';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/dashboard\" active>Dashboard</Header.NavItem>\n <Header.NavItem href=\"/projects\">Projects</Header.NavItem>\n <Header.NavItem href=\"/settings\">Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"secondary\" size=\"sm\">Sign In</Button>\n </Header.Actions>\n </Header>\n</Box>"},{"name":"Marketing Header","description":"Sticky page-width bar that gains a border on scroll, with a mobile drawer.","code":"import { Box } from '@/components/Box';\nimport { Button } from '@/components/Button';\nimport { Header } from '@/components/Header';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header position=\"sticky\" elevatedOnScroll navAlign=\"center\" container=\"page\">\n <Header.SkipLink href=\"#main-content\" />\n <Header.Brand asChild>\n <a href=\"/\" aria-label=\"Home\">Logo</a>\n </Header.Brand>\n <Header.Nav aria-label=\"Main navigation\">\n <Header.NavItem href=\"/docs\">Docs</Header.NavItem>\n <Header.NavItem href=\"/pricing\">Pricing</Header.NavItem>\n </Header.Nav>\n <Header.Actions>\n <Button size=\"sm\">Start free</Button>\n </Header.Actions>\n <Header.Trigger />\n <Header.MobileNav>\n <Header.MobileNavLink href=\"/docs\">Docs</Header.MobileNavLink>\n <Header.MobileNavLink href=\"/pricing\">Pricing</Header.MobileNavLink>\n <Header.MobileNavActions>\n <Button size=\"sm\">Start free</Button>\n </Header.MobileNavActions>\n </Header.MobileNav>\n </Header>\n</Box>"},{"name":"With Dropdown Nav","description":"Header.NavMenu groups related links behind one trigger.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/components\" active>Components</Header.NavItem>\n <Header.NavItem href=\"/blocks\">Blocks</Header.NavItem>\n <Header.NavMenu label=\"Docs\">\n <Header.NavMenuItem href=\"/getting-started\">Getting Started</Header.NavMenuItem>\n <Header.NavMenuItem href=\"/cli\">CLI Reference</Header.NavMenuItem>\n <Header.NavMenuItem href=\"/mcp\">MCP Tools</Header.NavMenuItem>\n </Header.NavMenu>\n <Header.NavItem href=\"/blog\">Blog</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n</Box>"},{"name":"For Sidebar Layout","description":"No brand — the logo lives in the sidebar instead.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Input } from '@/components/Input';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Search>\n <Input placeholder=\"Search...\" style={{ width: '240px' }} />\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n</Box>"},{"name":"Minimal","description":"Just the drawer trigger and actions.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n</Box>"},{"name":"With Skip Link","description":"Header.SkipLink gives keyboard users a jump to main content.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.SkipLink href=\"#main-content\">Skip to content</Header.SkipLink>\n <Header.Brand>Accessible App</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/\" active>Home</Header.NavItem>\n <Header.NavItem href=\"/about\">About</Header.NavItem>\n </Header.Nav>\n </Header>\n</Box>"},{"name":"With NavigationMenu","description":"Rich dropdown panels with titles and descriptions.","code":"import { Box } from '@/components/Box';\nimport { Button } from '@/components/Button';\nimport { Header } from '@/components/Header';\nimport { NavigationMenu } from '@/components/NavigationMenu';\nimport { Stack } from '@/components/Stack';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <NavigationMenu aria-label=\"Site navigation\">\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"products\">\n <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <Box padding=\"xs\" style={{ minWidth: '200px' }}>\n <Stack gap=\"none\">\n <NavigationMenu.Link href=\"/analytics\" title=\"Analytics\" description=\"Track your metrics.\" />\n <NavigationMenu.Link href=\"/automation\" title=\"Automation\" description=\"Automate workflows.\" />\n </Stack>\n </Box>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/pricing\">Pricing</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n </NavigationMenu>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"primary\" size=\"sm\">Sign Up</Button>\n </Header.Actions>\n </Header>\n</Box>"}],"contract":{"propsSummary":["height: string - header height (default: 56px)","position: static|fixed|sticky - positioning behavior","elevatedOnScroll: boolean|{ threshold?: number } - scroll-elevated boundary","navAlign: start|center - nav placement inside the header","container: full|page - content width and gutter","icons: { menu?, close?, navMenuChevron? } - custom internal control icons (ReactNode or render function)","Header.Brand asChild composes custom link components","Header.Trigger composes click handler with Sidebar toggle behavior","Header.NavMenu provides dropdown groups via Base UI Menu","Header.MobileNavActions provides an action row inside the mobile drawer"],"a11yRules":["A11Y_HEADER_LANDMARK","A11Y_NAV_LABEL","A11Y_SKIP_LINK","A11Y_BUTTON_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["SkipLink","Trigger","Brand","Nav","NavItem","MobileNav","MobileNavLink","MobileNavActions","NavMenu","NavMenuItem","Search","Spacer","Actions"],"commonPatterns":["<Header><Header.Brand href=\"/\">{appName}</Header.Brand><Header.Nav><Header.NavItem href=\"/home\" active>Home</Header.NavItem></Header.Nav><Header.Spacer /><Header.Actions>{actions}</Header.Actions></Header>","<Header position=\"sticky\" elevatedOnScroll navAlign=\"center\" container=\"page\"><Header.Brand asChild>{link}</Header.Brand><Header.Nav>{links}</Header.Nav><Header.Actions>{actions}</Header.Actions><Header.Trigger /><Header.MobileNav>{mobileLinks}<Header.MobileNavActions>{mobileActions}</Header.MobileNavActions></Header.MobileNav></Header>","<Header><Header.Nav><Header.NavItem href=\"/home\">Home</Header.NavItem><Header.NavMenu label=\"Docs\" active><Header.NavMenuItem href=\"/cli\">CLI</Header.NavMenuItem><Header.NavMenuItem href=\"/mcp\">MCP</Header.NavMenuItem></Header.NavMenu></Header.Nav></Header>"]},"propsSummary":["children: node (required)","height: string (default: 56px)","position: static|fixed|sticky (default: static)","elevatedOnScroll: boolean|{ threshold?: number }","navAlign: start|center (default: start)","container: full|page (default: full)","icons: object","style: object"],"sourcePath":"src/components/Header/index.tsx","exportName":"Header","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:58.820Z"},"performance":{"bundleSize":11261,"rawSize":37084,"complexity":"moderate","budgetPercent":73,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Sidebar","bytes":17399,"percent":47},{"path":"Header (self)","bytes":7135,"percent":19},{"path":"@phosphor-icons/react","bytes":5528,"percent":15},{"path":"src/recipes/popup.ts","bytes":2836,"percent":8},{"path":"ScrollArea","bytes":2512,"percent":7},{"path":"src/utils/a11y.tsx","bytes":779,"percent":2}]}},"Icon":{"filePath":"src/components/Icon/index.tsx","meta":{"name":"Icon","description":"Sizes and colors any icon so it lines up with the text beside it.","category":"display","tags":["icon","visual","symbol","graphic"],"status":"stable"},"usage":{"when":["A symbol sits beside text, inside a button, or leads a list item","State needs a glanceable marker"],"whenNot":["Artwork or illustration (use Image)","Multi-color or animated graphics"],"guidelines":["Reserve success, warning, and error colors for real state","Hold one size per context","Match weight to the text weight beside it","iconProps reaches options the wrapper does not expose"],"accessibility":["Icons ship aria-hidden — they are decoration until you label them","An icon-only button needs VisuallyHidden text","Color alone never carries the message"]},"props":{"style":{"type":"object","description":"","required":false},"icon":{"type":"union","description":"Icon component to render","required":true},"size":{"type":"enum","description":"Icon size","default":"md","required":false,"values":["xs","sm","md","lg","xl","2xl"]},"weight":{"type":"string","description":"Optional icon style/weight hint (forwarded when supported by the icon component)","default":"regular","required":false,"values":["thin","light","regular","bold","fill","duotone"]},"variant":{"type":"enum","description":"Semantic color variant","default":"default","required":false,"values":["default","primary","secondary","tertiary","accent","success","warning","error"]},"color":{"type":"enum","description":"Deprecated alias for variant","required":false,"values":["primary","secondary","tertiary","accent","success","warning","error"]},"iconProps":{"type":"object","description":"Additional props forwarded to the underlying icon component (typed from the icon prop in TypeScript)","required":false}},"relations":[{"component":"Button","relationship":"child","note":"Use inside icon-only buttons with VisuallyHidden label"},{"component":"VisuallyHidden","relationship":"sibling","note":"Pair with VisuallyHidden for accessible icon-only elements"},{"component":"Badge","relationship":"child","note":"Can be used as badge icon prop"}],"variants":[{"name":"Default","description":"Inherits the size and color of its surroundings.","code":"<Icon icon={Heart} />"},{"name":"Sizes","description":"Steps tuned to the type scale, so icons never float off the baseline.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Star} size=\"xs\" />\n <Icon icon={Star} size=\"sm\" />\n <Icon icon={Star} size=\"md\" />\n <Icon icon={Star} size=\"lg\" />\n <Icon icon={Star} size=\"xl\" />\n</div>"},{"name":"Semantic Colors","description":"Color states carry meaning — never use them for decoration.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Check} variant=\"success\" />\n <Icon icon={Warning} variant=\"warning\" />\n <Icon icon={Warning} variant=\"error\" />\n <Icon icon={Info} variant=\"accent\" />\n</div>"},{"name":"Weights","description":"Match the stroke to the text weight next to it.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Heart} weight=\"thin\" />\n <Icon icon={Heart} weight=\"light\" />\n <Icon icon={Heart} weight=\"regular\" />\n <Icon icon={Heart} weight=\"bold\" />\n <Icon icon={Heart} weight=\"fill\" />\n <Icon icon={Heart} weight=\"duotone\" />\n</div>"},{"name":"Advanced Icon Props","description":"iconProps passes anything the underlying icon package supports.","code":"<Icon icon={Heart} iconProps={{ mirrored: true }} />"}],"contract":{"propsSummary":["icon: React component - icon component (required)","size: xs|sm|md|lg|xl - icon size","weight: string - optional style/weight hint for icons that support it","variant: default|primary|secondary|tertiary|accent|success|warning|error - color","iconProps: typed from the passed icon component - advanced icon-specific props"],"a11yRules":["A11Y_ICON_LABEL","A11Y_COLOR_CONTRAST"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["style: object","icon: union (required)","size: xs|sm|md|lg|xl (default: md)","weight: string (default: regular)","variant: default|primary|secondary|tertiary|accent|success|warning|error","color: primary|secondary|tertiary|accent|success|warning|error","iconProps: object"],"sourcePath":"src/components/Icon/index.tsx","exportName":"Icon","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:58.998Z"},"performance":{"bundleSize":1692,"rawSize":3952,"complexity":"lightweight","budgetPercent":11,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"src/measurements/index.ts","bytes":2795,"percent":71},{"path":"Icon (self)","bytes":571,"percent":14}]}},"IconButton":{"filePath":"src/components/IconButton/index.tsx","meta":{"name":"IconButton","description":"Runs an action from an icon alone, for toolbars and table rows.","category":"actions","tags":["action","button","icon","toolbar","interactive"],"status":"stable"},"usage":{"when":["Toolbars and top bars where text buttons crowd","Row actions too narrow for a label","Toggle actions that show a pressed state"],"whenNot":["The action needs a visible label — use Button","It flips a persistent setting — use Switch","The icon is decorative — use Icon"],"guidelines":["aria-label or aria-labelledby is required, every time","ghost for ordinary toolbar actions; outlined when it needs separation","pressed only for real toggle state, not selection","Keep icon meaning obvious, or pair it with a Tooltip"],"accessibility":["Name the action, not the icon: \"Delete row\", not \"Trash\"","Pressed state is exposed via aria-pressed","Hit target stays at least 24px even at size=\"sm\""]},"props":{"children":{"type":"node","description":"Icon element rendered inside the button","required":true},"variant":{"type":"enum","description":"Visual treatment for the icon-only action","default":"ghost","required":false,"values":["ghost","subtle","outlined"]},"size":{"type":"enum","description":"Control size aligned with adjacent fields and toolbar actions","default":"\"md\"","required":false,"values":["sm","md","lg"]},"pressed":{"type":"boolean","description":"Marks a toggle-style action as pressed and sets aria-pressed","required":false},"aria-label":{"type":"string","description":"Accessible action name when no labelled-by relationship is available","required":false},"aria-labelledby":{"type":"string","description":"ID reference for an external accessible action label","required":false},"type":{"type":"enum","description":"","default":"button","required":false,"values":["submit","reset","button"]}},"relations":[{"component":"Button","relationship":"sibling","note":"Use Button when the action should have a visible text label or broader layout variants"},{"component":"Icon","relationship":"complementary","note":"Icon supplies the visual glyph rendered inside IconButton"}],"variants":[{"name":"Toolbar action","description":"Icon carries the action; the label lives in aria-label.","code":"import { Plus as PlusIcon } from '@phosphor-icons/react';\n\n<IconButton aria-label=\"Add item\">\n <PlusIcon aria-hidden />\n</IconButton>"},{"name":"Variants","description":"Rising chrome: transparent, tinted, then bordered.","code":"import { Plus as PlusIcon } from '@phosphor-icons/react';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <IconButton aria-label=\"Add item\" variant=\"ghost\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"subtle\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"outlined\">\n <PlusIcon aria-hidden />\n </IconButton>\n</Stack>"},{"name":"Sizes","description":"sm for table rows, lg for primary chrome.","code":"import { Plus as PlusIcon } from '@phosphor-icons/react';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <IconButton aria-label=\"Add item\" variant=\"outlined\" size=\"sm\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"outlined\" size=\"md\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"outlined\" size=\"lg\">\n <PlusIcon aria-hidden />\n </IconButton>\n</Stack>"},{"name":"Pressed state","description":"Toggle that stays on, reported through aria-pressed.","code":"import { PushPin as PinIcon } from '@phosphor-icons/react';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <IconButton aria-label=\"Pin item\" variant=\"outlined\">\n <PinIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Unpin item\" variant=\"outlined\" pressed>\n <PinIcon aria-hidden />\n </IconButton>\n</Stack>"},{"name":"Disabled","description":"Unavailable action, out of the tab order.","code":"import { Trash as TrashIcon } from '@phosphor-icons/react';\n\n<IconButton aria-label=\"Delete row\" variant=\"outlined\" disabled>\n <TrashIcon aria-hidden />\n</IconButton>"}],"contract":{"propsSummary":["children: ReactNode - icon element (required)","variant: ghost|subtle|outlined - visual treatment","size: sm|md|lg - square control size","pressed: boolean - toggle state exposed with aria-pressed","aria-label or aria-labelledby - required accessible name"],"a11yRules":["A11Y_BTN_LABEL","A11Y_BTN_FOCUS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","variant: ghost|subtle|outlined (default: ghost)","size: sm|md|lg (default: md)","pressed: boolean","aria-label: string","aria-labelledby: string"],"sourcePath":"src/components/IconButton/index.tsx","exportName":"IconButton","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-07-14T00:00:00.000Z"},"performance":{"bundleSize":714,"rawSize":1334,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"IconButton (self)","bytes":549,"percent":41},{"path":"ComponentDefaults","bytes":193,"percent":14}]}},"Image":{"filePath":"src/components/Image/index.tsx","meta":{"name":"Image","description":"Renders a picture at a fixed shape with a built-in fallback when loading fails.","category":"display","tags":["image","media","photo","picture","visual"],"status":"stable"},"usage":{"when":["Product shots, thumbnails, and hero art","Uploads you do not control and cannot trust to load"],"whenNot":["A person (use Avatar)","A symbol (use Icon)","Pure decoration behind content (use a CSS background)"],"guidelines":["Set aspectRatio so a grid holds its shape before the file arrives","objectFit=\"contain\" for logos, \"cover\" for photography","Always give fallback something to say","imgProps, onImageLoad, and onImageError expose the raw img when you need it"],"accessibility":["alt is required — describe what the picture shows","Decoration takes alt=\"\"","Words baked into an image must be repeated in alt"]},"props":{"src":{"type":"string","description":"Image source URL","required":true},"alt":{"type":"string","description":"Alt text for accessibility (required)","required":true},"aspectRatio":{"type":"enum","description":"Aspect ratio of the image container","default":"auto","required":false,"values":["1:1","4:3","16:9","21:9","auto"]},"objectFit":{"type":"enum","description":"How the image fits within its container","default":"cover","required":false,"values":["cover","contain","fill","none"]},"width":{"type":"union","description":"Width of the image container","required":false},"height":{"type":"union","description":"Height of the image container","required":false},"rounded":{"type":"enum","description":"Border radius","default":"none","required":false,"values":["none","sm","md","lg","full"]},"fallback":{"type":"node","description":"Content to show while loading or on error","required":false},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false},"imgProps":{"type":"object","description":"Additional props for the underlying img element (except src/alt/size/style/events)","required":false},"onImageLoad":{"type":"function","description":"Called when the underlying img element loads","required":false},"onImageError":{"type":"function","description":"Called when the underlying img element fails to load","required":false}},"relations":[{"component":"Card","relationship":"child","note":"Common pattern to use Image at top of product cards"},{"component":"Avatar","relationship":"alternative","note":"Use Avatar for user profile pictures"}],"variants":[{"name":"Default","description":"src plus alt — the shape follows the file.","code":"<Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=400&h=300&fit=crop\"\n alt=\"Code on a screen\"\n width={300}\n/>"},{"name":"Aspect Ratios","description":"Lock the frame so a grid stays even whatever the file is.","code":"<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=200&fit=crop\"\n alt=\"Square image\"\n aspectRatio=\"1:1\"\n width={100}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=150&fit=crop\"\n alt=\"4:3 image\"\n aspectRatio=\"4:3\"\n width={120}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=320&h=180&fit=crop\"\n alt=\"16:9 image\"\n aspectRatio=\"16:9\"\n width={160}\n />\n</div>"},{"name":"Rounded Corners","description":"Rounding softens the frame; match it to the surface it sits on.","code":"<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"No rounding\"\n rounded=\"none\"\n width={80}\n height={80}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"Medium rounding\"\n rounded=\"md\"\n width={80}\n height={80}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"Full rounding\"\n rounded=\"full\"\n width={80}\n height={80}\n />\n</div>"},{"name":"With Fallback","description":"A dead URL shows this instead of a broken-image glyph.","code":"<Image\n src=\"https://invalid-url.example/image.jpg\"\n alt=\"Image that will fail\"\n width={200}\n height={150}\n rounded=\"md\"\n fallback={\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', background: 'var(--fui-color-surface-secondary)' }}>\n <span style={{ color: 'var(--fui-color-text-tertiary)' }}>No image</span>\n </div>\n }\n/>"}],"contract":{"propsSummary":["src: string - image URL (required)","alt: string - accessibility text (required)","aspectRatio: 1:1|4:3|16:9|21:9|auto - container ratio","objectFit: cover|contain|fill|none - image fitting","rounded: none|sm|md|lg|full - border radius","fallback: ReactNode - loading/error content","imgProps/onImageLoad/onImageError - low-level img customization and events"],"a11yRules":["A11Y_IMG_ALT","A11Y_IMG_DECORATIVE"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["src: string (required)","alt: string (required)","aspectRatio: 1:1|4:3|16:9|21:9|auto (default: auto)","objectFit: cover|contain|fill|none (default: cover)","width: union","height: union","rounded: none|sm|md|lg|full (default: none)","fallback: node","className: string","style: object","imgProps: object","onImageLoad: function","onImageError: function"],"sourcePath":"src/components/Image/index.tsx","exportName":"Image","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.379Z"},"performance":{"bundleSize":972,"rawSize":1781,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Image (self)","bytes":1194,"percent":67}]}},"Input":{"filePath":"src/components/Input/index.tsx","meta":{"name":"Input","description":"Collects a single line of user-entered text.","category":"inputs","tags":["form","input","text"],"status":"stable"},"usage":{"when":["Single-line answers: name, email, password, phone, URL","Search fields","Short free-form values a list cannot cover"],"whenNot":["Multi-line text (use Textarea)","Selecting from predefined options (use Select)","Boolean input (use Checkbox or Switch)","Date/time input (use DatePicker)"],"guidelines":["Give every field a label","Match type to the data — it drives validation and mobile keyboards","Placeholder shows format; it never replaces the label","Pair error with helperText so the reason is announced","Use the shortcut prop for kbd hints instead of custom markup","shortcut is display-only; shortcutBehavior=\"focus-input\" adds the global hotkey"],"accessibility":["Label is programmatically tied to the input","Error text is announced to screen readers","Required fields are marked"]},"props":{"value":{"type":"string","description":"Current input value (controlled)","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","required":false},"placeholder":{"type":"string","description":"Placeholder text shown when empty","required":false,"constraints":["Use for format hints only, not as a replacement for labels"]},"type":{"type":"enum","description":"HTML input type for validation and keyboard","default":"text","required":false,"values":["number","text","email","password","tel","url"]},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Whether the input is interactive","default":"false","required":false},"error":{"type":"boolean","description":"Whether to show error styling","default":"false","required":false},"success":{"type":"boolean","description":"Whether to show success/validated styling","default":"false","required":false},"label":{"type":"string","description":"Label text displayed above input","required":false},"required":{"type":"boolean","description":"Whether the field is required (shows asterisk)","default":"false","required":false},"helperText":{"type":"string","description":"Helper or error message below input","required":false},"startAdornment":{"type":"node","description":"Content rendered before the input (icon or prefix text)","required":false},"endAdornment":{"type":"node","description":"Content rendered after the input (icon or suffix text)","required":false},"shortcut":{"type":"string","description":"Keyboard shortcut hint displayed as a visual kbd token inside the input","required":false},"shortcutBehavior":{"type":"enum","description":"Whether shortcut hint is visual only or also registers a global focus hotkey","default":"display-only","required":false,"values":["display-only","focus-input"]},"onChange":{"type":"function","description":"Called with new value on change","required":false},"onValueChange":{"type":"function","description":"Value-first change callback alias: (value: string) => void","required":false},"onBlur":{"type":"function","description":"","required":false},"onFocus":{"type":"function","description":"","required":false},"onKeyDown":{"type":"function","description":"","required":false},"rootProps":{"type":"object","description":"HTML attributes applied to the wrapper element","required":false},"inputStyle":{"type":"object","description":"Inline styles applied directly to the input element","required":false},"inputClassName":{"type":"string","description":"Class name applied directly to the input element","required":false},"withFieldWrapper":{"type":"boolean","description":"Render built-in label/helper wrapper (set false for Field composition or bare input rendering)","default":"true","required":false},"className":{"type":"string","description":"Wrapper class name","required":false},"style":{"type":"object","description":"Wrapper styles","required":false}},"relations":[{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line text input"},{"component":"Select","relationship":"alternative","note":"Use Select when choosing from predefined options"},{"component":"Field","relationship":"parent","note":"Use Field for advanced form composition and custom controls"}],"variants":[{"name":"Default","description":"Label plus a placeholder that hints the format.","code":"<Input label=\"Name\" placeholder=\"Enter your name\" />"},{"name":"With Value","description":"Starts with a value already in the field.","code":"<Input label=\"Email\" type=\"email\" value=\"user@example.com\" />"},{"name":"With Helper","description":"Supporting text sits under the field.","code":"<Input\n label=\"Password\"\n type=\"password\"\n placeholder=\"Create a password\"\n helperText=\"Must be at least 8 characters\"\n/>"},{"name":"Error State","description":"Red border, and helperText becomes the reason.","code":"<Input\n label=\"Email\"\n type=\"email\"\n value=\"invalid-email\"\n error\n helperText=\"Please enter a valid email address\"\n/>"},{"name":"Disabled","description":"Dimmed, unfocusable, still shows its value.","code":"<Input label=\"Username\" value=\"ada.lovelace\" disabled />"},{"name":"Required","description":"Asterisk marks the field as mandatory.","code":"<Input\n label=\"Email\"\n type=\"email\"\n placeholder=\"user@example.com\"\n required\n/>"},{"name":"Sizes","description":"Three heights: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '300px' }}>\n <Input label=\"Small\" size=\"sm\" placeholder=\"Small input\" />\n <Input label=\"Medium\" size=\"md\" placeholder=\"Medium input\" />\n <Input label=\"Large\" size=\"lg\" placeholder=\"Large input\" />\n</div>"},{"name":"Bare Input (Field Composition)","description":"Drops the built-in label wrapper so Field owns the layout.","code":"<Input\n withFieldWrapper={false}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n rootProps={{ 'data-demo': 'bare-input-wrapper' }}\n/>"},{"name":"Search With Shortcut","description":"Leading icon and a ⌘K hint that focuses the field.","code":"<Input\n aria-label=\"Search findings\"\n placeholder=\"Search findings...\"\n shortcut=\"⌘K\"\n shortcutBehavior=\"focus-input\"\n startAdornment={<MagnifyingGlass aria-hidden=\"true\" />}\n withFieldWrapper={false}\n/>"},{"name":"Success State","description":"Green border confirms the value passed validation.","code":"<Input\n label=\"Email\"\n type=\"email\"\n value=\"user@example.com\"\n success\n helperText=\"Email verified\"\n/>"},{"name":"With Start Adornment","description":"Prefix sits inside the field, before the text.","code":"<Input\n label=\"Price\"\n placeholder=\"0.00\"\n startAdornment={<span>$</span>}\n/>"},{"name":"With End Adornment","description":"Suffix sits inside the field, after the text.","code":"<Input\n label=\"Weight\"\n placeholder=\"0\"\n endAdornment={<span>kg</span>}\n/>"}],"contract":{"propsSummary":["type: text|email|password|number|tel|url (default: text)","value: string - controlled input value","label: string - accessible label text","placeholder: string - format hint only","disabled: boolean - disables interaction","required: boolean - required field indicator","error: boolean - shows error styling","success: boolean - shows success/validated styling","startAdornment: ReactNode - content before the input (icon or prefix)","endAdornment: ReactNode - content after the input (icon or suffix)","shortcut: string - visual kbd hint inside the input; do not hand-roll extra kbd markup","helperText: string - helper/error message","onValueChange: (value: string) => void - value-first change callback alias","rootProps: HTMLAttributes<HTMLDivElement> - wrapper element props","withFieldWrapper: boolean - toggle built-in wrapper/label rendering (default: true)","shortcutBehavior: display-only|focus-input (default: display-only)","...native input attributes are supported (autoComplete, required, inputMode, pattern, etc.)"],"a11yRules":["A11Y_INPUT_LABEL","A11Y_INPUT_ERROR","A11Y_INPUT_REQUIRED"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["value: string","defaultValue: string","placeholder: string","type: number|text|email|password|tel|url (default: text)","size: sm|md|lg (default: md)","disabled: boolean (default: false)","error: boolean (default: false)","success: boolean (default: false)","label: string","required: boolean (default: false)","helperText: string","startAdornment: node","endAdornment: node","shortcut: string","shortcutBehavior: display-only|focus-input (default: display-only)","onChange: function","onValueChange: function","onBlur: function","onFocus: function","onKeyDown: function","rootProps: object","inputStyle: object","inputClassName: string","withFieldWrapper: boolean (default: true)","className: string","style: object"],"sourcePath":"src/components/Input/index.tsx","exportName":"Input","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.208Z"},"performance":{"bundleSize":1723,"rawSize":3914,"complexity":"lightweight","budgetPercent":11,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Input (self)","bytes":3004,"percent":77},{"path":"ComponentDefaults","bytes":198,"percent":5},{"path":"src/utils/aria.ts","bytes":110,"percent":3}]}},"Link":{"filePath":"src/components/Link/index.tsx","meta":{"name":"Link","description":"Navigates somewhere else, inline or in chrome, with real link semantics.","category":"navigation","tags":["link","anchor","navigation","href","url"],"status":"stable"},"usage":{"when":["Inline links inside body text","Footer and sidebar navigation","\"Forgot password?\" and \"Sign up\" in forms","Pointing out to docs or external resources"],"whenNot":["A main call to action — use Button","Switching views in place — use Tabs","Dropdown items — use Menu"],"guidelines":["Name the destination; never \"click here\"","external sets target and rel — add your own \"opens in a new tab\" cue","subtle and muted for secondary and contextual links","Links must stay distinguishable from surrounding text","asChild composes handlers with the child rather than replacing them"],"accessibility":["The link text alone should make sense out of context","Say when a link opens a new window","Focus ring must stay visible","A link that looks like a button still needs link semantics"]},"props":{"children":{"type":"node","description":"Link text content","required":true},"variant":{"type":"enum","description":"Visual style variant","default":"default","required":false,"values":["default","subtle","muted"]},"underline":{"type":"enum","description":"Underline behavior","default":"hover","required":false,"values":["always","hover","none","dotted"]},"external":{"type":"boolean","description":"Opens in new tab with noopener noreferrer","default":"false","required":false},"asChild":{"type":"boolean","description":"Render as child element (polymorphic). Merges link props/classes and composes event handlers onto the single child (e.g. Next.js Link).","default":"false","required":false},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false},"target":{"type":"union","description":"","required":false},"rel":{"type":"string","description":"","required":false}},"relations":[{"component":"Button","relationship":"alternative","note":"Use Button for primary actions, Link for navigation"},{"component":"Text","relationship":"parent","note":"Links often appear within Text components"}],"variants":[{"name":"Default","description":"Accent text that underlines on hover.","code":"<Link href=\"#\">Learn more about our services</Link>"},{"name":"Variants","description":"Accent, then quieter, then quietest.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\" align=\"center\" wrap>\n <Link href=\"#\" variant=\"default\">Default</Link>\n <Link href=\"#\" variant=\"subtle\">Subtle</Link>\n <Link href=\"#\" variant=\"muted\">Muted</Link>\n</Stack>"},{"name":"Underline Styles","description":"Four rules for when the line shows.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\" align=\"center\" wrap>\n <Link href=\"#\" underline=\"always\">Always underlined</Link>\n <Link href=\"#\" underline=\"hover\">Underline on hover</Link>\n <Link href=\"#\" underline=\"dotted\">Dotted underline</Link>\n <Link href=\"#\" underline=\"none\">No underline</Link>\n</Stack>"},{"name":"External Link","description":"Sets target and rel; you still supply the visible cue.","code":"<Link href=\"https://example.com\" external>\n View documentation ↗\n</Link>"},{"name":"As Child (Polymorphic)","description":"Paints Link styling onto a router link and keeps both click handlers.","code":"<Link asChild variant=\"subtle\" onClick={() => {}}>\n <a href=\"#pricing\" onClick={() => {}}>\n Client-side navigation\n </a>\n</Link>"}],"contract":{"propsSummary":["children: ReactNode - link text (required)","href: string - destination URL","variant: default|subtle|muted - visual style","underline: always|hover|none|dotted - underline behavior","external: boolean - opens in new tab","asChild: boolean - polymorphic child rendering with merged styles and composed event handlers"],"a11yRules":["A11Y_LINK_TEXT","A11Y_LINK_FOCUS"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","variant: default|subtle|muted (default: default)","underline: always|hover|none|dotted (default: hover)","external: boolean (default: false)","asChild: boolean (default: false)","className: string","style: object","target: union","rel: string"],"sourcePath":"src/components/Link/index.tsx","exportName":"Link","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.546Z"},"performance":{"bundleSize":819,"rawSize":1449,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Link (self)","bytes":876,"percent":60}]}},"List":{"filePath":"src/components/List/index.tsx","meta":{"name":"List","description":"Stacks items down the page with evenly spaced bullets, numbers, or icons.","category":"display","tags":["list","items","bullet","ordered","unordered"],"status":"stable"},"usage":{"when":["Steps, instructions, or anything with an order","Feature and benefit lists","Plain stacks of links in a sidebar"],"whenNot":["Items are pickable (use Menu or Select)","Items have columns (use Table)","Items need their own surface (use Card in a Grid)"],"guidelines":["Order matters? Use as=\"ol\" so the numbers are real","Keep one icon meaning per list — mixing icons reads as noise","Write items in parallel grammar; scanning depends on it","Stop nesting at two levels"],"accessibility":["Real ul/ol markup means screen readers announce the item count","Icons are decorative — the text has to carry the meaning"]},"props":{"children":{"type":"node","description":"List.Item components","required":true},"as":{"type":"enum","description":"List type","default":"ul","required":false,"values":["ul","ol"]},"variant":{"type":"enum","description":"List style variant","default":"disc","required":false,"values":["none","disc","decimal","icon"]},"gap":{"type":"enum","description":"Spacing between items","default":"sm","required":false,"values":["none","xs","sm","md","lg"]},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Icon","relationship":"child","note":"Use Icon as List.Item icon prop"},{"component":"Stack","relationship":"alternative","note":"Use Stack for non-semantic vertical lists"}],"variants":[{"name":"Bullet List","description":"The default marker — reach for it when order does not matter.","code":"<List variant=\"disc\">\n <List.Item>First item</List.Item>\n <List.Item>Second item</List.Item>\n <List.Item>Third item</List.Item>\n</List>"},{"name":"Numbered List","description":"as=\"ol\" makes the sequence real, not just visual.","code":"<List as=\"ol\" variant=\"decimal\">\n <List.Item>Create your account</List.Item>\n <List.Item>Configure your settings</List.Item>\n <List.Item>Start building</List.Item>\n</List>"},{"name":"Icon List","description":"Each item takes its own icon — checkmarks sell a feature list.","code":"<List variant=\"icon\">\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Unlimited projects\n </List.Item>\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Priority support\n </List.Item>\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Advanced analytics\n </List.Item>\n</List>"},{"name":"No Style","description":"No markers, wider gap — the shape for stacked nav links.","code":"<List variant=\"none\" gap=\"md\">\n <List.Item>Dashboard</List.Item>\n <List.Item>Settings</List.Item>\n <List.Item>Profile</List.Item>\n</List>"}],"contract":{"propsSummary":["children: List.Item[] - list items (required)","as: ul|ol - list type","variant: none|disc|decimal|icon - list style","gap: none|xs|sm|md|lg - item spacing"],"a11yRules":["A11Y_LIST_SEMANTIC","A11Y_LIST_NESTING"]},"ai":{"compositionPattern":"compound","subComponents":["Item"],"commonPatterns":["<List>\n <List.Item>...</List.Item>\n</List>"],"requiredChildren":["Item"]},"propsSummary":["children: node (required)","as: ul|ol (default: ul)","variant: none|disc|decimal|icon (default: disc)","gap: none|xs|sm|md|lg (default: sm)","style: object"],"sourcePath":"src/components/List/index.tsx","exportName":"List","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.915Z"},"performance":{"bundleSize":749,"rawSize":1462,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"List (self)","bytes":828,"percent":57}]}},"Listbox":{"filePath":"src/components/Listbox/index.tsx","meta":{"name":"Listbox","description":"Shows a keyboard-navigable list of options with no trigger of its own.","category":"inputs","tags":["listbox","search","autocomplete","combobox","command","dropdown"],"status":"stable"},"usage":{"when":["Results under a search field","Autocomplete suggestions","Command palette results","Any list the user drives with arrow keys"],"whenNot":["A list nobody selects from (use List)","Actions behind a button (use Menu)","A form field (use Select)","Navigation (use Sidebar or Tabs)"],"guidelines":["You own open state — drive it from the input's focus and query","Arrows, Home, End, Enter, and Space are handled for you","Always supply Listbox.Empty","Group once the list draws from more than one source"],"accessibility":["Uses listbox and option ARIA roles","aria-selected indicates current selection","aria-disabled for non-interactive items","Connect to input with aria-controls for full combobox pattern"]},"props":{"children":{"type":"node","description":"Listbox.Item, Listbox.Group, or Listbox.Empty components","required":true},"style":{"type":"object","description":"","required":false},"tabIndex":{"type":"number","description":"","required":false},"onFocus":{"type":"function","description":"","required":false},"onKeyDown":{"type":"function","description":"","required":false}},"relations":[{"component":"Input","relationship":"sibling","note":"Pair with Input for search/autocomplete patterns"},{"component":"Menu","relationship":"alternative","note":"Use Menu when you need a trigger button"},{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"List","relationship":"alternative","note":"Use List for static, non-interactive lists"}],"variants":[{"name":"Default","description":"Plain options, one selectable at a time.","code":"<Listbox aria-label=\"Options\">\n <Listbox.Item selected>First option</Listbox.Item>\n <Listbox.Item>Second option</Listbox.Item>\n <Listbox.Item>Third option</Listbox.Item>\n</Listbox>"},{"name":"Search Results","description":"Trailing metadata explains each match.","code":"<Listbox aria-label=\"Search results\">\n <Listbox.Item selected>\n <span style={{ fontWeight: 500 }}>Button</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Components</span>\n </Listbox.Item>\n <Listbox.Item>\n <span style={{ fontWeight: 500 }}>Badge</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Components</span>\n </Listbox.Item>\n <Listbox.Item>\n <span style={{ fontWeight: 500 }}>Box</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Layout</span>\n </Listbox.Item>\n</Listbox>"},{"name":"With Groups","description":"Labels split the list by source.","code":"<Listbox aria-label=\"Commands\">\n <Listbox.Group label=\"Recent\">\n <Listbox.Item selected>Open file...</Listbox.Item>\n <Listbox.Item>Save as...</Listbox.Item>\n </Listbox.Group>\n <Listbox.Group label=\"Actions\">\n <Listbox.Item>Copy</Listbox.Item>\n <Listbox.Item>Paste</Listbox.Item>\n <Listbox.Item disabled>Cut</Listbox.Item>\n </Listbox.Group>\n</Listbox>"},{"name":"Empty State","description":"Says so when nothing matches.","code":"<Listbox aria-label=\"Search results\">\n <Listbox.Empty>No results found</Listbox.Empty>\n</Listbox>"},{"name":"With Disabled Items","description":"Unavailable rows stay visible but inert.","code":"<Listbox aria-label=\"Options\">\n <Listbox.Item>Available option</Listbox.Item>\n <Listbox.Item disabled>Disabled option</Listbox.Item>\n <Listbox.Item>Another option</Listbox.Item>\n</Listbox>"}],"contract":{"propsSummary":["children: ReactNode - Listbox.Item components (required)","aria-label: string - accessible label","Listbox.Item selected: boolean - highlight state","Listbox.Item disabled: boolean - non-interactive"],"a11yRules":["A11Y_LISTBOX_ROLE","A11Y_OPTION_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Group","Empty"],"requiredChildren":["Item"],"commonPatterns":["<Listbox aria-label=\"Search results\">{results.map(item => <Listbox.Item key={item.id} selected={item.id === selectedId} onClick={() => onSelect(item)}>{item.label}</Listbox.Item>)}</Listbox>"]},"propsSummary":["children: node (required)","style: object","tabIndex: number","onFocus: function","onKeyDown: function"],"sourcePath":"src/components/Listbox/index.tsx","exportName":"Listbox","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.924Z"},"performance":{"bundleSize":1661,"rawSize":3896,"complexity":"lightweight","budgetPercent":11,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Listbox (self)","bytes":3237,"percent":83}]}},"Loading":{"filePath":"src/components/Loading/index.tsx","meta":{"name":"Loading","description":"Signals that something is happening when you cannot say how long it will take.","category":"feedback","tags":["loading","spinner","progress","feedback","indicator","async"],"status":"stable"},"usage":{"when":["Fetching or processing content","Waiting on an async action to come back","Buttons, forms, and page sections mid-request","The first paint of an app or page"],"whenNot":["You know the percentage — use Progress","You know the page shape — use Skeleton","AI reasoning states — use ThinkingIndicator"],"guidelines":["spinner for general waits","dots for chat and messaging","pulse for quiet ambient waiting","Always pass a label describing what is loading","Loading.Screen for first page load, Loading.Inline to sit inside a sentence"],"accessibility":["Announced through role=\"status\" with aria-live=\"polite\"","label is what a screen reader reads — make it specific","Animation stops for prefers-reduced-motion"]},"props":{"size":{"type":"enum","description":"Size of the loading indicator","default":"md","required":false,"values":["sm","md","lg","xl"]},"variant":{"type":"enum","description":"Visual style of the loading animation","default":"spinner","required":false,"values":["spinner","dots","pulse"]},"label":{"type":"string","description":"Accessible label for screen readers","default":"Loading...","required":false},"centered":{"type":"boolean","description":"Whether to center the loading indicator in its container","default":"false","required":false},"fill":{"type":"boolean","description":"Whether to fill the parent container","default":"false","required":false},"overlay":{"type":"boolean","description":"Whether to show with a backdrop overlay","default":"false","required":false},"color":{"type":"enum","description":"Color variant - accent uses theme color, current inherits text color","default":"accent","required":false,"values":["accent","current","muted"]}},"relations":[],"variants":[{"name":"Default","description":"Spinner at medium size, accent coloured.","code":"<Loading label=\"Loading content\" />"},{"name":"Sizes","description":"sm inside controls, xl for a whole page.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"lg\" align=\"center\">\n <Loading size=\"sm\" label=\"Loading\" />\n <Loading size=\"md\" label=\"Loading\" />\n <Loading size=\"lg\" label=\"Loading\" />\n <Loading size=\"xl\" label=\"Loading\" />\n</Stack>"},{"name":"Dots","description":"Three bouncing dots, at home in a message thread.","code":"<Loading variant=\"dots\" label=\"Sending message\" />"},{"name":"Pulse","description":"One breathing dot for ambient background work.","code":"<Loading variant=\"pulse\" label=\"Syncing\" />"},{"name":"Colors","description":"Accent, muted, or whatever the surrounding text is.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"lg\" align=\"center\">\n <Loading color=\"accent\" label=\"Loading\" />\n <Loading color=\"muted\" label=\"Loading\" />\n <span style={{ color: 'var(--fui-color-info)' }}>\n <Loading color=\"current\" label=\"Loading\" />\n </span>\n</Stack>"},{"name":"Inline","description":"Sits on the text baseline mid-sentence.","code":"<p style={{ margin: 0 }}>\n Processing your request <Loading.Inline label=\"Processing\" /> please wait…\n</p>"},{"name":"Centered","description":"Fills its container and centres in it.","code":"<div\n style={{\n width: '200px',\n height: '100px',\n border: '1px dashed var(--fui-border)',\n borderRadius: 'var(--fui-radius-md)',\n }}\n>\n <Loading centered fill label=\"Loading section\" />\n</div>"},{"name":"Screen","description":"Covers the surface it sits on and names the wait.","code":"<div\n style={{\n position: 'relative',\n contain: 'layout',\n width: '300px',\n height: '200px',\n border: '1px solid var(--fui-border)',\n borderRadius: 'var(--fui-radius-md)',\n overflow: 'hidden',\n }}\n>\n <Loading.Screen size=\"lg\" label=\"Loading application…\" showLabel />\n</div>"}],"contract":{"propsSummary":["size: sm|md|lg|xl (default: md)","variant: spinner|dots|pulse (default: spinner)","label: string (default: Loading...)","centered: boolean (default: false)","fill: boolean (default: false)","overlay: boolean (default: false)","color: accent|current|muted (default: accent)"]},"ai":{"compositionPattern":"compound","subComponents":["Inline","Screen"]},"propsSummary":["size: sm|md|lg|xl (default: md)","variant: spinner|dots|pulse (default: spinner)","label: string (default: Loading...)","centered: boolean (default: false)","fill: boolean (default: false)","overlay: boolean (default: false)","color: accent|current|muted (default: accent)"],"sourcePath":"src/components/Loading/index.tsx","exportName":"Loading","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.576Z"},"performance":{"bundleSize":1129,"rawSize":2679,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Loading (self)","bytes":2035,"percent":76}]}},"Main":{"filePath":"src/components/Main/index.tsx","meta":{"name":"Main","description":"Owns a page's gutters, reading measure, and vertical rhythm.","category":"layout","tags":["main","page","layout","compound"],"status":"stable"},"usage":{"when":["Laying out a page's header, description, content, and footer","Giving a page one consistent gutter and measure"],"whenNot":["Shell-level navigation chrome (use AppShell)","Arbitrary spacing inside a component (use Stack or Box)"],"guidelines":["One Main per page owns the gutters — do not nest them","measure=\"narrow\" caps content for reading; \"full\" uses the whole canvas","Compose regions with Main.Header, Main.Description, Main.Content, Main.Footer","Main.Description caps itself at 68ch regardless of measure"],"accessibility":["Use the default main element unless an existing shell already owns the main landmark"]},"props":{"children":{"type":"node","description":"Page regions composed from Main.Header, Main.Description, Main.Content, and Main.Footer","required":true},"measure":{"type":"enum","description":"Maximum width applied to the page composition","default":"full","required":false,"values":["full","narrow"]},"as":{"type":"enum","description":"Semantic HTML element rendered by the root","default":"main","required":false,"values":["div","section","nav","article","aside","header","footer","main","ul","ol"]}},"relations":[],"variants":[{"name":"Full Measure","description":"Content fills the canvas, inset only by the page gutter.","code":"import { Box } from '@/components/Box';\nimport { Main } from '@/components/Main';\n\n<Box width=\"100%\" border rounded=\"md\">\n <Main measure=\"full\">\n <Main.Header>Findings</Main.Header>\n <Main.Description>\n Every governance finding raised against this repository, newest first.\n </Main.Description>\n <Main.Content>\n Content stretches edge to edge, inset only by the page gutter.\n </Main.Content>\n <Main.Footer>Export report</Main.Footer>\n </Main>\n</Box>"},{"name":"Narrow Measure","description":"Caps content at the reading measure and centres it on wide screens.","code":"import { Box } from '@/components/Box';\nimport { Main } from '@/components/Main';\n\n<Box width=\"100%\" border rounded=\"md\">\n <Main measure=\"narrow\">\n <Main.Header>Settings</Main.Header>\n <Main.Description>\n Manage the workspace contract, canonical components, and token files.\n </Main.Description>\n <Main.Content>\n Content is capped at the reading measure and centred, so long prose stays\n comfortable to read on wide displays.\n </Main.Content>\n <Main.Footer>Save changes</Main.Footer>\n </Main>\n</Box>"}],"contract":{"propsSummary":["children: node (required)","measure: full|narrow (default: full)","as: semantic element (default: main)"]},"ai":{"compositionPattern":"compound","subComponents":["Header","Description","Content","Footer"],"commonPatterns":["<Main>\n <Main.Header>...</Main.Header>\n <Main.Description>...</Main.Description>\n <Main.Content>...</Main.Content>\n <Main.Footer>...</Main.Footer>\n</Main>"],"requiredChildren":["Header","Description","Content","Footer"]},"propsSummary":["children: node (required)","measure: full|narrow (default: full)","as: semantic element (default: main)"],"sourcePath":"src/components/Main/index.tsx","exportName":"Main","provenance":{"source":"manual","verified":true,"frameworkSupport":"native"},"performance":{"bundleSize":2477,"rawSize":6486,"complexity":"lightweight","budgetPercent":16,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Stack","bytes":4773,"percent":74},{"path":"Main (self)","bytes":1139,"percent":18}]}},"Markdown":{"filePath":"src/components/Markdown/index.tsx","meta":{"name":"Markdown","description":"Turns a Markdown string into styled headings, lists, tables, code, and quotes.","category":"display","tags":["markdown","prose","content","text","ai","chat"],"status":"stable","dependencies":[{"name":"react-markdown","version":">=9.0.0","reason":"Optional — parses markdown; without it content renders as plain paragraphs."},{"name":"remark-gfm","version":">=4.0.0","reason":"Optional — adds GitHub-flavored markdown (tables, strikethrough, task lists)."}]},"usage":{"when":["Rendering an LLM reply","Showing text a user wrote in Markdown","Docs or readme content inside the app"],"whenNot":["The string has no formatting (use Text)","The user needs to edit it (use an editor)"],"guidelines":["react-markdown and remark-gfm are peer dependencies — install both","The parser loads on demand, so the first frame is plain text; call Markdown.preload() at startup to skip it","Without react-markdown installed it degrades to plain paragraphs","components overrides how any element renders","react-markdown sanitises the content for you"],"accessibility":["Output is real headings, lists, and tables","Links render as anchors, images keep their alt text"]},"props":{"content":{"type":"string","description":"Markdown string to render","required":true},"components":{"type":"object","description":"Override map for markdown element components (e.g., { h1: MyHeading }). Accepts custom renderer component signatures used by react-markdown","required":false},"className":{"type":"string","description":"Additional CSS class name","required":false}},"relations":[{"component":"Text","relationship":"alternative","note":"Use Text for plain, non-markdown text"},{"component":"CodeBlock","relationship":"complementary","note":"CodeBlock can be used via components prop for syntax highlighting"},{"component":"Message","relationship":"parent","note":"Message wraps Markdown when markdown prop is true"}],"variants":[{"name":"Default","description":"Headings, emphasis, lists, and quotes all pick up the type scale.","code":"<Markdown content={`# Hello World\n\nThis is a paragraph with **bold text** and *italic text*.\n\nHere is some \\`inline code\\` within a sentence.\n\n- First item\n- Second item\n- Third item\n\n> A blockquote for emphasis.\n`} />"},{"name":"GFM Table","description":"remark-gfm adds tables and checkbox items on top of the basics.","code":"<Markdown content={`## Data Overview\n\n| Feature | Status | Priority |\n|------------|-----------|----------|\n| Markdown | Done | High |\n| Tables | Done | Medium |\n| Task Lists | Planned | Low |\n\nNotes:\n- [x] Support GFM tables\n- [x] Support task lists\n- [ ] Syntax highlighting\n`} />"},{"name":"Code Block","description":"Fenced blocks get the same code surface as CodeBlock.","code":"<Markdown content={`## Code Example\n\nHere is a JavaScript function:\n\n```js\nfunction greet(name) {\n return 'Hello, ' + name;\n}\n```\n\nAnd some inline code: \\`const x = 42;\\``} />"},{"name":"Mixed Content","description":"A realistic document — the worst case worth checking.","code":"<Markdown content={`# Project Update\n\n## Summary\n\nThe project is progressing well. Here are the **key highlights**:\n\n1. Completed the *design system* components\n2. Added markdown rendering support\n3. Integrated with the documentation site\n\n### Performance Metrics\n\n| Metric | Before | After |\n|-------------|--------|-------|\n| Bundle Size | 142kb | 98kb |\n| Load Time | 1.2s | 0.8s |\n| Lighthouse | 72 | 95 |\n\n> These improvements were achieved through tree-shaking and code splitting.\n\n### Next Steps\n\n- [ ] Add syntax highlighting\n- [ ] Support custom themes\n- [x] GFM table support\n`} />"}],"contract":{"propsSummary":["content: string - Markdown string to render","components: object - Override map for element components (react-markdown renderer components)","className: string - Additional CSS class","Forwards standard HTML div attributes to the wrapper element"],"a11yRules":["A11Y_SEMANTIC_HTML"]},"ai":{"compositionPattern":"compound","subComponents":["Root","preload"]},"propsSummary":["content: string (required)","components: object","className: string"],"sourcePath":"src/components/Markdown/index.tsx","exportName":"Markdown","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.091Z"},"performance":{"bundleSize":50131,"rawSize":162539,"complexity":"heavy","budgetPercent":326,"overBudget":true,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"react-markdown","bytes":120667,"percent":74},{"path":"remark-gfm","bytes":40158,"percent":25},{"path":"Markdown (self)","bytes":962,"percent":1}]}},"Menu":{"filePath":"src/components/Menu/index.tsx","meta":{"name":"Menu","description":"Drops a list of actions below a trigger, driveable entirely by keyboard.","category":"overlays","tags":["menu","dropdown","actions","context-menu","commands","submenu"],"status":"stable"},"usage":{"when":["Actions that do not fit in the toolbar","Right-click context actions","Account and profile actions","Related actions that read better grouped"],"whenNot":["Picking a value for a form (use Select)","Moving between pages or views (use Tabs or NavigationMenu)","One of a few visible choices (use RadioGroup)"],"guidelines":["Group related actions and separate the rest","Show the keyboard shortcut where one exists","Mark destructive actions with the danger variant","Past a dozen rows, reach for Command instead","Nest at most one level of submenu","asChild on Trigger needs a single element child"],"accessibility":["Full keyboard navigation with arrow keys","Type-ahead search for items","Focus returns to trigger on close","Proper ARIA menu roles","ArrowRight opens submenus, ArrowLeft closes them"]},"props":{"children":{"type":"node","description":"Menu trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"modal":{"type":"boolean","description":"Whether menu is modal","default":"true","required":false}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"Popover","relationship":"alternative","note":"Use Popover for rich non-action content"}],"variants":[{"name":"Default","description":"Plain actions, one per row.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Actions</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>Edit</Menu.Item>\n <Menu.Item onSelect={() => {}}>Duplicate</Menu.Item>\n <Menu.Separator />\n <Menu.Item danger onSelect={() => {}}>Delete</Menu.Item>\n </Menu.Content>\n</Menu>"},{"name":"With Shortcuts","description":"Trailing keys teach the faster path.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Edit</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item shortcut=\"Ctrl+Z\" onSelect={() => {}}>Undo</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+Y\" onSelect={() => {}}>Redo</Menu.Item>\n <Menu.Separator />\n <Menu.Item shortcut=\"Ctrl+C\" onSelect={() => {}}>Copy</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+V\" onSelect={() => {}}>Paste</Menu.Item>\n </Menu.Content>\n</Menu>"},{"name":"With Groups","description":"Labels separate unrelated actions.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Options</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Group>\n <Menu.GroupLabel>View</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Zoom In</Menu.Item>\n <Menu.Item onSelect={() => {}}>Zoom Out</Menu.Item>\n </Menu.Group>\n <Menu.Separator />\n <Menu.Group>\n <Menu.GroupLabel>Layout</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Grid View</Menu.Item>\n <Menu.Item onSelect={() => {}}>List View</Menu.Item>\n </Menu.Group>\n </Menu.Content>\n</Menu>"},{"name":"With Checkboxes","description":"Rows that stay open while you toggle them.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">Display</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.CheckboxItem defaultChecked>Show Grid</Menu.CheckboxItem>\n <Menu.CheckboxItem defaultChecked>Show Rulers</Menu.CheckboxItem>\n <Menu.CheckboxItem>Show Guides</Menu.CheckboxItem>\n </Menu.Content>\n</Menu>"},{"name":"With Checked Items","description":"Ticks mark which filters are on.","code":"<CheckedItemsMenuDemo />"},{"name":"With Submenu","description":"Secondary options nest one level deep.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"secondary\">File</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>New File</Menu.Item>\n <Menu.Item onSelect={() => {}}>Open</Menu.Item>\n <Menu.Separator />\n <Menu.Submenu>\n <Menu.SubmenuTrigger>Export As</Menu.SubmenuTrigger>\n <Menu.Content side=\"right\" align=\"start\">\n <Menu.Item onSelect={() => {}}>PNG</Menu.Item>\n <Menu.Item onSelect={() => {}}>SVG</Menu.Item>\n <Menu.Item onSelect={() => {}}>PDF</Menu.Item>\n </Menu.Content>\n </Menu.Submenu>\n <Menu.Separator />\n <Menu.Item danger onSelect={() => {}}>Delete</Menu.Item>\n </Menu.Content>\n</Menu>"},{"name":"Link Trigger","description":"asChild lets a link open it.","code":"<Menu>\n <Menu.Trigger asChild>\n <a href=\"#menu-actions\">Open menu</a>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>Inspect</Menu.Item>\n <Menu.Item onSelect={() => {}}>Rename</Menu.Item>\n </Menu.Content>\n</Menu>"}],"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - state handler","Menu.Trigger asChild supports non-button trigger elements","Menu.Item onSelect: (event) => void - selection callback receives click event","Menu.Item danger: boolean - destructive styling","Menu.Item shortcut: string - keyboard shortcut text","Menu.Item checked: boolean - check indicator for selection state"],"a11yRules":["A11Y_MENU_KEYBOARD","A11Y_MENU_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Item","CheckboxItem","RadioGroup","RadioItem","Group","GroupLabel","Separator","Submenu","SubmenuTrigger"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Menu><Menu.Trigger asChild><Button>Actions</Button></Menu.Trigger><Menu.Content><Menu.Item>{action1}</Menu.Item><Menu.Separator /><Menu.Item danger>{delete}</Menu.Item></Menu.Content></Menu>"]},"propsSummary":["children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","modal: boolean (default: true)"],"sourcePath":"src/components/Menu/index.tsx","exportName":"Menu","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:00.159Z"},"performance":{"bundleSize":2627,"rawSize":7581,"complexity":"lightweight","budgetPercent":17,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Menu (self)","bytes":3945,"percent":52},{"path":"src/recipes/popup.ts","bytes":2831,"percent":37}]}},"Message":{"filePath":"src/components/Message/index.tsx","meta":{"name":"Message","description":"Shows one chat message, styled by who sent it.","category":"ai","tags":["message","chat","ai","conversation","bubble"],"status":"stable"},"usage":{"when":["Individual turns in a chat transcript","AI assistant and chatbot interfaces","User and assistant turns that must read differently","Turns carrying copy, regenerate, or feedback actions"],"whenNot":["Plain text with no chat context (use Text)","Notifications (use Alert or Toast)","Threads with nested replies (use Card with a custom layout)"],"guidelines":["Always set role — it drives alignment, avatar, and chrome","status covers sending, streaming, and error","Hide avatars with avatar={null}, or showAvatars={false} on ConversationList","User bubbles cap at 80% of the inline measure so the two sides stay distinct","Chrome stays on neutral surfaces; reserve accent for actions and semantic state","Add timestamps once a conversation runs long","Give assistant turns hover actions such as copy and regenerate"],"accessibility":["Uses semantic HTML for message structure","Role-based styling has sufficient color contrast","Actions are keyboard accessible","Streaming indicator respects reduced motion preferences"]},"props":{"role":{"type":"enum","description":"Message role determines styling and alignment","required":true,"values":["user","assistant","system"]},"children":{"type":"node","description":"Message content","required":true},"status":{"type":"enum","description":"Message state","default":"complete","required":false,"values":["sending","streaming","complete","error"]},"timestamp":{"type":"object","description":"When the message was sent","required":false},"avatar":{"type":"node","description":"Custom avatar override (null to hide)","required":false},"actions":{"type":"node","description":"Hover actions (copy, regenerate)","required":false}},"relations":[{"component":"ConversationList","relationship":"parent","note":"Messages are typically used within ConversationList"},{"component":"Avatar","relationship":"child","note":"Use Avatar component for custom avatar content"},{"component":"ThinkingIndicator","relationship":"sibling","note":"Show ThinkingIndicator while awaiting assistant response"}],"variants":[{"name":"User Message","description":"Right-aligned and capped at 80% of the available width.","code":"<Message role=\"user\">\n <Message.Content>\n Hello! Can you help me with a coding question?\n </Message.Content>\n</Message>"},{"name":"Assistant Message","description":"Left-aligned with an avatar and a wider measure.","code":"<Message role=\"assistant\">\n <Message.Content>\n Of course! I'd be happy to help. What would you like to know?\n </Message.Content>\n</Message>"},{"name":"System Message","description":"Centred and quiet, for context rather than conversation.","code":"<Message role=\"system\">\n <Message.Content>\n Conversation started. Model: GPT-4\n </Message.Content>\n</Message>"},{"name":"Streaming","description":"A blinking caret trails the text as it arrives.","code":"<Message role=\"assistant\" status=\"streaming\">\n <Message.Content>\n I'm currently generating a response for you\n </Message.Content>\n</Message>"},{"name":"With Timestamp","description":"A relative send time sits beneath the bubble.","code":"<Message role=\"assistant\" timestamp={new Date(Date.now() - 300000)}>\n <Message.Content>\n This message was sent 5 minutes ago.\n </Message.Content>\n <Message.Timestamp />\n</Message>"},{"name":"Error State","description":"A failed send turns the bubble and its border red.","code":"<Message role=\"user\" status=\"error\">\n <Message.Content>\n This message failed to send.\n </Message.Content>\n</Message>"},{"name":"Custom Avatars","description":"Photos replace the default glyphs on both sides.","code":"<>\n <Message\n role=\"user\"\n avatar={<Message.Avatar src=\"https://i.pravatar.cc/64?u=user\" alt=\"Jane\" />}\n >\n <Message.Content>\n Can you help me understand this error?\n </Message.Content>\n </Message>\n <Message\n role=\"assistant\"\n avatar={<Message.Avatar src=\"https://i.pravatar.cc/64?u=bot\" alt=\"AI Assistant\" />}\n >\n <Message.Content>\n Sure! Let me take a look at that for you.\n </Message.Content>\n </Message>\n</>"},{"name":"With Actions","description":"Controls stay hidden until the pointer enters the row.","code":"<Message\n role=\"assistant\"\n actions={\n <>\n <Button variant=\"ghost\" size=\"xs\">\n Copy\n </Button>\n <Button variant=\"ghost\" size=\"xs\">\n Regenerate\n </Button>\n </>\n }\n>\n <Message.Content>\n Hover over this message to see the actions.\n </Message.Content>\n</Message>"}],"contract":{"propsSummary":["role: \"user\" | \"assistant\" | \"system\" - determines styling","children: ReactNode - message content","status: \"sending\" | \"streaming\" | \"complete\" | \"error\" - message state","timestamp: Date - when message was sent","avatar: ReactNode - custom avatar (null to hide)","actions: ReactNode - hover actions","Avatar.src: string - image URL for avatar","Avatar.alt: string - alt text for image avatar"],"a11yRules":["A11Y_COLOR_CONTRAST","A11Y_MOTION_PREFERENCE"]},"ai":{"compositionPattern":"compound","subComponents":["Content","Actions","Timestamp","Avatar"],"commonPatterns":["<Message>\n <Message.Content>...</Message.Content>\n</Message>"],"requiredChildren":["Content"]},"propsSummary":["role: user|assistant|system (required)","children: node (required)","status: sending|streaming|complete|error (default: complete)","timestamp: object","avatar: node","actions: node"],"sourcePath":"src/components/Message/index.tsx","exportName":"Message","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:00.333Z"},"performance":{"bundleSize":53976,"rawSize":173874,"complexity":"heavy","budgetPercent":351,"overBudget":true,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Markdown","bytes":161807,"percent":93},{"path":"ConversationList","bytes":4749,"percent":3},{"path":"Avatar","bytes":3348,"percent":2},{"path":"Message (self)","bytes":3092,"percent":2}]}},"NavigationMenu":{"filePath":"src/components/NavigationMenu/index.tsx","meta":{"name":"NavigationMenu","description":"Site navigation whose dropdowns become a drawer on small screens.","category":"navigation","tags":["navigation","menu","header","dropdown","navbar","mobile","responsive","drawer"],"status":"stable"},"usage":{"when":["Header navigation with more than links","Dropdowns carrying titles, descriptions, or icons","Navigation that must survive a phone screen","Several sections that animate between each other"],"whenNot":["Flat links with no dropdowns (use Header.Nav)","Application actions like cut and paste (use Menu)","Persistent side navigation (use Sidebar)","Showing where the user already is (use Breadcrumbs)"],"guidelines":["Place it inside Header for site-level navigation","Add Viewport to animate between panels","Use MobileContent for sections that only make sense in the drawer","Title plus description for rich panels, plain Link for the rest","asChild on Link composes your handler and honours preventDefault()","Desktop triggers open on hover after a configurable delay","Point icons at your own icon package to replace the chevrons","Set mobileBreakpoint=\"lg\" when the shell drops its sidebar below 1024px"],"accessibility":["Uses disclosure pattern (not menu role) per W3C guidance","Keyboard: Arrow keys navigate between triggers, Enter/Space toggles, Escape closes","Content panels have role=\"region\" with aria-labelledby pointing to trigger","Mobile drawer has focus trap, Escape to close, and aria-modal","Supports prefers-reduced-motion for all animations"]},"props":{"children":{"type":"node","description":"NavigationMenu.List, NavigationMenu.Viewport, and optionally NavigationMenu.MobileContent","required":true},"value":{"type":"string","description":"Controlled open item value","required":false},"defaultValue":{"type":"string","description":"Default open item value","default":"''","required":false},"onValueChange":{"type":"function","description":"Callback when open item changes","required":false},"orientation":{"type":"enum","description":"'horizontal' | 'vertical'","default":"horizontal","required":false,"values":["horizontal","vertical"]},"delayDuration":{"type":"number","description":"Hover delay before opening (ms)","default":"200","required":false},"skipDelayDuration":{"type":"number","description":"Duration after close during which moving to another trigger opens instantly (ms)","default":"300","required":false},"icons":{"type":"object","description":"Optional icon overrides for triggerChevron, mobileMenu, mobileClose, and drawerClose controls","required":false},"mobileBreakpoint":{"type":"enum","description":"Viewport breakpoint below which the mobile drawer replaces desktop navigation","default":"md","required":false,"values":["md","lg"]}},"relations":[{"component":"Header","relationship":"sibling","note":"Place NavigationMenu inside Header for site navigation"},{"component":"Sidebar","relationship":"alternative","note":"Use Sidebar for persistent side navigation, NavigationMenu for header dropdowns"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action menus (role=menu), NavigationMenu for site navigation (disclosure pattern)"},{"component":"Breadcrumbs","relationship":"sibling","note":"Use Breadcrumbs for hierarchical page trail, NavigationMenu for site-level navigation"}],"variants":[{"name":"Default","description":"Two dropdowns beside one plain link.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"products\">\n <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <NavigationMenu.Link href=\"/analytics\" title=\"Analytics\" description=\"Track your metrics and KPIs.\" />\n <NavigationMenu.Link href=\"/automation\" title=\"Automation\" description=\"Automate your workflows.\" />\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"resources\">\n <NavigationMenu.Trigger>Resources</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <NavigationMenu.Link href=\"/docs\" title=\"Documentation\" description=\"Comprehensive API reference.\" />\n <NavigationMenu.Link href=\"/blog\" title=\"Blog\" description=\"Latest news and updates.\" />\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/pricing\">Pricing</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"With Rich Content","description":"A grid of icons, titles, and descriptions.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"platform\">\n <NavigationMenu.Trigger>Platform</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px', padding: '8px', minWidth: '400px' }}>\n <NavigationMenu.Link\n href=\"/dashboard\"\n title=\"Dashboard\"\n description=\"Overview of your project metrics.\"\n />\n <NavigationMenu.Link\n href=\"/analytics\"\n title=\"Analytics\"\n description=\"Deep dive into your data.\"\n />\n <NavigationMenu.Link\n href=\"/reports\"\n title=\"Reports\"\n description=\"Generate custom reports.\"\n />\n <NavigationMenu.Link\n href=\"/settings\"\n title=\"Settings\"\n description=\"Configure your workspace.\"\n />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"With Simple Links","description":"Link lists where descriptions would be noise.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"company\">\n <NavigationMenu.Trigger>Company</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'flex', flexDirection: 'column', padding: '4px', minWidth: '160px' }}>\n <NavigationMenu.Link href=\"/about\">About</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/careers\">Careers</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/contact\">Contact</NavigationMenu.Link>\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/blog\">Blog</NavigationMenu.Link>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/docs\">Docs</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"With Featured Card","description":"One promoted item leads the panel.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"learn\">\n <NavigationMenu.Trigger>Learn</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', padding: '8px', minWidth: '420px' }}>\n <NavigationMenu.Link\n href=\"/quickstart\"\n title=\"Quick Start\"\n description=\"Get up and running in 5 minutes with our getting started guide.\"\n featured\n />\n <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n <NavigationMenu.Link href=\"/docs\" title=\"Documentation\" description=\"API reference and guides.\" />\n <NavigationMenu.Link href=\"/examples\" title=\"Examples\" description=\"Browse example projects.\" />\n </div>\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"Vertical","description":"Panels open to the side instead of below.","code":"<div style={{ display: 'flex' }}>\n <NavigationMenu orientation=\"vertical\">\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"overview\">\n <NavigationMenu.Trigger>Overview</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ padding: '8px', minWidth: '200px' }}>\n <NavigationMenu.Link href=\"/intro\" title=\"Introduction\" description=\"Learn the basics.\" />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"guides\">\n <NavigationMenu.Trigger>Guides</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ padding: '8px', minWidth: '200px' }}>\n <NavigationMenu.Link href=\"/install\" title=\"Installation\" description=\"Get started quickly.\" />\n <NavigationMenu.Link href=\"/config\" title=\"Configuration\" description=\"Customize your setup.\" />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n </NavigationMenu>\n</div>"}],"contract":{"propsSummary":["value: string — controlled open item","onValueChange: (value) => void — open state handler","orientation: horizontal | vertical — layout direction","delayDuration: number — hover open delay (default: 200ms)","icons: { triggerChevron?, mobileMenu?, mobileClose?, drawerClose? } — custom internal control icons","mobileBreakpoint: md | lg — mobile drawer breakpoint (default: md)","NavigationMenu.Link: title + description + icon for structured links, or children for simple links","NavigationMenu.Link asChild: composes child and menu click handlers (preventDefault keeps menu open)","NavigationMenu.MobileContent: slot for extra mobile-only sections"],"a11yRules":["A11Y_DISCLOSURE_PATTERN","A11Y_KEYBOARD_NAV","A11Y_FOCUS_TRAP"]},"ai":{"compositionPattern":"compound","subComponents":["List","Item","Trigger","Content","Link","Indicator","Viewport","MobileBrand","MobileContent","MobileSection"],"requiredChildren":["List"],"commonPatterns":["<NavigationMenu><NavigationMenu.List><NavigationMenu.Item value=\"docs\"><NavigationMenu.Trigger>Docs</NavigationMenu.Trigger><NavigationMenu.Content><NavigationMenu.Link href=\"/guides\" title=\"Guides\" description=\"Learn the basics\" /></NavigationMenu.Content></NavigationMenu.Item></NavigationMenu.List><NavigationMenu.Viewport /></NavigationMenu>"]},"propsSummary":["children: node (required)","value: string","defaultValue: string","onValueChange: function","orientation: horizontal|vertical (default: horizontal)","delayDuration: number (default: 200)","skipDelayDuration: number (default: 300)","icons: object","mobileBreakpoint: md|lg (default: md)"],"sourcePath":"src/components/NavigationMenu/index.tsx","exportName":"NavigationMenu","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:01.458Z"},"performance":{"bundleSize":7933,"rawSize":25748,"complexity":"moderate","budgetPercent":52,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"NavigationMenu (self)","bytes":12903,"percent":50},{"path":"@phosphor-icons/react","bytes":5518,"percent":21},{"path":"Collapsible","bytes":2538,"percent":10},{"path":"ScrollArea","bytes":2504,"percent":10},{"path":"src/utils/a11y.tsx","bytes":1358,"percent":5}]}},"Pagination":{"filePath":"src/components/Pagination/index.tsx","meta":{"name":"Pagination","description":"Steps through content split across numbered pages.","category":"navigation","tags":["pagination","paging","pages","navigation"],"status":"stable"},"usage":{"when":["Data sets served a page at a time","Tables and lists with a known total","Search results past the first screen"],"whenNot":["Everything already fits on one page","Content that loads as the user scrolls","Switching between panels (use Tabs)","Steps in an order (use Stepper)"],"guidelines":["Sit it directly below what it pages","edgeCount keeps the first and last pages reachable","siblingCount sets how many neighbours show","The current page uses a neutral surface, not the brand accent","The root forwards id, aria-*, data-*, and handlers to <nav>","Your onClick runs first — call preventDefault() to stop the change"],"accessibility":["Uses nav element with aria-label=\"Pagination\"","aria-current=\"page\" marks the active page","Previous/Next buttons have descriptive aria-labels","Disabled buttons at boundaries prevent invalid navigation"]},"props":{"children":{"type":"node","description":"","required":true},"totalPages":{"type":"number","description":"Total number of pages","required":true},"page":{"type":"number","description":"Controlled current page (1-indexed)","required":false},"defaultPage":{"type":"number","description":"Default page (uncontrolled)","default":"1","required":false},"onPageChange":{"type":"function","description":"Called when page changes","required":false},"edgeCount":{"type":"number","description":"Number of pages shown at edges","default":"1","required":false},"siblingCount":{"type":"number","description":"Number of pages shown around current","default":"1","required":false},"size":{"type":"enum","description":"Visible action size. Resolves through ComponentDefaults when omitted.","required":false,"values":["sm","md","lg"]}},"relations":[{"component":"Table","relationship":"sibling","note":"Commonly paired for table pagination"},{"component":"Listbox","relationship":"alternative","note":"Use Listbox for small sets of options"}],"variants":[{"name":"Default","description":"Neighbours around the current page, ends always reachable.","code":"<Pagination totalPages={10} defaultPage={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"},{"name":"With Edge Pages","description":"Two pages pinned at each end.","code":"<Pagination totalPages={20} defaultPage={10} edgeCount={2} siblingCount={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"},{"name":"Compact","description":"Drops the neighbours when space is tight.","code":"<Pagination totalPages={20} defaultPage={10} siblingCount={0}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"},{"name":"Controlled","description":"You hold the page number in state.","code":"<Pagination totalPages={5} page={3}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"}],"contract":{"propsSummary":["totalPages: number - total page count (required)","page: number - controlled current page (1-indexed)","defaultPage: number - initial page (default: 1)","onPageChange: (page) => void - page change handler","edgeCount: number - pages at edges (default: 1)","siblingCount: number - pages around current (default: 1)","Forwards standard HTML nav attributes to the root element"],"a11yRules":["A11Y_NAV_LABEL","A11Y_CURRENT_PAGE"]},"ai":{"compositionPattern":"compound","subComponents":["Previous","Next","Items","Item","Ellipsis"],"requiredChildren":["Items"],"commonPatterns":["<Pagination totalPages={totalPages} page={currentPage} onPageChange={setPage}><Pagination.Previous /><Pagination.Items /><Pagination.Next /></Pagination>"]},"propsSummary":["children: node (required)","totalPages: number (required)","page: number","defaultPage: number (default: 1)","onPageChange: function","edgeCount: number (default: 1)","siblingCount: number (default: 1)"],"sourcePath":"src/components/Pagination/index.tsx","exportName":"Pagination","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:01.648Z"},"performance":{"bundleSize":1855,"rawSize":4918,"complexity":"lightweight","budgetPercent":12,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Pagination (self)","bytes":4002,"percent":81},{"path":"ComponentDefaults","bytes":194,"percent":4}]}},"Popover":{"filePath":"src/components/Popover/index.tsx","meta":{"name":"Popover","description":"Anchors interactive content to a trigger without blocking the page.","category":"overlays","tags":["popover","overlay","dropdown","floating","contextual"],"status":"stable"},"usage":{"when":["Editing a value in place","Previews richer than a line of text","Filter and picker panels","Content that outgrows a tooltip"],"whenNot":["A short hint (use Tooltip)","A list of actions (use Menu)","Anything that must block the page (use Dialog)","Feedback the user does not act on (use Toast or Alert)"],"guidelines":["One job per panel","Always give the user a visible way out","Pick a side that does not cover what the user just clicked","Add the arrow when the trigger is not obvious","asChild on Trigger and Close needs a single element child"],"accessibility":["Focus is moved to popover content on open","Closes on Escape key","Focus returns to trigger on close"]},"props":{"children":{"type":"node","description":"Popover trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"modal":{"type":"boolean","description":"Whether to block page interaction","default":"false","required":false}},"relations":[{"component":"Tooltip","relationship":"alternative","note":"Use Tooltip for brief, non-interactive hints"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for blocking interactions"}],"variants":[{"name":"Default","description":"Title, body, and a close control.","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Open Popover</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Close />\n <Popover.Title>Popover Title</Popover.Title>\n <Popover.Description>\n This is a popover with some content. It can contain text, forms, or other elements.\n </Popover.Description>\n </Popover.Content>\n</Popover>"},{"name":"With Form","description":"Enough room to edit a value in place.","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Edit Name</Button>\n </Popover.Trigger>\n <Popover.Content size=\"sm\">\n <Popover.Close />\n <Popover.Title>Edit Name</Popover.Title>\n <Popover.Body>\n <Input label=\"Display Name\" placeholder=\"Enter name\" />\n </Popover.Body>\n <Popover.Footer>\n <Popover.Close asChild>\n <Button variant=\"secondary\" size=\"sm\">Cancel</Button>\n </Popover.Close>\n <Button variant=\"primary\" size=\"sm\">Save</Button>\n </Popover.Footer>\n </Popover.Content>\n</Popover>"},{"name":"With Arrow","description":"The arrow ties the panel back to its trigger.","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Info</Button>\n </Popover.Trigger>\n <Popover.Content arrow>\n <Popover.Title>Quick Tip</Popover.Title>\n <Popover.Description>\n This popover has an arrow pointing to its trigger element.\n </Popover.Description>\n </Popover.Content>\n</Popover>"},{"name":"Positions","description":"Flips to the opposite side when space runs out.","code":"<div style={{ display: 'flex', gap: '16px', padding: '60px' }}>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Top</Button>\n </Popover.Trigger>\n <Popover.Content side=\"top\" size=\"sm\">\n <Popover.Description>Popover on top</Popover.Description>\n </Popover.Content>\n </Popover>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Bottom</Button>\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" size=\"sm\">\n <Popover.Description>Popover on bottom</Popover.Description>\n </Popover.Content>\n </Popover>\n</div>"},{"name":"Link Trigger","description":"asChild lets a link open it.","code":"<Popover>\n <Popover.Trigger asChild>\n <a href=\"#popover-help\">Open help</a>\n </Popover.Trigger>\n <Popover.Content size=\"sm\">\n <Popover.Description>Popover trigger can be an anchor when using asChild.</Popover.Description>\n </Popover.Content>\n</Popover>"}],"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - state handler","modal: boolean - blocks page interaction (default: false)","Popover.Trigger / Popover.Close asChild support non-button children","Popover.Content side: top|bottom|left|right - position"],"a11yRules":["A11Y_POPOVER_FOCUS","A11Y_POPOVER_ESCAPE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","Title","Description","Body","Footer"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Popover><Popover.Trigger asChild><Button>Open</Button></Popover.Trigger><Popover.Content><Popover.Close /><Popover.Title>{title}</Popover.Title><Popover.Description>{description}</Popover.Description></Popover.Content></Popover>","<Popover><Popover.Trigger asChild><a href=\"#help\">Open help</a></Popover.Trigger><Popover.Content>...</Popover.Content></Popover>"]},"propsSummary":["children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","modal: boolean (default: false)"],"sourcePath":"src/components/Popover/index.tsx","exportName":"Popover","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.154Z"},"performance":{"bundleSize":1344,"rawSize":3486,"complexity":"lightweight","budgetPercent":9,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Popover (self)","bytes":2744,"percent":79}]}},"Progress":{"filePath":"src/components/Progress/index.tsx","meta":{"name":"Progress","description":"Shows how far along a task is, as a bar or a ring.","category":"feedback","tags":["progress","loading","indicator","percentage","status"],"status":"stable"},"usage":{"when":["Upload and download progress","Percentage of a task finished","How much of a form is filled in","Waits where you know the duration"],"whenNot":["You cannot say how long — use Loading","Discrete steps — use a stepper","Status with no number — use Badge"],"guidelines":["Pass a value when you know the percentage; pass null when you do not","Add a label whenever the bar alone leaves the purpose unclear","success, warning, and danger carry state, not decoration","variant=\"neutral\" with role=\"meter\" for a magnitude where full is not success","Values outside min and max are clamped before display"],"accessibility":["Reports role=\"progressbar\" with aria-valuenow","role=\"meter\" is accepted for scalar readings inside a known range","The label is tied to the bar","Value changes are announced as they happen"]},"props":{"value":{"type":"number","description":"Current progress value (0-100). Null for indeterminate.","default":"null","required":false},"min":{"type":"number","description":"Minimum value","default":"0","required":false},"max":{"type":"number","description":"Maximum value","default":"100","required":false},"size":{"type":"enum","description":"Size of the progress bar","default":"md","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Color variant","default":"default","required":false,"values":["default","neutral","success","warning","danger"]},"label":{"type":"string","description":"Label text above the progress bar","required":false},"showValue":{"type":"boolean","description":"Show percentage value","default":"false","required":false},"formatValue":{"type":"function","description":"Custom formatter for displayed progress value","required":false},"role":{"type":"union","description":"","required":false}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for status without percentage"},{"component":"Alert","relationship":"sibling","note":"Use Alert for completion messages"}],"variants":[{"name":"Default","description":"Determinate bar with its percentage spelled out.","code":"<Progress value={60} label=\"Uploading…\" showValue />"},{"name":"Variants","description":"Colour carries state: normal, done, tight, critical.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <Progress value={75} variant=\"default\" label=\"Processing\" showValue />\n <Progress value={100} variant=\"success\" label=\"Complete\" showValue />\n <Progress value={80} variant=\"warning\" label=\"Almost full\" showValue />\n <Progress value={95} variant=\"danger\" label=\"Storage critical\" showValue />\n</Stack>"},{"name":"Meter","description":"A reading where hitting the top is not a win.","code":"<Progress\n value={42}\n variant=\"neutral\"\n role=\"meter\"\n label=\"Seats used\"\n showValue\n/>"},{"name":"Sizes","description":"Thin for table rows, thick when the bar is the point.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <Progress value={50} size=\"sm\" label=\"Small\" />\n <Progress value={50} size=\"md\" label=\"Medium\" />\n <Progress value={50} size=\"lg\" label=\"Large\" />\n</Stack>"},{"name":"Indeterminate","description":"value={null} sweeps instead of filling.","code":"<Progress value={null} label=\"Loading…\" />"},{"name":"Circular","description":"Same value in a ring, for tiles and compact chrome.","code":"import { CircularProgress } from '@/components/Progress';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"lg\" align=\"center\">\n <CircularProgress value={25} size=\"sm\" />\n <CircularProgress value={50} size=\"md\" showValue />\n <CircularProgress value={75} size=\"lg\" showValue variant=\"success\" />\n <CircularProgress value={null} size=\"md\" />\n</Stack>"}],"contract":{"propsSummary":["value: number|null - progress percentage (null for indeterminate)","size: sm|md|lg - bar thickness","variant: default|success|warning|danger - color","label: string - descriptive label","showValue: boolean - display percentage","Determinate display values are clamped (and invalid min/max ranges render as 0%)"],"a11yRules":["A11Y_PROGRESS_ROLE","A11Y_PROGRESS_VALUE"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Circular"]},"propsSummary":["value: number (default: null)","min: number (default: 0)","max: number (default: 100)","size: sm|md|lg (default: md)","variant: default|neutral|success|warning|danger (default: default)","role: progressbar|meter (default: progressbar)","label: string","showValue: boolean (default: false)","formatValue: function"],"sourcePath":"src/components/Progress/index.tsx","exportName":"Progress","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.339Z"},"performance":{"bundleSize":2546,"rawSize":6732,"complexity":"lightweight","budgetPercent":17,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Progress (self)","bytes":6118,"percent":91}]}},"Prompt":{"filePath":"src/components/Prompt/index.tsx","meta":{"name":"Prompt","description":"Collects multi-line input for AI and chat interfaces.","category":"ai","tags":["prompt","chat","ai","input","textarea","form"],"status":"stable"},"usage":{"when":["Chat and AI assistant interfaces","Multi-line input with a submit action","Toolbars carrying attachments or a model picker"],"whenNot":["Single-line text (use Input)","Multi-line with no toolbar (use Textarea)","Search-only fields (use Input with the search variant)"],"guidelines":["Always pass an onSubmit handler","Set loading while the request is in flight to block duplicate sends","Prompt.Textarea forwards native textarea props and composes your own handlers","appearance=\"seamless\" floats the controls on the writing surface instead of a footer","Seamless secondary controls stay transparent; only Prompt.Submit keeps a filled shape","Prompt.Submit uses a neutral inverse surface, never semantic brand color","Prompt.ModeButton toggles a setting; Prompt.Select picks one from a list","Wire onFiles once — the attach button, paste, and drop all route through it","Render Prompt.Attachments above Prompt.Textarea; they are part of the message"],"accessibility":["Enter submits, Shift+Enter for newline","Submit button is keyboard accessible","Loading state prevents duplicate submissions"]},"props":{"children":{"type":"node","description":"Prompt composition using Prompt sub-components","required":true},"value":{"type":"string","description":"Controlled input value","required":false},"defaultValue":{"type":"string","description":"Uncontrolled default value","default":"","required":false},"onChange":{"type":"function","description":"Called when value changes","required":false},"onSubmit":{"type":"function","description":"Called on form submission","required":false},"placeholder":{"type":"string","description":"Placeholder text for the textarea","default":"Ask, Search or Chat...","required":false},"disabled":{"type":"boolean","description":"Disable the entire prompt","default":"false","required":false},"loading":{"type":"boolean","description":"Show loading state","default":"false","required":false},"minRows":{"type":"number","description":"Minimum number of visible rows","default":"1","required":false},"maxRows":{"type":"number","description":"Maximum number of visible rows","default":"8","required":false},"autoResize":{"type":"boolean","description":"Enable auto-resize based on content","default":"true","required":false},"submitOnEnter":{"type":"boolean","description":"Submit on Enter (Shift+Enter for newline)","default":"true","required":false},"variant":{"type":"enum","description":"Visual/positioning variant","default":"default","required":false,"values":["default","fixed","sticky"]},"onFiles":{"type":"function","description":"Called with files added by the attach button, a paste, or a drop anywhere on the card. Providing it enables all three.","required":false},"accept":{"type":"string","description":"accept filter for the attach button's picker, e.g. \"image/*\"","required":false},"appearance":{"type":"enum","description":"How the card is divided up. \"panel\" keeps the toolbar as a filled footer under a rule; \"seamless\" makes the whole card one writing surface with the controls floating on it.","default":"panel","required":false,"values":["panel","seamless"]}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for simple single-line text input"},{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line without toolbar"}],"variants":[{"name":"Basic","description":"A textarea and a submit button, nothing else.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions />\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"With Actions","description":"Attach and mode controls sit to the left of submit.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"With Usage","description":"A quota readout sits beside the submit button.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton active>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"Agent Composer","description":"Controls float on the writing surface instead of a footer.","code":"<Prompt\n appearance=\"seamless\"\n submitOnEnter={false}\n minRows={3}\n onSubmit={(value) => console.log(value)}\n>\n <Prompt.Textarea placeholder=\"What should be true when this is done?\" />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.Select\n aria-label=\"Model\"\n defaultValue=\"claude-opus-4-8\"\n options={[{ value: 'claude-opus-4-8', label: 'Opus 4.8' }, { value: 'claude-sonnet-5', label: 'Sonnet 5' }]}\n />\n <Prompt.ModeButton>Plan</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"With Attachments","description":"Staged files list above the text they belong to.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Attachments\n items={[\n { id: '1', name: 'findings-export.csv', size: 20480 },\n { id: '2', name: 'dashboard.png', size: 153600 },\n ]}\n onRemove={(id) => console.log(id)}\n />\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"Loading State","description":"Input locks and submit spins while the request runs.","code":"<Prompt\n onSubmit={(value) => console.log(value)}\n loading\n defaultValue=\"Tell me about the weather...\"\n>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"Disabled","description":"Everything dims and stops responding to input.","code":"<Prompt onSubmit={(value) => console.log(value)} disabled>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"}],"contract":{"propsSummary":["value: string - controlled input value","onSubmit: (value: string) => void - submission handler","placeholder: string - hint text (default: \"Ask, Search or Chat...\")","disabled: boolean - disables interaction","loading: boolean - shows loading state","minRows/maxRows: number - row constraints (default: 1/8)","submitOnEnter: boolean - Enter key behavior (default: true)","Prompt.Textarea accepts native textarea props and optional aria-label override"],"a11yRules":["A11Y_TEXTAREA_LABEL","A11Y_BUTTON_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Textarea","Toolbar","Tabs","Tab","Actions","Info","ActionButton","ModeButton","Select","Attach","Attachments","Usage","Submit"],"commonPatterns":["<Prompt>\n <Prompt.Textarea>...</Prompt.Textarea>\n <Prompt.Toolbar>...</Prompt.Toolbar>\n <Prompt.Actions>...</Prompt.Actions>\n <Prompt.Info>...</Prompt.Info>\n <Prompt.Submit>...</Prompt.Submit>\n</Prompt>"],"requiredChildren":["Textarea","Toolbar","Actions","Info","Submit"]},"propsSummary":["children: node (required)","value: string","defaultValue: string (default: )","onChange: function","onSubmit: function","placeholder: string (default: Ask, Search or Chat...)","disabled: boolean (default: false)","loading: boolean (default: false)","minRows: number (default: 1)","maxRows: number (default: 8)","autoResize: boolean (default: true)","submitOnEnter: boolean (default: true)","variant: default|fixed|sticky (default: default)","appearance: panel|seamless (default: panel)","onFiles: function","accept: string"],"sourcePath":"src/components/Prompt/index.tsx","exportName":"Prompt","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.513Z"},"performance":{"bundleSize":6471,"rawSize":19132,"complexity":"moderate","budgetPercent":42,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Select","bytes":8393,"percent":44},{"path":"Prompt (self)","bytes":7780,"percent":41},{"path":"Loading","bytes":2058,"percent":11}]}},"RadioGroup":{"filePath":"src/components/RadioGroup/index.tsx","meta":{"name":"RadioGroup","description":"Selects one option from a mutually exclusive set.","category":"inputs","tags":["form","radio","selection","options"],"status":"stable"},"usage":{"when":["Exactly one answer out of two to five","Options rule each other out","Every option should be visible without opening anything"],"whenNot":["Several answers allowed (use a Checkbox group)","Long lists (use Select)","A single on/off (use Switch)","Options need searching (use Combobox)"],"guidelines":["Pre-select a sensible default whenever one exists","Order options predictably: alphabetical, by frequency, or by cost","Keep labels short","Put the trade-off in each item's helperText"],"accessibility":["The group carries its own label","Arrow keys move between options","The selected option reads as checked"]},"props":{"value":{"type":"string","description":"Controlled selected value","required":false},"defaultValue":{"type":"string","description":"Default value (uncontrolled)","required":false},"onValueChange":{"type":"function","description":"Callback when selection changes","required":false},"onChange":{"type":"function","description":"Alias for onValueChange","required":false},"orientation":{"type":"enum","description":"Layout orientation","default":"vertical","required":false,"values":["horizontal","vertical"]},"disabled":{"type":"boolean","description":"Disable all options","default":"false","required":false},"name":{"type":"string","description":"Form field name","required":false},"label":{"type":"string","description":"Group label","required":false},"helperText":{"type":"string","description":"Helper text shown below the group","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Visual variant. 'default' is the inline radio, 'card' renders each item as a full-width clickable card with the radio tucked inside.","default":"default","required":false,"values":["default","card"]},"wrapperClassName":{"type":"string","description":"Class name for the outer wrapper element","required":false},"groupClassName":{"type":"string","description":"Class name for the inner radio group element","required":false},"groupId":{"type":"string","description":"ID for the inner element with role=radiogroup; the inherited id remains on the outer field wrapper","required":false},"children":{"type":"node","description":"RadioGroup.Item elements","required":true},"form":{"type":"string","description":"ID of the form that owns the radio inputs","required":false},"inputRef":{"type":"union","description":"Ref to the hidden input element","required":false},"readOnly":{"type":"boolean","description":"Whether the selected value cannot be changed by the user","default":"false","required":false},"required":{"type":"boolean","description":"Whether the user must choose a value before submitting a form","default":"false","required":false}},"relations":[{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox for multiple selections"},{"component":"Select","relationship":"alternative","note":"Use Select for many options or limited space"},{"component":"Switch","relationship":"alternative","note":"Use Switch for binary on/off choices"}],"variants":[{"name":"Default","description":"Three options stacked, the first already chosen.","code":"<RadioGroup defaultValue=\"option1\" label=\"Select an option\">\n <RadioGroup.Item value=\"option1\" label=\"Option 1\" />\n <RadioGroup.Item value=\"option2\" label=\"Option 2\" />\n <RadioGroup.Item value=\"option3\" label=\"Option 3\" />\n</RadioGroup>"},{"name":"With Helper Text","description":"Each option carries the trade-off under its label.","code":"<RadioGroup defaultValue=\"standard\" label=\"Shipping Method\">\n <RadioGroup.Item\n value=\"standard\"\n label=\"Standard\"\n helperText=\"5-7 business days\"\n />\n <RadioGroup.Item\n value=\"express\"\n label=\"Express\"\n helperText=\"2-3 business days\"\n />\n <RadioGroup.Item\n value=\"overnight\"\n label=\"Overnight\"\n helperText=\"Next business day\"\n />\n</RadioGroup>"},{"name":"Horizontal","description":"One row — good for short labels like sizes.","code":"<RadioGroup orientation=\"horizontal\" defaultValue=\"small\" label=\"Size\">\n <RadioGroup.Item value=\"small\" label=\"S\" />\n <RadioGroup.Item value=\"medium\" label=\"M\" />\n <RadioGroup.Item value=\"large\" label=\"L\" />\n <RadioGroup.Item value=\"xlarge\" label=\"XL\" />\n</RadioGroup>"},{"name":"With Group Helper Text","description":"One note under the whole group instead of per option.","code":"<RadioGroup defaultValue=\"standard\" label=\"Plan\" helperText=\"You can change your plan at any time\">\n <RadioGroup.Item value=\"free\" label=\"Free\" />\n <RadioGroup.Item value=\"standard\" label=\"Standard\" />\n <RadioGroup.Item value=\"pro\" label=\"Pro\" />\n</RadioGroup>"},{"name":"With Error","description":"Passing a string to error tints the group and prints the reason.","code":"<RadioGroup label=\"Required selection\" error=\"Please select an option\">\n <RadioGroup.Item value=\"a\" label=\"Option A\" />\n <RadioGroup.Item value=\"b\" label=\"Option B\" />\n</RadioGroup>"},{"name":"Disabled","description":"The choice stays visible but nothing can change it.","code":"<RadioGroup disabled defaultValue=\"locked\" label=\"Locked selection\">\n <RadioGroup.Item value=\"locked\" label=\"This is locked\" />\n <RadioGroup.Item value=\"other\" label=\"Cannot select\" />\n</RadioGroup>"},{"name":"Styling Targets","description":"Named class hooks for the wrapper, the group, and each item.","code":"<RadioGroup\n defaultValue=\"a\"\n label=\"Display mode\"\n wrapperClassName=\"demo-radio-wrapper\"\n groupClassName=\"demo-radio-group\"\n>\n <RadioGroup.Item value=\"a\" label=\"Compact\" controlClassName=\"demo-radio-control\" contentClassName=\"demo-radio-content\" />\n <RadioGroup.Item value=\"b\" label=\"Comfortable\" />\n</RadioGroup>"}],"contract":{"propsSummary":["value: string - selected value","onValueChange: (value: string) => void","onChange: (value: string) => void - alias for onValueChange","orientation: horizontal|vertical (default: vertical)","size: sm|md|lg (default: md)","label: string - group label","helperText: string - helper text below the group","error: boolean | string - error styling and message","disabled: boolean - disable all options","wrapperClassName/groupClassName - explicit styling targets for wrapper and group","groupId: string - ID forwarded to the inner radiogroup while id remains on the wrapper","RadioGroup.Item supports helperText (preferred) and description (legacy alias) plus controlClassName/contentClassName for item-level styling"],"a11yRules":["A11Y_RADIO_GROUP","A11Y_LABEL_REQUIRED","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Item"],"commonPatterns":["<RadioGroup>\n <RadioGroup.Item>...</RadioGroup.Item>\n</RadioGroup>"],"requiredChildren":["Item"]},"propsSummary":["value: string","defaultValue: string","onValueChange: function","onChange: function","orientation: horizontal|vertical (default: vertical)","disabled: boolean (default: false)","name: string","label: string","helperText: string","error: union","size: sm|md|lg (default: md)","wrapperClassName: string","groupClassName: string","groupId: string","children: node (required)"],"sourcePath":"src/components/RadioGroup/index.tsx","exportName":"RadioGroup","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.692Z"},"performance":{"bundleSize":1510,"rawSize":3917,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"RadioGroup (self)","bytes":2689,"percent":69},{"path":"src/utils/aria.ts","bytes":433,"percent":11},{"path":"ComponentDefaults","bytes":198,"percent":5}]}},"ScrollArea":{"filePath":"src/components/ScrollArea/index.tsx","meta":{"name":"ScrollArea","description":"Scrolls overflowing content with a slim scrollbar and optional edge fades.","category":"layout","tags":["scroll","overflow","scrollbar","container","layout"],"status":"stable"},"usage":{"when":["Content that overflows a fixed-size container","Tab bars or chip rows that may run past the edge","Scrollable panels, sidebars, and menu content"],"whenNot":["Whole-page scrolling (use the native body scroll)","Content that can never overflow"],"guidelines":["orientation constrains which axis can scroll","showFades hints at hidden content when nothing else does","scrollbarVisibility=\"hover\" hides the thumb without shifting layout","The container needs a fixed height or the area cannot scroll"],"accessibility":["Preserves native scroll behavior and keyboard support across both axes","Scrollbar is visible on focus for keyboard users","Respects prefers-reduced-motion for fade transitions"]},"props":{"children":{"type":"node","description":"Scrollable content","required":true},"orientation":{"type":"enum","description":"Scroll direction","default":"vertical","required":false,"values":["horizontal","vertical","both"]},"scrollbarVisibility":{"type":"enum","description":"When to show the scrollbar","default":"auto","required":false,"values":["auto","always","hover"]},"showFades":{"type":"boolean","description":"Show gradient fade indicators at scroll edges","default":"false","required":false},"className":{"type":"string","description":"Additional class name","required":false},"dir":{"type":"string","description":"","required":false}},"relations":[],"variants":[{"name":"Vertical","description":"Scrolls down with a thin, always-visible thumb.","code":"import { Box } from '@/components/Box';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <ScrollArea style={{ height: '200px' }}>\n <Box padding=\"sm\">\n <Stack gap=\"sm\">\n <Text>Row 1</Text>\n <Text>Row 2</Text>\n <Text>Row 3</Text>\n <Text>Row 4</Text>\n <Text>Row 5</Text>\n <Text>Row 6</Text>\n <Text>Row 7</Text>\n <Text>Row 8</Text>\n <Text>Row 9</Text>\n <Text>Row 10</Text>\n <Text>Row 11</Text>\n <Text>Row 12</Text>\n </Stack>\n </Box>\n </ScrollArea>\n</Box>"},{"name":"Horizontal","description":"Keeps an overflowing row of chips on one line.","code":"import { Box } from '@/components/Box';\nimport { Chip } from '@/components/Chip';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\n\n<Box width=\"100%\">\n <ScrollArea orientation=\"horizontal\">\n <Stack direction=\"row\" gap=\"sm\">\n <Chip>React</Chip>\n <Chip>TypeScript</Chip>\n <Chip>Accessibility</Chip>\n <Chip>Docs</Chip>\n <Chip>Playground</Chip>\n <Chip>CLI</Chip>\n <Chip>Tokens</Chip>\n <Chip>Governance</Chip>\n <Chip>Contracts</Chip>\n <Chip>Registry</Chip>\n </Stack>\n </ScrollArea>\n</Box>"},{"name":"With Fades","description":"Edge fades signal there is more content each way.","code":"import { Box } from '@/components/Box';\nimport { Chip } from '@/components/Chip';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\n\n<Box width=\"100%\">\n <ScrollArea orientation=\"horizontal\" showFades>\n <Stack direction=\"row\" gap=\"sm\">\n <Chip>React</Chip>\n <Chip>TypeScript</Chip>\n <Chip>Accessibility</Chip>\n <Chip>Docs</Chip>\n <Chip>Playground</Chip>\n <Chip>CLI</Chip>\n <Chip>Tokens</Chip>\n <Chip>Governance</Chip>\n <Chip>Contracts</Chip>\n <Chip>Registry</Chip>\n </Stack>\n </ScrollArea>\n</Box>"},{"name":"Hover Scrollbar","description":"Thumb stays invisible until hover or keyboard focus.","code":"import { Box } from '@/components/Box';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <ScrollArea scrollbarVisibility=\"hover\" style={{ height: '200px' }}>\n <Box padding=\"sm\">\n <Stack gap=\"sm\">\n <Text>Row 1</Text>\n <Text>Row 2</Text>\n <Text>Row 3</Text>\n <Text>Row 4</Text>\n <Text>Row 5</Text>\n <Text>Row 6</Text>\n <Text>Row 7</Text>\n <Text>Row 8</Text>\n <Text>Row 9</Text>\n <Text>Row 10</Text>\n <Text>Row 11</Text>\n <Text>Row 12</Text>\n </Stack>\n </Box>\n </ScrollArea>\n</Box>"}],"contract":{"propsSummary":["orientation: horizontal|vertical|both - scroll direction","scrollbarVisibility: auto|always|hover - scrollbar display mode","showFades: boolean - gradient edge indicators"]},"ai":{"compositionPattern":"compound","subComponents":["Root"],"commonPatterns":["<ScrollArea orientation=\"horizontal\"><div style={{ display: \"flex\", gap: 8 }}>{items}</div></ScrollArea>","<ScrollArea style={{ height: 300 }}>{longContent}</ScrollArea>"]},"propsSummary":["children: node (required)","orientation: horizontal|vertical|both (default: vertical)","scrollbarVisibility: auto|always|hover (default: auto)","showFades: boolean (default: false)","className: string"],"sourcePath":"src/components/ScrollArea/index.tsx","exportName":"ScrollArea","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.867Z"},"performance":{"bundleSize":1519,"rawSize":3074,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"ScrollArea (self)","bytes":2482,"percent":81}]}},"Select":{"filePath":"src/components/Select/Select.fragment.tsx","meta":{"name":"Select","description":"Opens a list and returns the single option the user picks.","category":"inputs","status":"stable","tags":["select","dropdown","form","options","picker"]},"guidance":{"when":["Picking one value from a known list","More than 4-5 options — radios would crowd the form","Tight forms where the list should stay collapsed"],"whenNot":["Two or three options (use RadioGroup)","Users may type their own value (use Combobox)","Multiple selections (use a Checkbox group)","Actions rather than values (use Menu)"],"dont":[{"reason":"Do not use Select for a list of actions.","bad":"<Select>Delete</Select>","good":"<Select label=\"Choose a value\" options={[{ value: \"design\", label: \"Design\" }]} />"}],"guidelines":["Placeholder names the decision, e.g. \"Choose a team\"","Set label so the field is announced","helperText for guidance, error for the failure reason","Group related options with Select.Group","Keep option text short","Order options predictably: alphabetical, by frequency, or by category"],"accessibility":["Full keyboard navigation","Type-ahead jumps to matching options","Trigger and list carry the right ARIA roles"]},"usage":{"when":["Picking one value from a known list","More than 4-5 options — radios would crowd the form","Tight forms where the list should stay collapsed"],"whenNot":["Two or three options (use RadioGroup)","Users may type their own value (use Combobox)","Multiple selections (use a Checkbox group)","Actions rather than values (use Menu)"],"dont":[{"reason":"Do not use Select for a list of actions.","bad":"<Select>Delete</Select>","good":"<Select label=\"Choose a value\" options={[{ value: \"design\", label: \"Design\" }]} />"}],"guidelines":["Placeholder names the decision, e.g. \"Choose a team\"","Set label so the field is announced","helperText for guidance, error for the failure reason","Group related options with Select.Group","Keep option text short","Order options predictably: alphabetical, by frequency, or by category"],"accessibility":["Full keyboard navigation","Type-ahead jumps to matching options","Trigger and list carry the right ARIA roles"]},"props":{"autoComplete":{"type":"string","description":"Browser autofill hint for the hidden input","required":false},"children":{"type":"node","description":"","required":false},"className":{"type":"string","description":"Wrapper class name","required":false},"defaultOpen":{"type":"boolean","description":"Default open state","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","required":false},"disabled":{"type":"boolean","description":"Whether the field is disabled","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false},"form":{"type":"string","description":"ID of the form that owns the hidden input","required":false},"helperText":{"type":"string","description":"Helper text shown below the field","required":false},"inputRef":{"type":"union","description":"Ref to the hidden input element","required":false},"label":{"type":"string","description":"Visible label text","required":false},"name":{"type":"string","description":"Form field name","required":false},"onChange":{"type":"function","description":"Alias for onValueChange","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"onValueChange":{"type":"function","description":"Called when selection changes","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false},"options":{"type":"array","description":"Convenience API for simple selects (renders Select.Item entries when children are omitted)","required":false},"placeholder":{"type":"string","description":"Placeholder text when no value is selected","required":false},"readOnly":{"type":"boolean","description":"Whether the user cannot choose a different option","required":false},"required":{"type":"boolean","description":"Whether a selection is required","required":false},"size":{"type":"enum","description":"Size variant.","default":"\"md\"","required":false,"values":["sm","md","lg"]},"value":{"type":"string","description":"Controlled selected value","required":false},"variant":{"type":"enum","description":"Visual treatment. `ghost` drops the field shell for a compact, borderless\ncontrol — for toolbars and dense rows, where a bordered field reads as a\nform. Pair with `size=\"sm\"`.","default":"field","required":false,"values":["field","ghost"]}},"relations":[{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based dropdowns"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text entry"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox group for multiple selections"}],"variants":[{"name":"Default","description":"Label, placeholder, three options.","code":"<Select label=\"Team\" placeholder=\"Choose a team\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"design\">Design</Select.Item>\n <Select.Item value=\"engineering\">Engineering</Select.Item>\n <Select.Item value=\"product\">Product</Select.Item>\n </Select.Content>\n </Select>","canonical":true},{"name":"With Groups","description":"Headed sections separate related options.","code":"<Select placeholder=\"Choose a country\">\n <Select.Trigger />\n <Select.Content>\n <Select.Group>\n <Select.GroupLabel>Americas</Select.GroupLabel>\n <Select.Item value=\"us\">United States</Select.Item>\n <Select.Item value=\"ca\">Canada</Select.Item>\n </Select.Group>\n <Select.Group>\n <Select.GroupLabel>Europe</Select.GroupLabel>\n <Select.Item value=\"uk\">United Kingdom</Select.Item>\n <Select.Item value=\"de\">Germany</Select.Item>\n </Select.Group>\n </Select.Content>\n </Select>"},{"name":"With Label and Helper Text","description":"Helper text explains what the choice affects.","code":"<Select label=\"Timezone\" helperText=\"Used for reminders and calendar notifications.\">\n <Select.Trigger placeholder=\"Select a timezone\" />\n <Select.Content>\n <Select.Item value=\"pt\">Pacific Time</Select.Item>\n <Select.Item value=\"mt\">Mountain Time</Select.Item>\n <Select.Item value=\"ct\">Central Time</Select.Item>\n <Select.Item value=\"et\">Eastern Time</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Error State","description":"Red border, and the message replaces helper text.","code":"<Select label=\"Team\" placeholder=\"Choose a team\" error=\"Choose a team before continuing\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"design\">Design</Select.Item>\n <Select.Item value=\"engineering\">Engineering</Select.Item>\n </Select.Content>\n </Select>"},{"name":"With Disabled Options","description":"Unavailable options stay visible but cannot be picked.","code":"<Select placeholder=\"Select a plan\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"free\">Free</Select.Item>\n <Select.Item value=\"pro\">Pro</Select.Item>\n <Select.Item value=\"enterprise\" disabled>\n Enterprise (contact sales)\n </Select.Item>\n </Select.Content>\n </Select>"},{"name":"Scrollable List","description":"Caps at four rows and half-shows the fifth as a scroll hint.","code":"<Select placeholder=\"Select a timezone\">\n <Select.Trigger />\n <Select.Content maxVisibleItems={4}>\n <Select.Item value=\"utc-8\">Pacific Time (UTC-8)</Select.Item>\n <Select.Item value=\"utc-7\">Mountain Time (UTC-7)</Select.Item>\n <Select.Item value=\"utc-6\">Central Time (UTC-6)</Select.Item>\n <Select.Item value=\"utc-5\">Eastern Time (UTC-5)</Select.Item>\n <Select.Item value=\"utc-4\">Atlantic Time (UTC-4)</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Custom Max Visible Items","description":"maxVisibleItems raises the cap to six rows.","code":"<Select placeholder=\"Select a color\">\n <Select.Trigger />\n <Select.Content maxVisibleItems={6}>\n <Select.Item value=\"red\">Red</Select.Item>\n <Select.Item value=\"orange\">Orange</Select.Item>\n <Select.Item value=\"yellow\">Yellow</Select.Item>\n <Select.Item value=\"green\">Green</Select.Item>\n <Select.Item value=\"blue\">Blue</Select.Item>\n <Select.Item value=\"indigo\">Indigo</Select.Item>\n <Select.Item value=\"violet\">Violet</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Disabled","description":"Dimmed and cannot be opened.","code":"<Select disabled placeholder=\"Select an option\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"one\">Option 1</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Options Prop","description":"The options array replaces hand-written Select.Item children.","code":"<Select\n placeholder=\"Select a team\"\n options={[\n { value: \"engineering\", label: \"Engineering\" },\n { value: \"design\", label: \"Design\" },\n { value: \"product\", label: \"Product\" },\n ]}\n />"},{"name":"Long Localized Option","description":"The trigger grows to fit a long label instead of clipping it.","code":"<Select label=\"Workspace region\" placeholder=\"Choose a workspace region\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"eu-central\">\n Central European workspace with localized administrator recovery requirements\n </Select.Item>\n <Select.Item value=\"us-east\">United States East</Select.Item>\n </Select.Content>\n </Select>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Item","Group","GroupLabel"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Select placeholder=\"Select option\" options={[{ value: 'opt1', label: 'Option 1' }, { value: 'opt2', label: 'Option 2' }]} />","<Select placeholder=\"Select option\"><Select.Trigger /><Select.Content><Select.Item value=\"opt1\">{label1}</Select.Item><Select.Item value=\"opt2\">{label2}</Select.Item></Select.Content></Select>"]},"contract":{"propsSummary":["value: string | null - controlled selected value","onValueChange: (value: string | null) => void - selection handler","onChange: (value: string | null) => void - alias for onValueChange","label: string - visible label text","helperText: string - helper text below field","error: boolean | string - error styling and message","placeholder: string - placeholder text","disabled: boolean - disable select","size: sm|md|lg (default: md)","variant: field|ghost (default: field) - ghost is borderless, for toolbars","options: SelectOption[] - convenience API for simple option lists","maxVisibleItems: number - max visible options before scrolling (default 4)","Select.Trigger accepts an icon prop for a leading adornment"],"a11yRules":["A11Y_SELECT_KEYBOARD","A11Y_SELECT_LABEL"]},"matrix":{"axes":{"size":"auto","variant":"auto","theme":["light","dark"]},"forced":["open","focus","disabled","error"],"worstCase":{"options":"A long localized option label that remains readable inside the bounded list"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Select/index.tsx","exportName":"Select","performance":{"bundleSize":3469,"rawSize":9086,"complexity":"lightweight","budgetPercent":23,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Select (self)","bytes":4809,"percent":53},{"path":"src/recipes/popup.ts","bytes":2929,"percent":32},{"path":"src/utils/aria.ts","bytes":433,"percent":5},{"path":"ComponentDefaults","bytes":198,"percent":2}]}},"Separator":{"filePath":"src/components/Separator/index.tsx","meta":{"name":"Separator","description":"Draws a rule between sections of related content.","category":"layout","tags":["separator","divider","hr","line","layout"],"status":"stable"},"usage":{"when":["Dividing sections that spacing alone cannot separate","Labelled breaks such as an Or divider","Splitting items inside a toolbar or row"],"whenNot":["Whenever spacing already reads as a break","Decorative rules (use a border)","Building layout structure (use Grid)"],"guidelines":["Use sparingly — stacked rules read as noise","soft halves the rule's weight for quieter breaks","orientation=\"vertical\" needs a parent with a set height","Add aria-hidden when the rule is purely decorative"],"accessibility":["Uses role=\"separator\" for semantic meaning","Decorative separators should be aria-hidden"]},"props":{"orientation":{"type":"enum","description":"Direction of the separator","default":"horizontal","required":false,"values":["horizontal","vertical"]},"spacing":{"type":"enum","description":"Margin around the separator","default":"none","required":false,"values":["none","sm","md","lg"]},"soft":{"type":"boolean","description":"Softer, lighter appearance","default":"false","required":false},"label":{"type":"string","description":"Optional text label (horizontal only)","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Card","relationship":"sibling","note":"Cards provide stronger visual grouping"}],"variants":[{"name":"Default","description":"Standard and soft weights, one above the other.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <Text>Standard weight</Text>\n <Separator spacing=\"md\" />\n <Text>Soft weight</Text>\n <Separator soft spacing=\"md\" />\n <Text>Below</Text>\n</Box>"},{"name":"With Label","description":"A label sits inside the rule for a major break.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <Text>First section</Text>\n <Separator label=\"Or\" spacing=\"md\" />\n <Text>Second section</Text>\n</Box>"},{"name":"Vertical","description":"Divides items sitting in a row.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Stack direction=\"row\" align=\"center\" gap=\"md\" style={{ height: '40px' }}>\n <Text>Item 1</Text>\n <Separator orientation=\"vertical\" />\n <Text>Item 2</Text>\n <Separator orientation=\"vertical\" />\n <Text>Item 3</Text>\n</Stack>"},{"name":"Spacing Options","description":"spacing sets the breathing room around the rule.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <Text>none</Text>\n <Separator spacing=\"none\" />\n <Text>sm</Text>\n <Separator spacing=\"sm\" />\n <Text>md</Text>\n <Separator spacing=\"md\" />\n <Text>lg</Text>\n <Separator spacing=\"lg\" />\n <Text>End</Text>\n</Box>"}],"contract":{"propsSummary":["orientation: horizontal|vertical - direction","spacing: none|sm|md|lg - margin","soft: boolean - lighter appearance","label: string - centered label text"],"a11yRules":["A11Y_SEPARATOR_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["orientation: horizontal|vertical (default: horizontal)","spacing: none|sm|md|lg (default: none)","soft: boolean (default: false)","label: string","style: object"],"sourcePath":"src/components/Separator/index.tsx","exportName":"Separator","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:03.327Z"},"performance":{"bundleSize":750,"rawSize":1542,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Separator (self)","bytes":951,"percent":62}]}},"Sidebar":{"filePath":"src/components/Sidebar/index.tsx","meta":{"name":"Sidebar","description":"Collapsible navigation panel that turns into a drawer on mobile.","category":"layout","tags":["sidebar","navigation","drawer","menu","layout"],"status":"stable"},"usage":{"when":["Primary navigation for an app shell","Navigation that must collapse to icons or hide entirely","Grouped destinations with active state"],"whenNot":["Top-level horizontal navigation (use Header)","Temporary side panels for one task (use Drawer)","In-page section links (use a list of links)"],"guidelines":["Give every item an icon so the collapsed rail stays readable","collapsible=\"icon\" shrinks to a rail; \"offcanvas\" hides it completely","Wrap in SidebarProvider only when something outside must toggle it","An explicit collapsed prop overrides any surrounding provider","Sidebar.Rail and Sidebar.CollapseToggle are alternative toggles — pick one","Use Sidebar.MenuSkeleton while navigation data loads"],"accessibility":["Uses semantic <nav> element with aria-label","aria-current=\"page\" on active items","aria-expanded on items with submenus","Escape key closes mobile drawer","Cmd/Ctrl+B keyboard shortcut toggles sidebar (when using SidebarProvider)","Focus trap in mobile drawer mode","Minimum 44px touch targets"]},"props":{"children":{"type":"node","description":"Sidebar content (use Sidebar.Header, Sidebar.Nav, Sidebar.Section, etc.)","required":true},"collapsed":{"type":"boolean","description":"Icon-only mode for desktop (controlled)","required":false},"defaultCollapsed":{"type":"boolean","description":"Initial collapsed state (uncontrolled)","default":"false","required":false},"onCollapsedChange":{"type":"function","description":"Called when collapsed state changes","required":false},"open":{"type":"boolean","description":"Mobile drawer open state (controlled)","required":false},"defaultOpen":{"type":"boolean","description":"Initial open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"width":{"type":"string","description":"Width of expanded sidebar","default":"240px","required":false},"collapsedWidth":{"type":"string","description":"Width when collapsed","default":"var(--fui-navigation-sidebar-collapsed-width, 56px)","required":false},"position":{"type":"enum","description":"Sidebar position","default":"left","required":false,"values":["left","right"]},"collapsible":{"type":"enum","description":"Collapse behavior mode","default":"icon","required":false,"values":["icon","offcanvas","none"]},"activeIndicator":{"type":"enum","description":"Placement of the active-item affordance","default":"start","required":false,"values":["start","end"]},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for in-page section navigation"},{"component":"Menu","relationship":"composition","note":"Use Menu for contextual actions within sidebar"}],"variants":[{"name":"Default","description":"Sections group items; active marks the current page.","code":"<Sidebar>\n <Sidebar.Header>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />}>Team</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n <Sidebar.Section label=\"Settings\">\n <Sidebar.Item icon={<GearIcon />}>Preferences</Sidebar.Item>\n <Sidebar.Item icon={<HelpIcon />}>Help</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n</Sidebar>"},{"name":"Collapsed","description":"Icon-only rail; labels move into hover tooltips.","code":"function App() {\n const [collapsed, setCollapsed] = useState(true);\n\n return (\n <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed}>\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n );\n}"},{"name":"With Badges","description":"Trailing counts for unread or pending work.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />} badge=\"3\">Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />} badge=\"12\">Team</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Submenu","description":"Nested items; defaultExpanded sets the opening state.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />}>Dashboard</Sidebar.Item>\n {/* Use defaultExpanded for uncontrolled mode - no state needed! */}\n <Sidebar.Item icon={<FolderIcon />} hasSubmenu defaultExpanded>\n Projects\n </Sidebar.Item>\n <Sidebar.Submenu>\n <Sidebar.SubItem active>Website Redesign</Sidebar.SubItem>\n <Sidebar.SubItem>Mobile App</Sidebar.SubItem>\n <Sidebar.SubItem>API Integration</Sidebar.SubItem>\n </Sidebar.Submenu>\n {/* Multiple submenus work without tracking separate state */}\n <Sidebar.Item icon={<UsersIcon />} hasSubmenu>\n Team\n </Sidebar.Item>\n <Sidebar.Submenu>\n <Sidebar.SubItem>Engineering</Sidebar.SubItem>\n <Sidebar.SubItem>Design</Sidebar.SubItem>\n </Sidebar.Submenu>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Disabled Items","description":"Items switched off by permissions or feature flags.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />} disabled>\n Team (Coming Soon)\n </Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />} disabled>\n Projects (Upgrade)\n </Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Provider & External Trigger","description":"useSidebar drives the sidebar from anywhere, plus Cmd/Ctrl+B.","code":"function App() {\n return (\n <SidebarProvider>\n <Stack direction=\"row\" gap=\"lg\" align=\"start\">\n <Sidebar>\n <Sidebar.Header>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </Sidebar>\n <MainContent />\n </Stack>\n </SidebarProvider>\n );\n}\n\nfunction MainContent() {\n const { toggleSidebar, state } = useSidebar();\n\n return (\n <Stack gap=\"sm\" align=\"start\">\n <Text size=\"sm\" color=\"secondary\">State: {state}</Text>\n <Button size=\"sm\" variant=\"secondary\" onClick={toggleSidebar}>\n Toggle sidebar\n </Button>\n </Stack>\n );\n}"},{"name":"With asChild (Polymorphic)","description":"Render items as your router's link component.","code":"import Link from 'next/link';\n\n<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active asChild>\n <Link href=\"/dashboard\">Dashboard</Link>\n </Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />} asChild>\n <Link href=\"/analytics\">Analytics</Link>\n </Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Section Action","description":"A section header can carry one quick action.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section\n label=\"Projects\"\n action={\n <Sidebar.SectionAction aria-label=\"Add project\" onClick={handleAdd}>\n <PlusIcon />\n </Sidebar.SectionAction>\n }\n >\n <Sidebar.Item icon={<FolderIcon />}>Website Redesign</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Mobile App</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Loading Skeleton","description":"Placeholder rows to show while navigation data loads.","code":"<Sidebar>\n <Sidebar.Header>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.MenuSkeleton count={6} />\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Rail Toggle","description":"Drag-handle toggle on the sidebar edge — hover to reveal, click to collapse.","code":"function App() {\n const [collapsed, setCollapsed] = useState(false);\n\n return (\n <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed}>\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Rail />\n </Sidebar>\n );\n}"},{"name":"Offcanvas Collapsed","description":"Hides the panel entirely, leaving a floating re-open button.","code":"function App() {\n const [collapsed, setCollapsed] = useState(true);\n\n return (\n <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed} collapsible=\"offcanvas\">\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n );\n}"}],"contract":{"propsSummary":["collapsed: boolean - icon-only desktop mode","open: boolean - mobile drawer state","width: string - expanded width (default: 240px)","position: left|right - sidebar position","active: boolean - set on Sidebar.Item to mark current page (app-controlled)","Sidebar.Item/SubItem onClick: (event) => void - click handler receives mouse event"],"a11yRules":["A11Y_NAV_LANDMARK","A11Y_FOCUS_TRAP","A11Y_ESCAPE_CLOSE"]},"ai":{"compositionPattern":"compound","subComponents":["Header","Nav","Section","SectionAction","Item","SubItem","Submenu","Footer","Trigger","Overlay","CollapseToggle","Rail","MenuSkeleton"],"requiredChildren":["Nav"],"commonPatterns":["<Sidebar><Sidebar.Header>{logo}</Sidebar.Header><Sidebar.Nav><Sidebar.Section><Sidebar.Item icon={icon} active>{label}</Sidebar.Item></Sidebar.Section></Sidebar.Nav><Sidebar.Footer><Sidebar.CollapseToggle /></Sidebar.Footer></Sidebar>"]},"propsSummary":["children: node (required)","collapsed: boolean","defaultCollapsed: boolean (default: false)","onCollapsedChange: function","open: boolean","defaultOpen: boolean (default: false)","onOpenChange: function","width: string (default: 240px)","collapsedWidth: string (default: 56px)","position: left|right (default: left)","collapsible: icon|offcanvas|none (default: icon)","activeIndicator: start|end (default: start)","style: object"],"sourcePath":"src/components/Sidebar/index.tsx","exportName":"Sidebar","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:03.784Z"},"performance":{"bundleSize":8752,"rawSize":26459,"complexity":"moderate","budgetPercent":57,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Sidebar (self)","bytes":11974,"percent":45},{"path":"src/utils/keyboard-shortcuts.ts","bytes":3887,"percent":15},{"path":"Collapsible","bytes":2544,"percent":10},{"path":"ScrollArea","bytes":2508,"percent":9},{"path":"Tooltip","bytes":1461,"percent":6},{"path":"Skeleton","bytes":1281,"percent":5},{"path":"Badge","bytes":1061,"percent":4},{"path":"src/utils/a11y.tsx","bytes":779,"percent":3}]}},"Skeleton":{"filePath":"src/components/Skeleton/index.tsx","meta":{"name":"Skeleton","description":"Holds the shape of content that has not arrived yet.","category":"feedback","tags":["loading","placeholder","skeleton","shimmer"],"status":"stable"},"usage":{"when":["Content is still being fetched","You want to stop the layout jumping when it lands","Making a wait feel shorter than it is"],"whenNot":["Waits under about 300ms","A spinner says it better","Work the user cannot see anyway"],"guidelines":["Match the shape and size of the real content","Prefer the text, heading, and avatar variants over hand-rolled boxes","Give Skeleton.Text an ancestor with a real width — percentage lines collapse without one","A few big shapes beat many small ones","Skeleton and Skeleton.Text forward id, aria-*, data-* and handlers"],"accessibility":["Skeletons are decoration — hide them with aria-hidden","Announce the loading state separately if it matters","Keep the pulse subtle but visible against the surface"]},"props":{"variant":{"type":"enum","description":"Semantic variant that auto-sizes","default":"rect","required":false,"values":["text","heading","avatar","button","input","rect"]},"size":{"type":"enum","description":"Size for avatar/button variants","default":"md","required":false,"values":["sm","md","lg"]},"width":{"type":"union","description":"Custom width (string or number)","required":false},"height":{"type":"union","description":"Custom height (string or number)","required":false},"fill":{"type":"boolean","description":"Fill parent container","default":"false","required":false},"radius":{"type":"enum","description":"Border radius override","required":false,"values":["sm","md","lg","none","full"]},"static":{"type":"boolean","description":"Disable skeleton animation","default":"false","required":false}},"relations":[{"component":"Progress","relationship":"alternative","note":"Use Progress for determinate loading"}],"variants":[{"name":"Default","description":"One rectangle at an explicit size.","code":"<Skeleton width={200} height={20} />"},{"name":"Text Lines","description":"Stacked lines that fill the width they are given.","code":"<div style={{ width: 260 }}>\n <Skeleton.Text lines={3} />\n</div>"},{"name":"Semantic Variants","description":"Heading sits taller than the body lines under it.","code":"<div\n style={{\n width: 260,\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--fui-space-2)',\n }}\n>\n <Skeleton variant=\"heading\" width={200} />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"text\" width=\"80%\" />\n</div>"},{"name":"Avatar Skeleton","description":"Circles matching the three avatar sizes.","code":"<div style={{ display: 'flex', gap: 'var(--fui-space-1)', alignItems: 'center' }}>\n <Skeleton.Circle size=\"sm\" />\n <Skeleton.Circle size=\"md\" />\n <Skeleton.Circle size=\"lg\" />\n</div>"},{"name":"Card Skeleton","description":"Media, title, then body — the card before it loads.","code":"<div\n style={{\n width: 300,\n padding: 'var(--fui-space-2)',\n border: '1px solid var(--fui-border)',\n borderRadius: 'var(--fui-radius-lg)',\n }}\n>\n <Skeleton variant=\"rect\" height={120} radius=\"md\" />\n <div style={{ marginTop: 'var(--fui-space-2)' }}>\n <Skeleton variant=\"heading\" width=\"60%\" />\n </div>\n <div style={{ marginTop: 'var(--fui-space-1)' }}>\n <Skeleton.Text lines={2} />\n </div>\n</div>"}],"contract":{"propsSummary":["variant: text|heading|avatar|button|input|rect","size: sm|md|lg (for avatar/button)","width/height: custom dimensions","fill: boolean - fill parent","Skeleton / Skeleton.Text forward div DOM props"]},"ai":{"compositionPattern":"compound","subComponents":["Text","Circle"]},"propsSummary":["variant: text|heading|avatar|button|input|rect (default: rect)","size: sm|md|lg (default: md)","width: union","height: union","fill: boolean (default: false)","radius: sm|md|lg|none|full","static: boolean (default: false)"],"sourcePath":"src/components/Skeleton/index.tsx","exportName":"Skeleton","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:03.952Z"},"performance":{"bundleSize":944,"rawSize":1845,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Skeleton (self)","bytes":1268,"percent":69}]}},"Slider":{"filePath":"src/components/Slider/index.tsx","meta":{"name":"Slider","description":"Selects a numeric value within a defined range.","category":"inputs","tags":["slider","range","input","number","control"],"status":"stable"},"usage":{"when":["Any value along a range, where roughly right is good enough","Volume, brightness, opacity","Price and range filters","The effect is visible as the user drags"],"whenNot":["An exact number matters (use Input type=\"number\")","A handful of fixed choices (use RadioGroup or Select)","On or off (use Switch)"],"guidelines":["Label what the track controls","Turn on showValue whenever the number matters","Set min and max to the real limits, not 0-100 by habit","Pick a step the user can actually land on"],"accessibility":["Label is tied to the track","Arrow keys move the thumb","The current value is announced","Native slider semantics throughout"]},"props":{"label":{"type":"string","description":"Label text","required":false},"helperText":{"type":"string","description":"Helper text shown below the slider","required":false},"error":{"type":"boolean","description":"Show error styling","default":"false","required":false},"value":{"type":"number","description":"Controlled value","required":false},"defaultValue":{"type":"number","description":"Default value for uncontrolled usage","required":false},"onChange":{"type":"function","description":"Called with new value when changed","required":false},"onValueChange":{"type":"function","description":"Alias for onChange (Radix convention): (value: number) => void","required":false},"min":{"type":"number","description":"Minimum value","default":"0","required":false},"max":{"type":"number","description":"Maximum value","default":"100","required":false},"step":{"type":"number","description":"Step interval","default":"1","required":false},"showValue":{"type":"boolean","description":"Display current value","default":"false","required":false},"showValueOnDrag":{"type":"boolean","description":"Show current value in a floating bubble while dragging the thumb","default":"false","required":false},"valueSuffix":{"type":"string","description":"Suffix after value (e.g., \"%\", \"px\")","default":"","required":false},"disabled":{"type":"boolean","description":"Disable the slider","default":"false","required":false},"name":{"type":"string","description":"","required":false},"aria-label":{"type":"string","description":"Accessible label when visible label is omitted","required":false},"aria-labelledby":{"type":"string","description":"Accessible labelled-by relationship","required":false},"aria-describedby":{"type":"string","description":"Accessible described-by relationship","required":false},"id":{"type":"string","description":"","required":false},"form":{"type":"string","description":"ID of the form that owns the hidden slider input","required":false},"largeStep":{"type":"number","description":"Larger step used for Page Up/Page Down and shift-arrow keyboard input","required":false},"onValueCommitted":{"type":"function","description":"Callback when the user commits a slider value","required":false},"thumbAlignment":{"type":"enum","description":"How the thumb is aligned at the minimum and maximum edges","required":false,"values":["center","edge","edge-client-only"]}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for precise numeric entry"},{"component":"Progress","relationship":"sibling","note":"Similar visual, but Progress is read-only"}],"variants":[{"name":"Default","description":"0-100 with no number shown.","code":"<div style={{ width: '300px' }}>\n <Slider label=\"Volume\" defaultValue={50} />\n</div>"},{"name":"With Value Display","description":"showValue prints the number opposite the label.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Brightness\"\n defaultValue={75}\n showValue\n valueSuffix=\"%\"\n />\n</div>"},{"name":"Custom Range","description":"min, max and step bound the track to real-world units.","code":"<div style={{ width: '300px', display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Slider\n label=\"Temperature\"\n min={60}\n max={80}\n step={1}\n defaultValue={72}\n showValue\n valueSuffix=\"°F\"\n />\n <Slider\n label=\"Font Size\"\n min={12}\n max={32}\n step={2}\n defaultValue={16}\n showValue\n valueSuffix=\"px\"\n />\n</div>"},{"name":"Controlled","description":"The parent owns the value and can react to every move.","code":"<ControlledSliderDemo />"},{"name":"Drag Value Bubble","description":"The number floats above the thumb only while dragging.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Mix\"\n defaultValue={40}\n showValueOnDrag\n valueSuffix=\"%\"\n />\n</div>"},{"name":"With Helper Text","description":"A line below the track explains the trade-off.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Quality\"\n defaultValue={80}\n showValue\n valueSuffix=\"%\"\n helperText=\"Higher quality increases file size\"\n />\n</div>"},{"name":"Disabled","description":"Dimmed; the thumb will not move.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Locked Setting\"\n defaultValue={30}\n showValue\n disabled\n />\n</div>"}],"contract":{"propsSummary":["value: number - controlled value","defaultValue: number - initial value","onChange: (value: number) => void - change handler (or onValueChange)","min/max: number - range bounds","step: number - increment size","label: string - field label","helperText: string - helper text below slider","error: boolean - error styling","showValue: boolean - display value","showValueOnDrag: boolean - show value bubble during drag","valueSuffix: string - unit suffix"],"a11yRules":["A11Y_LABEL_REQUIRED","A11Y_KEYBOARD_ACCESSIBLE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["label: string","helperText: string","error: boolean (default: false)","value: number","defaultValue: number","onChange: function","onValueChange: function","min: number (default: 0)","max: number (default: 100)","step: number (default: 1)","showValue: boolean (default: false)","showValueOnDrag: boolean (default: false)","valueSuffix: string (default: )","disabled: boolean (default: false)","name: string","aria-label: string","aria-labelledby: string","aria-describedby: string","id: string"],"sourcePath":"src/components/Slider/index.tsx","exportName":"Slider","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.141Z"},"performance":{"bundleSize":1217,"rawSize":2657,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Slider (self)","bytes":2065,"percent":78}]}},"Stack":{"filePath":"src/components/Stack/index.tsx","meta":{"name":"Stack","description":"Stacks children in a row or column with one consistent gap.","category":"layout","tags":["stack","layout","flex","spacing","responsive"],"status":"stable"},"usage":{"when":["Spacing a short row or column of elements","Any one-directional flexbox arrangement","Layouts that flip direction at a breakpoint"],"whenNot":["Two-dimensional layouts (use Grid)","Grouping buttons into one control (use ButtonGroup)","Page shell regions (use AppShell)"],"guidelines":["Set gap once on the parent instead of margins on children","Numeric gaps (1-8) map to the same spacing scale as the tokens","direction, gap, and align all accept per-breakpoint objects","Use as=\"nav\" or as=\"ul\" so the markup stays semantic","separator draws dividers without extra elements"],"accessibility":["Use semantic elements (nav, section, etc.) via \"as\" prop","Maintains source order for screen readers","No accessibility concerns with visual arrangement"]},"props":{"children":{"type":"node","description":"Elements to arrange","required":true},"direction":{"type":"union","description":"Stack direction: \"row\", \"column\", or responsive object","default":"column","required":false},"gap":{"type":"union","description":"Spacing between items: \"none\"|\"xs\"|\"sm\"|\"md\"|\"lg\"|\"xl\", a number (1-8) for space scale, or responsive object","default":"md","required":false},"align":{"type":"enum","description":"Cross-axis alignment","required":false,"values":["start","center","end","stretch","baseline"]},"justify":{"type":"enum","description":"Main-axis alignment","required":false,"values":["start","center","end","between"]},"wrap":{"type":"boolean","description":"Allow items to wrap","default":"false","required":false},"separator":{"type":"node","description":"Render a separator between children. true = default 1px line, or pass a ReactNode for custom separators.","required":false},"as":{"type":"enum","description":"HTML element to render","default":"div","required":false,"values":["div","section","nav","article","aside","header","footer","main","ul","ol"]},"className":{"type":"string","description":"","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Grid","relationship":"alternative","note":"Use Grid for complex 2D layouts"},{"component":"ButtonGroup","relationship":"sibling","note":"ButtonGroup is specialized for buttons"},{"component":"Box","relationship":"sibling","note":"Box for single-element styling"}],"variants":[{"name":"Vertical Stack","description":"Children flow top to bottom — the default.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack gap=\"sm\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">One</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Two</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Three</Box>\n</Stack>"},{"name":"Horizontal Stack","description":"Children flow left to right.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">One</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Two</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Three</Box>\n</Stack>"},{"name":"Gap Sizes","description":"One spacing token sets every gap in the stack.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack gap=\"lg\">\n <Stack direction=\"row\" gap=\"xs\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">xs</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">xs</Box>\n </Stack>\n <Stack direction=\"row\" gap=\"sm\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">sm</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">sm</Box>\n </Stack>\n <Stack direction=\"row\" gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">md</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">md</Box>\n </Stack>\n <Stack direction=\"row\" gap=\"lg\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">lg</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">lg</Box>\n </Stack>\n</Stack>"},{"name":"Alignment","description":"justify positions children along the main axis.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack gap=\"md\">\n <Box width=\"240px\" border rounded=\"sm\" padding=\"sm\">\n <Stack direction=\"row\" gap=\"sm\" justify=\"between\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">Start</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">End</Box>\n </Stack>\n </Box>\n <Box width=\"240px\" border rounded=\"sm\" padding=\"sm\">\n <Stack direction=\"row\" gap=\"sm\" justify=\"center\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">Centered</Box>\n </Stack>\n </Box>\n</Stack>"},{"name":"Responsive","description":"Swap direction and gap per breakpoint with an object value.","code":"<Stack\n direction={{ base: 'column', md: 'row' }}\n gap={{ base: 'sm', md: 'lg' }}\n>\n <Button variant=\"secondary\">First</Button>\n <Button variant=\"secondary\">Second</Button>\n <Button variant=\"secondary\">Third</Button>\n</Stack>"},{"name":"With Separator","description":"Draws a divider between each child.","code":"import { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Stack gap=\"md\" separator>\n <Text>Section one</Text>\n <Text>Section two</Text>\n <Text>Section three</Text>\n</Stack>"},{"name":"Semantic Element","description":"The as prop renders a real nav, section, or list element.","code":"<Stack as=\"nav\" direction=\"row\" gap=\"md\">\n <Button variant=\"ghost\" size=\"sm\">Home</Button>\n <Button variant=\"ghost\" size=\"sm\">About</Button>\n <Button variant=\"ghost\" size=\"sm\">Contact</Button>\n</Stack>"}],"contract":{"propsSummary":["direction: row|column|{responsive} - stack direction","gap: none|xs|sm|md|lg|xl|number|{responsive} - spacing (number maps to space scale)","align: start|center|end|stretch|baseline - cross-axis","justify: start|center|end|between - main-axis","wrap: boolean - allow wrapping","separator: boolean|ReactNode - divider between children","as: string - HTML element","Pass-through DOM props supported on the root (id, role, aria-*, data-*, handlers)"],"a11yRules":["A11Y_SEMANTIC_ELEMENTS"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","direction: union (default: column)","gap: union (default: md)","align: start|center|end|stretch|baseline","justify: start|center|end|between","wrap: boolean (default: false)","separator: node","as: div|section|nav|article|aside|header|footer|main|ul|ol (default: div)","className: string","style: object"],"sourcePath":"src/components/Stack/index.tsx","exportName":"Stack","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.310Z"},"performance":{"bundleSize":2181,"rawSize":5349,"complexity":"lightweight","budgetPercent":14,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"src/utils/layout-spacing.ts","bytes":2779,"percent":52},{"path":"Stack (self)","bytes":1995,"percent":37}]}},"Switch":{"filePath":"src/components/Switch/index.tsx","meta":{"name":"Switch","description":"Toggles a setting that takes effect immediately.","category":"inputs","tags":["switch","toggle","boolean","settings","preference"],"status":"stable"},"usage":{"when":["Settings that apply the moment they change","Turning a feature on or off in a settings panel","The result is visible straight away"],"whenNot":["Choices that only apply on submit (use Checkbox)","Several options at once (use a Checkbox group)","Yes/no questions in a form (use RadioGroup)","More than two states (use Select or RadioGroup)"],"guidelines":["The label names what is being turned on","On always means enabled, never the reverse","Apply the change immediately — no save button","Add helperText when the label alone is ambiguous","Stack related switches together"],"accessibility":["role=\"switch\" with aria-checked","Every switch has a label, visible or aria-label","Focus ring stays visible","Flipping it is announced"]},"props":{"checked":{"type":"boolean","description":"Whether the switch is in the on state","default":"false","required":false},"defaultChecked":{"type":"boolean","description":"Default checked state (uncontrolled)","required":false},"onCheckedChange":{"type":"function","description":"Called when the switch is toggled: (checked: boolean) => void","required":false},"onChange":{"type":"function","description":"Alias for onCheckedChange: (checked: boolean) => void","required":false},"label":{"type":"string","description":"Visible label text","required":false},"helperText":{"type":"string","description":"Helper text shown below the label (preferred)","required":false},"description":{"type":"string","description":"Deprecated alias for helperText","required":false},"disabled":{"type":"boolean","description":"Whether the switch is non-interactive","default":"false","required":false},"size":{"type":"enum","description":"Switch track size","default":"md","required":false,"values":["sm","md","lg"]},"className":{"type":"string","description":"","required":false},"name":{"type":"string","description":"","required":false},"id":{"type":"string","description":"","required":false},"aria-label":{"type":"string","description":"","required":false},"aria-labelledby":{"type":"string","description":"","required":false},"aria-describedby":{"type":"string","description":"","required":false},"form":{"type":"string","description":"","required":false},"inputRef":{"type":"union","description":"","required":false},"readOnly":{"type":"boolean","description":"","default":"false","required":false},"required":{"type":"boolean","description":"","default":"false","required":false},"uncheckedValue":{"type":"string","description":"","required":false},"value":{"type":"string","description":"","required":false}},"relations":[{"component":"Input","relationship":"sibling","note":"Input handles text/number entry; Switch handles boolean state"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox when change requires form submission"}],"variants":[{"name":"Default Off","description":"Nothing happens until the user flips it.","code":"<StatefulSwitch label=\"Email notifications\" />","args":{"label":"Email notifications"}},{"name":"Checked","description":"Starts on; the track fills with the accent colour.","code":"<StatefulSwitch defaultChecked label=\"Dark mode\" />","args":{"defaultChecked":true,"label":"Dark mode"}},{"name":"With Helper Text","description":"Second line says what the setting actually does.","code":"<StatefulSwitch\n defaultChecked\n label=\"Auto-save\"\n helperText=\"Automatically save changes as you type\"\n/>","args":{"defaultChecked":true,"label":"Auto-save","helperText":"Automatically save changes as you type"}},{"name":"Sizes","description":"Three track sizes: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulSwitch size=\"sm\" defaultChecked label=\"Small switch\" />\n <StatefulSwitch size=\"md\" defaultChecked label=\"Medium switch (default)\" />\n <StatefulSwitch size=\"lg\" defaultChecked label=\"Large switch\" />\n</div>"},{"name":"Disabled States","description":"Locked off and locked on, both dimmed.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Switch disabled label=\"Premium feature (upgrade required)\" />\n <Switch disabled checked label=\"System managed (read-only)\" />\n</div>"},{"name":"Settings Panel","description":"Stacked switches sharing one rhythm and helper column.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>\n <StatefulSwitch\n defaultChecked\n label=\"Push notifications\"\n helperText=\"Receive push notifications on your device\"\n />\n <StatefulSwitch\n defaultChecked\n label=\"Email digest\"\n helperText=\"Weekly summary of your activity\"\n />\n <StatefulSwitch\n label=\"Marketing emails\"\n helperText=\"Product updates and promotional offers\"\n />\n</div>"}],"contract":{"propsSummary":["checked: boolean - on/off state","onCheckedChange: (checked) => void - state change handler","onChange: (checked) => void - alias for onCheckedChange","label: string - visible label text","helperText: string - helper text below label (preferred)","description: string - deprecated alias for helperText","disabled: boolean - non-interactive state","size: sm|md|lg - switch size"],"a11yRules":["A11Y_SWITCH_ROLE","A11Y_SWITCH_LABEL","A11Y_SWITCH_FOCUS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["checked: boolean","defaultChecked: boolean","onCheckedChange: function","onChange: function","label: string","helperText: string","description: string","disabled: boolean (default: false)","size: sm|md|lg (default: md)","className: string","name: string","id: string","aria-label: string","aria-labelledby: string","aria-describedby: string"],"sourcePath":"src/components/Switch/index.tsx","exportName":"Switch","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.429Z"},"performance":{"bundleSize":1033,"rawSize":2130,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Switch (self)","bytes":1238,"percent":58},{"path":"ComponentDefaults","bytes":194,"percent":9},{"path":"src/utils/aria.ts","bytes":109,"percent":5}]}},"Table":{"filePath":"src/components/Table/index.tsx","meta":{"name":"Table","description":"Renders tabular data as a real HTML table — headers, rows, footer.","category":"display","tags":["table","semantic","html","layout"],"status":"stable"},"usage":{"when":["The data is static — read it, do not interact with it","You need real thead/tbody/tfoot semantics","The table needs a caption or a totals footer"],"whenNot":["Rows need sorting, selection, or clicking (use DataTable)","Content is a single column of items (use List)"],"guidelines":["Header cells go in Table.HeaderCell — it sets scope=\"col\" for you","Give every table a caption or aria-label; visuallyHidden keeps it off screen","Reach for density, not the deprecated size prop","Narrow viewports scroll the table sideways — keep column count low"],"accessibility":["Semantic HTML table elements (thead, tbody, tfoot, th, td)","Column headers have scope=\"col\" by default","Caption provides table description for screen readers","Supports visually-hidden caption for screen-reader-only labels"]},"props":{"size":{"type":"enum","description":"Table density","default":"md","required":false,"values":["sm","md","compact"]},"striped":{"type":"boolean","description":"Show alternating row backgrounds","default":"false","required":false},"bordered":{"type":"boolean","description":"Wrap table in a bordered container","default":"false","required":false},"wrapperClassName":{"type":"string","description":"Class name for the outer scroll/wrapper container","required":false},"wrapperProps":{"type":"object","description":"HTML attributes for the outer scroll/wrapper container","required":false},"children":{"type":"node","description":"","required":false},"density":{"type":"enum","description":"Canonical row density.","required":false,"values":["compact","regular","relaxed"]}},"relations":[{"component":"DataTable","relationship":"alternative","note":"Use DataTable for sorting, selection, and TanStack features"}],"variants":[{"name":"Default","description":"Header row plus body rows, no extra styling.","code":"<Table aria-label=\"Team members\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Role</Table.HeaderCell>\n <Table.HeaderCell>Status</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Alice Johnson</Table.Cell>\n <Table.Cell>Engineer</Table.Cell>\n <Table.Cell>Active</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Bob Smith</Table.Cell>\n <Table.Cell>Designer</Table.Cell>\n <Table.Cell>Active</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Carol Williams</Table.Cell>\n <Table.Cell>PM</Table.Cell>\n <Table.Cell>Away</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Empty","description":"Keep the headers and fill one full-width cell so the layout holds.","code":"<Table aria-label=\"Team members\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Role</Table.HeaderCell>\n <Table.HeaderCell>Status</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell colSpan={3}>No team members yet.</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Striped","description":"Row tint alternates so the eye tracks across wide rows.","code":"<Table striped aria-label=\"Inventory\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Item</Table.HeaderCell>\n <Table.HeaderCell>Category</Table.HeaderCell>\n <Table.HeaderCell>Qty</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Widget A</Table.Cell>\n <Table.Cell>Hardware</Table.Cell>\n <Table.Cell>120</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget B</Table.Cell>\n <Table.Cell>Software</Table.Cell>\n <Table.Cell>85</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget C</Table.Cell>\n <Table.Cell>Hardware</Table.Cell>\n <Table.Cell>200</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget D</Table.Cell>\n <Table.Cell>Software</Table.Cell>\n <Table.Cell>50</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Bordered","description":"A border wraps the data so it reads as one block on a busy page.","code":"<Table bordered aria-label=\"Pricing\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n <Table.HeaderCell>Features</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Basic</Table.Cell>\n <Table.Cell>$9/mo</Table.Cell>\n <Table.Cell>5 projects</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Pro</Table.Cell>\n <Table.Cell>$29/mo</Table.Cell>\n <Table.Cell>Unlimited</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Compact","description":"Tighter rows fit more data in the same height.","code":"<Table density=\"compact\" aria-label=\"Shortcuts\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Key</Table.HeaderCell>\n <Table.HeaderCell>Action</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Ctrl+S</Table.Cell>\n <Table.Cell>Save</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+Z</Table.Cell>\n <Table.Cell>Undo</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+C</Table.Cell>\n <Table.Cell>Copy</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"With Caption","description":"A visible caption titles the data for every reader.","code":"<Table aria-label=\"Q1 results\">\n <Table.Caption>Quarterly Results (Q1 2026)</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Metric</Table.HeaderCell>\n <Table.HeaderCell>Value</Table.HeaderCell>\n <Table.HeaderCell>Change</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Revenue</Table.Cell>\n <Table.Cell>$1.2M</Table.Cell>\n <Table.Cell>+15%</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Users</Table.Cell>\n <Table.Cell>24,500</Table.Cell>\n <Table.Cell>+8%</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Screen Reader Caption","description":"The caption reaches screen readers only; the layout stays tight.","code":"<Table aria-label=\"API keys\">\n <Table.Caption visuallyHidden>API keys and last-used timestamps</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Prefix</Table.HeaderCell>\n <Table.HeaderCell>Last Used</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Deploy</Table.Cell>\n <Table.Cell>frg_live_...</Table.Cell>\n <Table.Cell>2 hours ago</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>CI</Table.Cell>\n <Table.Cell>frg_test_...</Table.Cell>\n <Table.Cell>Yesterday</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"With Footer","description":"Totals sit in a footer that stays separate from the data.","code":"<Table bordered aria-label=\"Expenses\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Category</Table.HeaderCell>\n <Table.HeaderCell>Amount</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Marketing</Table.Cell>\n <Table.Cell>$12,000</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Engineering</Table.Cell>\n <Table.Cell>$45,000</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Operations</Table.Cell>\n <Table.Cell>$8,000</Table.Cell>\n </Table.Row>\n </Table.Body>\n <Table.Footer>\n <Table.Row>\n <Table.Cell>Total</Table.Cell>\n <Table.Cell>$65,000</Table.Cell>\n </Table.Row>\n </Table.Footer>\n</Table>"}],"contract":{"propsSummary":["size: sm|md - table density","striped: boolean - alternating row backgrounds","bordered: boolean - bordered container","Table.Head, Table.Body, Table.Footer - section wrappers","Table.Row - table row with optional selected prop","Table.HeaderCell - th with scope=\"col\"","Table.Cell - td element","wrapperClassName/wrapperProps - customize outer scroll wrapper","Table.Caption - caption with visuallyHidden prop (hidden is deprecated alias)"],"a11yRules":["A11Y_TABLE_HEADERS","A11Y_TABLE_CAPTION"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Head","Body","Footer","Row","Cell","HeaderCell","Caption"],"commonPatterns":["<Table><Table.Head><Table.Row><Table.HeaderCell>Name</Table.HeaderCell></Table.Row></Table.Head><Table.Body><Table.Row><Table.Cell>Alice</Table.Cell></Table.Row></Table.Body></Table>"],"requiredChildren":["Head","Body","Row","Cell","HeaderCell"]},"propsSummary":["size: sm|md (default: md)","striped: boolean (default: false)","bordered: boolean (default: false)","wrapperClassName: string","wrapperProps: object","children: node"],"sourcePath":"src/components/Table/index.tsx","exportName":"Table","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.484Z"},"performance":{"bundleSize":2044,"rawSize":5464,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"src/recipes/table-chrome.ts","bytes":3076,"percent":56},{"path":"Table (self)","bytes":1801,"percent":33}]}},"TableOfContents":{"filePath":"src/components/TableOfContents/index.tsx","meta":{"name":"TableOfContents","description":"Indexes a long page and marks the section currently in view.","category":"navigation","tags":["toc","table-of-contents","navigation","sidebar","scroll-spy","headings","tree","hierarchy"],"status":"stable"},"usage":{"when":["Docs, articles, and other long reads","Reference pages with many sections","Filterable sidebars grouped by category","Anything past three headings"],"whenNot":["Pages with one or two sections","Site navigation (use Sidebar or Header)","Steps in an order (use Stepper)"],"guidelines":["Drive the active item from an IntersectionObserver scroll spy","Sub-items show by default — pass hideSubItems for a compact index","Group nests items under a labelled, optionally collapsible parent","Item ids must match the real heading ids","Items smooth-scroll — call preventDefault() in onClick to take over","Group is uncontrolled and open by default; pass open and onOpenChange to drive it","The legacy indent boolean still works; prefer Group in new code"],"accessibility":["Uses <nav aria-label=\"Table of contents\"> for landmark navigation","Active item is marked with aria-current=\"location\"","All items are links with smooth scroll behavior","Group toggle is a real <button> with aria-expanded reflecting open state","Focus-visible ring on keyboard navigation"]},"props":{"children":{"type":"node","description":"TableOfContents.Item or TableOfContents.Group elements","required":true},"label":{"type":"string","description":"Accessible label for the nav landmark","default":"Table of contents","required":false},"title":{"type":"string","description":"Visible title above the list","default":"On This Page","required":false},"hideTitle":{"type":"boolean","description":"Hide the visible title","default":"false","required":false},"hideSubItems":{"type":"boolean","description":"Hide indented items and nested groups","default":"false","required":false}},"relations":[{"component":"Breadcrumbs","relationship":"complementary","note":"Breadcrumbs show hierarchy, TOC shows page sections"},{"component":"Sidebar","relationship":"complementary","note":"Sidebar for site nav, TOC for in-page nav"},{"component":"Tabs","relationship":"alternative","note":"Tabs for switching views, TOC for scrolling to sections"}],"variants":[{"name":"Default","description":"Sections and their subsections, indented.","code":"<TableOfContents>\n <TableOfContents.Item id=\"introduction\">Introduction</TableOfContents.Item>\n <TableOfContents.Item id=\"getting-started\">Getting Started</TableOfContents.Item>\n <TableOfContents.Item id=\"installation\" indent>Installation</TableOfContents.Item>\n <TableOfContents.Item id=\"configuration\" indent>Configuration</TableOfContents.Item>\n <TableOfContents.Item id=\"api-reference\">API Reference</TableOfContents.Item>\n <TableOfContents.Item id=\"examples\">Examples</TableOfContents.Item>\n</TableOfContents>"},{"name":"Top-level Only","description":"Drops subsections when the index would crowd.","code":"<TableOfContents hideSubItems>\n <TableOfContents.Item id=\"overview\">Overview</TableOfContents.Item>\n <TableOfContents.Item id=\"basic-usage\" indent>Basic usage</TableOfContents.Item>\n <TableOfContents.Item id=\"advanced-usage\" indent>Advanced usage</TableOfContents.Item>\n <TableOfContents.Item id=\"accessibility\">Accessibility</TableOfContents.Item>\n</TableOfContents>"},{"name":"Nested Groups","description":"Collapsible categories with counts.","code":"<TableOfContents title=\"Components\">\n <TableOfContents.Item id=\"all\" active>All</TableOfContents.Item>\n <TableOfContents.Group label=\"Primitives\" trailing={<span>3</span>}>\n <TableOfContents.Item id=\"button\">Button</TableOfContents.Item>\n <TableOfContents.Item id=\"card\">Card</TableOfContents.Item>\n <TableOfContents.Item id=\"input\">Input</TableOfContents.Item>\n </TableOfContents.Group>\n <TableOfContents.Group label=\"Custom\" defaultOpen={false}>\n <TableOfContents.Item id=\"features\">Features</TableOfContents.Item>\n <TableOfContents.Item id=\"plans\">Plans</TableOfContents.Item>\n </TableOfContents.Group>\n</TableOfContents>"},{"name":"With Active Item","description":"The current section stays marked while you read.","code":"<TableOfContents>\n <TableOfContents.Item id=\"overview\">Overview</TableOfContents.Item>\n <TableOfContents.Item id=\"setup\" active>Setup</TableOfContents.Item>\n <TableOfContents.Item id=\"usage\" indent>Basic Usage</TableOfContents.Item>\n <TableOfContents.Item id=\"advanced\" indent>Advanced</TableOfContents.Item>\n <TableOfContents.Item id=\"props\">Props</TableOfContents.Item>\n <TableOfContents.Item id=\"accessibility\">Accessibility</TableOfContents.Item>\n</TableOfContents>"},{"name":"Custom Title","description":"Any heading in place of the default.","code":"<TableOfContents title=\"Contents\">\n <TableOfContents.Item id=\"chapter-1\">Chapter 1: The Beginning</TableOfContents.Item>\n <TableOfContents.Item id=\"chapter-2\">Chapter 2: The Middle</TableOfContents.Item>\n <TableOfContents.Item id=\"chapter-3\">Chapter 3: The End</TableOfContents.Item>\n</TableOfContents>"},{"name":"No Title","description":"Bare list where the surrounding layout already says enough.","code":"<TableOfContents hideTitle>\n <TableOfContents.Item id=\"section-a\">Section A</TableOfContents.Item>\n <TableOfContents.Item id=\"section-b\" active>Section B</TableOfContents.Item>\n <TableOfContents.Item id=\"section-c\">Section C</TableOfContents.Item>\n</TableOfContents>"}],"contract":{"propsSummary":["title: string - visible heading (default \"On This Page\")","hideTitle: boolean - hide the title","hideSubItems: boolean - hide indented items and nested groups (default false)","label: string - aria-label for nav landmark","TableOfContents.Item id: string - heading ID to link to","TableOfContents.Item active: boolean - highlight the current item with ink and weight","TableOfContents.Item indent: boolean - legacy depth=1 indent for flat lists; prefer Group for new code","TableOfContents.Item leading/trailing: node - optional adornments before/after the label","TableOfContents.Group label: node - header text for the group","TableOfContents.Group defaultOpen / open / onOpenChange - uncontrolled or controlled open state (default open)","TableOfContents.Group collapsible: boolean - render as a static label (default true)","TableOfContents.Group trailing/leading: node - optional adornments on the group header row","Forwards standard nav/anchor DOM props; TableOfContents.Item onClick can prevent default smooth scroll"],"a11yRules":["A11Y_NAV_LANDMARK","A11Y_ARIA_CURRENT","A11Y_ARIA_EXPANDED"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Group"],"requiredChildren":["Item","Group"],"commonPatterns":["<TableOfContents>{headings.map(h => <TableOfContents.Item key={h.id} id={h.id} active={activeId === h.id} indent={h.level === 3}>{h.text}</TableOfContents.Item>)}</TableOfContents>","<TableOfContents>{groups.map(g => <TableOfContents.Group key={g.label} label={g.label} trailing={g.count}>{g.items.map(i => <TableOfContents.Item key={i.id} id={i.id} active={activeId === i.id}>{i.label}</TableOfContents.Item>)}</TableOfContents.Group>)}</TableOfContents>"]},"propsSummary":["children: node (required)","label: string (default: Table of contents)","title: string (default: On This Page)","hideTitle: boolean (default: false)","hideSubItems: boolean (default: false)"],"sourcePath":"src/components/TableOfContents/index.tsx","exportName":"TableOfContents","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.685Z"},"performance":{"bundleSize":1959,"rawSize":4412,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"TableOfContents (self)","bytes":2956,"percent":67},{"path":"Text","bytes":782,"percent":18}]}},"Tabs":{"filePath":"src/components/Tabs/index.tsx","meta":{"name":"Tabs","description":"Swaps between sibling panels without leaving the page.","category":"navigation","tags":["tabs","navigation","panels","content-switcher"],"status":"stable"},"usage":{"when":["Sibling sections of equal weight","Cutting scroll on a long page","Settings split by category","One data set seen several ways"],"whenNot":["Moving between pages (use Sidebar or header navigation)","Steps in an order (use Stepper)","Content the user compares side by side","More options than fit in a row (use Select)"],"guidelines":["One or two words per label","Order by how often each panel is used","Past five or six tabs, split the page instead","Keep panels comparable in depth","Pills inside cards, underline at page level"],"accessibility":["Keyboard navigation with arrow keys","Tab panels are properly labeled","Focus management follows WAI-ARIA tabs pattern"]},"props":{"children":{"type":"node","description":"Tab list and panels (use Tabs.List, Tabs.Tab, Tabs.Panel)","required":true},"defaultValue":{"type":"string","description":"Initially active tab (uncontrolled)","required":false},"value":{"type":"string","description":"Controlled active tab value","required":false},"onValueChange":{"type":"function","description":"Called when active tab changes","required":false},"orientation":{"type":"enum","description":"Tab list orientation","default":"horizontal","required":false,"values":["horizontal","vertical"]},"variant":{"type":"enum","description":"Default visual style for Tabs.List (can be overridden on Tabs.List)","default":"underline","required":false,"values":["underline","pills"]},"size":{"type":"enum","description":"Tab control size. Defaults to the component-default control size.","required":false,"values":["sm","md","lg"]}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for many options in compact space"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based navigation"}],"variants":[{"name":"Underline","description":"A rule tracks the active panel.","code":"<Tabs defaultValue=\"overview\" variant=\"underline\">\n <Tabs.List>\n <Tabs.Tab value=\"overview\">Overview</Tabs.Tab>\n <Tabs.Tab value=\"analytics\">Analytics</Tabs.Tab>\n <Tabs.Tab value=\"settings\">Settings</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"overview\">\n <p>Overview content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"analytics\">\n <p>Analytics content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"settings\">\n <p>Settings content goes here.</p>\n </Tabs.Panel>\n</Tabs>"},{"name":"Pills","description":"A filled track suits panels inside a card.","code":"<Tabs defaultValue=\"all\" variant=\"pills\">\n <Tabs.List>\n <Tabs.Tab value=\"all\">All</Tabs.Tab>\n <Tabs.Tab value=\"active\">Active</Tabs.Tab>\n <Tabs.Tab value=\"archived\">Archived</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"all\">\n <p>Showing all items.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"active\">\n <p>Showing active items only.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"archived\">\n <p>Showing archived items.</p>\n </Tabs.Panel>\n</Tabs>"},{"name":"With Disabled","description":"An unavailable panel stays visible but unreachable.","code":"<Tabs defaultValue=\"general\" variant=\"underline\">\n <Tabs.List>\n <Tabs.Tab value=\"general\">General</Tabs.Tab>\n <Tabs.Tab value=\"security\">Security</Tabs.Tab>\n <Tabs.Tab value=\"billing\" disabled>Billing</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"general\">\n <p>General settings panel.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"security\">\n <p>Security settings panel.</p>\n </Tabs.Panel>\n</Tabs>"},{"name":"List Variant Override","description":"One list can opt out of the root's style.","code":"<Tabs defaultValue=\"overview\" variant=\"pills\">\n <Tabs.List variant=\"underline\">\n <Tabs.Tab value=\"overview\">Overview</Tabs.Tab>\n <Tabs.Tab value=\"activity\">Activity</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"overview\">\n <p>Root sets pills, but this list overrides to underline.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"activity\">\n <p>Per-list variant override example.</p>\n </Tabs.Panel>\n</Tabs>"}],"contract":{"propsSummary":["value: string - controlled active tab","defaultValue: string - initial active tab","onValueChange: (value) => void - tab change handler","variant: underline|pills - default style for Tabs.List","Tabs.List variant?: underline|pills - optional per-list override"],"a11yRules":["A11Y_TABS_KEYBOARD","A11Y_TABS_LABELS"]},"ai":{"compositionPattern":"compound","subComponents":["List","Tab","Panel"],"requiredChildren":["List","Panel"],"commonPatterns":["<Tabs defaultValue=\"tab1\"><Tabs.List><Tabs.Tab value=\"tab1\">{label1}</Tabs.Tab><Tabs.Tab value=\"tab2\">{label2}</Tabs.Tab></Tabs.List><Tabs.Panel value=\"tab1\">{content1}</Tabs.Panel><Tabs.Panel value=\"tab2\">{content2}</Tabs.Panel></Tabs>"]},"propsSummary":["children: node (required)","defaultValue: string","value: string","onValueChange: function","orientation: horizontal|vertical (default: horizontal)","variant: underline|pills (default: underline)"],"sourcePath":"src/components/Tabs/index.tsx","exportName":"Tabs","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.871Z"},"performance":{"bundleSize":1046,"rawSize":2518,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Tabs (self)","bytes":1687,"percent":67},{"path":"ComponentDefaults","bytes":193,"percent":8}]}},"Text":{"filePath":"src/components/Text/index.tsx","meta":{"name":"Text","description":"Applies the type scale to any text element, without hand-rolling font rules.","category":"display","tags":["text","typography","heading","paragraph","font"],"status":"stable"},"usage":{"when":["Any text that should sit on the type scale","Headings and paragraphs that need real tags","Text that must truncate or clamp"],"whenNot":["Rich or authored content (use Markdown)","Code (use CodeBlock)","Anything clickable (use Link or Button)"],"guidelines":["Pick the tag with as, the look with size — they are separate decisions","Never skip heading levels to get a smaller heading","Color is for hierarchy and state, not decoration","Truncated text needs the full string in title or a tooltip"],"accessibility":["as keeps the document outline intact for screen readers","Clamped text still exposes its full content to assistive tech"]},"props":{"children":{"type":"node","description":"Text content","required":true},"as":{"type":"enum","description":"HTML element to render","default":"span","required":false,"values":["h1","h2","h3","h4","h5","h6","p","span","label","div","strong","em","small","mark","del","ins","sub","sup","time","address","blockquote","cite","code","abbr"]},"variant":{"type":"enum","description":"Preset text variant","required":false,"values":["section-label","eyebrow"]},"size":{"type":"enum","description":"Font size. 2xs (10), xs (12), sm/base (14), md (15 prose body), lg (20), xl (24), 2xl (30), 3xl (36 page title), 4xl (48 hero).","required":false,"values":["2xs","xs","sm","base","md","lg","xl","2xl","3xl","4xl"]},"weight":{"type":"enum","description":"Font weight","default":"\"normal\"","required":false,"values":["normal","medium","semibold","bold"]},"color":{"type":"enum","description":"Text color (muted is an alias for tertiary; success/warning/danger are for a run of text that carries a state on its own — prefer Badge or Alert when the state deserves a container)","default":"\"primary\"","required":false,"values":["primary","secondary","tertiary","muted","accent","success","warning","danger"]},"font":{"type":"enum","description":"Font family","default":"sans","required":false,"values":["sans","mono"]},"truncate":{"type":"boolean","description":"Truncate with ellipsis on overflow","required":false},"lineClamp":{"type":"number","description":"Number of lines before truncating (requires truncate)","required":false},"style":{"type":"object","description":"","required":false},"letterSpacing":{"type":"enum","description":"","required":false,"values":["normal","tight","tighter","tightest"]},"role":{"type":"enum","description":"","required":false,"values":["caption","ui-compact","ui-standard","body-compact","body-relaxed","title-sm","title-md","title-lg","display","code"]},"tabularNums":{"type":"boolean","description":"Use tabular (fixed-width) numerals so digits align in columns. Ideal for\nstat values, tables, timestamps, and any updating number.","required":false}},"relations":[{"component":"Link","relationship":"sibling","note":"Use Link for clickable text"},{"component":"CodeBlock","relationship":"alternative","note":"Use CodeBlock for code display"},{"component":"Badge","relationship":"sibling","note":"Use Badge for labels/tags"}],"variants":[{"name":"Sizes","description":"Ten steps from caption to hero, all on the same scale.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text size=\"2xs\">Extra extra small (2xs — 10px)</Text>\n <Text size=\"xs\">Extra small (xs — 12px)</Text>\n <Text size=\"sm\">Small (sm — 14px)</Text>\n <Text size=\"base\">Base size (14px)</Text>\n <Text size=\"md\">Medium prose body (md — 15px)</Text>\n <Text size=\"lg\">Large (lg — 20px)</Text>\n <Text size=\"xl\">Extra large (xl — 24px)</Text>\n <Text size=\"2xl\">Extra extra large (2xl — 30px)</Text>\n <Text size=\"3xl\">Page title (3xl — 36px)</Text>\n <Text size=\"4xl\">Hero display (4xl — 48px)</Text>\n</div>"},{"name":"Weights","description":"Four weights — reach past semibold only for real emphasis.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text weight=\"normal\">Normal weight</Text>\n <Text weight=\"medium\">Medium weight</Text>\n <Text weight=\"semibold\">Semibold weight</Text>\n <Text weight=\"bold\">Bold weight</Text>\n</div>"},{"name":"Colors","description":"Dimmer tones push text back; success and danger carry state.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text color=\"primary\">Primary color (default)</Text>\n <Text color=\"secondary\">Secondary color</Text>\n <Text color=\"tertiary\">Tertiary color</Text>\n <Text color=\"muted\">Muted color (alias for tertiary)</Text>\n</div>"},{"name":"Semantic Elements","description":"The as prop picks the tag, so the outline stays correct.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Text as=\"h1\" size=\"3xl\" weight=\"semibold\">Heading 1</Text>\n <Text as=\"h2\" size=\"xl\" weight=\"semibold\">Heading 2</Text>\n <Text as=\"h3\" size=\"lg\" weight=\"semibold\">Heading 3</Text>\n <Text as=\"p\" size=\"md\" color=\"secondary\">\n This is a paragraph of text that demonstrates the Text component\n with semantic paragraph element.\n </Text>\n</div>"},{"name":"Monospace","description":"Fixed width for IDs, keys, and anything meant to be compared.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text font=\"mono\" size=\"sm\">const greeting = \"Hello, World!\";</Text>\n <Text font=\"mono\" size=\"sm\" color=\"secondary\">npm install @usefragments/ui</Text>\n</div>"},{"name":"Truncation","description":"One line with an ellipsis, or clamp to a set number of lines.","code":"<div style={{ width: '200px', display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Text truncate>\n This is a very long text that will be truncated with an ellipsis when it overflows.\n </Text>\n <Text truncate lineClamp={2}>\n This text will be clamped to two lines. Any content beyond two lines\n will be hidden and replaced with an ellipsis at the end.\n </Text>\n</div>"}],"contract":{"propsSummary":["as: string - HTML element","size: 2xs|xs|sm|base|md|lg|xl|2xl|3xl|4xl - font size (px: 10/12/14/14/15/20/24/30/36/48)","weight: normal|medium|semibold|bold - font weight","color: primary|secondary|tertiary|muted|accent|success|warning|danger - text color (muted = tertiary; accent = brand spend; semantic colours for inline state)","font: sans|mono - font family","truncate: boolean - enable truncation","lineClamp: number - max lines"],"a11yRules":["A11Y_HEADING_HIERARCHY","A11Y_SEMANTIC_ELEMENTS"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","as: h1|h2|h3|h4|h5|h6|p|span|label|div|strong|em|small|mark|del|ins|sub|sup|time|address|blockquote|cite|code|abbr (default: span)","variant: section-label","size: 2xs|xs|sm|base|md|lg|xl|2xl|3xl|4xl","weight: normal|medium|semibold|bold (default: \"normal\")","color: primary|secondary|tertiary|muted|accent|success|warning|danger (default: \"primary\")","font: sans|mono (default: sans)","truncate: boolean","lineClamp: number","style: object"],"sourcePath":"src/components/Text/index.tsx","exportName":"Text","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.045Z"},"performance":{"bundleSize":771,"rawSize":1355,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Text (self)","bytes":782,"percent":58}]}},"Textarea":{"filePath":"src/components/Textarea/index.tsx","meta":{"name":"Textarea","description":"Collects multi-line text for longer form content.","category":"inputs","tags":["input","text","form","multiline"],"status":"stable"},"usage":{"when":["Collecting multi-line text (comments, descriptions)","Free-form text input that may span multiple lines","Message composition fields","Code or content editing"],"whenNot":["Single-line input (use Input)","Rich text editing (use rich text editor)","Selecting from predefined options (use Select)"],"guidelines":["Set rows to match the expected answer length","Placeholder shows an example, not the label","Pair maxLength with showCharCount so the limit is visible","Use resize=\"none\" only when the layout truly cannot flex"],"accessibility":["Give every textarea a visible label","Put format hints in helperText, not the placeholder","Error text says what to fix, not just that it failed"]},"props":{"value":{"type":"string","description":"Controlled value","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","required":false},"placeholder":{"type":"string","description":"Placeholder text","required":false},"rows":{"type":"number","description":"Number of visible text rows","default":"3","required":false},"minRows":{"type":"number","description":"Minimum number of rows when auto-resizing","required":false},"maxRows":{"type":"number","description":"Maximum number of rows when auto-resizing","required":false},"resize":{"type":"enum","description":"Resize behavior","default":"vertical","required":false,"values":["none","vertical","horizontal","both"]},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Disabled state","default":"false","required":false},"error":{"type":"boolean","description":"Error state","default":"false","required":false},"success":{"type":"boolean","description":"Whether to show success/validated styling","default":"false","required":false},"showCharCount":{"type":"boolean","description":"Show character counter when maxLength is set","default":"false","required":false},"label":{"type":"string","description":"Label text above the textarea","required":false},"helperText":{"type":"string","description":"Helper text below the textarea","required":false},"onChange":{"type":"function","description":"Called when the textarea value changes","required":false},"onValueChange":{"type":"function","description":"Value-first change callback alias: (value: string) => void","required":false},"onBlur":{"type":"function","description":"Called when textarea loses focus","required":false},"onFocus":{"type":"function","description":"Called when textarea receives focus","required":false},"name":{"type":"string","description":"Form field name","required":false},"maxLength":{"type":"number","description":"Maximum character length","required":false},"required":{"type":"boolean","description":"Required field","required":false},"aria-label":{"type":"string","description":"Accessible label for no-visible-label usage","required":false},"aria-labelledby":{"type":"string","description":"Accessible labelled-by relationship","required":false},"aria-describedby":{"type":"string","description":"Accessible described-by relationship","required":false},"rootProps":{"type":"object","description":"HTML attributes applied to the wrapper element","required":false},"className":{"type":"string","description":"Wrapper class name","required":false},"style":{"type":"object","description":"Wrapper styles","required":false}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for single-line text"}],"variants":[{"name":"Default","description":"Three rows, draggable from the bottom-right corner.","code":"<Textarea\n label=\"Description\"\n placeholder=\"Enter a description...\"\n/>"},{"name":"With Helper Text","description":"Supporting text sits under the box.","code":"<Textarea\n label=\"Bio\"\n placeholder=\"Tell us about yourself...\"\n helperText=\"Max 500 characters\"\n maxLength={500}\n/>"},{"name":"Error State","description":"Red border, and helperText becomes the reason.","code":"<Textarea\n label=\"Comments\"\n placeholder=\"Add your comments...\"\n error\n helperText=\"This field is required\"\n/>"},{"name":"Disabled","description":"Dimmed and unfocusable.","code":"<Textarea\n label=\"Notes\"\n placeholder=\"Cannot edit...\"\n disabled\n/>"},{"name":"Custom Rows","description":"rows={6} doubles the visible height before scrolling.","code":"<Textarea\n label=\"Long Description\"\n placeholder=\"Enter detailed information...\"\n rows={6}\n/>"},{"name":"Sizes","description":"Three heights: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '400px' }}>\n <Textarea label=\"Small\" size=\"sm\" placeholder=\"Small textarea\" />\n <Textarea label=\"Medium\" size=\"md\" placeholder=\"Medium textarea\" />\n <Textarea label=\"Large\" size=\"lg\" placeholder=\"Large textarea\" />\n</div>"},{"name":"Fixed Height","description":"resize=\"none\" removes the drag handle so the box stays put.","code":"<Textarea\n label=\"Notes\"\n placeholder=\"Add notes...\"\n resize=\"none\"\n/>"},{"name":"Success State","description":"Green border confirms the value passed validation.","code":"<Textarea\n label=\"Bio\"\n value=\"A short bio about myself.\"\n success\n helperText=\"Looks great!\"\n/>"},{"name":"With Character Counter","description":"Live count against maxLength sits below the box.","code":"<Textarea\n label=\"Bio\"\n placeholder=\"Tell us about yourself...\"\n maxLength={200}\n showCharCount\n/>"}],"contract":{"propsSummary":["value: string - controlled value","rows: number - visible rows (default: 3)","label: string - label text","size: sm|md|lg (default: md)","error: boolean - error state","success: boolean - shows success/validated styling","showCharCount: boolean - show character counter (requires maxLength)","disabled: boolean - disabled state","resize: none|vertical|horizontal|both","onValueChange: (value: string) => void - value-first change callback alias","rootProps: HTMLAttributes<HTMLDivElement> - wrapper element props","...native textarea attributes are supported (readOnly, autoComplete, maxLength, onKeyDown, etc.)"],"a11yRules":["A11Y_LABEL_REQUIRED"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["value: string","defaultValue: string","placeholder: string","rows: number (default: 3)","minRows: number","maxRows: number","resize: none|vertical|horizontal|both (default: vertical)","size: sm|md|lg (default: md)","disabled: boolean (default: false)","error: boolean (default: false)","success: boolean (default: false)","showCharCount: boolean (default: false)","label: string","helperText: string","onChange: function","onValueChange: function","onBlur: function","onFocus: function","name: string","maxLength: number","required: boolean","aria-label: string","aria-labelledby: string","aria-describedby: string","rootProps: object","className: string","style: object"],"sourcePath":"src/components/Textarea/index.tsx","exportName":"Textarea","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.217Z"},"performance":{"bundleSize":1292,"rawSize":2713,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Textarea (self)","bytes":1813,"percent":67},{"path":"ComponentDefaults","bytes":198,"percent":7},{"path":"src/utils/aria.ts","bytes":110,"percent":4}]}},"Theme":{"filePath":"src/components/Theme/index.tsx","meta":{"name":"Theme","description":"Gives every component below it a light, dark, or system color mode, and remembers the choice.","category":"utilities","tags":["theme","dark-mode","light-mode","provider","toggle"],"status":"stable"},"usage":{"when":["An app needs light and dark modes","The user's choice should survive a reload","You want to honour the OS setting by default"],"whenNot":["Recoloring one component (use its props)","A single one-off color swap (use a CSS variable)"],"guidelines":["ThemeProvider goes at the root, once","useTheme reads and sets the mode anywhere below it","storageKey renames the localStorage entry","attribute=\"class\" if your CSS keys off .dark instead of data-theme","appearance=\"icon\" for tight toolbars; the default group shows both modes"],"accessibility":["The toggle's label names the mode it is in","System mode follows prefers-color-scheme"]},"props":{"children":{"type":"node","description":"Application content","required":true},"defaultMode":{"type":"enum","description":"Default theme mode for uncontrolled usage","default":"system","required":false,"values":["light","dark","system"]},"defaultTheme":{"type":"enum","description":"","required":false,"values":["light","dark","system"]},"mode":{"type":"enum","description":"Controlled theme mode","required":false,"values":["light","dark","system"]},"onModeChange":{"type":"function","description":"Callback when mode changes","required":false},"storageKey":{"type":"string","description":"localStorage key for persistence","default":"fui-theme","required":false},"attribute":{"type":"enum","description":"How to apply theme to DOM","default":"data-theme","required":false,"values":["data-theme","class"]},"componentDefaults":{"type":"object","description":"Default primitive component behavior for the subtree.","required":false}},"relations":[{"component":"AppShell","relationship":"sibling","note":"ThemeProvider typically wraps AppShell"}],"variants":[{"name":"Default","description":"Wrap the app once; every token below resolves to the active mode.","code":"<ThemeProvider defaultMode=\"system\">\n <div\n style={{\n padding: '16px',\n borderRadius: '8px',\n background: 'var(--fui-bg-elevated)',\n color: 'var(--fui-text-primary)',\n }}\n >\n Everything inside follows the system color scheme.\n </div>\n</ThemeProvider>"},{"name":"With Toggle","description":"The toggle cycles light, dark, then back to system.","code":"<ThemeProvider defaultMode=\"light\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n <ThemeToggle />\n <span>Click to cycle themes</span>\n </div>\n</ThemeProvider>"},{"name":"Toggle Sizes","description":"Three sizes so the control fits whatever bar holds it.","code":"<ThemeProvider defaultMode=\"light\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n <ThemeToggle size=\"sm\" />\n <ThemeToggle size=\"md\" />\n <ThemeToggle size=\"lg\" />\n </div>\n</ThemeProvider>"},{"name":"Icon Toggle","description":"A single icon button for toolbars with no room to spare.","code":"<ThemeProvider defaultMode=\"system\">\n <ThemeToggle appearance=\"icon\" aria-label=\"Switch color mode\" />\n</ThemeProvider>"}],"contract":{"propsSummary":["defaultMode: light|dark|system - initial theme mode","mode: light|dark|system - controlled mode","onModeChange: (mode) => void - change handler","attribute: data-theme|class - DOM theme attribute","ThemeToggle size: sm|md|lg - toggle button size","ThemeToggle appearance: group|icon - segmented or compact icon control (default: group)","ThemeToggle forwards div DOM props to the button group root"],"a11yRules":["A11Y_TARGET_SIZE_MIN"]},"propsSummary":["children: node (required)","defaultMode: light|dark|system","defaultTheme: light|dark|system","mode: light|dark|system","onModeChange: function","storageKey: string (default: fui-theme)","attribute: data-theme|class (default: data-theme)","ThemeToggle appearance: group|icon (default: group)"],"sourcePath":"src/components/Theme/index.tsx","exportName":"ThemeProvider","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.406Z"},"ai":{"subComponents":["Root","Provider","Toggle","useTheme"],"compositionPattern":"compound"},"performance":{"bundleSize":2859,"rawSize":7041,"complexity":"lightweight","budgetPercent":19,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"ThemeToggle (self)","bytes":3107,"percent":44},{"path":"(other)","bytes":2692,"percent":38},{"path":"ComponentDefaults","bytes":391,"percent":6},{"path":"Theme","bytes":192,"percent":3}]}},"ThinkingIndicator":{"filePath":"src/components/ThinkingIndicator/index.tsx","meta":{"name":"ThinkingIndicator","description":"Shows that an AI response is being generated.","category":"ai","tags":["thinking","loading","ai","processing","indicator","animation"],"status":"stable"},"usage":{"when":["A model is working on a request","Async AI work that would otherwise look frozen","Multi-stage tasks worth showing stage by stage","The moment before streaming starts"],"whenNot":["Ordinary loading (use Progress or Skeleton)","Form submission (use the Button loading state)","Whole-page loading (use Progress or Skeleton)"],"guidelines":["active controls whether it shows at all","dots suits chat; spinner suits a discrete action","Turn on showElapsed once waits run past a few seconds","Use steps for tool calls, research, and other staged work"],"accessibility":["Uses role=\"status\" and aria-live=\"polite\"","Provides aria-label for screen readers","Animations respect prefers-reduced-motion","Elapsed time uses tabular numbers for stability"]},"props":{"active":{"type":"boolean","description":"Whether thinking is active","default":"true","required":false},"label":{"type":"string","description":"Status text","default":"Thinking...","required":false},"variant":{"type":"enum","description":"Animation style","default":"dots","required":false,"values":["dots","pulse","spinner"]},"showElapsed":{"type":"boolean","description":"Show elapsed time","default":"false","required":false},"steps":{"type":"array","description":"Multi-step progress array","required":false}},"relations":[{"component":"Message","relationship":"sibling","note":"Show ThinkingIndicator while waiting for assistant message"},{"component":"ConversationList","relationship":"parent","note":"Typically placed at bottom of ConversationList"},{"component":"Progress","relationship":"alternative","note":"Use Progress for determinate progress"}],"variants":[{"name":"Dots (Default)","description":"Three dots bounce in sequence; the quietest option.","code":"<ThinkingIndicator variant=\"dots\" label=\"Thinking...\" />"},{"name":"Pulse","description":"A single ring breathes in place.","code":"<ThinkingIndicator variant=\"pulse\" label=\"Processing...\" />"},{"name":"Spinner","description":"A rotating arc, for work with a definite end.","code":"<ThinkingIndicator variant=\"spinner\" label=\"Loading...\" />"},{"name":"With Elapsed Time","description":"A live counter reassures the reader during long waits.","code":"<ThinkingIndicator\n variant=\"dots\"\n label=\"Generating response...\"\n showElapsed\n/>"},{"name":"Multi-Step Progress","description":"Finished, running, and queued stages read at a glance.","code":"<ThinkingIndicator\n variant=\"spinner\"\n label=\"Working...\"\n steps={[\n { id: '1', label: 'Analyzing request', status: 'complete' },\n { id: '2', label: 'Searching knowledge base', status: 'active' },\n { id: '3', label: 'Generating response', status: 'pending' },\n ]}\n/>"},{"name":"With Error Step","description":"A failed stage turns red while the next one retries.","code":"<ThinkingIndicator\n variant=\"spinner\"\n label=\"Retrying...\"\n steps={[\n { id: '1', label: 'Connecting to API', status: 'complete' },\n { id: '2', label: 'Fetching data', status: 'error' },\n { id: '3', label: 'Retrying with fallback', status: 'active' },\n ]}\n/>"},{"name":"Custom Label","description":"Name the actual task instead of a generic status.","code":"<ThinkingIndicator\n variant=\"dots\"\n label=\"Claude is writing code...\"\n/>"}],"contract":{"propsSummary":["active: boolean - whether indicator is visible (default: true)","label: string - status text (default: \"Thinking...\")","variant: \"dots\" | \"pulse\" | \"spinner\" - animation style","showElapsed: boolean - show elapsed time","steps: ThinkingStep[] - multi-step progress"],"a11yRules":["A11Y_ARIA_LIVE","A11Y_MOTION_PREFERENCE"]},"ai":{"compositionPattern":"compound","subComponents":["Steps","Step"]},"propsSummary":["active: boolean (default: true)","label: string (default: Thinking...)","variant: dots|pulse|spinner (default: dots)","showElapsed: boolean (default: false)","steps: array"],"sourcePath":"src/components/ThinkingIndicator/index.tsx","exportName":"ThinkingIndicator","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.747Z"},"performance":{"bundleSize":1926,"rawSize":5341,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"ThinkingIndicator (self)","bytes":2608,"percent":49},{"path":"Loading","bytes":2035,"percent":38}]}},"Toast":{"filePath":"src/components/Toast/index.tsx","meta":{"name":"Toast","description":"Briefly reports what just happened, without blocking the page.","category":"feedback","tags":["notification","alert","message","feedback"],"status":"stable"},"usage":{"when":["Confirming an action landed","Reporting whether an operation worked","News the user does not have to act on","Messages that can disappear on their own"],"whenNot":["Errors the user must resolve — use Dialog","Anything that must stay on screen — use Alert","Field-level validation — use form error states","Site-wide notices — use a banner"],"guidelines":["One sentence, plus a title if it helps","Match the variant to what actually happened","Auto-dismiss in three to five seconds","Anything with an action needs a manual dismiss too","Two or three on screen at once, no more","useToast() helpers take (title, description) or an options object for action, duration, and id"],"accessibility":["role=\"alert\" for anything the user must not miss","Leave enough time to read it","Never let colour be the only signal","Give the dismiss button a real label"]},"props":{"onDismiss":{"type":"function","description":"Callback when toast should be dismissed","required":false},"title":{"type":"string","description":"Toast title","required":false},"description":{"type":"string","description":"Additional message content","required":false},"variant":{"type":"enum","description":"Visual variant indicating message type","default":"default","required":false,"values":["default","success","error","warning","info"]},"duration":{"type":"number","description":"Auto-dismiss duration in ms (0 = no auto-dismiss)","default":8000,"required":false},"action":{"type":"object","description":"Optional action button { label, onClick }","required":false},"id":{"type":"string","description":"","required":false},"onPause":{"type":"function","description":"Callback when auto-dismiss timer should pause","required":false},"onResume":{"type":"function","description":"Callback when auto-dismiss timer should resume","required":false}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for persistent inline messages"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for messages requiring user action"}],"variants":[{"name":"Default","description":"Neutral message with a title and one line under it.","code":"<Toast\n title=\"Draft saved\"\n description=\"We will keep it until you publish.\"\n/>"},{"name":"Variants","description":"Icon and colour together carry the outcome.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"sm\">\n <Toast\n title=\"Success!\"\n description=\"Your changes have been saved.\"\n variant=\"success\"\n />\n <Toast\n title=\"Error\"\n description=\"Failed to save changes. Please try again.\"\n variant=\"error\"\n />\n <Toast\n title=\"Warning\"\n description=\"This action cannot be undone.\"\n variant=\"warning\"\n />\n <Toast\n title=\"New update\"\n description=\"Version 2.0 is now available.\"\n variant=\"info\"\n />\n</Stack>"},{"name":"With Action","description":"One-tap way back from something destructive.","code":"<Toast\n title=\"File deleted\"\n description=\"The file has been moved to trash.\"\n action={{\n label: 'Undo',\n onClick: () => {},\n }}\n/>"},{"name":"Dismissible","description":"onDismiss adds a close button for longer messages.","code":"<Toast\n title=\"Export running\"\n description=\"We will email you when the file is ready.\"\n variant=\"info\"\n onDismiss={() => {}}\n/>"}],"contract":{"propsSummary":["title: string - toast title","description: string - additional message","variant: default|success|error|warning|info","duration: number - ms before auto-dismiss","action: { label, onClick } - optional action","ToastInput (useToast): optional id for deterministic creation/replacement flows","useToast().success/error/warning/info: (title, description?) or ({ title, description, action, duration, id })"],"a11yRules":["A11Y_ALERT_ROLE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Provider"]},"propsSummary":["onDismiss: function","title: string","description: string","variant: default|success|error|warning|info (default: default)","duration: number","action: object","id: string","onPause: function","onResume: function"],"sourcePath":"src/components/Toast/index.tsx","exportName":"Toast","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.259Z"},"performance":{"bundleSize":2184,"rawSize":5969,"complexity":"lightweight","budgetPercent":14,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Toast (self)","bytes":5348,"percent":90}]}},"ToggleGroup":{"filePath":"src/components/ToggleGroup/index.tsx","meta":{"name":"ToggleGroup","description":"Picks exactly one option from a short row of toggle buttons.","category":"actions","tags":["toggle","group","fragmented","control","tabs","switch"],"status":"stable"},"usage":{"when":["Switching between mutually exclusive views or modes","Choosing one of two to five options","View switchers and segmented filters"],"whenNot":["More than one can be picked — use a Checkbox group","More than five options — use Select or RadioGroup","Moving between pages — use Tabs","A single on/off — use Switch"],"guidelines":["Two to five items","Labels short enough to scan in one pass","Icons work for well-known modes like grid and list","default for an inset tonal rail, pills for an open filter cluster, outlined for connected segments","Keep targets at least 24px on touch"],"accessibility":["The group is a radiogroup; each item is a radio with aria-checked","Arrow keys move between items, Tab enters and leaves the group","Icon-only items still need an aria-label","Focus stays visible on the selected item"]},"props":{"value":{"type":"string","description":"Currently selected value","required":false},"defaultValue":{"type":"string","description":"Initial selected value (uncontrolled)","required":false},"onChange":{"type":"function","description":"Called with new value when selection changes","required":false},"onValueChange":{"type":"function","description":"Alias for onChange (Radix convention): (value: string) => void","required":false},"children":{"type":"node","description":"ToggleGroup.Item components","required":true},"variant":{"type":"enum","description":"Visual style","default":"default","required":false,"values":["default","pills","outline","outlined"]},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"gap":{"type":"enum","description":"Gap between items in the pills variant. Connected variants intentionally ignore gaps.","required":false,"values":["sm","none","xs"]},"selectionMode":{"type":"enum","description":"Selection behavior","default":"single","required":false,"values":["single"]}},"relations":[{"component":"RadioGroup","relationship":"alternative","note":"RadioGroup for form-style single selection"},{"component":"Tabs","relationship":"alternative","note":"Tabs for content panel switching"},{"component":"Switch","relationship":"sibling","note":"Switch for single on/off control"}],"variants":[{"name":"Default","description":"Inset tonal rail; the selected segment lifts.","code":"<ToggleGroup value={value} onChange={setValue}>\n <ToggleGroup.Item value=\"left\">Left</ToggleGroup.Item>\n <ToggleGroup.Item value=\"center\">Center</ToggleGroup.Item>\n <ToggleGroup.Item value=\"right\">Right</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Pills","description":"Detached rounded buttons for open filter clusters.","code":"<ToggleGroup value={value} onChange={setValue} variant=\"pills\">\n <ToggleGroup.Item value=\"all\">All</ToggleGroup.Item>\n <ToggleGroup.Item value=\"active\">Active</ToggleGroup.Item>\n <ToggleGroup.Item value=\"completed\">Completed</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Outlined","description":"Bordered segments sharing one continuous edge.","code":"<ToggleGroup value={value} onChange={setValue} variant=\"outlined\">\n <ToggleGroup.Item value=\"day\">Day</ToggleGroup.Item>\n <ToggleGroup.Item value=\"week\">Week</ToggleGroup.Item>\n <ToggleGroup.Item value=\"month\">Month</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Uncontrolled","description":"defaultValue when nothing outside needs the selection.","code":"<ToggleGroup defaultValue=\"list\">\n <ToggleGroup.Item value=\"grid\">Grid</ToggleGroup.Item>\n <ToggleGroup.Item value=\"list\">List</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Sizes","description":"sm for toolbars, lg where the rail anchors a page.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\" align=\"start\">\n <ToggleGroup defaultValue=\"a\" size=\"sm\">\n <ToggleGroup.Item value=\"a\">Small</ToggleGroup.Item>\n <ToggleGroup.Item value=\"b\">Rail</ToggleGroup.Item>\n </ToggleGroup>\n <ToggleGroup defaultValue=\"a\" size=\"md\">\n <ToggleGroup.Item value=\"a\">Medium</ToggleGroup.Item>\n <ToggleGroup.Item value=\"b\">Rail</ToggleGroup.Item>\n </ToggleGroup>\n <ToggleGroup defaultValue=\"a\" size=\"lg\">\n <ToggleGroup.Item value=\"a\">Large</ToggleGroup.Item>\n <ToggleGroup.Item value=\"b\">Rail</ToggleGroup.Item>\n </ToggleGroup>\n</Stack>"},{"name":"View Switcher","description":"Icon-only modes, each named for screen readers.","code":"import { SquaresFour as GridIcon, ListBullets as ListIcon } from '@phosphor-icons/react';\n\n<ToggleGroup value={view} onChange={setView} size=\"sm\">\n <ToggleGroup.Item value=\"grid\" aria-label=\"Grid view\">\n <GridIcon aria-hidden />\n </ToggleGroup.Item>\n <ToggleGroup.Item value=\"list\" aria-label=\"List view\">\n <ListIcon aria-hidden />\n </ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Disabled Item","description":"One option locked out; the rest stay reachable.","code":"<ToggleGroup value={value} onChange={setValue}>\n <ToggleGroup.Item value=\"basic\">Basic</ToggleGroup.Item>\n <ToggleGroup.Item value=\"pro\">Pro</ToggleGroup.Item>\n <ToggleGroup.Item value=\"enterprise\" disabled>Enterprise</ToggleGroup.Item>\n</ToggleGroup>"}],"contract":{"propsSummary":["value?: string - controlled selected value","defaultValue?: string - initial selected value (uncontrolled)","onChange: (value: string) => void - change handler (or onValueChange)","children: ToggleGroup.Item[] - toggle items","variant: default|pills|outline|outlined - visual style (outlined aliases outline)","size: sm|md|lg - size variant","gap: none|xs|sm - pills spacing (xs by default; connected variants remain gapless)","selectionMode: single (default: single)"],"a11yRules":["A11Y_GROUP_ROLE","A11Y_KEYBOARD_ACCESSIBLE"]},"ai":{"compositionPattern":"compound","subComponents":["Item"],"commonPatterns":["<ToggleGroup>\n <ToggleGroup.Item>...</ToggleGroup.Item>\n</ToggleGroup>"],"requiredChildren":["Item"]},"propsSummary":["value: string","defaultValue: string","onChange: function","onValueChange: function","children: node (required)","variant: default|pills|outline|outlined (default: default)","size: sm|md|lg (default: md)","gap: sm|none|xs (default: xs for pills; none otherwise)","selectionMode: single (default: single)"],"sourcePath":"src/components/ToggleGroup/index.tsx","exportName":"ToggleGroup","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:07.233Z"},"performance":{"bundleSize":1445,"rawSize":2943,"complexity":"lightweight","budgetPercent":9,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"ToggleGroup (self)","bytes":2088,"percent":71},{"path":"ComponentDefaults","bytes":193,"percent":7}]}},"Tooltip":{"filePath":"src/components/Tooltip/index.tsx","meta":{"name":"Tooltip","description":"Shows a one-line hint when a control is hovered or focused.","category":"overlays","tags":["tooltip","hint","help","hover","contextual"],"status":"stable"},"usage":{"when":["Naming icon-only buttons","Showing text that had to be truncated","Surfacing a keyboard shortcut","One line of help, no more"],"whenNot":["Help longer than a line — use Popover","Anything the user must not miss — use Alert","Content they need to click — use Popover or Menu","Touch-first screens, where there is no hover"],"guidelines":["Under 80 characters","Sentence case, no trailing period","Never just repeat the visible label","Always leave a non-hover path to the same information","contentProps sets attributes and styling on the popup"],"accessibility":["Opens on keyboard focus, not only hover","The open delay stops tooltips flashing while the pointer crosses the screen","Do not put anything critical here — treat it as a hint, not a label"]},"props":{"children":{"type":"element","description":"The element that triggers the tooltip","required":true},"content":{"type":"node","description":"Content to display in the tooltip","required":true},"side":{"type":"enum","description":"Which side to show the tooltip","default":"top","required":false,"values":["top","bottom","left","right"]},"align":{"type":"enum","description":"Alignment along the side","default":"center","required":false,"values":["start","center","end"]},"sideOffset":{"type":"number","description":"Distance from trigger in pixels","default":"6","required":false},"delay":{"type":"number","description":"Delay before showing (ms)","default":"400","required":false},"closeDelay":{"type":"number","description":"Delay before hiding (ms)","default":"0","required":false},"disabled":{"type":"boolean","description":"Disable the tooltip","default":"false","required":false},"arrow":{"type":"boolean","description":"Show arrow pointing to trigger","default":"true","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state","default":"false","required":false},"onOpenChange":{"type":"function","description":"Callback when open state changes","required":false},"contentProps":{"type":"object","description":"Props forwarded to the tooltip popup element (preferred way to pass popup attrs/className/style)","required":false},"style":{"type":"object","description":"","required":false},"closeOnClick":{"type":"boolean","description":"Whether clicking the trigger closes the tooltip.","default":"false","required":false}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for interactive or longer content"},{"component":"Alert","relationship":"alternative","note":"Use Alert for critical information that must be visible"}],"variants":[{"name":"Default","description":"Appears after a short delay above the trigger.","code":"<Tooltip content=\"Save your changes\">\n <Button>Save</Button>\n</Tooltip>"},{"name":"Positions","description":"Four sides; it flips if the edge is too close.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\" align=\"center\" wrap>\n <Tooltip content=\"Top tooltip\" side=\"top\">\n <Button variant=\"secondary\">Top</Button>\n </Tooltip>\n <Tooltip content=\"Bottom tooltip\" side=\"bottom\">\n <Button variant=\"secondary\">Bottom</Button>\n </Tooltip>\n <Tooltip content=\"Left tooltip\" side=\"left\">\n <Button variant=\"secondary\">Left</Button>\n </Tooltip>\n <Tooltip content=\"Right tooltip\" side=\"right\">\n <Button variant=\"secondary\">Right</Button>\n </Tooltip>\n</Stack>"},{"name":"With Shortcut","description":"Spells out the key combination the icon implies.","code":"<Tooltip content=\"Undo (Ctrl+Z)\">\n <Button variant=\"ghost\">Undo</Button>\n</Tooltip>"},{"name":"No Arrow","description":"Drops the pointer for tooltips packed into dense chrome.","code":"<Tooltip content=\"No arrow on this one\" arrow={false}>\n <Button variant=\"secondary\">Arrowless</Button>\n</Tooltip>"},{"name":"With Content Props","description":"contentProps lands on the popup element itself.","code":"<Tooltip\n content=\"Styled through contentProps\"\n contentProps={{ id: 'custom-tooltip-popup' }}\n>\n <Button variant=\"secondary\">Custom popup</Button>\n</Tooltip>"}],"contract":{"propsSummary":["content: ReactNode - tooltip content","side: top|bottom|left|right - position","delay: number - show delay in ms (default: 400)","arrow: boolean - show arrow (default: true)","contentProps: HTMLAttributes<HTMLDivElement> - popup element props"],"a11yRules":["A11Y_TOOLTIP_FOCUS","A11Y_TOOLTIP_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Provider"]},"propsSummary":["children: element (required)","content: node (required)","side: top|bottom|left|right (default: top)","align: start|center|end (default: center)","sideOffset: number (default: 6)","delay: number","closeDelay: number","disabled: boolean (default: false)","arrow: boolean (default: true)","open: boolean","defaultOpen: boolean","onOpenChange: function","contentProps: object","style: object"],"sourcePath":"src/components/Tooltip/index.tsx","exportName":"Tooltip","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:07.058Z"},"performance":{"bundleSize":1069,"rawSize":2053,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"Tooltip (self)","bytes":1443,"percent":70}]}},"VisuallyHidden":{"filePath":"src/components/VisuallyHidden/index.tsx","meta":{"name":"VisuallyHidden","description":"Keeps text in the accessibility tree while taking it off the screen.","category":"utilities","tags":["accessibility","a11y","screen-reader","hidden","sr-only"],"status":"stable"},"usage":{"when":["An icon-only control needs a name","A link's text is vague out of context","A skip link needs to hide until focused"],"whenNot":["Nobody should see or hear it (render nothing)","The content is just collapsed (use aria-expanded)"],"guidelines":["Every icon-only button gets one","Say the action, not the icon: \"Search\", not \"magnifier\"","Keep it short — it is read aloud","Visible text beats hidden text whenever there is room"],"accessibility":["Screen readers announce it; the layout never moves","Focusable children inside still receive focus","Required for WCAG 2.1 on icon-only controls"]},"props":{"children":{"type":"node","description":"Content to hide visually","required":true},"as":{"type":"enum","description":"HTML element to render","default":"span","required":false,"values":["span","div"]}},"relations":[{"component":"Button","relationship":"child","note":"Use inside icon-only buttons for accessible labels"},{"component":"Icon","relationship":"sibling","note":"Pair with icons to provide text alternatives"}],"variants":[{"name":"Icon Button Label","description":"The only thing telling a screen reader what this button does.","code":"<button style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n border: '1px solid var(--fui-border-default)',\n borderRadius: '8px',\n background: 'var(--fui-color-surface-primary)',\n cursor: 'pointer'\n}}>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n <VisuallyHidden>Search</VisuallyHidden>\n</button>"},{"name":"Supplementary Text","description":"Gives a vague link the context sighted readers get from layout.","code":"<a href=\"#\" style={{ color: 'var(--fui-color-accent)' }}>\n Read more\n <VisuallyHidden> about our accessibility features</VisuallyHidden>\n</a>"},{"name":"Skip Link","description":"Hidden until focused, then it jumps keyboard users past the nav.","code":"<div>\n <VisuallyHidden as=\"div\">\n <a\n href=\"#main-content\"\n style={{\n position: 'absolute',\n padding: '8px 16px',\n background: 'var(--fui-color-accent)',\n color: 'white'\n }}\n >\n Skip to main content\n </a>\n </VisuallyHidden>\n <p style={{ color: 'var(--fui-color-text-tertiary)', fontSize: '14px' }}>\n (Screen reader only: \"Skip to main content\" link)\n </p>\n</div>"}],"contract":{"propsSummary":["children: ReactNode - hidden text (required)","as: span|div - HTML element","Forwards standard DOM props (id, aria-*, data-*, className, handlers)"],"a11yRules":["A11Y_SR_ONLY","A11Y_ICON_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","as: span|div (default: span)"],"sourcePath":"src/components/VisuallyHidden/index.tsx","exportName":"VisuallyHidden","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.625Z"},"performance":{"bundleSize":535,"rawSize":894,"complexity":"lightweight","budgetPercent":3,"overBudget":false,"measuredAt":"2026-09-03T13:46:03.910Z","imports":[{"path":"VisuallyHidden (self)","bytes":311,"percent":35}]}}},"blocks":{"Account Settings":{"filePath":"src/blocks/AccountSettings.block.ts","name":"Account Settings","description":"Tabbed account settings with profile, security and billing sections","category":"settings","components":["Card","Tabs","Stack","Input","Button","Text"],"code":"<Card>\n <Card.Header>\n <Card.Title>Account Settings</Card.Title>\n </Card.Header>\n <Tabs defaultValue=\"profile\">\n <Tabs.List>\n <Tabs.Tab value=\"profile\">Profile</Tabs.Tab>\n <Tabs.Tab value=\"security\">Security</Tabs.Tab>\n <Tabs.Tab value=\"billing\">Billing</Tabs.Tab>\n </Tabs.List>\n <Card.Body>\n <Tabs.Panel value=\"profile\">\n <Stack gap=\"md\">\n <Input label=\"Display Name\" defaultValue=\"Jane Doe\" />\n <Input label=\"Email\" type=\"email\" defaultValue=\"jane@example.com\" />\n <Button variant=\"primary\">Save Changes</Button>\n </Stack>\n </Tabs.Panel>\n <Tabs.Panel value=\"security\">\n <Stack gap=\"md\">\n <Input label=\"Current Password\" type=\"password\" />\n <Input label=\"New Password\" type=\"password\" />\n <Input label=\"Confirm Password\" type=\"password\" />\n <Button variant=\"primary\">Update Password</Button>\n </Stack>\n </Tabs.Panel>\n <Tabs.Panel value=\"billing\">\n <Stack gap=\"md\">\n <Text>Current Plan: <Text weight=\"semibold\">Pro</Text></Text>\n <Text size=\"sm\" color=\"tertiary\">Your next billing date will appear here</Text>\n <Button variant=\"secondary\">Manage Subscription</Button>\n </Stack>\n </Tabs.Panel>\n </Card.Body>\n </Tabs>\n</Card>","tags":["account","settings","tabs","profile","security","billing"]},"Activity Feed":{"filePath":"src/blocks/ActivityFeed.block.ts","name":"Activity Feed","description":"Timeline of user activities with avatars and timestamps","category":"dashboard","components":["Card","Stack","Text","Avatar"],"code":"const activities = [\n { id: 1, user: 'Alice Chen', action: 'created a new project', time: '2 minutes ago', initials: 'AC' },\n { id: 2, user: 'Bob Smith', action: 'commented on your post', time: '15 minutes ago', initials: 'BS' },\n { id: 3, user: 'Carol Davis', action: 'shared a document', time: '1 hour ago', initials: 'CD' },\n { id: 4, user: 'Dan Wilson', action: 'completed a task', time: '3 hours ago', initials: 'DW' },\n];\n\n<Card>\n <Card.Header>\n <Card.Title>Recent Activity</Card.Title>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n {activities.map((activity) => (\n <Stack key={activity.id} direction=\"row\" gap=\"md\" align=\"center\">\n <Avatar size=\"sm\" initials={activity.initials} />\n <Stack gap=\"xs\" style={{ flex: 1 }}>\n <Text>\n <Text weight=\"semibold\">{activity.user}</Text> {activity.action}\n </Text>\n <Text size=\"sm\" color=\"tertiary\">{activity.time}</Text>\n </Stack>\n </Stack>\n ))}\n </Stack>\n </Card.Body>\n</Card>","tags":["activity","feed","timeline","notifications"]},"Activity Feed Skeleton":{"filePath":"src/blocks/ActivityFeedSkeleton.block.ts","name":"Activity Feed Skeleton","description":"Skeleton avatar circles with text rows for loading activity feeds","category":"loading","components":["Card","Stack","Skeleton"],"code":"<Card>\n <Card.Header>\n <Skeleton variant=\"heading\" width={160} />\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Stack key={i} direction=\"row\" gap=\"md\" align=\"center\">\n <Skeleton.Circle size=\"sm\" />\n <Stack gap=\"xs\" style={{ flex: 1 }}>\n <Skeleton variant=\"text\" width=\"70%\" />\n <Skeleton variant=\"text\" width=\"30%\" />\n </Stack>\n </Stack>\n ))}\n </Stack>\n </Card.Body>\n</Card>","tags":["activity","feed","skeleton","loading","placeholder"]},"Blog Editor":{"filePath":"src/blocks/BlogEditor.block.ts","name":"Blog Editor","description":"Full blog post editor with formatting toolbar, auto-save, publish button, and word count","category":"content","components":["Editor","Button"],"code":"<Editor\n placeholder=\"Start typing your masterpiece here...\"\n onValueChange={(value) => console.log(value)}\n onAutoSave={(value) => console.log('Auto-saved:', value)}\n autoSaveInterval={5000}\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n <Editor.ToolbarButton format=\"strikethrough\" />\n <Editor.ToolbarButton format=\"link\" />\n <Editor.ToolbarButton format=\"code\" />\n <Editor.ToolbarButton format=\"bulletList\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Actions\">\n <Editor.StatusIndicator status=\"saved\" />\n <Button variant=\"accent\" size=\"sm\">Publish</Button>\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>","tags":["blog","editor","writing","rich-text","publishing","content"]},"Chat Interface":{"filePath":"src/blocks/ChatInterface.block.ts","name":"Chat Interface","description":"Full AI chat with conversation list, messages, and prompt input","category":"ai","components":["Stack","Box","ConversationList","Message","Prompt"],"code":"<Stack style={{ height: '500px', border: '1px solid var(--fui-border)', borderRadius: 'var(--fui-radius-lg)', overflow: 'hidden' }}>\n <ConversationList autoScroll=\"smart\" style={{ flex: 1 }}>\n <Message role=\"system\">\n <Message.Content>\n Conversation started with Claude\n </Message.Content>\n </Message>\n <Message role=\"user\">\n <Message.Content>\n Hello! What can you help me with today?\n </Message.Content>\n </Message>\n <Message role=\"assistant\">\n <Message.Content>\n Hi! I'm here to help with coding questions, writing, analysis, and more. What would you like to explore?\n </Message.Content>\n </Message>\n </ConversationList>\n <Box borderTop>\n <Prompt placeholder=\"Message Claude...\" onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Attach file\">+</Prompt.ActionButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n </Prompt>\n </Box>\n</Stack>","tags":["chat","ai","assistant","conversation","prompt"]},"Chat Messages":{"filePath":"src/blocks/ChatMessages.block.ts","name":"Chat Messages","description":"User and assistant message exchange with role-based styling","category":"ai","components":["Stack","Message"],"code":"<Stack gap=\"md\" style={{ maxWidth: '600px' }}>\n <Message role=\"user\">\n <Message.Content>\n Can you explain how React hooks work?\n </Message.Content>\n </Message>\n <Message role=\"assistant\">\n <Message.Content>\n React Hooks are functions that let you use state and other React features in functional components. The most common hooks are:\n\n • useState - for managing local state\n • useEffect - for side effects like API calls\n • useContext - for consuming context values\n • useRef - for mutable refs that persist across renders\n\n Would you like me to show you some examples?\n </Message.Content>\n </Message>\n <Message role=\"user\">\n <Message.Content>\n Yes, please show me a useState example!\n </Message.Content>\n </Message>\n</Stack>","tags":["chat","messages","ai","conversation"]},"Checkout Form":{"filePath":"src/blocks/CheckoutForm.block.ts","name":"Checkout Form","description":"E-commerce checkout with billing address, payment details and order summary","category":"ecommerce","components":["Card","Stack","Text","Input","Separator","Button"],"code":"<Card variant=\"elevated\">\n <Card.Header>\n <Card.Title>Checkout</Card.Title>\n <Card.Description>Complete your purchase</Card.Description>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"lg\">\n <Stack gap=\"md\">\n <Text weight=\"semibold\">Billing Address</Text>\n <Input label=\"Full Name\" placeholder=\"John Doe\" />\n <Input label=\"Address\" placeholder=\"123 Main St\" />\n <Stack direction={{ base: 'column', sm: 'row' }} gap=\"md\">\n <Input label=\"City\" placeholder=\"San Francisco\" style={{ flex: 1 }} />\n <Input label=\"State\" placeholder=\"CA\" style={{ width: '100px' }} />\n <Input label=\"ZIP\" placeholder=\"94102\" style={{ width: '120px' }} />\n </Stack>\n </Stack>\n\n <Separator />\n\n <Stack gap=\"md\">\n <Text weight=\"semibold\">Payment Details</Text>\n <Input label=\"Card Number\" placeholder=\"4242 4242 4242 4242\" />\n <Stack direction={{ base: 'column', sm: 'row' }} gap=\"md\">\n <Input label=\"Expiry\" placeholder=\"MM/YY\" style={{ flex: 1 }} />\n <Input label=\"CVC\" placeholder=\"123\" style={{ width: '100px' }} />\n </Stack>\n </Stack>\n\n <Separator />\n\n <Stack gap=\"sm\">\n <Stack direction=\"row\" justify=\"between\">\n <Text color=\"tertiary\">Subtotal</Text>\n <Text>$99.00</Text>\n </Stack>\n <Stack direction=\"row\" justify=\"between\">\n <Text color=\"tertiary\">Tax</Text>\n <Text>$8.91</Text>\n </Stack>\n <Separator />\n <Stack direction=\"row\" justify=\"between\">\n <Text weight=\"semibold\">Total</Text>\n <Text weight=\"semibold\">$107.91</Text>\n </Stack>\n </Stack>\n\n <Button variant=\"primary\" fullWidth>Complete Purchase</Button>\n </Stack>\n </Card.Body>\n</Card>","tags":["checkout","payment","ecommerce","form","billing"]},"Command Palette":{"filePath":"src/blocks/CommandPalette.block.ts","name":"Command Palette","description":"Modal command palette for quick actions, composed with Dialog and Command","category":"navigation","components":["Dialog","Command"],"code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"secondary\">Open Command Palette</Button>\n </Dialog.Trigger>\n <Dialog.Content size=\"sm\">\n <Command>\n <Command.Input placeholder=\"Search commands...\" />\n <Command.List>\n <Command.Group heading=\"Actions\">\n <Command.Item onItemSelect={() => console.log('new')}>New File</Command.Item>\n <Command.Item onItemSelect={() => console.log('open')}>Open Recent</Command.Item>\n <Command.Item onItemSelect={() => console.log('save')}>Save All</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Settings\">\n <Command.Item onItemSelect={() => console.log('prefs')}>Preferences</Command.Item>\n <Command.Item onItemSelect={() => console.log('keys')}>Keyboard Shortcuts</Command.Item>\n </Command.Group>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n </Dialog.Content>\n</Dialog>","tags":["command","palette","search","spotlight","quick-actions"]},"Contact Form":{"filePath":"src/blocks/ContactForm.block.ts","name":"Contact Form","description":"Contact form with name, email, subject and message fields","category":"marketing","components":["Card","Stack","Input","Textarea","Button"],"code":"<Card variant=\"elevated\">\n <Card.Header>\n <Card.Title>Contact Us</Card.Title>\n <Card.Description>Send us a message and we'll get back to you soon.</Card.Description>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n <Stack direction={{ base: 'column', sm: 'row' }} gap=\"md\">\n <Input label=\"Name\" placeholder=\"Your name\" style={{ flex: 1 }} />\n <Input label=\"Email\" type=\"email\" placeholder=\"your@email.com\" style={{ flex: 1 }} />\n </Stack>\n <Input label=\"Subject\" placeholder=\"How can we help?\" />\n <Textarea label=\"Message\" placeholder=\"Tell us more about your inquiry...\" rows={5} />\n <Button variant=\"primary\" fullWidth>Send Message</Button>\n </Stack>\n </Card.Body>\n</Card>","tags":["contact","form","marketing","message"]},"Dashboard Layout":{"filePath":"src/blocks/DashboardLayout.block.ts","name":"Dashboard Layout","description":"Full application shell with sidebar navigation, header, and metrics grid","category":"dashboard","components":["AppShell","Header","Sidebar","Stack","Grid","Card","Text","Badge","Input","ThemeToggle","Avatar"],"code":"const navItems = [\n { label: 'Dashboard', active: true },\n { label: 'Analytics', active: false },\n { label: 'Projects', active: false },\n { label: 'Settings', active: false },\n];\n\nconst metrics = [\n { label: 'Total Users', value: '12,847', change: '+12%' },\n { label: 'Revenue', value: '$48,352', change: '+8%' },\n { label: 'Active Projects', value: '23', change: '+3' },\n];\n\n<AppShell>\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Input placeholder=\"Search...\" style={{ width: '240px' }} />\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n <Avatar size=\"sm\" initials=\"JD\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n <AppShell.Sidebar width=\"220px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <Text weight=\"semibold\" size=\"lg\">Acme Inc</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Main\">\n {navItems.map((item) => (\n <Sidebar.Item key={item.label} active={item.active}>\n {item.label}\n </Sidebar.Item>\n ))}\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Text size=\"sm\" color=\"tertiary\">v2.0.0</Text>\n </Sidebar.Footer>\n </AppShell.Sidebar>\n <AppShell.Main padding=\"lg\">\n <Stack gap=\"lg\">\n <Stack gap=\"xs\">\n <Text size=\"xl\" weight=\"semibold\">Dashboard</Text>\n <Text color=\"tertiary\">Welcome back! Here's an overview of your metrics.</Text>\n </Stack>\n <Grid columns={{ base: 1, md: 3 }} gap=\"md\">\n {metrics.map((metric) => (\n <Card key={metric.label}>\n <Card.Body>\n <Stack gap=\"sm\">\n <Text size=\"sm\" color=\"tertiary\">{metric.label}</Text>\n <Stack direction=\"row\" justify=\"between\" align=\"baseline\">\n <Text size=\"2xl\" weight=\"semibold\">{metric.value}</Text>\n <Badge variant=\"success\">{metric.change}</Badge>\n </Stack>\n </Stack>\n </Card.Body>\n </Card>\n ))}\n </Grid>\n </Stack>\n </AppShell.Main>\n</AppShell>","tags":["dashboard","layout","sidebar","app-shell","navigation"]},"Dashboard Page":{"filePath":"src/blocks/DashboardPage.block.ts","name":"Dashboard Page","description":"Full dashboard page with sidebar navigation, stats cards, revenue chart, transactions table, and activity feed","category":"kitchen-sink","components":["AppShell","Header","Sidebar","Grid","Card","Stack","Box","Text","Badge","Icon","Avatar","Input","Button","Separator","Table","ChartContainer","ChartTooltip","Breadcrumbs","ThemeToggle","Progress","Tabs"],"code":"import { AreaChart, Area, XAxis } from 'recharts';\nimport {\n TrendUp, TrendDown, Bell, SquaresFour, ChartBar,\n FileText, GearSix, Users, UserCircle, CreditCard,\n Bank, Lightning, Wallet, CheckCircle, Clock, XCircle,\n ArrowClockwise, DownloadSimple,\n} from '@phosphor-icons/react';\n\n// ── Stats data ──────────────────────────────────────────────\nconst stats = [\n { label: 'Total Revenue', value: '$45,231', change: '+20.1%', up: true },\n { label: 'Active Users', value: '2,350', change: '+12.5%', up: true },\n { label: 'Sessions', value: '12,543', change: '-3.2%', up: false },\n { label: 'Growth Rate', value: '4.5%', change: '+0.8%', up: true },\n];\n\n// ── Chart data ──────────────────────────────────────────────\nconst revenueData = [\n { month: 'Sep', revenue: 3200 },\n { month: 'Oct', revenue: 4100 },\n { month: 'Nov', revenue: 3800 },\n { month: 'Dec', revenue: 5200 },\n { month: 'Jan', revenue: 4800 },\n { month: 'Feb', revenue: 6100 },\n];\n\nconst chartConfig = {\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n};\n\n// ── Table data ──────────────────────────────────────────────\nconst methodIcons = { card: CreditCard, bank: Bank, crypto: Lightning, wallet: Wallet };\nconst methodLabels = { card: 'Card', bank: 'Bank', crypto: 'Crypto', wallet: 'Wallet' };\nconst statusConfig = {\n completed: { variant: 'success', icon: CheckCircle, label: 'Completed' },\n pending: { variant: 'warning', icon: Clock, label: 'Pending' },\n failed: { variant: 'error', icon: XCircle, label: 'Failed' },\n refunded: { variant: 'info', icon: ArrowClockwise, label: 'Refunded' },\n};\n\nconst transactions = [\n { id: '1', customer: 'Alice Chen', method: 'card', amount: '$1,250.00', status: 'completed', date: 'Feb 3' },\n { id: '2', customer: 'Bob Park', method: 'bank', amount: '$890.00', status: 'pending', date: 'Feb 2' },\n { id: '3', customer: 'Clara Liu', method: 'crypto', amount: '$2,100.00', status: 'completed', date: 'Feb 1' },\n { id: '4', customer: 'David Kim', method: 'wallet', amount: '$450.00', status: 'failed', date: 'Jan 31' },\n { id: '5', customer: 'Eva Santos', method: 'card', amount: '$3,200.00', status: 'completed', date: 'Jan 30' },\n];\n\nconst columns = createColumns([\n {\n key: 'customer',\n header: 'Customer',\n cell: (row) => (\n <Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <Icon icon={UserCircle} size=\"sm\" />\n <Text size=\"sm\" weight=\"medium\">{row.customer}</Text>\n </Stack>\n ),\n },\n {\n key: 'method',\n header: 'Method',\n cell: (row) => (\n <Stack direction=\"row\" gap=\"xs\" align=\"center\">\n <Icon icon={methodIcons[row.method]} size=\"xs\" />\n <Text size=\"sm\" color=\"secondary\">{methodLabels[row.method]}</Text>\n </Stack>\n ),\n },\n {\n key: 'amount',\n header: 'Amount',\n cell: (row) => <Text size=\"sm\" weight=\"medium\" font=\"mono\">{row.amount}</Text>,\n },\n {\n key: 'status',\n header: 'Status',\n cell: (row) => {\n const cfg = statusConfig[row.status];\n return (\n <Badge variant={cfg.variant} size=\"sm\" icon={<Icon icon={cfg.icon} size=\"xs\" />}>\n {cfg.label}\n </Badge>\n );\n },\n },\n { key: 'date', header: 'Date' },\n]);\n\n// ── Activity data ───────────────────────────────────────────\nconst activities = [\n { id: 1, user: 'Alice Chen', action: 'completed a purchase', time: '2 min ago', initials: 'AC' },\n { id: 2, user: 'Bob Park', action: 'submitted a support ticket', time: '15 min ago', initials: 'BP' },\n { id: 3, user: 'Clara Liu', action: 'upgraded to Pro plan', time: '1 hour ago', initials: 'CL' },\n { id: 4, user: 'David Kim', action: 'left a review', time: '3 hours ago', initials: 'DK' },\n];\n\n// ── Layout ──────────────────────────────────────────────────\n\n<AppShell>\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Nav>\n <Breadcrumbs>\n <Breadcrumbs.Item>Dashboard</Breadcrumbs.Item>\n <Breadcrumbs.Item>Overview</Breadcrumbs.Item>\n </Breadcrumbs>\n </Header.Nav>\n <Header.Spacer />\n <Header.Search>\n <Input placeholder=\"Search...\" size=\"sm\" style={{ width: 200 }} />\n </Header.Search>\n <Header.Actions>\n <Button variant=\"ghost\" size=\"sm\" icon aria-label=\"Notifications\">\n <Icon icon={Bell} />\n </Button>\n <ThemeToggle size=\"sm\" />\n <Avatar size=\"sm\" initials=\"JD\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"220px\" collapsible=\"icon\">\n <Sidebar.Header>\n <Text weight=\"semibold\" size=\"lg\">Acme Inc</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Main\">\n <Sidebar.Item icon={<Icon icon={SquaresFour} />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Users} />}>Customers</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={FileText} />}>Reports</Sidebar.Item>\n </Sidebar.Section>\n <Sidebar.Section label=\"System\">\n <Sidebar.Item icon={<Icon icon={GearSix} />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"lg\">\n <Stack gap=\"lg\">\n {/* Page header */}\n <Stack direction=\"row\" justify=\"between\" align=\"end\">\n <Stack gap=\"xs\">\n <Text size=\"xl\" weight=\"semibold\">Dashboard</Text>\n <Text color=\"secondary\">Welcome back! Here's an overview of your metrics.</Text>\n </Stack>\n <Button variant=\"primary\" size=\"sm\">\n <Icon icon={DownloadSimple} size=\"sm\" /> Export\n </Button>\n </Stack>\n\n {/* Stats cards */}\n <Grid columns={{ base: 1, sm: 2, lg: 4 }} gap=\"md\">\n {stats.map((stat) => (\n <Card key={stat.label}>\n <Card.Body>\n <Stack gap=\"xs\">\n <Text size=\"sm\" color=\"secondary\">{stat.label}</Text>\n <Text size=\"2xl\" weight=\"semibold\">{stat.value}</Text>\n <Badge\n variant={stat.up ? 'success' : 'warning'}\n size=\"sm\"\n icon={<Icon icon={stat.up ? TrendUp : TrendDown} size=\"xs\" />}\n >\n {stat.change}\n </Badge>\n </Stack>\n </Card.Body>\n </Card>\n ))}\n </Grid>\n\n {/* Chart + Activity feed row */}\n <Grid columns={{ base: 1, lg: 3 }} gap=\"md\">\n <Grid.Item colSpan={2}>\n <Card style={{ height: '100%' }}>\n <Card.Header>\n <Stack direction=\"row\" justify=\"between\" align=\"center\">\n <Card.Title>Revenue</Card.Title>\n <Text size=\"sm\" color=\"secondary\">Last 6 months</Text>\n </Stack>\n </Card.Header>\n <Card.Body>\n <Box style={{ height: 220 }}>\n <ChartContainer config={chartConfig}>\n <AreaChart data={revenueData} margin={{ top: 5, right: 5, bottom: 0, left: -20 }}>\n <XAxis dataKey=\"month\" tickLine={false} axisLine={false} />\n <Area\n type=\"monotone\"\n dataKey=\"revenue\"\n stroke=\"var(--fui-color-accent)\"\n fill=\"var(--fui-color-accent)\"\n fillOpacity={0.15}\n strokeWidth={2}\n />\n <ChartTooltip />\n </AreaChart>\n </ChartContainer>\n </Box>\n </Card.Body>\n </Card>\n </Grid.Item>\n\n <Card>\n <Card.Header>\n <Card.Title>Recent Activity</Card.Title>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n {activities.map((a) => (\n <Stack key={a.id} direction=\"row\" gap=\"sm\" align=\"center\">\n <Avatar size=\"sm\" initials={a.initials} />\n <Stack gap=\"xs\" style={{ flex: 1 }}>\n <Text size=\"sm\">\n <Text size=\"sm\" weight=\"semibold\">{a.user}</Text> {a.action}\n </Text>\n <Text size=\"xs\" color=\"tertiary\">{a.time}</Text>\n </Stack>\n </Stack>\n ))}\n </Stack>\n </Card.Body>\n </Card>\n </Grid>\n\n {/* Transactions table */}\n <Card>\n <Card.Header>\n <Stack direction=\"row\" justify=\"between\" align=\"center\">\n <Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <Card.Title>Recent Transactions</Card.Title>\n <Badge variant=\"outline\" size=\"sm\">5 total</Badge>\n </Stack>\n <Button variant=\"ghost\" size=\"sm\" icon aria-label=\"Download\">\n <Icon icon={DownloadSimple} size=\"sm\" />\n </Button>\n </Stack>\n </Card.Header>\n <Table\n columns={columns}\n data={transactions}\n size=\"sm\"\n caption=\"Recent transactions\"\n captionHidden\n />\n </Card>\n </Stack>\n </AppShell.Main>\n</AppShell>","tags":["dashboard","full-page","kitchen-sink","chart","table","sidebar","stats","metrics","analytics"]},"Dashboard Skeleton":{"filePath":"src/blocks/DashboardSkeleton.block.ts","name":"Dashboard Skeleton","description":"Grid of card shells with skeleton text and headings for dashboard loading states","category":"loading","components":["Card","Grid","Skeleton"],"code":"<Grid columns={{ base: 1, md: 2, lg: 3 }} gap=\"md\">\n {Array.from({ length: 6 }).map((_, i) => (\n <Card key={i}>\n <Card.Body>\n <Stack gap=\"md\">\n <Skeleton variant=\"heading\" width=\"60%\" />\n <Skeleton.Text lines={2} />\n <Skeleton variant=\"rect\" height={120} radius=\"md\" />\n <Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <Skeleton variant=\"button\" width={80} />\n <Skeleton variant=\"text\" width={60} />\n </Stack>\n </Stack>\n </Card.Body>\n </Card>\n ))}\n</Grid>","tags":["dashboard","skeleton","loading","placeholder"]},"Data Table":{"filePath":"src/blocks/DataTable.block.ts","name":"Data Table","description":"Table displaying structured data with columns","category":"dashboard","components":["Card","Table"],"code":"const columns = [\n { accessorKey: 'name', header: 'Name' },\n { accessorKey: 'email', header: 'Email' },\n { accessorKey: 'status', header: 'Status' },\n];\n\nconst data = [\n { name: 'John Doe', email: 'john@example.com', status: 'Active' },\n { name: 'Jane Smith', email: 'jane@example.com', status: 'Pending' },\n { name: 'Bob Wilson', email: 'bob@example.com', status: 'Active' },\n];\n\n<Card>\n <Card.Header>\n <Card.Title>Users</Card.Title>\n </Card.Header>\n <Table data={data} columns={columns} />\n</Card>","tags":["table","data","grid","dashboard","list"]},"Empty State":{"filePath":"src/blocks/EmptyState.block.ts","name":"Empty State","description":"Placeholder with icon, message, and action when no content exists","category":"dashboard","components":["EmptyState","Icon","Button"],"code":"import { ArchiveBox } from '@phosphor-icons/react';\n\n<EmptyState>\n <EmptyState.Icon>\n <Icon icon={ArchiveBox} size=\"xl\" />\n </EmptyState.Icon>\n <EmptyState.Title>No items yet</EmptyState.Title>\n <EmptyState.Description>Get started by creating your first item.</EmptyState.Description>\n <EmptyState.Actions>\n <Button variant=\"primary\">Create Item</Button>\n </EmptyState.Actions>\n</EmptyState>","tags":["empty","placeholder","zero-state","no-data"]},"FAQ Section":{"filePath":"src/blocks/FAQSection.block.ts","name":"FAQ Section","description":"Frequently asked questions with accordion component","category":"marketing","components":["Card","Accordion","Text"],"code":"const faqs = [\n { question: 'How do I get started?', answer: 'Simply install the package via npm and import the components you need. Check our documentation for detailed setup instructions.' },\n { question: 'Is it compatible with my framework?', answer: 'Yes! Our components work with React, Next.js, Remix, and any other React-based framework.' },\n { question: 'Can I customize the styling?', answer: 'Absolutely. All components support custom CSS, CSS variables, and our built-in theming system.' },\n { question: 'Do you offer support?', answer: 'We offer community support through GitHub discussions and premium support for enterprise customers.' },\n];\n\n<Card>\n <Card.Header>\n <Card.Title>Frequently Asked Questions</Card.Title>\n </Card.Header>\n <Card.Body>\n <Accordion type=\"single\" collapsible>\n {faqs.map((faq, index) => (\n <Accordion.Item key={index} value={`item-${index}`}>\n <Accordion.Trigger>{faq.question}</Accordion.Trigger>\n <Accordion.Content>\n <Text color=\"secondary\">{faq.answer}</Text>\n </Accordion.Content>\n </Accordion.Item>\n ))}\n </Accordion>\n </Card.Body>\n</Card>","tags":["faq","questions","accordion","marketing","help"]},"Feature Grid":{"filePath":"src/blocks/FeatureGrid.block.ts","name":"Feature Grid","description":"Grid of features with icons and descriptions","category":"marketing","components":["Grid","Card","Stack","Icon","Text"],"code":"const features = [\n { icon: Rocket, title: 'Fast Performance', description: 'Optimized for speed with minimal bundle size' },\n { icon: Shield, title: 'Secure by Default', description: 'Built-in security best practices' },\n { icon: Puzzle, title: 'Modular Design', description: 'Pick only what you need' },\n { icon: Sparkle, title: 'Modern Stack', description: 'Built with the latest technologies' },\n];\n\n<Grid columns={{ base: 1, md: 2, lg: 4 }} gap=\"lg\">\n {features.map((feature) => (\n <Card key={feature.title}>\n <Card.Body>\n <Stack gap=\"md\">\n <Icon icon={feature.icon} size=\"lg\" variant=\"accent\" />\n <Stack gap=\"xs\">\n <Text weight=\"semibold\">{feature.title}</Text>\n <Text size=\"sm\" color=\"tertiary\">{feature.description}</Text>\n </Stack>\n </Stack>\n </Card.Body>\n </Card>\n ))}\n</Grid>","tags":["features","grid","marketing","icons"]},"Hero Section":{"filePath":"src/blocks/HeroSection.block.ts","name":"Hero Section","description":"Landing page hero with headline, description and CTA buttons","category":"marketing","components":["Stack","Text","Button","Image"],"code":"<Stack gap=\"xl\" align=\"center\" style={{ textAlign: 'center', padding: '64px 24px' }}>\n <Stack gap=\"md\" align=\"center\" style={{ maxWidth: '600px' }}>\n <Text as=\"h1\" size=\"2xl\" weight=\"semibold\">Build beautiful products faster</Text>\n <Text size=\"lg\" color=\"secondary\">\n A modern component library designed for developers who want to ship quality interfaces without the complexity.\n </Text>\n </Stack>\n <Stack direction={{ base: 'column', sm: 'row' }} gap=\"md\">\n <Button variant=\"primary\">Get Started</Button>\n <Button variant=\"secondary\">Learn More</Button>\n </Stack>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=800&h=400&fit=crop\"\n alt=\"Code on screen\"\n aspectRatio=\"16:9\"\n rounded=\"lg\"\n width=\"100%\"\n style={{ maxWidth: '800px' }}\n />\n</Stack>","tags":["hero","landing","marketing","cta"]},"Login Form":{"filePath":"src/blocks/LoginForm.block.ts","name":"Login Form","description":"Email/password authentication form with card layout and footer links","category":"authentication","components":["Card","Stack","Input","Button","Text","Link"],"code":"<Card variant=\"elevated\">\n <Card.Header>\n <Card.Title>Sign In</Card.Title>\n <Card.Description>Welcome back! Please enter your details.</Card.Description>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n <Input label=\"Email\" type=\"email\" placeholder=\"Enter your email\" />\n <Input label=\"Password\" type=\"password\" placeholder=\"Enter your password\" />\n <Link href=\"#\" variant=\"subtle\"><Text size=\"sm\">Forgot password?</Text></Link>\n <Button variant=\"primary\" fullWidth>Sign In</Button>\n </Stack>\n </Card.Body>\n <Card.Footer>\n <Text size=\"sm\" color=\"tertiary\">Don't have an account? <Link href=\"#\">Sign up</Link></Text>\n </Card.Footer>\n</Card>","tags":["auth","login","signin","form"]},"Navigation Header":{"filePath":"src/blocks/NavigationHeader.block.ts","name":"Navigation Header","description":"Site header with rich dropdown navigation panels, structured links with descriptions, and automatic mobile drawer. Uses NavigationMenu inside Header.","category":"marketing","components":["Header","NavigationMenu","ThemeToggle","Button"],"code":"<Header>\n <Header.Brand href=\"/\">Acme</Header.Brand>\n <NavigationMenu aria-label=\"Main navigation\">\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"products\">\n <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px', padding: '8px', minWidth: '400px' }}>\n <NavigationMenu.Link\n href=\"/analytics\"\n title=\"Analytics\"\n description=\"Track your metrics and KPIs in real time.\"\n />\n <NavigationMenu.Link\n href=\"/automation\"\n title=\"Automation\"\n description=\"Automate repetitive workflows with ease.\"\n />\n <NavigationMenu.Link\n href=\"/integrations\"\n title=\"Integrations\"\n description=\"Connect with your favorite tools.\"\n />\n <NavigationMenu.Link\n href=\"/security\"\n title=\"Security\"\n description=\"Enterprise-grade protection for your data.\"\n />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"resources\">\n <NavigationMenu.Trigger>Resources</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '4px', padding: '8px', minWidth: '220px' }}>\n <NavigationMenu.Link\n href=\"/docs\"\n title=\"Documentation\"\n description=\"Comprehensive API reference and guides.\"\n />\n <NavigationMenu.Link\n href=\"/blog\"\n title=\"Blog\"\n description=\"Latest news, updates, and tutorials.\"\n />\n <NavigationMenu.Link\n href=\"/changelog\"\n title=\"Changelog\"\n description=\"See what's new in every release.\"\n />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/pricing\">Pricing</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n <NavigationMenu.MobileContent>\n <NavigationMenu.MobileSection label=\"Company\">\n <NavigationMenu.Link href=\"/about\">About</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/careers\">Careers</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/contact\">Contact</NavigationMenu.Link>\n </NavigationMenu.MobileSection>\n </NavigationMenu.MobileContent>\n </NavigationMenu>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"primary\" size=\"sm\">Get Started</Button>\n </Header.Actions>\n</Header>","tags":["header","navigation","dropdown","mobile","responsive","navbar"]},"Paginated Table":{"filePath":"src/blocks/PaginatedTable.block.ts","name":"Paginated Table","description":"Data table with pagination controls at the bottom","category":"dashboard","components":["Card","Table","Pagination"],"code":"const columns = [\n { accessorKey: 'name', header: 'Name' },\n { accessorKey: 'email', header: 'Email' },\n { accessorKey: 'status', header: 'Status' },\n];\n\nconst data = [\n { name: 'John Doe', email: 'john@example.com', status: 'Active' },\n { name: 'Jane Smith', email: 'jane@example.com', status: 'Pending' },\n { name: 'Bob Wilson', email: 'bob@example.com', status: 'Active' },\n];\n\n<Card>\n <Card.Header>\n <Card.Title>Users</Card.Title>\n </Card.Header>\n <Table data={data} columns={columns} />\n <Card.Footer>\n <Pagination totalPages={10} defaultPage={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n </Pagination>\n </Card.Footer>\n</Card>","tags":["table","pagination","data","dashboard","list"]},"Pricing Comparison":{"filePath":"src/blocks/PricingComparison.block.ts","name":"Pricing Comparison","description":"Multiple pricing tiers displayed side by side with features and CTAs","category":"marketing","components":["Grid","Card","Stack","Text","Separator","Button"],"code":"const tiers = [\n { name: 'Basic', price: '$9', period: '/month', description: 'For individuals', features: ['5 projects', 'Basic analytics', 'Email support'], ctaText: 'Get Started' },\n { name: 'Pro', price: '$29', period: '/month', description: 'For small teams', features: ['Unlimited projects', 'Advanced analytics', 'Priority support', 'API access'], ctaText: 'Start Free Trial' },\n { name: 'Enterprise', price: '$99', period: '/month', description: 'For large organizations', features: ['Everything in Pro', 'Custom integrations', 'Dedicated support', 'SLA guarantee'], ctaText: 'Contact Sales' },\n];\n\n<Grid columns={{ base: 1, lg: 3 }} gap=\"lg\">\n {tiers.map((tier) => (\n <Card key={tier.name}>\n <Card.Header>\n <Card.Title>{tier.name}</Card.Title>\n <Card.Description>{tier.description}</Card.Description>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n <Stack direction=\"row\" align=\"baseline\" gap=\"xs\">\n <Text size=\"2xl\" weight=\"semibold\">{tier.price}</Text>\n <Text color=\"tertiary\">{tier.period}</Text>\n </Stack>\n <Separator />\n <Stack gap=\"sm\">\n {tier.features.map((feature) => (\n <Text key={feature}>✓ {feature}</Text>\n ))}\n </Stack>\n </Stack>\n </Card.Body>\n <Card.Footer>\n <Button variant=\"primary\" fullWidth>{tier.ctaText}</Button>\n </Card.Footer>\n </Card>\n ))}\n</Grid>","tags":["pricing","plans","tiers","marketing","comparison"]},"Product Card":{"filePath":"src/blocks/ProductCard.block.ts","name":"Product Card","description":"Product display with image, price, stock badge and add to cart button","category":"ecommerce","components":["Card","Image","Stack","Text","Badge","Button"],"code":"<Card style={{ maxWidth: '320px' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=400&h=300&fit=crop\"\n alt=\"Product\"\n aspectRatio=\"4:3\"\n />\n <Card.Body>\n <Stack gap=\"sm\">\n <Stack direction=\"row\" justify=\"between\" align=\"start\">\n <Stack gap=\"xs\">\n <Text weight=\"semibold\">Minimalist Watch</Text>\n <Text size=\"sm\" color=\"tertiary\">Premium Collection</Text>\n </Stack>\n <Badge variant=\"success\">In Stock</Badge>\n </Stack>\n <Stack direction=\"row\" justify=\"between\" align=\"center\">\n <Text size=\"lg\" weight=\"semibold\">$299</Text>\n <Button variant=\"primary\" size=\"sm\">Add to Cart</Button>\n </Stack>\n </Stack>\n </Card.Body>\n</Card>","tags":["product","card","ecommerce","shopping"]},"Registration Form":{"filePath":"src/blocks/RegistrationForm.block.ts","name":"Registration Form","description":"Signup form with name, email, password fields and terms checkbox","category":"authentication","components":["Card","Stack","Input","Checkbox","Button","Text","Link"],"code":"<Card variant=\"elevated\">\n <Card.Header>\n <Card.Title>Create Account</Card.Title>\n <Card.Description>Sign up to get started with your free account.</Card.Description>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n <Stack direction={{ base: 'column', sm: 'row' }} gap=\"md\">\n <Input label=\"First Name\" placeholder=\"John\" style={{ flex: 1 }} />\n <Input label=\"Last Name\" placeholder=\"Doe\" style={{ flex: 1 }} />\n </Stack>\n <Input label=\"Email\" type=\"email\" placeholder=\"john@example.com\" />\n <Input label=\"Password\" type=\"password\" placeholder=\"Create a password\" />\n <Input label=\"Confirm Password\" type=\"password\" placeholder=\"Confirm your password\" />\n <Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <Checkbox id=\"terms\" />\n <Text as=\"label\" htmlFor=\"terms\" size=\"sm\">\n I agree to the Terms of Service and Privacy Policy\n </Text>\n </Stack>\n <Button variant=\"primary\" fullWidth>Create Account</Button>\n </Stack>\n </Card.Body>\n <Card.Footer>\n <Text size=\"sm\" color=\"tertiary\">Already have an account? <Link href=\"#\">Sign in</Link></Text>\n </Card.Footer>\n</Card>","tags":["auth","signup","registration","form"]},"Settings Drawer":{"filePath":"src/blocks/SettingsDrawer.block.ts","name":"Settings Drawer","description":"Side panel for editing settings with form fields and save/cancel actions","category":"settings","components":["Drawer","Form","Field","Button","Switch"],"code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button variant=\"secondary\">Settings</Button>\n </Drawer.Trigger>\n <Drawer.Content size=\"md\">\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Settings</Drawer.Title>\n <Drawer.Description>Manage your preferences.</Drawer.Description>\n </Drawer.Header>\n <Drawer.Body>\n <Form>\n <Stack gap=\"md\">\n <Field>\n <Field.Label>Display Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Enter name\" />\n </Field.Control>\n </Field>\n <Field>\n <Field.Label>Email Notifications</Field.Label>\n <Field.Control>\n <Switch defaultChecked />\n </Field.Control>\n </Field>\n </Stack>\n </Form>\n </Drawer.Body>\n <Drawer.Footer>\n <Drawer.Close asChild>\n <Button variant=\"secondary\">Cancel</Button>\n </Drawer.Close>\n <Button variant=\"primary\">Save Changes</Button>\n </Drawer.Footer>\n </Drawer.Content>\n</Drawer>","tags":["drawer","settings","form","panel","editor"]},"Settings Panel":{"filePath":"src/blocks/SettingsPanel.block.ts","name":"Settings Panel","description":"Settings panel with switches and descriptions","category":"settings","components":["Card","Stack","Text","Switch"],"code":"const settings = [\n { label: 'Email Notifications', description: 'Receive updates via email', defaultChecked: true },\n { label: 'Push Notifications', description: 'Receive push notifications on your device', defaultChecked: false },\n { label: 'Marketing Emails', description: 'Receive product updates and tips', defaultChecked: false },\n];\n\n<Card>\n <Card.Header>\n <Card.Title>Settings</Card.Title>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"lg\">\n {settings.map((setting) => (\n <Stack key={setting.label} direction=\"row\" justify=\"between\" align=\"center\">\n <Stack gap=\"xs\">\n <Text weight=\"medium\">{setting.label}</Text>\n <Text size=\"sm\" color=\"tertiary\">{setting.description}</Text>\n </Stack>\n <Switch defaultChecked={setting.defaultChecked} />\n </Stack>\n ))}\n </Stack>\n </Card.Body>\n</Card>","tags":["settings","switches","preferences","panel"]},"Shopping Cart":{"filePath":"src/blocks/ShoppingCart.block.ts","name":"Shopping Cart","description":"Cart with item images, quantities, totals and checkout button","category":"ecommerce","components":["Card","Stack","Text","Image","Badge","Separator","Button"],"code":"const items = [\n { name: 'Wireless Headphones', price: 199, quantity: 1, image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=100&h=100&fit=crop' },\n { name: 'Smart Watch', price: 299, quantity: 1, image: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=100&h=100&fit=crop' },\n];\n\n<Card>\n <Card.Header>\n <Stack direction=\"row\" justify=\"between\" align=\"center\">\n <Card.Title>Shopping Cart</Card.Title>\n <Badge>2 items</Badge>\n </Stack>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n {items.map((item) => (\n <Stack key={item.name} direction=\"row\" gap=\"md\" align=\"center\">\n <Image src={item.image} alt={item.name} width={64} height={64} rounded=\"md\" />\n <Stack gap=\"xs\" style={{ flex: 1 }}>\n <Text weight=\"semibold\">{item.name}</Text>\n <Text size=\"sm\" color=\"tertiary\">Qty: {item.quantity}</Text>\n </Stack>\n <Text weight=\"semibold\">${item.price}</Text>\n </Stack>\n ))}\n <Separator />\n <Stack direction=\"row\" justify=\"between\">\n <Text weight=\"semibold\">Total</Text>\n <Text weight=\"semibold\">$498</Text>\n </Stack>\n </Stack>\n </Card.Body>\n <Card.Footer>\n <Button variant=\"primary\" fullWidth>Checkout</Button>\n </Card.Footer>\n</Card>","tags":["cart","shopping","ecommerce","checkout"]},"Stats Card":{"filePath":"src/blocks/StatsCard.block.ts","name":"Stats Card","description":"Metric card with value, change indicator and icon","category":"dashboard","components":["Card","Stack","Text","Badge","Icon"],"code":"<Card>\n <Card.Body>\n <Stack direction=\"row\" justify=\"between\" align=\"start\">\n <Stack gap=\"xs\">\n <Text size=\"sm\" color=\"tertiary\">Total Revenue</Text>\n <Text size=\"2xl\" weight=\"semibold\">$45,231</Text>\n <Stack direction=\"row\" gap=\"xs\" align=\"center\">\n <Badge variant=\"success\">+12.5%</Badge>\n <Text size=\"sm\" color=\"tertiary\">from last month</Text>\n </Stack>\n </Stack>\n <Icon icon={TrendUp} size=\"lg\" color=\"success\" />\n </Stack>\n </Card.Body>\n</Card>","tags":["stats","metrics","kpi","dashboard","card"]},"Stats Card Skeleton":{"filePath":"src/blocks/StatsCardSkeleton.block.ts","name":"Stats Card Skeleton","description":"Card with skeleton metric value, label, and badge for loading stat displays","category":"loading","components":["Card","Stack","Skeleton"],"code":"<Card>\n <Card.Body>\n <Stack direction=\"row\" justify=\"between\" align=\"start\">\n <Stack gap=\"sm\">\n <Skeleton variant=\"text\" width={100} />\n <Skeleton variant=\"heading\" width={140} />\n <Stack direction=\"row\" gap=\"xs\" align=\"center\">\n <Skeleton variant=\"button\" width={60} height={22} />\n <Skeleton variant=\"text\" width={90} />\n </Stack>\n </Stack>\n <Skeleton.Circle size=\"lg\" />\n </Stack>\n </Card.Body>\n</Card>","tags":["stats","skeleton","loading","placeholder"]},"Table Skeleton":{"filePath":"src/blocks/TableSkeleton.block.ts","name":"Table Skeleton","description":"Table-shaped skeleton rows for loading data tables","category":"loading","components":["Card","Stack","Skeleton"],"code":"<Card>\n <Card.Header>\n <Stack direction=\"row\" justify=\"between\" align=\"center\">\n <Skeleton variant=\"heading\" width={120} />\n <Skeleton variant=\"input\" width={200} />\n </Stack>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"none\">\n {/* Table header row */}\n <Stack direction=\"row\" gap=\"lg\" style={{ padding: 'var(--fui-space-2) 0', borderBottom: '1px solid var(--fui-border)' }}>\n <Skeleton variant=\"text\" width=\"25%\" />\n <Skeleton variant=\"text\" width=\"30%\" />\n <Skeleton variant=\"text\" width=\"20%\" />\n <Skeleton variant=\"text\" width=\"15%\" />\n </Stack>\n {/* Table body rows */}\n {Array.from({ length: 5 }).map((_, i) => (\n <Stack key={i} direction=\"row\" gap=\"lg\" align=\"center\" style={{ padding: 'var(--fui-space-2) 0', borderBottom: '1px solid var(--fui-border)' }}>\n <Skeleton variant=\"text\" width=\"25%\" />\n <Skeleton variant=\"text\" width=\"30%\" />\n <Skeleton variant=\"button\" width=\"20%\" />\n <Skeleton variant=\"text\" width=\"15%\" />\n </Stack>\n ))}\n </Stack>\n </Card.Body>\n</Card>","tags":["table","skeleton","loading","placeholder"]},"Thinking States":{"filePath":"src/blocks/ThinkingStates.block.ts","name":"Thinking States","description":"Various AI thinking indicator states: dots, pulse, spinner with steps","category":"ai","components":["Stack","Card","ThinkingIndicator"],"code":"<Stack gap=\"lg\">\n <Card>\n <Card.Header>\n <Card.Title>Dots Animation</Card.Title>\n </Card.Header>\n <Card.Body>\n <ThinkingIndicator variant=\"dots\" label=\"Thinking...\" />\n </Card.Body>\n </Card>\n\n <Card>\n <Card.Header>\n <Card.Title>Pulse Animation</Card.Title>\n </Card.Header>\n <Card.Body>\n <ThinkingIndicator variant=\"pulse\" label=\"Processing request...\" />\n </Card.Body>\n </Card>\n\n <Card>\n <Card.Header>\n <Card.Title>Spinner with Steps</Card.Title>\n </Card.Header>\n <Card.Body>\n <ThinkingIndicator\n variant=\"spinner\"\n label=\"Working on your request...\"\n showElapsed\n steps={[\n { id: '1', label: 'Understanding your question', status: 'complete' },\n { id: '2', label: 'Searching knowledge base', status: 'active' },\n { id: '3', label: 'Generating response', status: 'pending' },\n ]}\n />\n </Card.Body>\n </Card>\n</Stack>","tags":["thinking","loading","ai","indicator","spinner"]}},"tokens":{"prefix":"--","total":620,"categories":{"bentogrid-item":[{"name":"--_col-span","value":"1"},{"name":"--_row-span","value":"1"}],"colors":[{"name":"--_button-bg","value":"transparent"},{"name":"--_button-color","value":"var(--fui-text-primary, #{$fui-text-primary})"},{"name":"--shiki-color-text","value":"var(--fui-code-text, var(--fui-text-primary, #{$fui-text-primary}))"},{"name":"--shiki-color-background","value":"var(--fui-code-bg, #{$fui-code-bg})"},{"name":"$fui-colorpicker-size","value":"200px"},{"name":"$fui-colorpicker-hue-height","value":"$fui-target-size-min"},{"name":"$fui-colorpicker-pointer-size","value":"$fui-target-size-min"},{"name":"--fui-data-table-bg","value":"transparent)"},{"name":"--fui-sidebar-hover-bg","value":"var(--fui-sidebar-item-hover-bg, var(--fui-bg-hover, #{$fui-bg-hover}))"},{"name":"--fui-table-row-bg","value":"var(--fui-table-row-base-bg)"},{"name":"--fui-table-row-base-bg","value":"var(--fui-table-subrow-bg, var(--fui-bg-subtle, #{$fui-bg-subtle}))"},{"name":"--fui-stroke-hairline","value":"1px"},{"name":"--fui-stroke-default","value":"2px"},{"name":"--fui-stroke-strong","value":"3px"},{"name":"--fui-color-accent","value":"light-dark(#{$fui-color-accent}, #{$fui-dark-color-accent})"},{"name":"--fui-color-on-accent","value":"light-dark(#{$fui-color-on-accent}, #{$fui-dark-color-on-accent})"},{"name":"--fui-color-danger","value":"#{$fui-color-danger}"},{"name":"--fui-color-danger-hover","value":"#{$fui-color-danger-hover}"},{"name":"--fui-color-success","value":"#{$fui-color-success}"},{"name":"--fui-color-warning","value":"#{$fui-color-warning}"},{"name":"--fui-color-info","value":"#{$fui-color-info}"},{"name":"--fui-selection-color","value":"var(--fui-text-primary)"},{"name":"--fui-control-selected-bg","value":"color-mix(in srgb, var(--fui-text-primary) 9%, transparent)"},{"name":"--fui-control-checked-bg","value":"var(--fui-color-accent)"},{"name":"--fui-control-checked-bg-hover","value":"var(--fui-color-accent-hover)"},{"name":"--fui-control-checked-color","value":"var(--fui-color-on-accent)"},{"name":"--fui-field-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 72%, transparent)"},{"name":"--fui-field-bg-disabled","value":"color-mix(in srgb, var(--fui-bg-tertiary) 78%, var(--fui-bg-primary))"},{"name":"--fui-field-selection-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-field-selection-bg-hover","value":"color-mix(in srgb, var(--fui-text-primary) 11%, transparent)"},{"name":"--fui-field-selection-color","value":"var(--fui-text-primary)"},{"name":"--fui-form-group-bg","value":"color-mix(in srgb, var(--fui-bg-secondary) 48%, var(--fui-bg-primary))"},{"name":"--fui-kbd-bg","value":"color-mix(in srgb, var(--fui-text-primary) 4%, transparent)"},{"name":"--fui-kbd-color","value":"var(--fui-text-tertiary)"},{"name":"--fui-card-accent-bg","value":"var(--fui-bg-tertiary)"},{"name":"--fui-app-canvas-bg","value":"var(--fui-body-bg)"},{"name":"--fui-app-main-bg","value":"var(--fui-body-bg)"},{"name":"--fui-app-sidebar-bg","value":"var(--fui-bg-tertiary)"},{"name":"--fui-sidebar-bg","value":"var(--fui-app-sidebar-bg)"},{"name":"--fui-sidebar-item-color","value":"var(--fui-text-secondary)"},{"name":"--fui-sidebar-item-icon-color","value":"var(--fui-text-tertiary)"},{"name":"--fui-sidebar-item-hover-bg","value":"var(--fui-bg-hover)"},{"name":"--fui-sidebar-item-hover-color","value":"var(--fui-text-primary)"},{"name":"--fui-sidebar-item-active-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-sidebar-item-active-color","value":"var(--fui-text-primary)"},{"name":"--fui-badge-dot-color","value":"currentColor"},{"name":"--fui-card-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 92%, transparent)"},{"name":"--fui-card-header-bg","value":"var(--fui-bg-subtle)"},{"name":"--fui-card-hover-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 88%, var(--fui-text-primary) 4%)"},{"name":"--fui-card-stat-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 74%, transparent)"},{"name":"--fui-panel-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 74%, transparent)"},{"name":"--fui-table-bg","value":"transparent"},{"name":"--fui-table-header-bg","value":"color-mix(in srgb, var(--fui-text-primary) 5%, transparent)"},{"name":"--fui-table-row-hover-bg","value":"var(--fui-bg-hover)"},{"name":"--fui-table-row-active-bg","value":"var(--fui-bg-active)"},{"name":"--fui-table-row-selected-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-table-subrow-bg","value":"color-mix(in srgb, var(--fui-bg-secondary) 62%, transparent)"},{"name":"--fui-tabs-pills-bg","value":"color-mix(in srgb, var(--fui-text-primary) 5%, transparent)"},{"name":"--fui-tabs-pill-hover-bg","value":"transparent"},{"name":"--fui-tabs-pill-active-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-toggle-group-selected-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-color-accent-hover","value":"#{$_rt-dark-accent-hover}"},{"name":"--fui-color-accent-active","value":"#{$_rt-dark-accent-active}"},{"name":"--fui-color-danger-bg","value":"color-mix(in oklch, var(--fui-seed-danger) 24%, black)"},{"name":"--fui-color-success-bg","value":"color-mix(in oklch, var(--fui-seed-success) 24%, black)"},{"name":"--fui-color-warning-bg","value":"color-mix(in oklch, var(--fui-seed-warning) 24%, black)"},{"name":"--fui-color-info-bg","value":"color-mix(in oklch, var(--fui-seed-info) 24%, black)"},{"name":"--fui-color-danger-text","value":"color-mix(in oklch, var(--fui-seed-danger) 78%, white 22%)"},{"name":"--fui-color-success-text","value":"color-mix(in oklch, var(--fui-seed-success) 78%, white 22%)"},{"name":"--fui-color-warning-text","value":"color-mix(in oklch, var(--fui-seed-warning) 78%, white 22%)"},{"name":"--fui-color-info-text","value":"color-mix(in oklch, var(--fui-seed-info) 78%, white 22%)"}],"surfaces":[{"name":"--_button-bg-hover","value":"var(--fui-bg-hover, #{$fui-bg-hover})"},{"name":"--_button-bg-active","value":"var(--fui-bg-active, #{$fui-bg-active})"},{"name":"--fui-bg-primary","value":"light-dark(#{$fui-bg-primary}, #{$fui-dark-bg-primary})"},{"name":"--fui-bg-secondary","value":"light-dark(#{$fui-bg-secondary}, #{$fui-dark-bg-secondary})"},{"name":"--fui-bg-tertiary","value":"light-dark(#{$fui-bg-tertiary}, #{$fui-dark-bg-tertiary})"},{"name":"--fui-bg-elevated","value":"light-dark(#{$fui-bg-elevated}, #{$fui-dark-bg-elevated})"},{"name":"--fui-bg-subtle","value":"light-dark(#{$fui-bg-subtle}, #{$fui-dark-bg-subtle})"},{"name":"--fui-bg-hover","value":"light-dark(#{$fui-bg-hover}, #{$fui-dark-bg-hover})"},{"name":"--fui-bg-active","value":"light-dark(#{$fui-bg-active}, #{$fui-dark-bg-active})"},{"name":"--fui-body-bg","value":"light-dark(#{$fui-body-bg}, #{$fui-dark-body-bg})"},{"name":"--fui-main-bg","value":"light-dark(#{$fui-main-bg}, #{$fui-dark-main-bg})"},{"name":"--fui-bg-inverse","value":"light-dark(#{$fui-bg-inverse}, #{$fui-dark-bg-inverse})"},{"name":"--fui-bg-highlight","value":"color-mix(in srgb, var(--fui-text-primary) 7%, transparent)"}],"borders":[{"name":"--_button-border","value":"transparent"},{"name":"--_button-border-hover","value":"transparent"},{"name":"--fui-sidebar-active-border","value":"transparent"},{"name":"--fui-border","value":"light-dark(#{$fui-border}, #{$fui-dark-border})"},{"name":"--fui-border-default","value":"light-dark(#{$fui-border-default}, #{$fui-dark-border-default})"},{"name":"--fui-border-strong","value":"light-dark(#{$fui-border-strong}, #{$fui-dark-border-strong})"},{"name":"--fui-border-subtle","value":"color-mix(in srgb, var(--fui-border-default) 68%, transparent)"},{"name":"--fui-control-checked-border","value":"var(--fui-color-accent)"},{"name":"--fui-control-checked-border-hover","value":"var(--fui-color-accent-hover)"},{"name":"--fui-field-border","value":"var(--fui-border-strong)"},{"name":"--fui-field-border-focus","value":"var(--fui-text-primary)"},{"name":"--fui-field-selection-border","value":"var(--fui-border-strong)"},{"name":"--fui-form-group-border","value":"var(--fui-border-default)"},{"name":"--fui-kbd-border","value":"color-mix(in srgb, var(--fui-border-strong) 72%, transparent)"},{"name":"--fui-card-accent-border","value":"color-mix(in srgb, var(--fui-color-accent) 30%, var(--fui-border))"},{"name":"--fui-sidebar-border","value":"var(--fui-border-default)"},{"name":"--fui-sidebar-item-active-border","value":"transparent"},{"name":"--fui-sidebar-footer-border","value":"color-mix(in srgb, var(--fui-border-default) 68%, transparent)"},{"name":"--fui-card-border","value":"color-mix(in srgb, var(--fui-border-default) 86%, transparent)"},{"name":"--fui-card-outlined-border","value":"var(--fui-card-border)"},{"name":"--fui-card-hover-border","value":"color-mix(in srgb, var(--fui-border-strong) 86%, transparent)"},{"name":"--fui-card-stat-border","value":"color-mix(in srgb, var(--fui-border-default) 78%, transparent)"},{"name":"--fui-panel-border","value":"color-mix(in srgb, var(--fui-border-default) 78%, transparent)"},{"name":"--fui-table-border","value":"var(--fui-border-default)"},{"name":"--fui-table-header-border","value":"var(--fui-border-strong)"},{"name":"--fui-table-row-selected-border","value":"var(--fui-border-strong)"},{"name":"--fui-tabs-pills-border","value":"var(--fui-border-default)"},{"name":"--fui-tabs-pill-active-border","value":"transparent"},{"name":"--fui-toggle-group-selected-border","value":"transparent"},{"name":"--fui-field-border-hover","value":"var(--fui-text-primary)"}],"shadows":[{"name":"--_button-shadow","value":"none"},{"name":"--_button-shadow-hover","value":"none"},{"name":"--_button-shadow-active","value":"none"},{"name":"--fui-card-active-shadow","value":"inset 0 1px 2px color-mix(in srgb, black 12%, transparent)"},{"name":"--fui-card-panel-shadow","value":"var(--fui-card-shadow)"},{"name":"--fui-card-stat-shadow","value":"var(--fui-card-shadow)"},{"name":"--fui-tabs-pill-active-shadow","value":"none"},{"name":"--fui-toggle-group-selected-shadow","value":"none"},{"name":"--fui-shadow-sm","value":"#{$fui-shadow-sm}"},{"name":"--fui-shadow-md","value":"#{$fui-shadow-md}"},{"name":"--fui-shadow-lg","value":"#{$fui-shadow-lg}"}],"other":[{"name":"--fui-card-consumer-fixture","value":"1"},{"name":"--shiki-token-keyword","value":"#9a3412"},{"name":"--shiki-token-string","value":"light-dark(#166534, #7dcea0)"},{"name":"--shiki-token-string-expression","value":"light-dark(#166534, #7dcea0)"},{"name":"--shiki-token-comment","value":"#5c5348"},{"name":"--shiki-token-function","value":"#1e3a8a"},{"name":"--shiki-token-constant","value":"light-dark(#92400e, #e8b86d)"},{"name":"--shiki-token-parameter","value":"#3d3429"},{"name":"--shiki-token-punctuation","value":"#3d3429"},{"name":"--shiki-token-link","value":"var(--fui-link-ink, #{$fui-link-ink})"},{"name":"--_cols","value":"1"},{"name":"--beam-angle","value":"0deg"},{"name":"--_gutter","value":"var(--fui-space-3, #{$fui-space-3})"},{"name":"--fui-scrollarea-inline-fade","value":"48px})"},{"name":"--fui-scrollarea-block-fade","value":"32px})"},{"name":"--_fui-scrollarea-inline-mask","value":"linear-gradient(black, black)"},{"name":"--_fui-scrollarea-block-mask","value":"linear-gradient(black, black)"},{"name":"--fui-sidebar-gutter","value":"var(--fui-navigation-gutter)"},{"name":"--fui-line-clamp","value":"2"},{"name":"--fui-navmenu-viewport-left","value":"0px"},{"name":"--fui-control-track-micro","value":"24px"},{"name":"--fui-control-track-sm","value":"28px"},{"name":"--fui-control-track-md","value":"32px"},{"name":"--fui-control-track-lg","value":"40px"},{"name":"--fui-field-track-sm","value":"28px"},{"name":"--fui-field-track-md","value":"32px"},{"name":"--fui-field-track-lg","value":"40px"},{"name":"--fui-icon-xs","value":"12px"},{"name":"--fui-icon-sm","value":"14px"},{"name":"--fui-icon-md","value":"16px"},{"name":"--fui-icon-lg","value":"20px"},{"name":"--fui-icon-xl","value":"24px"},{"name":"--fui-icon-2xl","value":"32px"},{"name":"--fui-layout-measure-inline-floor","value":"56px"},{"name":"--fui-layout-measure-compact-content","value":"168px"},{"name":"--fui-layout-measure-grid-cell","value":"224px"},{"name":"--fui-layout-measure-composer-item","value":"210px"},{"name":"--fui-layout-measure-page-narrow","value":"800px"},{"name":"--fui-type-caption-line","value":"16px"},{"name":"--fui-type-caption-weight","value":"400"},{"name":"--fui-type-caption-tracking","value":"0"},{"name":"--fui-type-ui-compact-line","value":"16px"},{"name":"--fui-type-ui-compact-weight","value":"500"},{"name":"--fui-type-ui-compact-tracking","value":"-0.01em"},{"name":"--fui-type-ui-standard-line","value":"20px"},{"name":"--fui-type-ui-standard-weight","value":"500"},{"name":"--fui-type-ui-standard-tracking","value":"-0.01em"},{"name":"--fui-type-body-compact-line","value":"20px"},{"name":"--fui-type-body-compact-weight","value":"400"},{"name":"--fui-type-body-compact-tracking","value":"0"},{"name":"--fui-type-body-relaxed-line","value":"24px"},{"name":"--fui-type-body-relaxed-weight","value":"400"},{"name":"--fui-type-body-relaxed-tracking","value":"0"},{"name":"--fui-type-display-line","value":"40px"},{"name":"--fui-type-display-weight","value":"600"},{"name":"--fui-type-display-tracking","value":"-0.02em"},{"name":"--fui-type-title-sm-line","value":"24px"},{"name":"--fui-type-title-sm-weight","value":"600"},{"name":"--fui-type-title-sm-tracking","value":"-0.01em"},{"name":"--fui-type-title-md-line","value":"28px"},{"name":"--fui-type-title-md-weight","value":"600"},{"name":"--fui-type-title-md-tracking","value":"-0.02em"},{"name":"--fui-type-title-lg-line","value":"32px"},{"name":"--fui-type-title-lg-weight","value":"600"},{"name":"--fui-type-title-lg-tracking","value":"-0.02em"},{"name":"--fui-type-code-line","value":"20px"},{"name":"--fui-type-code-weight","value":"400"},{"name":"--fui-type-code-tracking","value":"0"},{"name":"--fui-navigation-sidebar-gutter","value":"8px"},{"name":"--fui-navigation-sidebar-leading-box","value":"16px"},{"name":"--fui-navigation-sidebar-dot","value":"6px"},{"name":"--fui-navigation-sidebar-rail","value":"2px"},{"name":"--fui-navigation-sidebar-label-offset","value":"1px"},{"name":"--fui-seed-brand","value":"#{$fui-color-accent}"},{"name":"--fui-seed-danger","value":"#{$fui-color-danger}"},{"name":"--fui-seed-success","value":"#{$fui-color-success}"},{"name":"--fui-seed-warning","value":"#{$fui-color-warning}"},{"name":"--fui-seed-info","value":"#{$fui-color-info}"},{"name":"--fui-skeleton","value":"color-mix(in srgb, var(--fui-border-default) 62%, var(--fui-bg-secondary))"},{"name":"--fui-skeleton-hi","value":"color-mix(in srgb, var(--fui-border-default) 24%, var(--fui-bg-secondary))"},{"name":"--fui-link-ink","value":"light-dark(#{$fui-link-ink}, #{$fui-dark-link-ink})"},{"name":"--fui-sidebar-item-active-indicator","value":"transparent"}],"spacing":[{"name":"--_card-root-forced-inset","value":"#{surface.inset(\"panel\")}"},{"name":"--_card-body-inset","value":"#{surface.inset(\"panel\")}"},{"name":"--_control-padding","value":"var(--fui-space-2, #{$fui-space-2})"},{"name":"--_chip-padding","value":"var(--fui-space-1, #{$fui-space-1})"},{"name":"--fui-sidebar-row-gap","value":"var(--fui-navigation-content-gap)"},{"name":"--fui-sidebar-row-padding-x","value":"var(--fui-navigation-inline-inset)"},{"name":"--fui-prompt-inset-left","value":"0px"},{"name":"--fui-stack-gap","value":"0"},{"name":"--fui-stack-gap-sm","value":"0"},{"name":"--fui-stack-gap-md","value":"0"},{"name":"--fui-stack-gap-lg","value":"0"},{"name":"--fui-stack-gap-xl","value":"0"},{"name":"--fui-raw-space-0","value":"0"},{"name":"--fui-raw-space-2","value":"2px"},{"name":"--fui-raw-space-4","value":"4px"},{"name":"--fui-raw-space-6","value":"6px"},{"name":"--fui-raw-space-8","value":"8px"},{"name":"--fui-raw-space-10","value":"10px"},{"name":"--fui-raw-space-12","value":"12px"},{"name":"--fui-raw-space-16","value":"16px"},{"name":"--fui-raw-space-20","value":"20px"},{"name":"--fui-raw-space-24","value":"24px"},{"name":"--fui-raw-space-32","value":"32px"},{"name":"--fui-raw-space-40","value":"40px"},{"name":"--fui-raw-space-48","value":"48px"},{"name":"--fui-raw-space-64","value":"64px"},{"name":"--fui-field-inline-inset-sm","value":"10px"},{"name":"--fui-field-inline-inset-md","value":"12px"},{"name":"--fui-field-inline-inset-lg","value":"16px"},{"name":"--fui-surface-inset-panel","value":"0"},{"name":"--fui-surface-inset-compact","value":"12px"},{"name":"--fui-surface-inset-default","value":"16px"},{"name":"--fui-surface-inset-roomy","value":"24px"},{"name":"--fui-space-px","value":"#{$fui-space-px}"},{"name":"--fui-space-0-5","value":"#{$fui-space-0-5}"},{"name":"--fui-space-0-75","value":"#{$fui-space-0-75}"},{"name":"--fui-space-1","value":"#{$fui-space-1}"},{"name":"--fui-space-2","value":"#{$fui-space-2}"},{"name":"--fui-space-3","value":"#{$fui-space-3}"},{"name":"--fui-space-4","value":"#{$fui-space-4}"},{"name":"--fui-space-5","value":"#{$fui-space-5}"},{"name":"--fui-space-6","value":"#{$fui-space-6}"},{"name":"--fui-space-8","value":"#{$fui-space-8}"},{"name":"--fui-space-10","value":"#{$fui-space-10}"},{"name":"--fui-space-12","value":"#{$fui-space-12}"},{"name":"--fui-popup-padding","value":"#{$fui-popup-padding}"},{"name":"--fui-popup-row-gap","value":"1px"},{"name":"--fui-popup-item-padding-block","value":"#{$fui-popup-item-padding-block}"},{"name":"--fui-popup-item-padding-inline","value":"#{$fui-popup-item-padding-inline}"},{"name":"--fui-kbd-padding-x","value":"var(--fui-space-0-75)"},{"name":"--fui-kbd-gap","value":"calc(var(--fui-space-px) * 2)"}],"padding":[{"name":"--_card-root-requested-inset","value":"#{surface.inset(\"panel\")}"}],"code":[{"name":"--_fui-code-inline-inset","value":"16px"},{"name":"--fui-code-bg","value":"#{$fui-code-bg}"},{"name":"--fui-code-selection-bg","value":"#{$fui-code-selection-bg}"},{"name":"--fui-code-text","value":"var(--fui-text-primary)"},{"name":"--fui-code-token-string","value":"light-dark(#166534, #7dcea0)"},{"name":"--fui-code-token-number","value":"light-dark(#92400e, #e8b86d)"}],"sizing":[{"name":"--_day-size","value":"#{action.track(\"md\")}"},{"name":"--fui-editor-min-block-sm","value":"120px"},{"name":"--fui-editor-min-block-md","value":"200px"},{"name":"--fui-editor-min-block-lg","value":"400px"},{"name":"--_chip-height","value":"#{action.track(\"sm\")}"},{"name":"--fui-scrollarea-track-size","value":"6px})"},{"name":"--fui-sidebar-row-height","value":"var(--fui-navigation-row-track)"},{"name":"--fui-sidebar-icon-size","value":"16px)"},{"name":"--fui-sidebar-leading-size","value":"var(--fui-navigation-leading-box)"},{"name":"--fui-sidebar-active-dot-size","value":"var(--fui-navigation-active-dot)"},{"name":"--_fui-target-hit-size","value":"#{target.hit-size(\"touch\")}"},{"name":"--fui-grid-min-child-width","value":"224px"},{"name":"--fui-navmenu-viewport-height","value":"0px"},{"name":"--fui-navmenu-viewport-width","value":"0px"},{"name":"--fui-select-max-items","value":"4.5"},{"name":"--fui-layout-measure-field-minimum","value":"140px"},{"name":"--fui-layout-measure-menu-min","value":"192px"},{"name":"--fui-type-caption-size","value":"12px"},{"name":"--fui-type-ui-compact-size","value":"12px"},{"name":"--fui-type-ui-standard-size","value":"14px"},{"name":"--fui-type-body-compact-size","value":"14px"},{"name":"--fui-type-body-relaxed-size","value":"16px"},{"name":"--fui-type-display-size","value":"32px"},{"name":"--fui-type-title-sm-size","value":"16px"},{"name":"--fui-type-title-md-size","value":"20px"},{"name":"--fui-type-title-lg-size","value":"24px"},{"name":"--fui-type-code-size","value":"14px"},{"name":"--fui-navigation-app-shell-header-height","value":"56px"},{"name":"--fui-navigation-sidebar-collapsed-width","value":"56px"},{"name":"--fui-kbd-height","value":"1.286rem","description":"18px at 14px root"},{"name":"--fui-kbd-min-width","value":"1.714rem","description":"24px"},{"name":"--fui-kbd-reserved-width","value":"2.714rem","description":"38px, enough for \"⌘K\""},{"name":"--fui-control-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"--fui-control-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"--fui-control-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"--fui-control-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"--fui-target-size-min","value":"#{$fui-target-size-min}"},{"name":"--fui-sidebar-item-height","value":"#{$fui-sidebar-item-height}"}],"inline-variant":[{"name":"--inline-size","value":"0.875em","description":"Relative to surrounding text"}],"typography":[{"name":"--fui-markdown-text","value":"currentColor"},{"name":"--fui-font-sans","value":"\"Onest Variable\", Onest, -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif"},{"name":"--fui-font-mono","value":"\"JetBrains Mono Variable\", \"JetBrains Mono\", ui-monospace, \"SF Mono\", Menlo, monospace"},{"name":"--fui-font-size-2xs","value":"#{$fui-font-size-2xs}"},{"name":"--fui-font-size-xs","value":"#{$fui-font-size-xs}"},{"name":"--fui-font-size-sm","value":"#{$fui-font-size-sm}"},{"name":"--fui-font-size-base","value":"#{$fui-font-size-base}"},{"name":"--fui-font-size-md","value":"#{$fui-font-size-md}"},{"name":"--fui-font-size-lg","value":"#{$fui-font-size-lg}"},{"name":"--fui-font-size-xl","value":"#{$fui-font-size-xl}"},{"name":"--fui-font-size-2xl","value":"#{$fui-font-size-2xl}"},{"name":"--fui-font-size-3xl","value":"#{$fui-font-size-3xl}"},{"name":"--fui-font-size-4xl","value":"#{$fui-font-size-4xl}"},{"name":"--fui-popup-item-font-size","value":"#{$fui-popup-item-font-size}"},{"name":"--fui-font-weight-normal","value":"#{$fui-font-weight-normal}"},{"name":"--fui-font-weight-medium","value":"#{$fui-font-weight-medium}"},{"name":"--fui-font-weight-semibold","value":"#{$fui-font-weight-semibold}"},{"name":"--fui-font-weight-bold","value":"#{$fui-font-weight-bold}"},{"name":"--fui-line-height-tight","value":"#{$fui-line-height-tight}"},{"name":"--fui-line-height-normal","value":"#{$fui-line-height-normal}"},{"name":"--fui-line-height-relaxed","value":"#{$fui-line-height-relaxed}"},{"name":"--fui-line-height-display","value":"#{$fui-line-height-display}"},{"name":"--fui-line-height-prose","value":"#{$fui-line-height-prose}"},{"name":"--fui-letter-spacing-tight","value":"#{$fui-letter-spacing-tight}"},{"name":"--fui-letter-spacing-normal","value":"#{$fui-letter-spacing-normal}"},{"name":"--fui-letter-spacing-display","value":"#{$fui-letter-spacing-display}"},{"name":"--fui-letter-spacing-wide","value":"#{$fui-letter-spacing-wide}"},{"name":"--fui-kbd-font-size","value":"var(--fui-font-size-2xs)"}],"radius":[{"name":"--fui-sidebar-row-radius","value":"var(--fui-radius-full, #{$fui-radius-full})"},{"name":"--fui-checkbox-radius","value":"var(--fui-radius-sm)"},{"name":"--fui-radius-sm","value":"#{$fui-radius-sm}"},{"name":"--fui-radius-md","value":"#{$fui-radius-md}"},{"name":"--fui-radius-lg","value":"#{$fui-radius-lg}"},{"name":"--fui-radius-xl","value":"#{$fui-radius-xl}"},{"name":"--fui-radius-full","value":"#{$fui-radius-full}"},{"name":"--fui-kbd-radius","value":"var(--fui-radius-sm)"},{"name":"--fui-card-accent-radius","value":"#{$fui-card-accent-radius}"},{"name":"--fui-badge-radius","value":"var(--fui-radius-lg)"},{"name":"--fui-card-radius","value":"var(--fui-radius-lg)"}],"size-variants":[{"name":"--_fui-textarea-block-inset","value":"6px})"}],"z-index":[{"name":"--fui-stack-direction","value":"column"},{"name":"--fui-stack-direction-sm","value":"column"},{"name":"--fui-stack-direction-md","value":"column"},{"name":"--fui-stack-direction-lg","value":"column"},{"name":"--fui-stack-direction-xl","value":"column"}],"base":[{"name":"--fui-base-unit","value":"#{$fui-base-unit}"}],"transitions":[{"name":"--fui-transition-fast","value":"160ms cubic-bezier(0.25, 0.46, 0.45, 0.94)"},{"name":"--fui-transition-normal","value":"200ms cubic-bezier(0.4, 0, 0.2, 1)"}],"motion-primitives":[{"name":"--fui-anim-offset-sm","value":"4px"},{"name":"--fui-anim-offset-md","value":"8px"},{"name":"--fui-duration-spin","value":"800ms"},{"name":"--fui-duration-pulse","value":"1500ms"},{"name":"--fui-duration-shimmer","value":"2000ms"}],"overlay-stacking-layers":[{"name":"--fui-overlay-layer-swipe","value":"49"},{"name":"--fui-overlay-layer-backdrop","value":"50"},{"name":"--fui-overlay-layer-modal","value":"51"},{"name":"--fui-overlay-layer-anchored","value":"52"},{"name":"--fui-overlay-layer-tooltip","value":"60"}],"backdrop":[{"name":"--fui-backdrop","value":"light-dark(#{$fui-backdrop}, #{$fui-dark-backdrop})"}],"text":[{"name":"--fui-text-primary","value":"light-dark(#{$fui-text-primary}, #{$fui-dark-text-primary})"},{"name":"--fui-text-secondary","value":"light-dark(#{$fui-text-secondary}, #{$fui-dark-text-secondary})"},{"name":"--fui-text-tertiary","value":"light-dark(#{$fui-text-tertiary}, #{$fui-dark-text-tertiary})"},{"name":"--fui-text-inverse","value":"light-dark(#{$fui-text-inverse}, #{$fui-dark-text-inverse})"}],"component-sizing":[{"name":"--fui-button-primary-base","value":"var(--fui-bg-inverse)"},{"name":"--fui-button-primary-color","value":"var(--fui-text-inverse)"},{"name":"--fui-button-radius","value":"var(--fui-radius-xl)"},{"name":"--fui-button-primary-hover","value":"var(--fui-color-accent-hover)"},{"name":"--fui-button-primary-active","value":"var(--fui-color-accent-active)"},{"name":"--fui-button-primary-border","value":"var(--fui-button-primary-base)"},{"name":"--fui-button-primary-border-hover","value":"var(--fui-button-primary-hover)"},{"name":"--fui-button-primary-bg","value":"var(--fui-button-primary-base)"},{"name":"--fui-button-primary-bg-hover","value":"var(--fui-button-primary-hover)"},{"name":"--fui-button-primary-bg-active","value":"var(--fui-button-primary-active)"},{"name":"--fui-button-primary-shadow","value":"none"},{"name":"--fui-button-primary-shadow-active","value":"none"},{"name":"--fui-button-neutral-color","value":"var(--fui-text-primary)"},{"name":"--fui-button-outlined-shadow","value":"none"},{"name":"--fui-button-neutral-shadow","value":"none"},{"name":"--fui-button-neutral-shadow-active","value":"none"},{"name":"--fui-button-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"--fui-button-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"--fui-button-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"--fui-button-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"--fui-input-height-sm","value":"28px"},{"name":"--fui-input-height","value":"32px"},{"name":"--fui-input-height-lg","value":"40px"},{"name":"--fui-touch-sm","value":"#{$fui-touch-sm}"},{"name":"--fui-touch-md","value":"#{$fui-touch-md}"},{"name":"--fui-touch-lg","value":"#{$fui-touch-lg}"}],"layout":[{"name":"--fui-header-search-bg","value":"var(--fui-bg-hover)"},{"name":"--fui-appshell-header-height","value":"#{$fui-appshell-header-height}"},{"name":"--fui-header-z-index","value":"40"}],"focus":[{"name":"--fui-focus-ring-color","value":"light-dark(#{$fui-focus-ring-color}, #{$fui-dark-focus-ring-color})"},{"name":"--fui-focus-ring-offset","value":"2px"},{"name":"--fui-focus-ring-width","value":"2px"}],"scrollbar":[{"name":"--fui-scrollbar-width","value":"8px"},{"name":"--fui-scrollbar-track","value":"light-dark(#{$fui-scrollbar-track}, #{$fui-dark-scrollbar-track})"},{"name":"--fui-scrollbar-thumb","value":"light-dark(#{$fui-scrollbar-thumb}, #{$fui-dark-scrollbar-thumb})"},{"name":"--fui-scrollbar-thumb-hover","value":"#{$fui-dark-scrollbar-thumb-hover}"},{"name":"$fui-base-font-size","value":"computed.$computed-base-font-size"},{"name":"$fui-base-unit","value":"computed.$computed-base-unit"},{"name":"$fui-font-sans","value":"\"Onest Variable\", Onest, -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif"},{"name":"$fui-font-mono","value":"\"JetBrains Mono Variable\", \"JetBrains Mono\", ui-monospace, \"SF Mono\", Menlo, monospace"},{"name":"$fui-font-size-2xs","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"2xs\")"},{"name":"$fui-font-size-xs","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"xs\")"},{"name":"$fui-font-size-sm","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"sm\")"},{"name":"$fui-font-size-base","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"base\")"},{"name":"$fui-font-size-md","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"md\")"},{"name":"$fui-font-size-lg","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"lg\")"},{"name":"$fui-font-size-xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"xl\")"},{"name":"$fui-font-size-2xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"2xl\")"},{"name":"$fui-font-size-3xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"3xl\")"},{"name":"$fui-font-size-4xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"4xl\")"},{"name":"$fui-popup-item-font-size","value":"$fui-font-size-xs"},{"name":"$fui-font-weight-normal","value":"map.get( measurements.$legacy, \"typography\", \"fontWeight\", \"normal\" )"},{"name":"$fui-font-weight-medium","value":"map.get( measurements.$legacy, \"typography\", \"fontWeight\", \"medium\" )"},{"name":"$fui-font-weight-semibold","value":"map.get( measurements.$legacy, \"typography\", \"fontWeight\", \"semibold\" )"},{"name":"$fui-font-weight-bold","value":"map.get(measurements.$legacy, \"typography\", \"fontWeight\", \"bold\")"},{"name":"$fui-line-height-tight","value":"map.get(measurements.$legacy, \"typography\", \"lineHeight\", \"tight\")"},{"name":"$fui-line-height-normal","value":"map.get( measurements.$legacy, \"typography\", \"lineHeight\", \"normal\" )"},{"name":"$fui-line-height-relaxed","value":"map.get( measurements.$legacy, \"typography\", \"lineHeight\", \"relaxed\" )"},{"name":"$fui-line-height-display","value":"map.get( measurements.$legacy, \"typography\", \"lineHeight\", \"display\" )"},{"name":"$fui-line-height-prose","value":"map.get(measurements.$legacy, \"typography\", \"lineHeight\", \"prose\")"},{"name":"$fui-letter-spacing-tight","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"tight\" )"},{"name":"$fui-letter-spacing-normal","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"normal\" )"},{"name":"$fui-letter-spacing-display","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"display\" )"},{"name":"$fui-letter-spacing-wide","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"wide\" )"},{"name":"$fui-space-px","value":"computed.$computed-space-px"},{"name":"$fui-space-0-5","value":"computed.$computed-space-0-5"},{"name":"$fui-space-0-75","value":"computed.$computed-space-0-75"},{"name":"$fui-space-1","value":"computed.$computed-space-1"},{"name":"$fui-space-2","value":"computed.$computed-space-2"},{"name":"$fui-space-3","value":"computed.$computed-space-3"},{"name":"$fui-space-4","value":"computed.$computed-space-4"},{"name":"$fui-space-5","value":"computed.$computed-space-5"},{"name":"$fui-space-6","value":"computed.$computed-space-6"},{"name":"$fui-space-8","value":"computed.$computed-space-8"},{"name":"$fui-space-10","value":"computed.$computed-space-10"},{"name":"$fui-space-12","value":"computed.$computed-space-12"},{"name":"$fui-popup-padding","value":"$fui-space-1"},{"name":"$fui-popup-row-gap","value":"1px"},{"name":"$fui-popup-item-padding-block","value":"$fui-space-1"},{"name":"$fui-popup-item-padding-inline","value":"$fui-space-2"},{"name":"$fui-radius-sm","value":"computed.$computed-radius-sm"},{"name":"$fui-radius-md","value":"computed.$computed-radius-md"},{"name":"$fui-radius-lg","value":"computed.$computed-radius-lg"},{"name":"$fui-radius-xl","value":"computed.$computed-radius-xl"},{"name":"$fui-radius-full","value":"computed.$computed-radius-full"},{"name":"$fui-stroke-hairline","value":"measurements.target-value(\"stroke\", \"hairline\")"},{"name":"$fui-stroke-default","value":"measurements.target-value(\"stroke\", \"default\")"},{"name":"$fui-stroke-strong","value":"measurements.target-value(\"stroke\", \"strong\")"},{"name":"$fui-control-track-micro","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$fui-control-track-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"$fui-control-track-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$fui-control-track-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"$fui-transition-fast","value":"160ms cubic-bezier(0.25, 0.46, 0.45, 0.94)"},{"name":"$fui-transition-normal","value":"200ms cubic-bezier(0.4, 0, 0.2, 1)"},{"name":"$fui-color-accent","value":"computed.$computed-color-accent"},{"name":"$fui-color-on-accent","value":"computed.$computed-color-on-accent"},{"name":"$fui-color-accent-hover","value":"computed.$computed-color-accent-hover"},{"name":"$fui-color-accent-active","value":"computed.$computed-color-accent-active"},{"name":"$fui-color-danger","value":"computed.$computed-color-danger"},{"name":"$fui-color-danger-hover","value":"computed.$computed-color-danger-hover"},{"name":"$fui-color-success","value":"computed.$computed-color-success"},{"name":"$fui-color-warning","value":"computed.$computed-color-warning"},{"name":"$fui-color-info","value":"computed.$computed-color-info"},{"name":"$fui-color-danger-bg","value":"computed.$computed-color-danger-bg"},{"name":"$fui-color-success-bg","value":"computed.$computed-color-success-bg"},{"name":"$fui-color-warning-bg","value":"computed.$computed-color-warning-bg"},{"name":"$fui-color-info-bg","value":"computed.$computed-color-info-bg"},{"name":"$fui-color-danger-text","value":"computed.$computed-color-danger-text"},{"name":"$fui-color-success-text","value":"computed.$computed-color-success-text"},{"name":"$fui-color-warning-text","value":"computed.$computed-color-warning-text"},{"name":"$fui-color-info-text","value":"computed.$computed-color-info-text"},{"name":"$fui-color-danger-border","value":"color-mix(in srgb, $fui-color-danger-text 30%, transparent)"},{"name":"$fui-color-success-border","value":"color-mix(in srgb, $fui-color-success-text 28%, transparent)"},{"name":"$fui-color-warning-border","value":"color-mix(in srgb, $fui-color-warning-text 28%, transparent)"},{"name":"$fui-color-info-border","value":"color-mix(in srgb, $fui-color-info-text 30%, transparent)"},{"name":"$fui-bg-primary","value":"computed.$computed-bg-primary"},{"name":"$fui-bg-secondary","value":"computed.$computed-bg-secondary"},{"name":"$fui-bg-tertiary","value":"computed.$computed-bg-tertiary"},{"name":"$fui-bg-elevated","value":"computed.$computed-bg-elevated"},{"name":"$fui-bg-subtle","value":"computed.$computed-bg-subtle"},{"name":"$fui-bg-hover","value":"computed.$computed-bg-hover"},{"name":"$fui-bg-active","value":"computed.$computed-bg-active"},{"name":"$fui-body-bg","value":"computed.$computed-body-bg"},{"name":"$fui-main-bg","value":"computed.$computed-main-bg"},{"name":"$fui-text-primary","value":"computed.$computed-text-primary"},{"name":"$fui-text-secondary","value":"computed.$computed-text-secondary"},{"name":"$fui-text-tertiary","value":"computed.$computed-text-tertiary"},{"name":"$fui-text-inverse","value":"computed.$computed-text-inverse"},{"name":"$fui-bg-inverse","value":"$fui-text-primary"},{"name":"$fui-border","value":"computed.$computed-border"},{"name":"$fui-border-default","value":"computed.$computed-border-default"},{"name":"$fui-border-strong","value":"computed.$computed-border-strong"},{"name":"$fui-shadow-sm","value":"computed.$computed-shadow-sm"},{"name":"$fui-shadow-md","value":"computed.$computed-shadow-md"},{"name":"$fui-shadow-lg","value":"computed.$computed-shadow-lg"},{"name":"$fui-focus-ring-color","value":"computed.$computed-focus-ring-color"},{"name":"$fui-focus-ring-offset","value":"2px"},{"name":"$fui-focus-ring-width","value":"2px"},{"name":"$fui-scrollbar-width","value":"8px"},{"name":"$fui-scrollbar-track","value":"computed.$computed-scrollbar-track"},{"name":"$fui-scrollbar-thumb","value":"computed.$computed-scrollbar-thumb"},{"name":"$fui-scrollbar-thumb-hover","value":"computed.$computed-scrollbar-thumb-hover"},{"name":"$fui-dark-color-accent","value":"computed.$computed-dark-color-accent"},{"name":"$fui-dark-color-on-accent","value":"computed.$computed-dark-color-on-accent"},{"name":"$fui-dark-color-accent-hover","value":"computed.$computed-dark-color-accent-hover"},{"name":"$fui-dark-color-accent-active","value":"computed.$computed-dark-color-accent-active"},{"name":"$fui-brand-is-default","value":"computed.$brand-is-fragments-default"},{"name":"$_rt-dark-accent","value":"$fui-dark-color-accent"},{"name":"$_rt-dark-accent-hover","value":"$fui-dark-color-accent-hover"},{"name":"$_rt-dark-accent-active","value":"$fui-dark-color-accent-active"},{"name":"$fui-dark-bg-primary","value":"computed.$computed-dark-bg-primary"},{"name":"$fui-dark-bg-secondary","value":"computed.$computed-dark-bg-secondary"},{"name":"$fui-dark-bg-tertiary","value":"computed.$computed-dark-bg-tertiary"},{"name":"$fui-dark-bg-elevated","value":"computed.$computed-dark-bg-elevated"},{"name":"$fui-dark-bg-subtle","value":"computed.$computed-dark-bg-subtle"},{"name":"$fui-dark-bg-hover","value":"computed.$computed-dark-bg-hover"},{"name":"$fui-dark-bg-active","value":"computed.$computed-dark-bg-active"},{"name":"$fui-dark-body-bg","value":"computed.$computed-dark-body-bg"},{"name":"$fui-dark-main-bg","value":"computed.$computed-dark-main-bg"},{"name":"$fui-dark-text-primary","value":"computed.$computed-dark-text-primary"},{"name":"$fui-dark-text-secondary","value":"computed.$computed-dark-text-secondary"},{"name":"$fui-dark-text-tertiary","value":"computed.$computed-dark-text-tertiary"},{"name":"$fui-dark-text-inverse","value":"computed.$computed-dark-text-inverse"},{"name":"$fui-dark-bg-inverse","value":"computed.$computed-dark-text-primary"},{"name":"$fui-dark-border","value":"computed.$computed-dark-border"},{"name":"$fui-dark-border-default","value":"computed.$computed-dark-border-default"},{"name":"$fui-dark-border-strong","value":"computed.$computed-dark-border-strong"},{"name":"$fui-dark-shadow-sm","value":"computed.$computed-dark-shadow-sm"},{"name":"$fui-dark-shadow-md","value":"computed.$computed-dark-shadow-md"},{"name":"$fui-dark-shadow-lg","value":"computed.$computed-dark-shadow-lg"},{"name":"$fui-dark-color-danger-bg","value":"computed.$computed-dark-color-danger-bg"},{"name":"$fui-dark-color-success-bg","value":"computed.$computed-dark-color-success-bg"},{"name":"$fui-dark-color-warning-bg","value":"computed.$computed-dark-color-warning-bg"},{"name":"$fui-dark-color-info-bg","value":"computed.$computed-dark-color-info-bg"},{"name":"$fui-dark-color-danger-text","value":"computed.$computed-dark-color-danger-text"},{"name":"$fui-dark-color-success-text","value":"computed.$computed-dark-color-success-text"},{"name":"$fui-dark-color-warning-text","value":"computed.$computed-dark-color-warning-text"},{"name":"$fui-dark-color-info-text","value":"computed.$computed-dark-color-info-text"},{"name":"$fui-dark-focus-ring-color","value":"computed.$computed-dark-focus-ring-color"},{"name":"$fui-dark-scrollbar-track","value":"computed.$computed-dark-scrollbar-track"},{"name":"$fui-dark-scrollbar-thumb","value":"computed.$computed-dark-scrollbar-thumb"},{"name":"$fui-dark-scrollbar-thumb-hover","value":"computed.$computed-dark-scrollbar-thumb-hover"},{"name":"$fui-backdrop","value":"computed.$computed-backdrop"},{"name":"$fui-dark-backdrop","value":"computed.$computed-dark-backdrop"},{"name":"$fui-breakpoint-sm","value":"640px"},{"name":"$fui-breakpoint-md","value":"768px"},{"name":"$fui-breakpoint-lg","value":"1024px"},{"name":"$fui-breakpoint-xl","value":"1280px"},{"name":"$fui-control-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$fui-control-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"$fui-control-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$fui-control-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"$fui-button-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$fui-button-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"$fui-button-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$fui-button-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"$fui-button-outlined-shadow","value":"none"},{"name":"$fui-input-height-sm","value":"measurements.target-value(\"fieldTrack\", \"sm\")"},{"name":"$fui-input-height","value":"measurements.target-value(\"fieldTrack\", \"md\")"},{"name":"$fui-input-height-lg","value":"measurements.target-value(\"fieldTrack\", \"lg\")"},{"name":"$fui-touch-sm","value":"computed.$computed-touch-sm"},{"name":"$fui-touch-md","value":"computed.$computed-touch-md"},{"name":"$fui-touch-lg","value":"computed.$computed-touch-lg"},{"name":"$fui-target-size-min","value":"map.get(measurements.$legacy, \"touch\", \"minimum\")"},{"name":"$fui-target-size-comfortable","value":"$fui-touch-md"},{"name":"$fui-icon-xs","value":"measurements.target-value(\"icon\", \"xs\")"},{"name":"$fui-icon-sm","value":"measurements.target-value(\"icon\", \"sm\")"},{"name":"$fui-icon-md","value":"measurements.target-value(\"icon\", \"md\")"},{"name":"$fui-icon-lg","value":"measurements.target-value(\"icon\", \"lg\")"},{"name":"$fui-icon-xl","value":"measurements.target-value(\"icon\", \"xl\")"},{"name":"$fui-icon-2xl","value":"measurements.target-value(\"icon\", \"2xl\")"},{"name":"$fui-anim-offset-sm","value":"4px"},{"name":"$fui-anim-offset-md","value":"8px"},{"name":"$fui-duration-spin","value":"800ms"},{"name":"$fui-duration-pulse","value":"1500ms"},{"name":"$fui-duration-shimmer","value":"2000ms"},{"name":"$fui-overlay-layer-swipe","value":"49"},{"name":"$fui-overlay-layer-backdrop","value":"50"},{"name":"$fui-overlay-layer-modal","value":"51"},{"name":"$fui-overlay-layer-anchored","value":"52"},{"name":"$fui-overlay-layer-tooltip","value":"60"},{"name":"$fui-sidebar-item-height","value":"computed.$computed-sidebar-item-height"},{"name":"$fui-appshell-header-height","value":"map.get( measurements.$legacy, \"navigation\", \"appShellHeaderHeight\" )"},{"name":"$fui-header-z-index","value":"40"},{"name":"$fui-code-bg","value":"light-dark(#{$fui-bg-tertiary}, #{$fui-dark-bg-tertiary})"},{"name":"$fui-card-accent-bg","value":"$fui-bg-tertiary"},{"name":"$fui-card-accent-border","value":"color-mix(in srgb, $fui-color-accent 30%, $fui-border)"},{"name":"$fui-card-accent-radius","value":"$fui-radius-xl"},{"name":"$fui-code-selection-bg","value":"color-mix( in srgb, var(--fui-color-accent, #f56138) 30%, transparent )"},{"name":"$fui-code-text","value":"$fui-text-primary"},{"name":"$fui-code-token-keyword","value":"#9a3412"},{"name":"$fui-code-token-string","value":"#166534"},{"name":"$fui-code-token-comment","value":"#5c5348"},{"name":"$fui-code-token-function","value":"#1e3a8a"},{"name":"$fui-code-token-number","value":"#92400e"},{"name":"$fui-code-token-punctuation","value":"#3d3429"},{"name":"$fui-code-token-variable","value":"#3d3429"},{"name":"$fui-dark-code-token-keyword","value":"#f56138"},{"name":"$fui-dark-code-token-string","value":"#7dcea0"},{"name":"$fui-dark-code-token-comment","value":"#a89b8c"},{"name":"$fui-dark-code-token-function","value":"#8cb4e8"},{"name":"$fui-dark-code-token-number","value":"#e8b86d"},{"name":"$fui-dark-code-token-punctuation","value":"#c9c2b8"},{"name":"$fui-dark-code-token-variable","value":"#f0ede9"},{"name":"$fui-link-ink","value":"#9a3412"},{"name":"$fui-dark-link-ink","value":"$fui-dark-color-accent"}],"semantic-borders":[{"name":"--fui-color-danger-border","value":"color-mix(in srgb, var(--fui-color-danger-text) 30%, transparent)"},{"name":"--fui-color-success-border","value":"color-mix(in srgb, var(--fui-color-success-text) 28%, transparent)"},{"name":"--fui-color-warning-border","value":"color-mix(in srgb, var(--fui-color-warning-text) 28%, transparent)"},{"name":"--fui-color-info-border","value":"color-mix(in srgb, var(--fui-color-info-text) 30%, transparent)"}]}},"graph":{"nodes":[{"name":"Accordion","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Item","Trigger","Content"]},{"name":"Alert","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Icon","Body","Title","Content","Actions","Action","Close"]},{"name":"AppShell","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Sidebar","Main","Aside"]},{"name":"Avatar","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Group"]},{"name":"Badge","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"BentoGrid","category":"layout","status":"stable"},{"name":"Box","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Breadcrumbs","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Item","Separator"]},{"name":"Button","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"ButtonGroup","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Card","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Title","Description","Body","Footer"]},{"name":"Chart","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root","Tooltip","TooltipContent","Legend","LegendContent","preload"]},{"name":"Checkbox","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Chip","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Group"]},{"name":"CodeBlock","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Tabbed"]},{"name":"Collapsible","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root","Trigger","Content"]},{"name":"ColorPicker","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root","preload"]},{"name":"Combobox","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Input","Trigger","Content","Item","ItemIndicator","Empty","Group","GroupLabel"]},{"name":"Command","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Input","List","Item","Group","Empty","Separator"]},{"name":"ConversationList","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["DateSeparator","TypingIndicator"]},{"name":"DataTable","category":"display","status":"stable","compositionPattern":"simple","subComponents":["Root","Columns","preload"]},{"name":"DatePicker","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Calendar","Preset","preload"]},{"name":"Dialog","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Close","Header","Title","Description","Body","Footer"]},{"name":"Drawer","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Close","SwipeArea","Header","Title","Description","Body","Footer"]},{"name":"Editor","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Toolbar","ToolbarGroup","ToolbarButton","Separator","StatusIndicator","Content","StatusBar","preload"]},{"name":"EmptyState","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Icon","Title","Description","Actions"]},{"name":"Field","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Label","Control","Description","Error","Validity","Required"]},{"name":"Fieldset","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Legend","Description"]},{"name":"Form","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root","Actions"]},{"name":"Grid","category":"layout","status":"stable"},{"name":"Header","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["SkipLink","Trigger","Brand","Nav","NavItem","MobileNav","MobileNavLink","MobileNavActions","NavMenu","NavMenuItem","Search","Spacer","Actions"]},{"name":"Icon","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"IconButton","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Image","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Input","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Link","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"List","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Item"]},{"name":"Listbox","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Item","Group","Empty"]},{"name":"Loading","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Inline","Screen"]},{"name":"Main","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Description","Content","Footer"]},{"name":"Markdown","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root","preload"]},{"name":"Menu","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Item","CheckboxItem","RadioGroup","RadioItem","Group","GroupLabel","Separator","Submenu","SubmenuTrigger"]},{"name":"Message","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["Content","Actions","Timestamp","Avatar"]},{"name":"NavigationMenu","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["List","Item","Trigger","Content","Link","Indicator","Viewport","MobileBrand","MobileContent","MobileSection"]},{"name":"Pagination","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Previous","Next","Items","Item","Ellipsis"]},{"name":"Popover","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Close","Title","Description","Body","Footer"]},{"name":"Progress","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Root","Circular"]},{"name":"Prompt","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["Textarea","Toolbar","Tabs","Tab","Actions","Info","ActionButton","ModeButton","Select","Attach","Attachments","Usage","Submit"]},{"name":"RadioGroup","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Item"]},{"name":"ScrollArea","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Select","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Item","Group","GroupLabel"]},{"name":"Separator","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Sidebar","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Nav","Section","SectionAction","Item","SubItem","Submenu","Footer","Trigger","Overlay","CollapseToggle","Rail","MenuSkeleton"]},{"name":"Skeleton","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Text","Circle"]},{"name":"Slider","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Stack","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Switch","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Table","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root","Head","Body","Footer","Row","Cell","HeaderCell","Caption"]},{"name":"TableOfContents","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Item","Group"]},{"name":"Tabs","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["List","Tab","Panel"]},{"name":"Text","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Textarea","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Theme","category":"utilities","status":"stable","compositionPattern":"compound","subComponents":["Root","Provider","Toggle","useTheme"]},{"name":"ThinkingIndicator","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["Steps","Step"]},{"name":"Toast","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Provider"]},{"name":"ToggleGroup","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Item"]},{"name":"Tooltip","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Root","Provider"]},{"name":"VisuallyHidden","category":"utilities","status":"stable","compositionPattern":"compound","subComponents":["Root"]}],"edges":[{"s":"AppShell","t":"Sidebar","ty":"imports","w":1,"p":"source:AppShell/index.tsx"},{"s":"AppShell","t":"Sidebar","ty":"hook-depends","w":0.75,"p":"source:AppShell/index.tsx"},{"s":"ColorPicker","t":"Input","ty":"imports","w":1,"p":"source:ColorPicker/index.tsx"},{"s":"ConversationList","t":"Loading","ty":"imports","w":1,"p":"source:ConversationList/index.tsx"},{"s":"DataTable","t":"Checkbox","ty":"imports","w":1,"p":"source:DataTable/index.tsx"},{"s":"Header","t":"ScrollArea","ty":"imports","w":1,"p":"source:Header/index.tsx"},{"s":"Header","t":"Sidebar","ty":"hook-depends","w":0.75,"p":"source:Header/index.tsx"},{"s":"Main","t":"Stack","ty":"imports","w":1,"p":"source:Main/index.tsx"},{"s":"Message","t":"Avatar","ty":"imports","w":1,"p":"source:Message/index.tsx"},{"s":"Message","t":"Markdown","ty":"imports","w":1,"p":"source:Message/index.tsx"},{"s":"NavigationMenu","t":"Collapsible","ty":"imports","w":1,"p":"source:NavigationMenu/index.tsx"},{"s":"NavigationMenu","t":"ScrollArea","ty":"imports","w":1,"p":"source:NavigationMenu/index.tsx"},{"s":"Prompt","t":"Loading","ty":"imports","w":1,"p":"source:Prompt/index.tsx"},{"s":"Prompt","t":"Select","ty":"imports","w":1,"p":"source:Prompt/index.tsx"},{"s":"Sidebar","t":"Badge","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"Tooltip","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"Skeleton","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"Collapsible","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"ScrollArea","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"TableOfContents","t":"Text","ty":"imports","w":1,"p":"source:TableOfContents/index.tsx"},{"s":"ThinkingIndicator","t":"Loading","ty":"imports","w":1,"p":"source:ThinkingIndicator/index.tsx"},{"s":"AppShell","t":"Box","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Header","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Sidebar","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Icon","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Stack","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Text","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"Avatar","t":"Stack","ty":"renders","w":0.5,"p":"variant:Avatar"},{"s":"Badge","t":"Stack","ty":"renders","w":0.5,"p":"variant:Badge"},{"s":"BentoGrid","t":"Box","ty":"renders","w":0.5,"p":"variant:BentoGrid"},{"s":"Box","t":"Stack","ty":"renders","w":0.5,"p":"variant:Box"},{"s":"Button","t":"Stack","ty":"renders","w":0.5,"p":"variant:Button"},{"s":"ButtonGroup","t":"Button","ty":"renders","w":0.5,"p":"variant:ButtonGroup"},{"s":"ButtonGroup","t":"Stack","ty":"renders","w":0.5,"p":"variant:ButtonGroup"},{"s":"Card","t":"Text","ty":"renders","w":0.5,"p":"variant:Card"},{"s":"Chip","t":"Stack","ty":"renders","w":0.5,"p":"variant:Chip"},{"s":"CodeBlock","t":"Button","ty":"renders","w":0.5,"p":"variant:CodeBlock"},{"s":"CodeBlock","t":"Card","ty":"renders","w":0.5,"p":"variant:CodeBlock"},{"s":"Command","t":"Dialog","ty":"renders","w":0.5,"p":"variant:Command"},{"s":"Command","t":"Button","ty":"renders","w":0.5,"p":"variant:Command"},{"s":"ConversationList","t":"Message","ty":"renders","w":0.5,"p":"variant:ConversationList"},{"s":"ConversationList","t":"EmptyState","ty":"renders","w":0.5,"p":"variant:ConversationList"},{"s":"DataTable","t":"Stack","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"DataTable","t":"Avatar","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"DataTable","t":"Badge","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"DataTable","t":"Input","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"Dialog","t":"Button","ty":"renders","w":0.5,"p":"variant:Dialog"},{"s":"Drawer","t":"Button","ty":"renders","w":0.5,"p":"variant:Drawer"},{"s":"Drawer","t":"Stack","ty":"renders","w":0.5,"p":"variant:Drawer"},{"s":"Drawer","t":"Input","ty":"renders","w":0.5,"p":"variant:Drawer"},{"s":"Editor","t":"Button","ty":"renders","w":0.5,"p":"variant:Editor"},{"s":"EmptyState","t":"Button","ty":"renders","w":0.5,"p":"variant:EmptyState"},{"s":"Field","t":"Input","ty":"renders","w":0.5,"p":"variant:Field"},{"s":"Field","t":"Grid","ty":"renders","w":0.5,"p":"variant:Field"},{"s":"Fieldset","t":"Grid","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Field","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Input","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Textarea","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Select","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Checkbox","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Form","t":"Grid","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Field","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Input","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Checkbox","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Button","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Fieldset","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Select","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Textarea","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Switch","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"RadioGroup","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Grid","t":"Box","ty":"renders","w":0.5,"p":"variant:Grid"},{"s":"Grid","t":"Field","ty":"renders","w":0.5,"p":"variant:Grid"},{"s":"Grid","t":"Input","ty":"renders","w":0.5,"p":"variant:Grid"},{"s":"Header","t":"Box","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"Button","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"Input","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"NavigationMenu","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"Stack","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"IconButton","t":"Stack","ty":"renders","w":0.5,"p":"variant:IconButton"},{"s":"Link","t":"Stack","ty":"renders","w":0.5,"p":"variant:Link"},{"s":"Loading","t":"Stack","ty":"renders","w":0.5,"p":"variant:Loading"},{"s":"Main","t":"Box","ty":"renders","w":0.5,"p":"variant:Main"},{"s":"Menu","t":"Button","ty":"renders","w":0.5,"p":"variant:Menu"},{"s":"Message","t":"Button","ty":"renders","w":0.5,"p":"variant:Message"},{"s":"Popover","t":"Button","ty":"renders","w":0.5,"p":"variant:Popover"},{"s":"Popover","t":"Input","ty":"renders","w":0.5,"p":"variant:Popover"},{"s":"Progress","t":"Stack","ty":"renders","w":0.5,"p":"variant:Progress"},{"s":"ScrollArea","t":"Box","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"ScrollArea","t":"Stack","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"ScrollArea","t":"Text","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"ScrollArea","t":"Chip","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"Separator","t":"Box","ty":"renders","w":0.5,"p":"variant:Separator"},{"s":"Separator","t":"Text","ty":"renders","w":0.5,"p":"variant:Separator"},{"s":"Separator","t":"Stack","ty":"renders","w":0.5,"p":"variant:Separator"},{"s":"Sidebar","t":"Stack","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Sidebar","t":"Text","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Sidebar","t":"Button","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Sidebar","t":"Link","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Stack","t":"Box","ty":"renders","w":0.5,"p":"variant:Stack"},{"s":"Stack","t":"Button","ty":"renders","w":0.5,"p":"variant:Stack"},{"s":"Stack","t":"Text","ty":"renders","w":0.5,"p":"variant:Stack"},{"s":"Toast","t":"Stack","ty":"renders","w":0.5,"p":"variant:Toast"},{"s":"ToggleGroup","t":"Stack","ty":"renders","w":0.5,"p":"variant:ToggleGroup"},{"s":"Tooltip","t":"Button","ty":"renders","w":0.5,"p":"variant:Tooltip"},{"s":"Tooltip","t":"Stack","ty":"renders","w":0.5,"p":"variant:Tooltip"},{"s":"Card","t":"Tabs","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Card","t":"Stack","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Card","t":"Input","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Card","t":"Button","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Card","t":"Text","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Tabs","t":"Stack","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Tabs","t":"Input","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Tabs","t":"Button","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Tabs","t":"Text","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Stack","t":"Input","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Stack","t":"Button","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Stack","t":"Text","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Input","t":"Button","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Input","t":"Text","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Button","t":"Text","ty":"composes","w":0.5,"p":"block:Account Settings"},{"s":"Card","t":"Avatar","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Stack","t":"Avatar","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Text","t":"Avatar","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Card","t":"Skeleton","ty":"composes","w":0.5,"p":"block:Activity Feed Skeleton"},{"s":"Stack","t":"Skeleton","ty":"composes","w":0.5,"p":"block:Activity Feed Skeleton"},{"s":"Editor","t":"Button","ty":"composes","w":0.5,"p":"block:Blog Editor"},{"s":"Stack","t":"Box","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Stack","t":"ConversationList","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Stack","t":"Message","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Stack","t":"Prompt","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Box","t":"ConversationList","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Box","t":"Message","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Box","t":"Prompt","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"ConversationList","t":"Message","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"ConversationList","t":"Prompt","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Message","t":"Prompt","ty":"composes","w":0.5,"p":"block:Chat Interface"},{"s":"Card","t":"Separator","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Stack","t":"Separator","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Text","t":"Input","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Text","t":"Separator","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Text","t":"Button","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Input","t":"Separator","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Separator","t":"Button","ty":"composes","w":0.5,"p":"block:Checkout Form"},{"s":"Dialog","t":"Command","ty":"composes","w":0.5,"p":"block:Command Palette"},{"s":"Card","t":"Textarea","ty":"composes","w":0.5,"p":"block:Contact Form"},{"s":"Stack","t":"Textarea","ty":"composes","w":0.5,"p":"block:Contact Form"},{"s":"Input","t":"Textarea","ty":"composes","w":0.5,"p":"block:Contact Form"},{"s":"Textarea","t":"Button","ty":"composes","w":0.5,"p":"block:Contact Form"},{"s":"AppShell","t":"Header","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Sidebar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Sidebar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Card","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Card","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Text","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Text","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Badge","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Badge","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Badge","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Input","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Input","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"ThemeToggle","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Box","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"AppShell","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Box","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Header","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Box","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Sidebar","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Box","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Grid","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"Box","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Stack","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Box","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Text","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Icon","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Badge","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Icon","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Button","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Avatar","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Input","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Input","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Input","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Input","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Input","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Input","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"Separator","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Button","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"Table","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Separator","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Table","t":"ChartContainer","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Table","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Table","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Table","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Table","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Table","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartContainer","t":"ChartTooltip","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartContainer","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartContainer","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartContainer","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartContainer","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartTooltip","t":"Breadcrumbs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartTooltip","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartTooltip","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ChartTooltip","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Breadcrumbs","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Breadcrumbs","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Breadcrumbs","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ThemeToggle","t":"Progress","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"ThemeToggle","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Progress","t":"Tabs","ty":"composes","w":0.5,"p":"block:Dashboard Page"},{"s":"Card","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Skeleton"},{"s":"Grid","t":"Skeleton","ty":"composes","w":0.5,"p":"block:Dashboard Skeleton"},{"s":"EmptyState","t":"Icon","ty":"composes","w":0.5,"p":"block:Empty State"},{"s":"EmptyState","t":"Button","ty":"composes","w":0.5,"p":"block:Empty State"},{"s":"Card","t":"Accordion","ty":"composes","w":0.5,"p":"block:FAQ Section"},{"s":"Accordion","t":"Text","ty":"composes","w":0.5,"p":"block:FAQ Section"},{"s":"Icon","t":"Text","ty":"composes","w":0.5,"p":"block:Feature Grid"},{"s":"Stack","t":"Image","ty":"composes","w":0.5,"p":"block:Hero Section"},{"s":"Text","t":"Image","ty":"composes","w":0.5,"p":"block:Hero Section"},{"s":"Button","t":"Image","ty":"composes","w":0.5,"p":"block:Hero Section"},{"s":"Card","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Stack","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Input","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Button","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Text","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Header","t":"NavigationMenu","ty":"composes","w":0.5,"p":"block:Navigation Header"},{"s":"NavigationMenu","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Navigation Header"},{"s":"NavigationMenu","t":"Button","ty":"composes","w":0.5,"p":"block:Navigation Header"},{"s":"ThemeToggle","t":"Button","ty":"composes","w":0.5,"p":"block:Navigation Header"},{"s":"Card","t":"Pagination","ty":"composes","w":0.5,"p":"block:Paginated Table"},{"s":"Table","t":"Pagination","ty":"composes","w":0.5,"p":"block:Paginated Table"},{"s":"Card","t":"Image","ty":"composes","w":0.5,"p":"block:Product Card"},{"s":"Image","t":"Stack","ty":"composes","w":0.5,"p":"block:Product Card"},{"s":"Image","t":"Text","ty":"composes","w":0.5,"p":"block:Product Card"},{"s":"Image","t":"Badge","ty":"composes","w":0.5,"p":"block:Product Card"},{"s":"Image","t":"Button","ty":"composes","w":0.5,"p":"block:Product Card"},{"s":"Card","t":"Checkbox","ty":"composes","w":0.5,"p":"block:Registration Form"},{"s":"Stack","t":"Checkbox","ty":"composes","w":0.5,"p":"block:Registration Form"},{"s":"Input","t":"Checkbox","ty":"composes","w":0.5,"p":"block:Registration Form"},{"s":"Checkbox","t":"Button","ty":"composes","w":0.5,"p":"block:Registration Form"},{"s":"Checkbox","t":"Text","ty":"composes","w":0.5,"p":"block:Registration Form"},{"s":"Checkbox","t":"Link","ty":"composes","w":0.5,"p":"block:Registration Form"},{"s":"Drawer","t":"Form","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Drawer","t":"Field","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Drawer","t":"Button","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Drawer","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Form","t":"Field","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Form","t":"Button","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Form","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Field","t":"Button","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Field","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Button","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Drawer"},{"s":"Card","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Panel"},{"s":"Stack","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Panel"},{"s":"Text","t":"Switch","ty":"composes","w":0.5,"p":"block:Settings Panel"},{"s":"Image","t":"Separator","ty":"composes","w":0.5,"p":"block:Shopping Cart"},{"s":"Stack","t":"ThinkingIndicator","ty":"composes","w":0.5,"p":"block:Thinking States"},{"s":"Card","t":"ThinkingIndicator","ty":"composes","w":0.5,"p":"block:Thinking States"},{"s":"Accordion","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Use Tabs for horizontal switching between related views"},{"s":"Accordion","t":"Dialog","ty":"alternative-to","w":1,"p":"relation","no":"Use Dialog for focused content that interrupts the flow"},{"s":"Alert","t":"Badge","ty":"alternative-to","w":1,"p":"relation","no":"Use Badge for compact, inline status labels"},{"s":"Alert","t":"Toast","ty":"alternative-to","w":1,"p":"relation","no":"Use Toast for transient notifications that auto-dismiss"},{"s":"Alert","t":"Dialog","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Dialog for blocking confirmations"},{"s":"Theme","t":"AppShell","ty":"parent-of","w":1,"p":"relation","no":"AppShell should be wrapped in ThemeProvider"},{"s":"AppShell","t":"Header","ty":"parent-of","w":1,"p":"relation","no":"Header is placed inside AppShell.Header"},{"s":"AppShell","t":"Sidebar","ty":"parent-of","w":1,"p":"relation","no":"Sidebar content goes inside AppShell.Sidebar"},{"s":"Avatar","t":"Image","ty":"alternative-to","w":1,"p":"relation","no":"Use Image for content pictures that are not a person or entity"},{"s":"Avatar","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with Badge to show presence or role beside a name"},{"s":"Badge","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for prominent, longer messages with actions"},{"s":"Badge","t":"Chip","ty":"sibling-of","w":0.75,"p":"relation","no":"Chip is interactive (clickable/filterable); Badge is display-only"},{"s":"BentoGrid","t":"Grid","ty":"alternative-to","w":1,"p":"relation","no":"Use Grid for uniform layouts; BentoGrid for asymmetric spans with built-in surfaces"},{"s":"BentoGrid","t":"Card","ty":"sibling-of","w":0.75,"p":"relation","no":"BentoGrid.Item has built-in surface styling similar to Card"},{"s":"Box","t":"Stack","ty":"alternative-to","w":1,"p":"relation","no":"Use Stack for directional layouts with gap"},{"s":"Box","t":"Grid","ty":"alternative-to","w":1,"p":"relation","no":"Use Grid for column-based layouts"},{"s":"Box","t":"Card","ty":"alternative-to","w":1,"p":"relation","no":"Use Card for content containers with structure"},{"s":"Breadcrumbs","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Use Tabs for flat, non-hierarchical navigation"},{"s":"Button","t":"Link","ty":"alternative-to","w":1,"p":"relation","no":"Use Link for navigation without action context"},{"s":"ButtonGroup","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Use ButtonGroup for related action sets"},{"s":"ButtonGroup","t":"Stack","ty":"alternative-to","w":1,"p":"relation","no":"Use Stack for more general layout needs"},{"s":"Grid","t":"Card","ty":"parent-of","w":1,"p":"relation","no":"Use Grid + Card for responsive card layouts"},{"s":"Card","t":"List","ty":"alternative-to","w":1,"p":"relation","no":"Use List for linear, text-first layouts"},{"s":"Card","t":"Chart","ty":"parent-of","w":1,"p":"relation","no":"Charts are typically placed inside Cards"},{"s":"Chart","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress for single-value completion"},{"s":"Chart","t":"Table","ty":"sibling-of","w":0.75,"p":"relation","no":"Combine with Table for full data views"},{"s":"Checkbox","t":"Switch","ty":"alternative-to","w":1,"p":"relation","no":"Use Switch for immediate-effect settings"},{"s":"Checkbox","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Checkbox handles boolean; Input handles text"},{"s":"Chip","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Badge is display-only; Chip is interactive"},{"s":"Chip","t":"ToggleGroup","ty":"alternative-to","w":1,"p":"relation","no":"Use ToggleGroup for mutually exclusive options"},{"s":"Chip","t":"Button","ty":"alternative-to","w":1,"p":"relation","no":"Use Button for primary actions, Chip for selection/filtering"},{"s":"Card","t":"CodeBlock","ty":"parent-of","w":1,"p":"relation","no":"Can be wrapped in Card for additional context"},{"s":"CodeBlock","t":"Tabs","ty":"parent-of","w":1,"p":"relation","no":"Use in Tabs for showing code in multiple languages"},{"s":"Collapsible","t":"Accordion","ty":"alternative-to","w":1,"p":"relation","no":"Use Accordion for multiple exclusive collapsible sections"},{"s":"Collapsible","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for dropdown navigation with actions"},{"s":"ColorPicker","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"ColorPicker is a specialized input for colors"},{"s":"ColorPicker","t":"RadioGroup","ty":"alternative-to","w":1,"p":"relation","no":"Use RadioGroup for predefined color choices"},{"s":"Field","t":"ColorPicker","ty":"parent-of","w":1,"p":"relation","no":"ColorPicker uses Field internally for structure"},{"s":"Combobox","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select when search/filtering is not needed"},{"s":"Combobox","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Input for free-form text entry"},{"s":"Combobox","t":"Listbox","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Listbox for inline option lists"},{"s":"Command","t":"Dialog","ty":"sibling-of","w":0.75,"p":"relation","no":"Compose inside Dialog for modal command palette"},{"s":"Command","t":"Listbox","ty":"sibling-of","w":0.75,"p":"relation","no":"Command uses Listbox-like keyboard navigation internally"},{"s":"Command","t":"Combobox","ty":"alternative-to","w":1,"p":"relation","no":"Use Combobox for form field selection with search"},{"s":"ConversationList","t":"Message","ty":"parent-of","w":1,"p":"relation","no":"ConversationList contains Message components"},{"s":"ConversationList","t":"ThinkingIndicator","ty":"parent-of","w":1,"p":"relation","no":"Show ThinkingIndicator at bottom while awaiting response"},{"s":"ConversationList","t":"Prompt","ty":"sibling-of","w":0.75,"p":"relation","no":"Typically paired with Prompt for input"},{"s":"DataTable","t":"Table","ty":"alternative-to","w":1,"p":"relation","no":"Use Table for simple semantic HTML tables"},{"s":"DataTable","t":"EmptyState","ty":"sibling-of","w":0.75,"p":"relation","no":"Use EmptyState for empty table states"},{"s":"DataTable","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Badge for status columns"},{"s":"DataTable","t":"Menu","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Menu for filter dropdowns"},{"s":"DataTable","t":"Checkbox","ty":"sibling-of","w":0.75,"p":"relation","no":"Built-in checkbox selection via showCheckbox"},{"s":"DatePicker","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for choosing from a list of options"},{"s":"DatePicker","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Input for free-form text date entry"},{"s":"DatePicker","t":"Popover","ty":"composes","w":0.5,"p":"relation","no":"DatePicker uses Popover for the calendar dropdown"},{"s":"Dialog","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for non-modal contextual content"},{"s":"Dialog","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action lists"},{"s":"Dialog","t":"Alert","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Alert for inline notifications"},{"s":"Drawer","t":"Dialog","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Dialog for centered modal overlays"},{"s":"Drawer","t":"Sidebar","ty":"alternative-to","w":1,"p":"relation","no":"Use Sidebar for permanent side navigation"},{"s":"Drawer","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for small contextual content"},{"s":"Editor","t":"Prompt","ty":"sibling-of","w":0.75,"p":"relation","no":"Prompt is for AI/chat input; Editor is for long-form content editing"},{"s":"Editor","t":"Textarea","ty":"alternative-to","w":1,"p":"relation","no":"Use Textarea for simple multi-line input without formatting toolbar"},{"s":"Editor","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for single-line text input"},{"s":"EmptyState","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for error states with retry"},{"s":"EmptyState","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress/Spinner for loading states"},{"s":"Field","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for simple fields with built-in label/error"},{"s":"Form","t":"Field","ty":"parent-of","w":1,"p":"relation","no":"Wrap in Form for server-side error distribution"},{"s":"Field","t":"Fieldset","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Fieldset to group related fields"},{"s":"Fieldset","t":"Field","ty":"sibling-of","w":0.75,"p":"relation","no":"Contains Field components"},{"s":"Form","t":"Fieldset","ty":"parent-of","w":1,"p":"relation","no":"Used within a Form"},{"s":"Fieldset","t":"Card","ty":"alternative-to","w":1,"p":"relation","no":"Use Card for non-form visual grouping"},{"s":"Form","t":"Field","ty":"sibling-of","w":0.75,"p":"relation","no":"Contains Field components for error distribution"},{"s":"Form","t":"Fieldset","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Fieldset to group fields within a Form"},{"s":"Form","t":"Button","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Button type=\"submit\" for form submission"},{"s":"Grid","t":"Separator","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Separator between grid sections"},{"s":"Header","t":"Sidebar","ty":"sibling-of","w":0.75,"p":"relation","no":"Header.Trigger toggles Sidebar on mobile"},{"s":"Header","t":"Theme","ty":"parent-of","w":1,"p":"relation","no":"ThemeToggle is commonly placed in Header.Actions"},{"s":"Header","t":"NavigationMenu","ty":"parent-of","w":1,"p":"relation","no":"Use NavigationMenu inside Header for rich dropdown nav with auto mobile drawer"},{"s":"Icon","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Use inside icon-only buttons with VisuallyHidden label"},{"s":"Icon","t":"VisuallyHidden","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with VisuallyHidden for accessible icon-only elements"},{"s":"Icon","t":"Badge","ty":"parent-of","w":1,"p":"relation","no":"Can be used as badge icon prop"},{"s":"IconButton","t":"Button","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Button when the action should have a visible text label or broader layout variants"},{"s":"Image","t":"Card","ty":"parent-of","w":1,"p":"relation","no":"Common pattern to use Image at top of product cards"},{"s":"Image","t":"Avatar","ty":"alternative-to","w":1,"p":"relation","no":"Use Avatar for user profile pictures"},{"s":"Input","t":"Textarea","ty":"alternative-to","w":1,"p":"relation","no":"Use Textarea for multi-line text input"},{"s":"Input","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select when choosing from predefined options"},{"s":"Field","t":"Input","ty":"parent-of","w":1,"p":"relation","no":"Use Field for advanced form composition and custom controls"},{"s":"Link","t":"Button","ty":"alternative-to","w":1,"p":"relation","no":"Use Button for primary actions, Link for navigation"},{"s":"Text","t":"Link","ty":"parent-of","w":1,"p":"relation","no":"Links often appear within Text components"},{"s":"List","t":"Icon","ty":"parent-of","w":1,"p":"relation","no":"Use Icon as List.Item icon prop"},{"s":"List","t":"Stack","ty":"alternative-to","w":1,"p":"relation","no":"Use Stack for non-semantic vertical lists"},{"s":"Listbox","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with Input for search/autocomplete patterns"},{"s":"Listbox","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu when you need a trigger button"},{"s":"Listbox","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for form field selection"},{"s":"Listbox","t":"List","ty":"alternative-to","w":1,"p":"relation","no":"Use List for static, non-interactive lists"},{"s":"Markdown","t":"Text","ty":"alternative-to","w":1,"p":"relation","no":"Use Text for plain, non-markdown text"},{"s":"Message","t":"Markdown","ty":"parent-of","w":1,"p":"relation","no":"Message wraps Markdown when markdown prop is true"},{"s":"Menu","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for form field selection"},{"s":"Menu","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for rich non-action content"},{"s":"Message","t":"Avatar","ty":"parent-of","w":1,"p":"relation","no":"Use Avatar component for custom avatar content"},{"s":"Message","t":"ThinkingIndicator","ty":"sibling-of","w":0.75,"p":"relation","no":"Show ThinkingIndicator while awaiting assistant response"},{"s":"NavigationMenu","t":"Header","ty":"sibling-of","w":0.75,"p":"relation","no":"Place NavigationMenu inside Header for site navigation"},{"s":"NavigationMenu","t":"Sidebar","ty":"alternative-to","w":1,"p":"relation","no":"Use Sidebar for persistent side navigation, NavigationMenu for header dropdowns"},{"s":"NavigationMenu","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action menus (role=menu), NavigationMenu for site navigation (disclosure pattern)"},{"s":"NavigationMenu","t":"Breadcrumbs","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Breadcrumbs for hierarchical page trail, NavigationMenu for site-level navigation"},{"s":"Pagination","t":"Table","ty":"sibling-of","w":0.75,"p":"relation","no":"Commonly paired for table pagination"},{"s":"Pagination","t":"Listbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Listbox for small sets of options"},{"s":"Popover","t":"Tooltip","ty":"alternative-to","w":1,"p":"relation","no":"Use Tooltip for brief, non-interactive hints"},{"s":"Popover","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action lists"},{"s":"Popover","t":"Dialog","ty":"alternative-to","w":1,"p":"relation","no":"Use Dialog for blocking interactions"},{"s":"Progress","t":"Badge","ty":"alternative-to","w":1,"p":"relation","no":"Use Badge for status without percentage"},{"s":"Progress","t":"Alert","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Alert for completion messages"},{"s":"Prompt","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for simple single-line text input"},{"s":"Prompt","t":"Textarea","ty":"alternative-to","w":1,"p":"relation","no":"Use Textarea for multi-line without toolbar"},{"s":"RadioGroup","t":"Checkbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Checkbox for multiple selections"},{"s":"RadioGroup","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for many options or limited space"},{"s":"RadioGroup","t":"Switch","ty":"alternative-to","w":1,"p":"relation","no":"Use Switch for binary on/off choices"},{"s":"Select","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action-based dropdowns"},{"s":"Select","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Input for free-form text entry"},{"s":"Select","t":"Checkbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Checkbox group for multiple selections"},{"s":"Separator","t":"Card","ty":"sibling-of","w":0.75,"p":"relation","no":"Cards provide stronger visual grouping"},{"s":"Sidebar","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Use Tabs for in-page section navigation"},{"s":"Sidebar","t":"Menu","ty":"composes","w":0.5,"p":"relation","no":"Use Menu for contextual actions within sidebar"},{"s":"Skeleton","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress for determinate loading"},{"s":"Slider","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for precise numeric entry"},{"s":"Slider","t":"Progress","ty":"sibling-of","w":0.75,"p":"relation","no":"Similar visual, but Progress is read-only"},{"s":"Stack","t":"Grid","ty":"alternative-to","w":1,"p":"relation","no":"Use Grid for complex 2D layouts"},{"s":"Stack","t":"ButtonGroup","ty":"sibling-of","w":0.75,"p":"relation","no":"ButtonGroup is specialized for buttons"},{"s":"Stack","t":"Box","ty":"sibling-of","w":0.75,"p":"relation","no":"Box for single-element styling"},{"s":"Switch","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Input handles text/number entry; Switch handles boolean state"},{"s":"Switch","t":"Checkbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Checkbox when change requires form submission"},{"s":"Table","t":"DataTable","ty":"alternative-to","w":1,"p":"relation","no":"Use DataTable for sorting, selection, and TanStack features"},{"s":"TableOfContents","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Tabs for switching views, TOC for scrolling to sections"},{"s":"Tabs","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for many options in compact space"},{"s":"Tabs","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action-based navigation"},{"s":"Text","t":"Link","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Link for clickable text"},{"s":"Text","t":"CodeBlock","ty":"alternative-to","w":1,"p":"relation","no":"Use CodeBlock for code display"},{"s":"Text","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Badge for labels/tags"},{"s":"Textarea","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for single-line text"},{"s":"Theme","t":"AppShell","ty":"sibling-of","w":0.75,"p":"relation","no":"ThemeProvider typically wraps AppShell"},{"s":"ThinkingIndicator","t":"Message","ty":"sibling-of","w":0.75,"p":"relation","no":"Show ThinkingIndicator while waiting for assistant message"},{"s":"ThinkingIndicator","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress for determinate progress"},{"s":"Toast","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for persistent inline messages"},{"s":"Toast","t":"Dialog","ty":"alternative-to","w":1,"p":"relation","no":"Use Dialog for messages requiring user action"},{"s":"ToggleGroup","t":"RadioGroup","ty":"alternative-to","w":1,"p":"relation","no":"RadioGroup for form-style single selection"},{"s":"ToggleGroup","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Tabs for content panel switching"},{"s":"ToggleGroup","t":"Switch","ty":"sibling-of","w":0.75,"p":"relation","no":"Switch for single on/off control"},{"s":"Tooltip","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for interactive or longer content"},{"s":"Tooltip","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for critical information that must be visible"},{"s":"VisuallyHidden","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Use inside icon-only buttons for accessible labels"},{"s":"VisuallyHidden","t":"Icon","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with icons to provide text alternatives"}],"health":{"orphans":[],"hubs":[{"name":"Stack","degree":64},{"name":"Button","degree":60},{"name":"Input","degree":50},{"name":"Card","degree":42},{"name":"Text","degree":42},{"name":"Sidebar","degree":39},{"name":"Box","degree":36},{"name":"Grid","degree":34},{"name":"Header","degree":34},{"name":"Badge","degree":33}],"compositionCoverage":56,"connectedComponents":[["Accordion","Alert","AppShell","Avatar","Badge","BentoGrid","Box","Breadcrumbs","Button","ButtonGroup","Card","Chart","ChartContainer","ChartTooltip","Checkbox","Chip","CodeBlock","Collapsible","ColorPicker","Combobox","Command","ConversationList","DataTable","DatePicker","Dialog","Drawer","Editor","EmptyState","Field","Fieldset","Form","Grid","Header","Icon","IconButton","Image","Input","Link","List","Listbox","Loading","Main","Markdown","Menu","Message","NavigationMenu","Pagination","Popover","Progress","Prompt","RadioGroup","ScrollArea","Select","Separator","Sidebar","Skeleton","Slider","Stack","Switch","Table","TableOfContents","Tabs","Text","Textarea","Theme","ThemeToggle","ThinkingIndicator","Toast","ToggleGroup","Tooltip","VisuallyHidden"]],"averageDegree":15.97,"nodeCount":68,"edgeCount":543}},"performanceSummary":{"preset":"standard","budget":15360,"total":68,"overBudget":3,"tiers":{"lightweight":58,"moderate":7,"heavy":3}}}
|
|
1
|
+
{"version":"1.0.0","generatedAt":"2026-09-07T16:46:04.054Z","generatorVersion":"sha256:deea39c65b3a3a6dc24f36bcd4934c99c5a805d61ac68f207cc41c1029339282","buildInputs":["fragments.config.ts","src/assets/fragments-logo.tsx","src/assets/fragments-wordmark.tsx","src/assets/nav-glyph.tsx","src/blocks/ActivityFeed.block.ts","src/blocks/DashboardLayout.block.ts","src/blocks/LoginForm.block.ts","src/blocks/StatsCard.block.ts","src/blocks/components/ActivityFeed.tsx","src/blocks/components/DashboardLayout.tsx","src/blocks/components/LoginForm.tsx","src/blocks/components/StatsCard.tsx","src/components/Accordion/Accordion.contract.json","src/components/Accordion/Accordion.module.scss","src/components/Accordion/Accordion.stories.tsx","src/components/Accordion/index.tsx","src/components/Alert/Alert.contract.json","src/components/Alert/Alert.module.scss","src/components/Alert/Alert.stories.tsx","src/components/Alert/index.tsx","src/components/AppShell/AppShell.contract.json","src/components/AppShell/AppShell.module.scss","src/components/AppShell/AppShell.stories.tsx","src/components/AppShell/index.tsx","src/components/Avatar/Avatar.contract.json","src/components/Avatar/Avatar.module.scss","src/components/Avatar/Avatar.stories.tsx","src/components/Avatar/index.tsx","src/components/Badge/Badge.contract.json","src/components/Badge/Badge.module.scss","src/components/Badge/Badge.stories.tsx","src/components/Badge/index.tsx","src/components/BentoGrid/BentoGrid.contract.json","src/components/BentoGrid/BentoGrid.module.scss","src/components/BentoGrid/BentoGrid.stories.tsx","src/components/BentoGrid/index.tsx","src/components/Box/Box.contract.json","src/components/Box/Box.module.scss","src/components/Box/Box.stories.tsx","src/components/Box/index.tsx","src/components/Breadcrumbs/Breadcrumbs.contract.json","src/components/Breadcrumbs/Breadcrumbs.module.scss","src/components/Breadcrumbs/Breadcrumbs.stories.tsx","src/components/Breadcrumbs/index.tsx","src/components/Button/Button.fragment.tsx","src/components/Button/Button.module.scss","src/components/Button/Button.stories.tsx","src/components/Button/index.tsx","src/components/ButtonGroup/ButtonGroup.contract.json","src/components/ButtonGroup/ButtonGroup.module.scss","src/components/ButtonGroup/ButtonGroup.stories.tsx","src/components/ButtonGroup/index.tsx","src/components/Card/Card.consumer-fixture.module.scss","src/components/Card/Card.fragment.tsx","src/components/Card/Card.module.scss","src/components/Card/Card.stories.tsx","src/components/Card/index.tsx","src/components/Chart/Chart.contract.json","src/components/Chart/Chart.module.scss","src/components/Chart/Chart.stories.tsx","src/components/Chart/index.tsx","src/components/Checkbox/Checkbox.contract.json","src/components/Checkbox/Checkbox.module.scss","src/components/Checkbox/Checkbox.stories.tsx","src/components/Checkbox/index.tsx","src/components/Chip/Chip.contract.json","src/components/Chip/Chip.module.scss","src/components/Chip/Chip.stories.tsx","src/components/Chip/index.tsx","src/components/CodeBlock/CodeBlock.contract.json","src/components/CodeBlock/CodeBlock.module.scss","src/components/CodeBlock/CodeBlock.stories.tsx","src/components/CodeBlock/index.tsx","src/components/Collapsible/Collapsible.contract.json","src/components/Collapsible/Collapsible.module.scss","src/components/Collapsible/Collapsible.stories.tsx","src/components/Collapsible/index.tsx","src/components/ColorPicker/ColorPicker.contract.json","src/components/ColorPicker/ColorPicker.module.scss","src/components/ColorPicker/ColorPicker.stories.tsx","src/components/ColorPicker/index.tsx","src/components/Combobox/Combobox.contract.json","src/components/Combobox/Combobox.module.scss","src/components/Combobox/Combobox.stories.tsx","src/components/Combobox/index.tsx","src/components/Command/Command.contract.json","src/components/Command/Command.module.scss","src/components/Command/Command.stories.tsx","src/components/Command/index.tsx","src/components/ComponentDefaults/ComponentDefaults.contract.json","src/components/ComponentDefaults/index.tsx","src/components/ConversationList/ConversationList.contract.json","src/components/ConversationList/ConversationList.module.scss","src/components/ConversationList/ConversationList.stories.tsx","src/components/ConversationList/index.tsx","src/components/DataTable/DataTable.fragment.tsx","src/components/DataTable/DataTable.icons.tsx","src/components/DataTable/DataTable.module.scss","src/components/DataTable/DataTable.stories.tsx","src/components/DataTable/DataTable.support.tsx","src/components/DataTable/DataTable.virtual.tsx","src/components/DataTable/index.tsx","src/components/DatePicker/DatePicker.contract.json","src/components/DatePicker/DatePicker.module.scss","src/components/DatePicker/DatePicker.stories.tsx","src/components/DatePicker/index.tsx","src/components/Dialog/Dialog.fragment.tsx","src/components/Dialog/Dialog.module.scss","src/components/Dialog/Dialog.stories.tsx","src/components/Dialog/index.tsx","src/components/Drawer/Drawer.contract.json","src/components/Drawer/Drawer.module.scss","src/components/Drawer/Drawer.stories.tsx","src/components/Drawer/index.tsx","src/components/Editor/Editor.contract.json","src/components/Editor/Editor.module.scss","src/components/Editor/Editor.stories.tsx","src/components/Editor/index.tsx","src/components/EmptyState/EmptyState.contract.json","src/components/EmptyState/EmptyState.module.scss","src/components/EmptyState/EmptyState.stories.tsx","src/components/EmptyState/index.tsx","src/components/Field/Field.contract.json","src/components/Field/Field.module.scss","src/components/Field/Field.stories.tsx","src/components/Field/index.tsx","src/components/Fieldset/Fieldset.contract.json","src/components/Fieldset/Fieldset.module.scss","src/components/Fieldset/Fieldset.stories.tsx","src/components/Fieldset/index.tsx","src/components/Form/Form.contract.json","src/components/Form/Form.module.scss","src/components/Form/Form.stories.tsx","src/components/Form/index.tsx","src/components/Grid/Grid.contract.json","src/components/Grid/Grid.module.scss","src/components/Grid/Grid.stories.tsx","src/components/Grid/index.tsx","src/components/Header/Header.contract.json","src/components/Header/Header.module.scss","src/components/Header/Header.stories.tsx","src/components/Header/index.tsx","src/components/Icon/Icon.contract.json","src/components/Icon/Icon.module.scss","src/components/Icon/Icon.stories.tsx","src/components/Icon/index.tsx","src/components/IconButton/IconButton.contract.json","src/components/IconButton/IconButton.module.scss","src/components/IconButton/IconButton.stories.tsx","src/components/IconButton/index.tsx","src/components/Image/Image.contract.json","src/components/Image/Image.module.scss","src/components/Image/Image.stories.tsx","src/components/Image/index.tsx","src/components/Input/Input.contract.json","src/components/Input/Input.module.scss","src/components/Input/Input.stories.tsx","src/components/Input/index.tsx","src/components/Link/Link.contract.json","src/components/Link/Link.module.scss","src/components/Link/Link.stories.tsx","src/components/Link/index.tsx","src/components/List/List.contract.json","src/components/List/List.module.scss","src/components/List/List.stories.tsx","src/components/List/index.tsx","src/components/Listbox/Listbox.contract.json","src/components/Listbox/Listbox.module.scss","src/components/Listbox/Listbox.stories.tsx","src/components/Listbox/index.tsx","src/components/Loading/Loading.contract.json","src/components/Loading/Loading.module.scss","src/components/Loading/Loading.stories.tsx","src/components/Loading/index.tsx","src/components/Main/Main.contract.json","src/components/Main/Main.module.scss","src/components/Main/Main.stories.tsx","src/components/Main/index.tsx","src/components/Markdown/Markdown.contract.json","src/components/Markdown/Markdown.module.scss","src/components/Markdown/Markdown.stories.tsx","src/components/Markdown/index.tsx","src/components/Menu/Menu.contract.json","src/components/Menu/Menu.module.scss","src/components/Menu/Menu.stories.tsx","src/components/Menu/index.tsx","src/components/Message/Message.contract.json","src/components/Message/Message.module.scss","src/components/Message/Message.stories.tsx","src/components/Message/index.tsx","src/components/NavigationMenu/NavigationMenu.contract.json","src/components/NavigationMenu/NavigationMenu.module.scss","src/components/NavigationMenu/NavigationMenu.stories.tsx","src/components/NavigationMenu/index.tsx","src/components/Pagination/Pagination.contract.json","src/components/Pagination/Pagination.module.scss","src/components/Pagination/Pagination.stories.tsx","src/components/Pagination/index.tsx","src/components/Popover/Popover.contract.json","src/components/Popover/Popover.module.scss","src/components/Popover/Popover.stories.tsx","src/components/Popover/index.tsx","src/components/Progress/Progress.contract.json","src/components/Progress/Progress.module.scss","src/components/Progress/Progress.stories.tsx","src/components/Progress/index.tsx","src/components/Prompt/Prompt.contract.json","src/components/Prompt/Prompt.module.scss","src/components/Prompt/Prompt.stories.tsx","src/components/Prompt/index.tsx","src/components/RadioGroup/RadioGroup.contract.json","src/components/RadioGroup/RadioGroup.module.scss","src/components/RadioGroup/RadioGroup.stories.tsx","src/components/RadioGroup/index.tsx","src/components/ScrollArea/ScrollArea.contract.json","src/components/ScrollArea/ScrollArea.module.scss","src/components/ScrollArea/ScrollArea.stories.tsx","src/components/ScrollArea/index.tsx","src/components/Select/Select.fragment.tsx","src/components/Select/Select.module.scss","src/components/Select/Select.stories.tsx","src/components/Select/index.tsx","src/components/Separator/Separator.contract.json","src/components/Separator/Separator.module.scss","src/components/Separator/Separator.stories.tsx","src/components/Separator/index.tsx","src/components/Sidebar/Sidebar.contract.json","src/components/Sidebar/Sidebar.module.scss","src/components/Sidebar/Sidebar.stories.tsx","src/components/Sidebar/index.tsx","src/components/Skeleton/Skeleton.contract.json","src/components/Skeleton/Skeleton.module.scss","src/components/Skeleton/Skeleton.stories.tsx","src/components/Skeleton/index.tsx","src/components/Slider/Slider.contract.json","src/components/Slider/Slider.module.scss","src/components/Slider/Slider.stories.tsx","src/components/Slider/index.tsx","src/components/Stack/Stack.contract.json","src/components/Stack/Stack.module.scss","src/components/Stack/Stack.stories.tsx","src/components/Stack/index.tsx","src/components/Switch/Switch.contract.json","src/components/Switch/Switch.module.scss","src/components/Switch/Switch.stories.tsx","src/components/Switch/index.tsx","src/components/Table/Table.contract.json","src/components/Table/Table.module.scss","src/components/Table/Table.stories.tsx","src/components/Table/index.tsx","src/components/TableOfContents/TableOfContents.contract.json","src/components/TableOfContents/TableOfContents.module.scss","src/components/TableOfContents/TableOfContents.stories.tsx","src/components/TableOfContents/index.tsx","src/components/Tabs/Tabs.contract.json","src/components/Tabs/Tabs.module.scss","src/components/Tabs/Tabs.stories.tsx","src/components/Tabs/index.tsx","src/components/Text/Text.contract.json","src/components/Text/Text.module.scss","src/components/Text/Text.stories.tsx","src/components/Text/index.tsx","src/components/Textarea/Textarea.contract.json","src/components/Textarea/Textarea.module.scss","src/components/Textarea/Textarea.stories.tsx","src/components/Textarea/index.tsx","src/components/Theme/Theme.contract.json","src/components/Theme/Theme.stories.tsx","src/components/Theme/index.tsx","src/components/ThemeToggle/ThemeToggle.module.scss","src/components/ThinkingIndicator/ThinkingIndicator.contract.json","src/components/ThinkingIndicator/ThinkingIndicator.module.scss","src/components/ThinkingIndicator/ThinkingIndicator.stories.tsx","src/components/ThinkingIndicator/index.tsx","src/components/Toast/Toast.contract.json","src/components/Toast/Toast.module.scss","src/components/Toast/Toast.stories.tsx","src/components/Toast/index.tsx","src/components/ToggleGroup/ToggleGroup.contract.json","src/components/ToggleGroup/ToggleGroup.module.scss","src/components/ToggleGroup/ToggleGroup.stories.tsx","src/components/ToggleGroup/index.tsx","src/components/Tooltip/Tooltip.contract.json","src/components/Tooltip/Tooltip.module.scss","src/components/Tooltip/Tooltip.stories.tsx","src/components/Tooltip/index.tsx","src/components/VisuallyHidden/VisuallyHidden.contract.json","src/components/VisuallyHidden/VisuallyHidden.module.scss","src/components/VisuallyHidden/VisuallyHidden.stories.tsx","src/components/VisuallyHidden/index.tsx","src/measurements/MeasurementTargets.stories.tsx","src/recipes/_action.scss","src/recipes/_boolean-range.scss","src/recipes/_feedback.scss","src/recipes/_field.scss","src/recipes/_layout.scss","src/recipes/_navigation.scss","src/recipes/_overlay.scss","src/recipes/_popup.scss","src/recipes/_prose.scss","src/recipes/_representation.scss","src/recipes/_segmented.scss","src/recipes/_surface.scss","src/recipes/_table-chrome.scss","src/recipes/_target.scss","src/recipes/_typography.scss","src/test/utils.tsx","src/tokens/_component-properties.scss","src/tokens/_measurements.catalog.generated.css","src/tokens/_variables.scss","src/utils/a11y.tsx"],"packageName":"@usefragments/ui","fragments":{"Accordion":{"filePath":"src/components/Accordion/index.tsx","meta":{"name":"Accordion","description":"Stacks sections that expand one at a time, or several at once.","category":"layout","tags":["accordion","collapse","expand","disclosure","faq"],"status":"stable"},"usage":{"when":["Answers most readers skip","Settings grouped by area","Long forms broken into stages","Navigation with nested children"],"whenNot":["Content everyone needs to read","A line or two — just show it","Steps in an order (use Stepper)","Switching between panels (use Tabs)"],"guidelines":["Headers should say what is inside","Single mode when one answer at a time is enough","Multiple mode when sections get compared","Open the section most readers came for","Never nest an accordion inside an accordion"],"accessibility":["Keyboard navigation with Enter/Space to toggle","Uses proper ARIA expanded/controls attributes","Focus is visible on accordion triggers"]},"props":{"type":{"type":"enum","description":"Whether one or multiple items can be open","default":"single","required":false,"values":["single","multiple"]},"value":{"type":"union","description":"Controlled open item(s): string in single mode, string[] in multiple mode","required":false},"defaultValue":{"type":"union","description":"Initially open item(s): string in single mode, string[] in multiple mode","required":false},"onValueChange":{"type":"union","description":"Called when open items change (single: string | undefined, multiple: string[])","required":false},"children":{"type":"node","description":"Accordion items (use Accordion.Item with Accordion.Trigger and Accordion.Content)","required":true},"collapsible":{"type":"boolean","description":"Whether all items can be closed (single mode only)","default":"false","required":false},"headingLevel":{"type":"union","description":"Semantic heading level for accordion triggers","default":"3","required":false,"values":["2","3","4","5","6"]}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for horizontal switching between related views"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for focused content that interrupts the flow"},{"component":"Card","relationship":"complementary","note":"Accordion items can contain Card-like content"}],"variants":[{"name":"Basic","description":"Opening one section closes the last.","code":"import { Accordion } from '@/components/Accordion';\n\n<Accordion type=\"single\" collapsible defaultValue=\"item-1\">\n <Accordion.Item value=\"item-1\">\n <Accordion.Trigger>What is Fragments UI?</Accordion.Trigger>\n <Accordion.Content>\n Fragments UI is a modern React component library built on Base UI primitives, providing accessible and customizable components.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"item-2\">\n <Accordion.Trigger>How do I install it?</Accordion.Trigger>\n <Accordion.Content>\n Install via npm or pnpm: pnpm add @usefragments/ui\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"item-3\">\n <Accordion.Trigger>Is it accessible?</Accordion.Trigger>\n <Accordion.Content>\n Yes! All components follow WAI-ARIA guidelines and support keyboard navigation.\n </Accordion.Content>\n </Accordion.Item>\n</Accordion>"},{"name":"Multiple Open","description":"Sections stay open so answers can be compared.","code":"import { Accordion } from '@/components/Accordion';\n\n<Accordion type=\"multiple\" defaultValue={['features', 'pricing']}>\n <Accordion.Item value=\"features\">\n <Accordion.Trigger>Features</Accordion.Trigger>\n <Accordion.Content>\n Comprehensive component library with theming support, accessibility built-in, and TypeScript-first development.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"pricing\">\n <Accordion.Trigger>Pricing</Accordion.Trigger>\n <Accordion.Content>\n Free and open source. MIT licensed for both personal and commercial use.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"support\">\n <Accordion.Trigger>Support</Accordion.Trigger>\n <Accordion.Content>\n Community support via GitHub issues and discussions.\n </Accordion.Content>\n </Accordion.Item>\n</Accordion>"},{"name":"With Disabled","description":"An unavailable section stays visible but inert.","code":"import { Accordion } from '@/components/Accordion';\n\n<Accordion type=\"single\" collapsible defaultValue=\"available\">\n <Accordion.Item value=\"available\">\n <Accordion.Trigger>Notification preferences</Accordion.Trigger>\n <Accordion.Content>\n Choose which events send you an email and how often digests arrive.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"disabled\" disabled>\n <Accordion.Trigger>Billing history</Accordion.Trigger>\n <Accordion.Content>\n Unavailable until a payment method is on file.\n </Accordion.Content>\n </Accordion.Item>\n <Accordion.Item value=\"another\">\n <Accordion.Trigger>Connected accounts</Accordion.Trigger>\n <Accordion.Content>\n Review the services linked to this workspace and revoke the ones you no longer use.\n </Accordion.Content>\n </Accordion.Item>\n</Accordion>"}],"contract":{"propsSummary":["type: single|multiple - controls how many items can be open","value/defaultValue are type-discriminated (single -> string, multiple -> string[])","onValueChange is type-discriminated by mode (single -> string|undefined, multiple -> string[])","collapsible: boolean - allow all closed in single mode","Accordion.Trigger forwards button props and defaults type=\"button\""],"a11yRules":["A11Y_DISCLOSURE_KEYBOARD","A11Y_FOCUS_VISIBLE"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Trigger","Content"],"requiredChildren":["Item"],"commonPatterns":["<Accordion type=\"single\" collapsible><Accordion.Item value=\"item-1\"><Accordion.Trigger>{title}</Accordion.Trigger><Accordion.Content>{content}</Accordion.Content></Accordion.Item></Accordion>"]},"propsSummary":["type: single|multiple (default: single)","value: union","defaultValue: union","onValueChange: union","children: node (required)","collapsible: boolean (default: false)","headingLevel: union (default: 3)"],"sourcePath":"src/components/Accordion/index.tsx","exportName":"Accordion","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:49.840Z"},"performance":{"bundleSize":1558,"rawSize":3499,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Accordion (self)","bytes":2826,"percent":81}]}},"Alert":{"filePath":"src/components/Alert/index.tsx","meta":{"name":"Alert","description":"Tells the user what just happened, or what is about to.","category":"feedback","tags":["notification","message","feedback","banner","toast"],"status":"stable"},"usage":{"when":["Reporting the outcome of something the user did","Flagging a risk before the user hits it","Standing status that must stay on screen"],"whenNot":["A one-word status (use Badge)","A message that should fade away (use Toast)","An invalid field (use the Input error prop)","A decision the user must make first (use Dialog)"],"guidelines":["Match tone to real stakes — an error that is not an error trains people to ignore you","Every danger alert says what to do next","Add Alert.Title only when the message needs two lines","One action per alert","Only dismissible when losing the message costs nothing","Alert.Action and Alert.Close default to type=\"button\", so they are safe inside a form","Alert.Close runs your onClick and still respects preventDefault()"],"accessibility":["role=\"alert\" means assistive tech announces it on arrival","Alert.Close needs its own label","Icon plus wording carry the tone — never color alone"]},"props":{"children":{"type":"node","description":"Alert content - use Alert.Icon, Alert.Body, Alert.Title, Alert.Content, Alert.Actions, Alert.Close sub-components","required":true},"tone":{"type":"enum","description":"Tone; controls colour, icon and live-region role","default":"info","required":false,"values":["info","success","warning","danger"]},"emphasis":{"type":"enum","description":"How much surface the tone claims. `tint` washes the card in the tone colour; `surface` keeps the page background and colours only the hairline and title.","default":"tint","required":false,"values":["tint","surface"]}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for compact, inline status labels"},{"component":"Toast","relationship":"alternative","note":"Use Toast for transient notifications that auto-dismiss"},{"component":"Dialog","relationship":"sibling","note":"Use Dialog for blocking confirmations"}],"variants":[{"name":"Info","description":"Neutral context — nothing went wrong, nothing needs doing.","code":"import { Alert } from '@/components/Alert';\n\n<Alert tone=\"info\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>\n Your session will expire in 15 minutes. Save your work to avoid losing changes.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"Success","description":"Confirms the thing the user just did actually landed.","code":"import { Alert } from '@/components/Alert';\n\n<Alert tone=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Payment processed</Alert.Title>\n <Alert.Content>\n Your order #12345 has been confirmed. You will receive a confirmation email shortly.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"Warning","description":"Nothing is broken yet — act before it is.","code":"import { Alert } from '@/components/Alert';\n\n<Alert tone=\"warning\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Storage almost full</Alert.Title>\n <Alert.Content>\n You have used 90% of your storage quota. Consider deleting unused files.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"Error","description":"Something failed; say what to do about it.","code":"import { Alert } from '@/components/Alert';\n\n<Alert tone=\"danger\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Upload failed</Alert.Title>\n <Alert.Content>\n The file could not be uploaded. Check your connection and try again.\n </Alert.Content>\n </Alert.Body>\n</Alert>"},{"name":"With Action","description":"One button, one job — more than one stalls the reader.","code":"import { Alert } from '@/components/Alert';\n\n<Alert tone=\"warning\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Update available</Alert.Title>\n <Alert.Content>\n A new version is available with important security fixes.\n </Alert.Content>\n <Alert.Actions>\n <Alert.Action onClick={() => {}}>Update now</Alert.Action>\n </Alert.Actions>\n </Alert.Body>\n</Alert>"},{"name":"Dismissible","description":"A close button suits news the user can safely ignore.","code":"import { Alert } from '@/components/Alert';\n\n<Alert tone=\"info\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Content>\n You can customize your notification preferences in Settings.\n </Alert.Content>\n </Alert.Body>\n <Alert.Close />\n</Alert>"}],"contract":{"propsSummary":["tone: info|success|warning|danger - colour, icon and live-region role","Sub-components: Alert.Icon, Alert.Body, Alert.Title, Alert.Content, Alert.Actions, Alert.Action, Alert.Close","Alert.Action / Alert.Close accept button props and default type=\"button\""],"a11yRules":["A11Y_ALERT_ROLE","A11Y_ALERT_DISMISS","A11Y_ALERT_CONTRAST","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Icon","Body","Title","Content","Actions","Action","Close"],"requiredChildren":["Body"],"commonPatterns":["<Alert tone=\"info\"><Alert.Icon /><Alert.Body><Alert.Content>{message}</Alert.Content></Alert.Body></Alert>","<Alert tone=\"warning\"><Alert.Icon /><Alert.Body><Alert.Title>{title}</Alert.Title><Alert.Content>{message}</Alert.Content></Alert.Body></Alert>","<Alert tone=\"danger\"><Alert.Icon /><Alert.Body><Alert.Title>{title}</Alert.Title><Alert.Content>{message}</Alert.Content></Alert.Body><Alert.Close /></Alert>"]},"propsSummary":["children: node (required)","tone: info|success|warning|danger (default: info)","emphasis: tint|surface (default: tint)"],"sourcePath":"src/components/Alert/index.tsx","exportName":"Alert","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.066Z"},"performance":{"bundleSize":1247,"rawSize":3074,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Alert (self)","bytes":2336,"percent":76}]}},"AppShell":{"filePath":"src/components/AppShell/index.tsx","meta":{"name":"AppShell","description":"Lays out header, sidebar, main, and optional aside as one responsive app frame.","category":"layout","tags":["layout","shell","scaffold","dashboard","app-layout"],"status":"stable"},"usage":{"when":["Dashboards and internal tools","Apps with persistent sidebar navigation","Layouts needing header, sidebar, and main together","Navigation that must collapse to a drawer on mobile"],"whenNot":["Marketing and landing pages","Content-first sites with no app navigation","Single-screen tools with no chrome"],"guidelines":["layout=\"default\" puts the logo in a full-width header","layout=\"sidebar\" puts the logo in a full-height sidebar","variant=\"floating\" is per slot — mix it with any layout","bg overrides one slot's background without touching the rest","AppShell supplies SidebarProvider; do not add your own","Set width and collapse behaviour on AppShell.Sidebar","Main reflows automatically when the sidebar collapses","Aside hides itself on mobile"],"accessibility":["Main content area has id=\"main-content\" for skip links","Use Header.SkipLink for keyboard navigation","Sidebar drawer has proper focus trap on mobile","Keyboard navigation supported throughout"]},"props":{"children":{"type":"node","description":"Layout content (use AppShell.Header, AppShell.Sidebar, AppShell.Main, AppShell.Aside)","required":true},"layout":{"type":"enum","description":"Structural layout for CSS grid areas","default":"default","required":false,"values":["default","sidebar","sidebar-floating","floating"]},"bg":{"type":"string","description":"Background color override for the shell container (accepts any CSS color or token reference like \"var(--fui-bg-secondary)\")","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Theme","relationship":"parent","note":"AppShell should be wrapped in ThemeProvider"},{"component":"Header","relationship":"child","note":"Header is placed inside AppShell.Header"},{"component":"Sidebar","relationship":"child","note":"Sidebar content goes inside AppShell.Sidebar"}],"variants":[{"name":"Default Layout","description":"Header spans the full width above the sidebar.","code":"import { ChartBar, Gear, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"default\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Brand>MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem active>Dashboard</Header.NavItem>\n <Header.NavItem>Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Default Layout</Text>\n <Text as=\"p\" color=\"secondary\">\n Header spans full width. Logo is in the header.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Sidebar Layout","description":"Sidebar runs full height with the header beside it.","code":"import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">\n <Stack direction=\"row\" align=\"center\" gap=\"sm\">\n <Icon icon={MagnifyingGlass} size=\"sm\" color=\"tertiary\" />\n <Text scale=\"sm\" color=\"tertiary\">Search...</Text>\n </Stack>\n </Box>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Sidebar Layout</Text>\n <Text as=\"p\" color=\"secondary\">\n Sidebar is full height. Logo is in the sidebar header.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"With Aside Panel","description":"Adds a right rail for context, filters, or actions.","code":"import { ChartBar, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"default\">\n <AppShell.Header>\n <Header>\n <Header.Brand>App</Header.Brand>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"180px\" collapsible=\"offcanvas\">\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Stats</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Main Content</Text>\n <Text as=\"p\">Content with aside panel on the right.</Text>\n </Stack>\n </AppShell.Main>\n\n <AppShell.Aside width=\"180px\">\n <Box padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h3\" scale=\"sm\" weight=\"semibold\">Aside Panel</Text>\n <Text as=\"p\" scale=\"sm\" color=\"secondary\">\n Additional context, filters, or quick actions.\n </Text>\n </Stack>\n </Box>\n </AppShell.Aside>\n </AppShell>\n</Box>"},{"name":"Collapsible Icon Sidebar","description":"Sidebar shrinks to icons on desktop via the footer toggle.","code":"import { ChartBar, Gear, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar collapsible=\"icon\" width=\"200px\" collapsedWidth=\"56px\">\n <Sidebar.Header>\n <Text weight=\"semibold\">App</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\">\n <Text as=\"p\">\n Click the collapse button in the sidebar footer to toggle between expanded and icon-only modes.\n </Text>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Floating Main","description":"Only the main slot floats — rounded, raised, on its own background.","code":"import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Box background=\"primary\" border rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">\n <Stack direction=\"row\" align=\"center\" gap=\"sm\">\n <Icon icon={MagnifyingGlass} size=\"sm\" color=\"tertiary\" />\n <Text scale=\"sm\" color=\"tertiary\">Search...</Text>\n </Stack>\n </Box>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\" variant=\"floating\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" variant=\"floating\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Floating Main</Text>\n <Text as=\"p\" color=\"secondary\">\n Main content has rounded corners and visual separation from the sidebar.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Floating Main & Aside","description":"Two slots float independently; the sidebar stays flush.","code":"import { ChartBar, Gear, House, MagnifyingGlass } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Box background=\"primary\" border rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">\n <Stack direction=\"row\" align=\"center\" gap=\"sm\">\n <Icon icon={MagnifyingGlass} size=\"sm\" color=\"tertiary\" />\n <Text scale=\"sm\" color=\"tertiary\">Search...</Text>\n </Stack>\n </Box>\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\" variant=\"floating\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={Gear} size=\"md\" />}>Settings</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>v1.0.0</Sidebar.Footer>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" variant=\"floating\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Floating Main & Aside</Text>\n <Text as=\"p\" color=\"secondary\">\n Both main content and aside panel float with rounded corners.\n </Text>\n </Stack>\n </AppShell.Main>\n\n <AppShell.Aside width=\"200px\" variant=\"floating\">\n <Box padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h3\" scale=\"sm\" weight=\"semibold\">Aside Panel</Text>\n <Text as=\"p\" scale=\"sm\" color=\"secondary\">\n This aside also floats, matching the main content area.\n </Text>\n </Stack>\n </Box>\n </AppShell.Aside>\n </AppShell>\n</Box>"},{"name":"Floating Default Layout","description":"Floating works under any layout, including header-on-top.","code":"import { ChartBar, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"default\">\n <AppShell.Header>\n <Header>\n <Header.Brand>MyApp</Header.Brand>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"180px\" collapsible=\"offcanvas\" variant=\"floating\">\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Stats</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" variant=\"floating\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Floating Default Layout</Text>\n <Text as=\"p\" color=\"secondary\">\n Default structure (header on top) with floating main content. Any slot can float in any layout.\n </Text>\n </Stack>\n </AppShell.Main>\n </AppShell>\n</Box>"},{"name":"Custom Backgrounds","description":"Each slot takes its own bg, so regions read apart.","code":"import { ChartBar, House } from '@phosphor-icons/react';\nimport { AppShell } from '@/components/AppShell';\nimport { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Icon } from '@/components/Icon';\nimport { Sidebar } from '@/components/Sidebar';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box height=\"360px\" overflow=\"hidden\" border rounded=\"md\">\n <AppShell layout=\"sidebar\">\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n\n <AppShell.Sidebar width=\"200px\" collapsible=\"offcanvas\" bg=\"var(--fui-bg-elevated)\">\n <Sidebar.Header>\n <Text weight=\"semibold\">MyApp</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Menu\">\n <Sidebar.Item icon={<Icon icon={House} size=\"md\" />} active>Home</Sidebar.Item>\n <Sidebar.Item icon={<Icon icon={ChartBar} size=\"md\" />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </AppShell.Sidebar>\n\n <AppShell.Main padding=\"md\" bg=\"var(--fui-bg-primary)\">\n <Stack gap=\"xs\">\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Custom Backgrounds</Text>\n <Text as=\"p\" color=\"secondary\">\n Sidebar uses bg-elevated (lighter), main uses bg-primary (darker). Any CSS color or token works.\n </Text>\n </Stack>\n </AppShell.Main>\n\n <AppShell.Aside width=\"200px\" bg=\"var(--fui-bg-elevated)\">\n <Box padding=\"md\">\n <Stack gap=\"xs\">\n <Text as=\"h3\" scale=\"sm\" weight=\"semibold\">Aside Panel</Text>\n <Text as=\"p\" scale=\"sm\" color=\"secondary\">\n Aside with bg-elevated background matching the sidebar.\n </Text>\n </Stack>\n </Box>\n </AppShell.Aside>\n </AppShell>\n</Box>"}],"contract":{"propsSummary":["children: node (required)","layout: default|sidebar|sidebar-floating|floating (default: default)","bg: string","style: object"]},"ai":{"compositionPattern":"compound","subComponents":["Header","Sidebar","Main","Aside"],"commonPatterns":["<AppShell>\n <AppShell.Header>...</AppShell.Header>\n <AppShell.Sidebar>...</AppShell.Sidebar>\n <AppShell.Main>...</AppShell.Main>\n</AppShell>"],"requiredChildren":["Header","Sidebar","Main"]},"propsSummary":["children: node (required)","layout: default|sidebar|sidebar-floating|floating (default: default)","bg: string","style: object"],"sourcePath":"src/components/AppShell/index.tsx","exportName":"AppShell","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.550Z"},"performance":{"bundleSize":9882,"rawSize":31037,"complexity":"moderate","budgetPercent":64,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Sidebar","bytes":25663,"percent":83},{"path":"AppShell (self)","bytes":4649,"percent":15}]}},"Avatar":{"filePath":"src/components/Avatar/index.tsx","meta":{"name":"Avatar","description":"Shows who someone is — their photo, or their initials when there is none.","category":"display","tags":["user","profile","image","identity"],"status":"stable"},"usage":{"when":["A row, comment, or card needs to say who","Several people belong to one thing — use Avatar.Group"],"whenNot":["The picture is content, not identity (use Image)","A profile hero at display size (build the layout yourself)"],"guidelines":["Pass name even when you pass src — it is the fallback and the label","Hold one size per context; mixed sizes read as a mistake","Avatar.Group max caps the stack and counts the rest","imageProps carries loading, decoding, referrerPolicy"],"accessibility":["alt describes the person, not the word \"avatar\"","Initials come from name, so screen readers get the whole name","Purely decorative? Pass alt=\"\""]},"props":{"src":{"type":"string","description":"Image source URL","required":false},"alt":{"type":"string","description":"Alt text for the image","default":"","required":false},"initials":{"type":"string","description":"Fallback initials (1-2 characters)","required":false},"name":{"type":"string","description":"Full name - used to generate initials","required":false},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["xs","sm","md","lg","xl"]},"customSize":{"type":"union","description":"Custom avatar size (number in px or CSS size string like \"2.25rem\"), overrides size width/height","required":false},"shape":{"type":"enum","description":"Shape variant","default":"circle","required":false,"values":["circle","square"]},"color":{"type":"string","description":"Custom background color for fallback avatar","required":false},"imageStyle":{"type":"object","description":"Inline style object applied to the underlying image element","required":false},"imageProps":{"type":"object","description":"Additional props for the underlying img element (except src/alt/className/style)","required":false},"style":{"type":"object","description":"","required":false},"fallback":{"type":"node","description":"Visual fallback rendered after initials/name and before the generic icon","required":false}},"relations":[{"component":"Image","relationship":"alternative","note":"Use Image for content pictures that are not a person or entity"},{"component":"Badge","relationship":"sibling","note":"Pair with Badge to show presence or role beside a name"}],"variants":[{"name":"Default","description":"A photo, cropped to the circle and centred.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar\n src=\"https://i.pravatar.cc/150?u=jane\"\n alt=\"Jane Doe\"\n name=\"Jane Doe\"\n/>"},{"name":"With Initials","description":"No src, so the name collapses to initials.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar name=\"John Smith\" />"},{"name":"Sizes","description":"Five steps, xs through xl — pick one per context and stick to it.","code":"import { Avatar } from '@/components/Avatar';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Avatar name=\"XS\" size=\"xs\" />\n <Avatar name=\"SM\" size=\"sm\" />\n <Avatar name=\"MD\" size=\"md\" />\n <Avatar name=\"LG\" size=\"lg\" />\n <Avatar name=\"XL\" size=\"xl\" />\n</Stack>"},{"name":"Custom Size","description":"customSize takes any number when the scale does not fit.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar name=\"Conan McNicholl\" customSize={36} />"},{"name":"Square Shape","description":"Squares read as products or orgs, circles as people.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar name=\"App\" shape=\"square\" />"},{"name":"Group","description":"Overlapping stack with a count for whoever did not fit.","code":"import { Avatar } from '@/components/Avatar';\n\n<Avatar.Group max={3} size=\"md\">\n <Avatar name=\"Alice Johnson\" />\n <Avatar name=\"Bob Smith\" />\n <Avatar name=\"Carol Williams\" />\n <Avatar name=\"David Brown\" />\n <Avatar name=\"Eve Davis\" />\n</Avatar.Group>"}],"contract":{"propsSummary":["src: string - image URL","name: string - used for initials fallback","size: xs|sm|md|lg|xl (default: md)","customSize: number|string - custom size override","imageStyle: CSSProperties - inline image styling","imageProps: ImgHTMLAttributes - advanced img attributes","shape: circle|square (default: circle)"],"a11yRules":["A11Y_IMG_ALT"]},"ai":{"compositionPattern":"compound","subComponents":["Group"]},"propsSummary":["src: string","alt: string (default: )","initials: string","name: string","size: xs|sm|md|lg|xl (default: md)","customSize: union","shape: circle|square (default: circle)","color: string","imageStyle: object","imageProps: object","style: object"],"sourcePath":"src/components/Avatar/index.tsx","exportName":"Avatar","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.743Z"},"performance":{"bundleSize":1972,"rawSize":3875,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Avatar (self)","bytes":3286,"percent":85}]}},"Badge":{"filePath":"src/components/Badge/index.tsx","meta":{"name":"Badge","description":"Labels a status, count, or category without pulling focus.","category":"display","tags":["status","label","tag","count","chip"],"status":"stable"},"usage":{"when":["Marking item status: active, pending, archived","Showing a count inline","Tagging or categorising content","Flagging what is new or changed"],"whenNot":["Real errors that need attention — use Alert","Anything longer than a few words — use Alert","Clickable filters — use Chip or ToggleGroup","View switching — use Tabs or links"],"guidelines":["Under 20 characters","dot for live status; add dotPulse only while it is still changing","Semantic tones are borderless soft pills on shared status tokens","outline pairs with dotColor; ghost pairs with active for filter chrome","onRemove for user-created tags only, never system labels"],"accessibility":["The text must carry the meaning — colour alone never does","Removable badges need a named dismiss button","Badges are silent to screen readers unless you pass announce","Do not make a badge the only signal that something changed"]},"props":{"children":{"type":"node","description":"Badge label text","required":true},"variant":{"type":"enum","description":"Chrome family. `soft` is the tinted pill; `outline` is a hairline metadata pill (pair with dotColor); `ghost` is transparent filter chrome (pair with active).","default":"soft","required":false,"values":["soft","outline","ghost"]},"tone":{"type":"enum","description":"Colour on the shared status ramp; `neutral` is the plain badge.","default":"neutral","required":false,"values":["neutral","accent","info","success","warning","danger"]},"size":{"type":"enum","description":"Badge size","default":"md","required":false,"values":["sm","md","lg"]},"dot":{"type":"boolean","description":"Show a colored dot indicator before the label","default":"false","required":false},"dotPulse":{"type":"boolean","description":"Breathe the status dot, for a state that is still happening rather than one that has settled. Opacity only, and honours prefers-reduced-motion","default":"false","required":false},"dotColor":{"type":"string","description":"Color for the leading status dot. Accepts any CSS color including CSS custom properties.","required":false},"icon":{"type":"node","description":"Optional icon element before the text","required":false},"active":{"type":"boolean","description":"Marks variant=\"ghost\" as the currently selected filter. Has no effect on other variants.","default":"false","required":false},"onRemove":{"type":"function","description":"Makes the badge removable. Called when X is clicked.","required":false},"announce":{"type":"boolean","description":"Opt into role=\"status\" live announcement semantics","default":"false","required":false},"role":{"type":"union","description":"","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for prominent, longer messages with actions"},{"component":"Chip","relationship":"sibling","note":"Chip is interactive (clickable/filterable); Badge is display-only"}],"variants":[{"name":"Tones","description":"Neutral through info, on shared status tokens.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge>Neutral</Badge>\n <Badge tone=\"success\">Active</Badge>\n <Badge tone=\"warning\">Pending</Badge>\n <Badge tone=\"danger\">Failed</Badge>\n <Badge tone=\"info\">New</Badge>\n</Stack>"},{"name":"With Dot","description":"Leading dot for live state; it breathes while still moving.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge tone=\"success\" dot>Online</Badge>\n <Badge tone=\"warning\" dot>Away</Badge>\n <Badge tone=\"danger\" dot>Offline</Badge>\n <Badge tone=\"info\" dot dotPulse>Syncing</Badge>\n</Stack>"},{"name":"Outline and Ghost","description":"Hairline metadata pill, and filter chrome that marks the active one.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge variant=\"outline\" dotColor=\"var(--fui-color-accent)\">Design</Badge>\n <Badge variant=\"outline\" dotColor=\"var(--fui-color-success)\">Shipped</Badge>\n <Badge variant=\"ghost\" active>All</Badge>\n <Badge variant=\"ghost\">Archived</Badge>\n</Stack>"},{"name":"Outline","description":"Bordered and transparent, when a fill would shout.","code":"<Badge variant=\"outline\">Outline</Badge>"},{"name":"Sizes","description":"sm for dense tables, lg for reference status pills.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Badge tone=\"success\" size=\"sm\">Small</Badge>\n <Badge tone=\"success\" size=\"md\">Medium</Badge>\n <Badge tone=\"success\" size=\"lg\">Large</Badge>\n</Stack>"},{"name":"Removable","description":"Dismissible tags the user added themselves.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Badge tone=\"info\" onRemove={() => {}}>React</Badge>\n <Badge tone=\"info\" onRemove={() => {}}>TypeScript</Badge>\n <Badge tone=\"info\" onRemove={() => {}}>CSS</Badge>\n</Stack>"},{"name":"Announced Status","description":"Looks the same, but screen readers now hear the change.","code":"<Badge tone=\"success\" announce>Saved</Badge>"}],"contract":{"propsSummary":["children: ReactNode - badge label (required)","variant: soft|outline|ghost - chrome family","tone: neutral|accent|info|success|warning|danger - colour","size: sm|md|lg - badge size","dot: boolean - show status dot indicator","dotPulse: boolean - breathe the dot for an in-progress state (respects prefers-reduced-motion)","dotColor: string - color for the leading status dot","active: boolean - marks variant=\"ghost\" as the selected filter","onRemove: () => void - makes badge removable","announce: boolean - opt into role=\"status\" + auto status aria-label"],"a11yRules":["A11Y_BADGE_CONTRAST","A11Y_BADGE_DISMISS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","variant: soft|outline|ghost (default: soft)","tone: neutral|accent|info|success|warning|danger (default: neutral)","size: sm|md|lg (default: md)","dot: boolean (default: false)","dotPulse: boolean (default: false)","dotColor: string","icon: node","active: boolean (default: false)","onRemove: function","announce: boolean (default: false)","role: union"],"sourcePath":"src/components/Badge/index.tsx","exportName":"Badge","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:50.941Z"},"performance":{"bundleSize":945,"rawSize":1802,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Badge (self)","bytes":1215,"percent":67}]}},"BentoGrid":{"filePath":"src/components/BentoGrid/index.tsx","meta":{"name":"BentoGrid","description":"Asymmetric feature grid where tiles span different widths and heights.","category":"layout","tags":["bento","grid","layout","responsive","feature-grid","asymmetric"],"status":"stable"},"usage":{"when":["Feature grids with one hero tile and supporting tiles","Dashboards where cards carry different weight","Marketing sections with mixed-size blocks"],"whenNot":["Uniform tiles of one size (use Grid)","Labelled form fields (use Grid)","A single column of content (use Stack)"],"guidelines":["colSpan and rowSpan take per-breakpoint objects","A hero tile is usually colSpan 2 and rowSpan 2 from lg up","Tiles carry their own surface — do not wrap them in Card","Columns collapse 3 to 2 below lg, and to 1 below sm","Keep source order equal to visual order for screen readers"],"accessibility":["Grid is purely visual — it does not affect reading order or semantics","Ensure logical source order matches visual order for screen readers","Hover effects are disabled when prefers-reduced-motion is set","Border thickness increases in prefers-contrast: more mode"]},"props":{"children":{"type":"node","description":"BentoGrid.Item children","required":false},"columns":{"type":"union","description":"Number of columns — auto-collapses responsively (3→2→1)","default":"3","required":false,"values":["2","3","4"]},"gap":{"type":"enum","description":"Gap between grid items, mapped to spacing tokens","default":"md","required":false,"values":["none","xs","sm","md","lg","xl"]},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Grid","relationship":"alternative","note":"Use Grid for uniform layouts; BentoGrid for asymmetric spans with built-in surfaces"},{"component":"Card","relationship":"sibling","note":"BentoGrid.Item has built-in surface styling similar to Card"}],"variants":[{"name":"Default","description":"Equal tiles, each on its own surface.","code":"import { BentoGrid } from '@/components/BentoGrid';\nimport { Box } from '@/components/Box';\n\n<Box width=\"100%\">\n <BentoGrid columns={3} gap=\"md\">\n <BentoGrid.Item>Item 1</BentoGrid.Item>\n <BentoGrid.Item>Item 2</BentoGrid.Item>\n <BentoGrid.Item>Item 3</BentoGrid.Item>\n <BentoGrid.Item>Item 4</BentoGrid.Item>\n <BentoGrid.Item>Item 5</BentoGrid.Item>\n <BentoGrid.Item>Item 6</BentoGrid.Item>\n </BentoGrid>\n</Box>"},{"name":"Hero Layout","description":"One tile takes two columns and two rows; the rest fill around it.","code":"import { BentoGrid } from '@/components/BentoGrid';\nimport { Box } from '@/components/Box';\n\n<Box width=\"100%\">\n <BentoGrid columns={3} gap=\"md\">\n <BentoGrid.Item colSpan={{ base: 1, lg: 2 }} rowSpan={{ base: 1, lg: 2 }}>\n Hero content\n </BentoGrid.Item>\n <BentoGrid.Item>Item 2</BentoGrid.Item>\n <BentoGrid.Item>Item 3</BentoGrid.Item>\n <BentoGrid.Item>Item 4</BentoGrid.Item>\n <BentoGrid.Item>Item 5</BentoGrid.Item>\n </BentoGrid>\n</Box>"},{"name":"Two Column","description":"colSpan stretches a tile across the whole row.","code":"import { BentoGrid } from '@/components/BentoGrid';\nimport { Box } from '@/components/Box';\n\n<Box width=\"100%\">\n <BentoGrid columns={2} gap=\"md\">\n <BentoGrid.Item>Item 1</BentoGrid.Item>\n <BentoGrid.Item>Item 2</BentoGrid.Item>\n <BentoGrid.Item colSpan={2}>Wide item</BentoGrid.Item>\n <BentoGrid.Item>Item 4</BentoGrid.Item>\n <BentoGrid.Item>Item 5</BentoGrid.Item>\n </BentoGrid>\n</Box>"}],"contract":{"propsSummary":["columns: 2|3|4 (default: 3) — auto-collapses responsively","gap: none|xs|sm|md|lg|xl (default: md)","BentoGrid.Item colSpan: 1|2|3 | { base, sm, md, lg, xl }","BentoGrid.Item rowSpan: 1|2|3 | { base, sm, md, lg, xl }","BentoGrid and BentoGrid.Item forward div DOM props; Item style is merged with generated span vars"]},"propsSummary":["children: node","columns: union (default: 3)","gap: none|xs|sm|md|lg|xl (default: md)","style: object"],"sourcePath":"src/components/BentoGrid/index.tsx","exportName":"BentoGrid","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.407Z"},"performance":{"bundleSize":882,"rawSize":1730,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"BentoGrid (self)","bytes":1152,"percent":67}]}},"Box":{"filePath":"src/components/Box/index.tsx","meta":{"name":"Box","description":"Applies spacing, background, border, and radius to any element.","category":"layout","tags":["layout","container","spacing","primitive","box"],"status":"stable"},"usage":{"when":["Padding or insetting a section of content","Bordered or elevated containers","Rendering a semantic element with design-system spacing"],"whenNot":["Spacing a row or column of siblings (use Stack)","Two-dimensional layouts (use Grid)","Header/body/footer surfaces (use Card)","Styling text alone (use Text)"],"guidelines":["Use the padding and margin props, never inline styles","Set as=\"section\" or as=\"article\" so the markup stays semantic","Backgrounds come from the token scale — no custom colours","Reach for Stack or Grid before nesting Boxes for layout"],"accessibility":["Choose semantic as prop values for proper document structure","Avoid div-soup; use meaningful elements like section, article","Ensure proper heading hierarchy within Box containers"]},"props":{"children":{"type":"node","description":"Content to render inside the box","required":false},"as":{"type":"enum","description":"HTML element to render","default":"div","required":false,"values":["div","section","article","aside","main","header","footer","nav","span"]},"padding":{"type":"enum","description":"Padding on all sides","required":false,"values":["none","xs","sm","md","lg","xl"]},"paddingX":{"type":"enum","description":"Horizontal padding","required":false,"values":["none","xs","sm","md","lg","xl"]},"paddingY":{"type":"enum","description":"Vertical padding","required":false,"values":["none","xs","sm","md","lg","xl"]},"margin":{"type":"enum","description":"Margin on all sides","required":false,"values":["none","xs","sm","md","lg","xl","auto"]},"marginX":{"type":"enum","description":"Horizontal margin","required":false,"values":["none","xs","sm","md","lg","xl","auto"]},"marginY":{"type":"enum","description":"Vertical margin","required":false,"values":["none","xs","sm","md","lg","xl","auto"]},"background":{"type":"enum","description":"Background color","required":false,"values":["none","primary","secondary","tertiary","elevated"]},"rounded":{"type":"enum","description":"Border radius","required":false,"values":["none","sm","md","lg","full"]},"border":{"type":"boolean","description":"Show border","default":"false","required":false},"borderTop":{"type":"boolean","description":"Show top border only","default":"false","required":false},"borderBottom":{"type":"boolean","description":"Show bottom border only","default":"false","required":false},"borderLeft":{"type":"boolean","description":"Show left border only","default":"false","required":false},"borderRight":{"type":"boolean","description":"Show right border only","default":"false","required":false},"borderColor":{"type":"enum","description":"Border color variant (requires border or directional border)","required":false,"values":["default","strong","accent","danger"]},"shadow":{"type":"enum","description":"Box shadow","required":false,"values":["none","sm","md","lg"]},"overflow":{"type":"enum","description":"Overflow behavior","required":false,"values":["hidden","auto","scroll","visible"]},"color":{"type":"enum","description":"Text color","required":false,"values":["primary","secondary","tertiary","accent","inverse"]},"display":{"type":"enum","description":"Display type","required":false,"values":["none","block","inline","inline-block","flex","inline-flex","grid"]},"width":{"type":"union","description":"Width (CSS value, e.g. \"100%\", \"300px\", or number for px)","required":false},"minWidth":{"type":"union","description":"Min width","required":false},"maxWidth":{"type":"union","description":"Max width","required":false},"height":{"type":"union","description":"Height (CSS value)","required":false},"minHeight":{"type":"union","description":"Min height","required":false},"maxHeight":{"type":"union","description":"Max height","required":false},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false}},"relations":[{"component":"Stack","relationship":"alternative","note":"Use Stack for directional layouts with gap"},{"component":"Grid","relationship":"alternative","note":"Use Grid for column-based layouts"},{"component":"Card","relationship":"alternative","note":"Use Card for content containers with structure"}],"variants":[{"name":"Default","description":"Padding, background, and radius in one element.","code":"<Box padding=\"md\" background=\"secondary\" rounded=\"md\">\n Content with padding and background\n</Box>"},{"name":"With Border","description":"A hairline border instead of a filled background.","code":"<Box padding=\"lg\" border rounded=\"md\">\n Bordered content area\n</Box>"},{"name":"Directional Padding","description":"Horizontal and vertical padding set separately.","code":"<Box paddingX=\"xl\" paddingY=\"sm\" background=\"tertiary\" rounded=\"sm\">\n Wide horizontal padding, short vertical\n</Box>"},{"name":"Centered with Auto Margin","description":"marginX=\"auto\" centres a fixed-width box in a wider parent.","code":"import { Box } from '@/components/Box';\n\n<Box width=\"100%\" border rounded=\"md\" padding=\"md\">\n <Box padding=\"md\" marginX=\"auto\" width=\"240px\" background=\"elevated\" rounded=\"lg\">\n Centred by auto margin\n </Box>\n</Box>"},{"name":"Directional Borders","description":"Border on chosen sides only.","code":"<Box padding=\"md\" borderTop borderBottom>\n Top and bottom borders only\n</Box>"},{"name":"With Shadow","description":"Shadow lifts the surface off the page.","code":"<Box padding=\"lg\" rounded=\"md\" shadow=\"md\" background=\"primary\">\n Elevated content with shadow\n</Box>"},{"name":"Overflow Hidden","description":"Content past the box's height is clipped, not scrolled.","code":"import { Box } from '@/components/Box';\n\n<Box padding=\"md\" overflow=\"hidden\" border rounded=\"md\" width=\"320px\" height=\"72px\">\n This box clips its overflowing content. Lorem ipsum dolor sit amet, consectetur\n adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna\n aliqua, and this final sentence never becomes visible.\n</Box>"},{"name":"Text Colors","description":"Text colour tokens, from strongest to accent.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\">\n <Box color=\"primary\">Primary</Box>\n <Box color=\"secondary\">Secondary</Box>\n <Box color=\"tertiary\">Tertiary</Box>\n <Box color=\"accent\">Accent</Box>\n</Stack>"}],"contract":{"propsSummary":["as: div|section|article|... - HTML element","padding: none|xs|sm|md|lg|xl - all-sides padding","paddingX/paddingY: directional padding overrides","margin: none|xs|sm|md|lg|xl|auto - margin","background: none|primary|secondary|tertiary|elevated","rounded: none|sm|md|lg|full - border radius","border: boolean - show border","borderTop/borderBottom/borderLeft/borderRight: boolean - directional borders","borderColor: default|strong|accent|danger - border color variant","shadow: sm|md|lg|none - box shadow","overflow: hidden|auto|scroll|visible - overflow behavior","color: primary|secondary|tertiary|accent|inverse - text color","width/minWidth/maxWidth: string|number - sizing","height/minHeight/maxHeight: string|number - sizing","All standard HTMLElement props are forwarded to the rendered element"],"a11yRules":["A11Y_SEMANTIC_HTML"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node","as: div|section|article|aside|main|header|footer|nav|span (default: div)","padding: none|xs|sm|md|lg|xl","paddingX: none|xs|sm|md|lg|xl","paddingY: none|xs|sm|md|lg|xl","margin: none|xs|sm|md|lg|xl|auto","marginX: none|xs|sm|md|lg|xl|auto","marginY: none|xs|sm|md|lg|xl|auto","background: none|primary|secondary|tertiary|elevated","rounded: none|sm|md|lg|full","border: boolean","borderTop: boolean","borderBottom: boolean","borderLeft: boolean","borderRight: boolean","borderColor: default|strong|accent|danger","shadow: none|sm|md|lg","overflow: hidden|auto|scroll|visible","color: primary|secondary|tertiary|accent|inverse","display: none|block|inline|inline-block|flex|inline-flex|grid","width: union","minWidth: union","maxWidth: union","height: union","minHeight: union","maxHeight: union","className: string","style: object"],"sourcePath":"src/components/Box/index.tsx","exportName":"Box","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:51.126Z"},"performance":{"bundleSize":967,"rawSize":1876,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Box (self)","bytes":1304,"percent":70}]}},"Breadcrumbs":{"filePath":"src/components/Breadcrumbs/index.tsx","meta":{"name":"Breadcrumbs","description":"Shows where the user is and links back up the hierarchy.","category":"navigation","tags":["breadcrumbs","navigation","hierarchy","wayfinding"],"status":"stable"},"usage":{"when":["Nested content more than two levels deep","Jumping back to a parent in one click","Documentation and catalogue hierarchies"],"whenNot":["Flat structures with no parents (use Tabs or header navigation)","Steps in an order (use Stepper)","Primary navigation (use Sidebar or Header)"],"guidelines":["End on the current page, unlinked","Short labels — the trail is a path, not a summary","Set maxItems to fold long paths, keeping first and last","The separator defaults to a slash and takes any node","Set label to rename the landmark (defaults to \"Breadcrumb\")","Crumbs truncate at 200px so one long title cannot push the rest out"],"accessibility":["Uses <nav aria-label=\"Breadcrumb\"> for landmark navigation","Current page is marked with aria-current=\"page\"","Separators are hidden from screen readers with aria-hidden","Ellipsis button has aria-label for collapsed items"]},"props":{"children":{"type":"node","description":"Breadcrumb items (use Breadcrumbs.Item)","required":true},"separator":{"type":"node","description":"Custom separator between items","default":"/","required":false},"maxItems":{"type":"number","description":"Maximum visible items before collapsing middle items with ellipsis","required":false},"label":{"type":"string","description":"Custom aria-label for the breadcrumb nav landmark","default":"Breadcrumb","required":false}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for flat, non-hierarchical navigation"},{"component":"Sidebar","relationship":"complementary","note":"Breadcrumbs complement sidebar navigation for deep hierarchies"}],"variants":[{"name":"Default","description":"Each ancestor links; the last one does not.","code":"<Breadcrumbs>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Products</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Category</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Current Page</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"With Icons","description":"Glyphs mark what kind of thing each level is.","code":"<Breadcrumbs>\n <Breadcrumbs.Item\n href=\"#\"\n icon={\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M8 1.25l-7 6v7.5c0 .138.112.25.25.25H5.5V10h5v5h4.25a.25.25 0 0 0 .25-.25v-7.5l-7-6z\" />\n </svg>\n }\n >\n Home\n </Breadcrumbs.Item>\n <Breadcrumbs.Item\n href=\"#\"\n icon={\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75z\" />\n </svg>\n }\n >\n Documents\n </Breadcrumbs.Item>\n <Breadcrumbs.Item current>Report.pdf</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"Collapsed","description":"Middle levels fold behind an ellipsis.","code":"<Breadcrumbs maxItems={3}>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Category</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Subcategory</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Section</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Current Page</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"Custom Separator","description":"Any node can replace the slash.","code":"<Breadcrumbs\n separator={\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06z\" />\n </svg>\n }\n>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Settings</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Profile</Breadcrumbs.Item>\n</Breadcrumbs>"},{"name":"Custom Landmark Label","description":"Renames the landmark screen readers announce.","code":"<Breadcrumbs label=\"Documentation breadcrumbs\">\n <Breadcrumbs.Item href=\"#\">Docs</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Components</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Breadcrumbs</Breadcrumbs.Item>\n</Breadcrumbs>"}],"contract":{"propsSummary":["separator: ReactNode - custom separator (default \"/\")","maxItems: number - collapse middle items with ellipsis","label: string - nav landmark label (default \"Breadcrumb\")","Breadcrumbs.Item href: string - makes item a link","Breadcrumbs.Item current: boolean - marks current page","Breadcrumbs.Item icon: ReactNode - icon before label"],"a11yRules":["A11Y_NAV_LANDMARK","A11Y_ARIA_CURRENT","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Separator"],"requiredChildren":["Item"],"commonPatterns":["<Breadcrumbs><Breadcrumbs.Item href=\"/\">Home</Breadcrumbs.Item><Breadcrumbs.Item href=\"/products\">Products</Breadcrumbs.Item><Breadcrumbs.Item current>Widget</Breadcrumbs.Item></Breadcrumbs>"]},"propsSummary":["children: node (required)","separator: node (default: /)","maxItems: number","label: string (default: Breadcrumb)"],"sourcePath":"src/components/Breadcrumbs/index.tsx","exportName":"Breadcrumbs","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:51.312Z"},"performance":{"bundleSize":1161,"rawSize":2752,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Breadcrumbs (self)","bytes":2091,"percent":76}]}},"Button":{"filePath":"src/components/Button/Button.fragment.tsx","meta":{"name":"Button","description":"Triggers an action — save, submit, delete, open.","category":"actions","status":"stable","tags":["action","button","form","interactive"]},"guidance":{"when":["Running an action: save, submit, delete","Submitting a form","Opening a dialog or menu"],"whenNot":["Plain navigation — use Link","Toggling state — use Switch or Checkbox","Picking an option — use Select or RadioGroup"],"dont":[{"reason":"Do not use a Button for plain navigation.","bad":"<Button href=\"/settings\">Settings</Button>","good":"<Link href=\"/settings\">Settings</Link>"}],"guidelines":["One solid accent button per form or section","tone=\"danger\" for anything destructive","Chroma is earned: leave tone at its default unless the action carries that meaning","Loading state must also disable the button","With asChild, put interaction and a11y props on Button — they forward to the child","icon={true} with any variant for icon-only actions"],"accessibility":["Label the action, not the widget","No \"Click here\"","Icon-only buttons need aria-label"]},"usage":{"when":["Running an action: save, submit, delete","Submitting a form","Opening a dialog or menu"],"whenNot":["Plain navigation — use Link","Toggling state — use Switch or Checkbox","Picking an option — use Select or RadioGroup"],"dont":[{"reason":"Do not use a Button for plain navigation.","bad":"<Button href=\"/settings\">Settings</Button>","good":"<Link href=\"/settings\">Settings</Link>"}],"guidelines":["One solid accent button per form or section","tone=\"danger\" for anything destructive","Chroma is earned: leave tone at its default unless the action carries that meaning","Loading state must also disable the button","With asChild, put interaction and a11y props on Button — they forward to the child","icon={true} with any variant for icon-only actions"],"accessibility":["Label the action, not the widget","No \"Click here\"","Icon-only buttons need aria-label"]},"props":{"as":{"type":"enum","description":"","required":false,"values":["a","button"]},"asChild":{"type":"boolean","description":"Merge props onto child element instead of rendering a button. Useful for composition with Link components.","required":false},"children":{"type":"node","description":"","required":true},"fullWidth":{"type":"boolean","description":"Make button full width of container","required":false},"icon":{"type":"boolean","description":"Render as icon-only button (square aspect ratio). Always pass `aria-label`.","required":false},"size":{"type":"enum","description":"Control height.","default":"\"md\"","required":false,"values":["sm","md","lg"]},"tone":{"type":"enum","description":"Colour. Defaults to `\"accent\"` on `solid` and `link`, `\"neutral\"` on\n`soft`, `outline` and `ghost`.","required":false,"values":["neutral","accent","info","success","warning","danger"]},"variant":{"type":"enum","description":"Chrome family.","default":"\"solid\"","required":false,"values":["solid","soft","outline","ghost","link"]}},"relations":[{"component":"Link","relationship":"alternative","note":"Use Link for navigation without action context"},{"component":"Icon","relationship":"complementary","note":"Use Icon inside Button for icon-leading/trailing or icon-only actions"},{"component":"ButtonGroup","relationship":"parent","note":"Use ButtonGroup for related action sets"}],"variants":[{"name":"Solid","description":"The one action you want people to take here. Accent tone by default.","code":"<Button variant=\"solid\">Save changes</Button>","canonical":true},{"name":"Soft","description":"Supporting action that sits beside the main one. Neutral tone by default.","code":"<Button variant=\"soft\">Cancel</Button>"},{"name":"Ghost","description":"No fill, no border — for dense toolbars and repeated rows.","code":"<Button variant=\"ghost\">Learn more</Button>"},{"name":"Link","description":"Reads like a link, behaves like an action.","code":"<Button variant=\"link\">View all →</Button>"},{"name":"Danger","description":"Destructive action people cannot undo: solid chrome, danger tone.","code":"<Button variant=\"solid\" tone=\"danger\">\n Delete item\n </Button>"},{"name":"Tones","description":"Tone is colour and colour is meaning; it works on every variant.","code":"<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Button variant=\"soft\" tone=\"accent\">\n Accent\n </Button>\n <Button variant=\"soft\" tone=\"info\">\n Info\n </Button>\n <Button variant=\"soft\" tone=\"success\">\n Success\n </Button>\n <Button variant=\"soft\" tone=\"warning\">\n Warning\n </Button>\n <Button variant=\"soft\" tone=\"danger\">\n Danger\n </Button>\n </Stack>"},{"name":"Outline","description":"Bordered and transparent — reads over any surface.","code":"<Button variant=\"outline\">View details</Button>"},{"name":"Icon","description":"Square icon-only action. Always pass aria-label.","code":"<Button icon variant=\"outline\" aria-label=\"Add item\">\n <span aria-hidden>+</span>\n </Button>"},{"name":"Sizes","description":"sm for inline row actions, lg for hero calls to action.","code":"<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Button size=\"sm\">Small</Button>\n <Button size=\"md\">Medium</Button>\n <Button size=\"lg\">Large</Button>\n </Stack>"},{"name":"Disabled","description":"Blocks clicks and drops the button out of the tab order.","code":"<Button disabled>Unavailable</Button>"},{"name":"As Child","description":"Paints button styles onto an anchor or router link; props forward to the child.","code":"<Button asChild variant=\"outline\" aria-label=\"Open billing settings\">\n <a href=\"#billing-settings\">Billing settings</a>\n </Button>"},{"name":"Long Label","description":"Long labels stay on one line; shorten the label or give the button room.","code":"<Button>\n Save the localized account preferences and notify every affected workspace administrator\n </Button>"}],"ai":{"compositionPattern":"compound","subComponents":["Root"]},"contract":{"propsSummary":["variant: solid|soft|outline|ghost|link (default: solid)","tone: neutral|accent|info|success|warning|danger (default: accent on solid/link, neutral on soft/outline/ghost)","size: sm|md|lg (default: md)","disabled: boolean - disables interaction","type: button|submit|reset (default: button)","onClick: (event) => void - action handler","asChild: boolean - composes styles/props onto a child element (links/router links)","icon: boolean - icon-only square layout (can be combined with visual variants)"],"a11yRules":["A11Y_BTN_LABEL","A11Y_BTN_FOCUS"]},"matrix":{"axes":{"variant":"auto","tone":"auto","size":"auto","theme":["light","dark"]},"forced":["hover","focus","disabled"],"worstCase":{"children":"A long localized action label that wraps without hiding the action"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Button/index.tsx","exportName":"Button","performance":{"bundleSize":1272,"rawSize":2544,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Button (self)","bytes":1544,"percent":61},{"path":"src/utils/canonical-stamp.ts","bytes":217,"percent":9},{"path":"ComponentDefaults","bytes":194,"percent":8}]}},"ButtonGroup":{"filePath":"src/components/ButtonGroup/index.tsx","meta":{"name":"ButtonGroup","description":"Lays out related buttons in a row with one shared gap and alignment.","category":"actions","tags":["button","group","toolbar","actions","layout"],"status":"stable"},"usage":{"when":["Confirm/cancel pairs at the end of a form","Toolbars and action bars","Pagination controls"],"whenNot":["Unrelated buttons — use Stack","Navigation links — use a nav element","A single button"],"guidelines":["Two to four buttons; more belongs in a Menu","Confirming action goes last","One primary button per group","align=\"end\" for form footers","Pass role, aria-label, id and data-* straight through to ButtonGroup"],"accessibility":["Each button stays individually focusable","Add role=\"group\" plus aria-label when the set needs a name","Order buttons the way they read, not the way they look"]},"props":{"children":{"type":"node","description":"Button elements to group together","required":true},"gap":{"type":"enum","description":"Spacing between buttons","default":"sm","required":false,"values":["none","xs","sm","md"]},"wrap":{"type":"boolean","description":"Allow buttons to wrap to next line","default":"false","required":false},"align":{"type":"enum","description":"Alignment of buttons","required":false,"values":["start","center","end"]}},"relations":[{"component":"Button","relationship":"child","note":"ButtonGroup contains Button components"},{"component":"Stack","relationship":"alternative","note":"Use Stack for more general layout needs"}],"variants":[{"name":"Default","description":"Confirming action sits last in the row.","code":"<ButtonGroup>\n <Button variant=\"soft\">Cancel</Button>\n <Button variant=\"solid\">Save</Button>\n</ButtonGroup>"},{"name":"Spacing","description":"Four gap steps, from touching to airy.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <ButtonGroup gap=\"none\">\n <Button variant=\"soft\" size=\"sm\">None</Button>\n <Button variant=\"soft\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"xs\">\n <Button variant=\"soft\" size=\"sm\">XS</Button>\n <Button variant=\"soft\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"sm\">\n <Button variant=\"soft\" size=\"sm\">SM</Button>\n <Button variant=\"soft\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"md\">\n <Button variant=\"soft\" size=\"sm\">MD</Button>\n <Button variant=\"soft\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n</Stack>"},{"name":"Alignment","description":"Pins the row to the left, centre, or right of its container.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <ButtonGroup align=\"start\">\n <Button variant=\"soft\" size=\"sm\">Start</Button>\n <Button variant=\"soft\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"center\">\n <Button variant=\"soft\" size=\"sm\">Center</Button>\n <Button variant=\"soft\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"end\">\n <Button variant=\"soft\" size=\"sm\">End</Button>\n <Button variant=\"soft\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n</Stack>"},{"name":"Wrapping","description":"Buttons drop to a second line instead of overflowing.","code":"<ButtonGroup wrap>\n <Button variant=\"soft\" size=\"sm\">Approve</Button>\n <Button variant=\"soft\" size=\"sm\">Request changes</Button>\n <Button variant=\"soft\" size=\"sm\">Reassign reviewer</Button>\n <Button variant=\"soft\" size=\"sm\">Move to backlog</Button>\n <Button variant=\"soft\" size=\"sm\">Archive</Button>\n</ButtonGroup>"},{"name":"Form Actions","description":"Right-aligned pair, named for screen readers.","code":"<ButtonGroup align=\"end\" role=\"group\" aria-label=\"Form actions\">\n <Button variant=\"ghost\">Cancel</Button>\n <Button variant=\"solid\">Submit</Button>\n</ButtonGroup>"}],"contract":{"propsSummary":["children: ReactNode - buttons to group","gap: none|xs|sm|md - spacing between buttons","wrap: boolean - allow wrapping","align: start|center|end - alignment","Pass-through DOM props supported on root (id, role, aria-*, data-*, handlers)"],"a11yRules":["A11Y_GROUP_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","gap: none|xs|sm|md (default: sm)","wrap: boolean (default: false)","align: start|center|end"],"sourcePath":"src/components/ButtonGroup/index.tsx","exportName":"ButtonGroup","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:51.693Z"},"performance":{"bundleSize":599,"rawSize":1007,"complexity":"lightweight","budgetPercent":4,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ButtonGroup (self)","bytes":427,"percent":42}]}},"Card":{"filePath":"src/components/Card/Card.fragment.tsx","meta":{"name":"Card","description":"Groups related content onto one bounded surface.","category":"layout","status":"stable","tags":["container","layout","surface"]},"guidance":{"when":["Grouping related content behind one boundary","Previews, summaries, and dashboard tiles","Separating sections that spacing alone cannot"],"whenNot":["Plain text that needs no grouping","Modal surfaces (use Dialog)","Navigation items (use List or Sidebar)"],"dont":[{"reason":"Do not use a Card as a modal surface.","bad":"<Card>Confirm deletion</Card>","good":"<Card variant=\"outline\">\n <Card.Body>Inline summary</Card.Body>\n </Card>"}],"guidelines":["Keep one variant per context — mixed variants read as noise","Cards sharing a grid row should size uniformly","tone is earned: accent, warning and danger paint the capsule — reserve it for one surface per page","soft with padding=\"none\" plus Card.Header divided and Card.Body padding is the dashboard panel","Prefer a Button or Link inside the card over making the whole card clickable"],"accessibility":["Card is a semantic container (article/div/section); onClick adds keyboard and role=\"button\" behavior, but explicit Button or Link actions are preferred","Card titles should be appropriate heading levels"]},"usage":{"when":["Grouping related content behind one boundary","Previews, summaries, and dashboard tiles","Separating sections that spacing alone cannot"],"whenNot":["Plain text that needs no grouping","Modal surfaces (use Dialog)","Navigation items (use List or Sidebar)"],"dont":[{"reason":"Do not use a Card as a modal surface.","bad":"<Card>Confirm deletion</Card>","good":"<Card variant=\"outline\">\n <Card.Body>Inline summary</Card.Body>\n </Card>"}],"guidelines":["Keep one variant per context — mixed variants read as noise","Cards sharing a grid row should size uniformly","tone is earned: accent, warning and danger paint the capsule — reserve it for one surface per page","soft with padding=\"none\" plus Card.Header divided and Card.Body padding is the dashboard panel","Prefer a Button or Link inside the card over making the whole card clickable"],"accessibility":["Card is a semantic container (article/div/section); onClick adds keyboard and role=\"button\" behavior, but explicit Button or Link actions are preferred","Card titles should be appropriate heading levels"]},"props":{"as":{"type":"enum","description":"Root element tag.","default":"article","required":false,"values":["article","div","section"]},"children":{"type":"node","description":"","required":true},"padding":{"type":"enum","description":"Inner padding.","default":"md","required":false,"values":["none","sm","md","lg"]},"style":{"type":"object","description":"","required":false},"tone":{"type":"enum","description":"Earned-moment capsule. Any tone other than `neutral` paints a\ntone-tinted hairline, a radial wash and the capsule radius on top of the\nvariant: `accent` (the moment), `danger` (a merge is held), `warning`\n(enforcement lapsed). Reserve it for the few surfaces that earn emphasis.","default":"neutral","required":false,"values":["neutral","accent","warning","danger"]},"variant":{"type":"enum","description":"Surface chrome.\n\n- `solid`: the filled, elevated surface for general-purpose cards.\n- `soft`: quiet tint fill for metric tiles and dashboard panels. Add\n `padding=\"none\"` and let `Card.Header divided` + `Card.Body padding`\n own their inset for a panel.\n- `outline`: transparent with a hairline border, for dense layouts.","default":"solid","required":false,"values":["solid","soft","outline"]}},"relations":[{"component":"Grid","relationship":"parent","note":"Use Grid + Card for responsive card layouts"},{"component":"List","relationship":"alternative","note":"Use List for linear, text-first layouts"}],"variants":[{"name":"Default","description":"Quiet surface with a title and description.","code":"<Card>\n <Card.Header>\n <Card.Title>Card title</Card.Title>\n <Card.Description>A brief description</Card.Description>\n </Card.Header>\n <Card.Body>Related content</Card.Body>\n </Card>","canonical":true},{"name":"Content Only","description":"Body alone, when there is nothing to title.","code":"<Card>\n <Card.Body>Just content, no header or footer.</Card.Body>\n </Card>"},{"name":"With Footer","description":"Footer parks the actions below the content.","code":"<Card>\n <Card.Header>\n <Card.Title>Card with footer</Card.Title>\n <Card.Description>Complete card layout</Card.Description>\n </Card.Header>\n <Card.Body>Main content area.</Card.Body>\n <Card.Footer>Footer actions go here</Card.Footer>\n </Card>"},{"name":"Outline","description":"Hairline border on a transparent surface, for dense layouts.","code":"<Card variant=\"outline\">\n <Card.Body>Related content</Card.Body>\n </Card>"},{"name":"Soft","description":"Quiet tint fill: metric tiles and dashboard panels read as one system.","code":"<Card variant=\"soft\">\n <Card.Body>\n <Text scale=\"xl\" weight=\"semibold\">\n 94%\n </Text>\n <Text scale=\"sm\" color=\"secondary\">\n Component coverage\n </Text>\n </Card.Body>\n </Card>"},{"name":"Panel","description":"Divided header; the body owns its own spacing.","code":"<Card variant=\"soft\" padding=\"none\">\n <Card.Header divided>\n <Card.Title>Overview</Card.Title>\n </Card.Header>\n <Card.Body padding=\"md\">Panel content</Card.Body>\n </Card>"},{"name":"Accent","description":"Earned-moment capsule: accent hairline and wash, for the few surfaces that deserve emphasis.","code":"<Card variant=\"soft\" tone=\"accent\" padding=\"lg\">\n <Card.Header>\n <Card.Title>Finish setting up governance</Card.Title>\n <Card.Description>Run the first scan to start tracking drift.</Card.Description>\n </Card.Header>\n </Card>"},{"name":"Danger Tone","description":"The same capsule carrying state: the wash and hairline follow the tone.","code":"<Card variant=\"soft\" tone=\"danger\">\n <Card.Header>\n <Card.Title>Merge held</Card.Title>\n <Card.Description>Two blocking findings need a decision.</Card.Description>\n </Card.Header>\n </Card>"},{"name":"Interactive","description":"onClick adds keyboard and button behaviour to the whole surface.","code":"<Card as=\"section\" onClick={() => undefined}>\n <Card.Header>\n <Card.Title>Open details</Card.Title>\n <Card.Description>This card is interactive</Card.Description>\n </Card.Header>\n <Card.Body>Activate the card to view more.</Card.Body>\n </Card>"},{"name":"Section Root","description":"The as prop matches the surrounding document semantics.","code":"<Card as=\"section\" aria-labelledby=\"billing-card-title\">\n <Card.Header>\n <Card.Title id=\"billing-card-title\">Billing summary</Card.Title>\n </Card.Header>\n <Card.Body>Section semantics support the surrounding document outline.</Card.Body>\n </Card>"},{"name":"Nested Heading","description":"Pick the heading level the page outline expects.","code":"<Card variant=\"soft\" padding=\"none\">\n <Card.Header divided>\n <Card.Title as=\"h4\">Nested panel</Card.Title>\n </Card.Header>\n <Card.Body padding=\"md\">Panel content</Card.Body>\n </Card>"},{"name":"Long Content","description":"Long titles and dense text wrap without breaking the surface.","code":"<Card>\n <Card.Header>\n <Card.Title>\n A detailed localized account recovery policy for administrators across multiple\n workspaces\n </Card.Title>\n <Card.Description>\n Supporting content remains readable when translated strings take substantially more\n space than the English source.\n </Card.Description>\n </Card.Header>\n <Card.Body>\n Recovery settings apply to every affected administrator and retain an auditable history\n of the notification decision.\n </Card.Body>\n </Card>"}],"ai":{"compositionPattern":"compound","subComponents":["Header","Title","Description","Body","Footer"],"requiredChildren":["Body"],"commonPatterns":["<Card><Card.Body>{content}</Card.Body></Card>","<Card><Card.Header><Card.Title>{title}</Card.Title></Card.Header><Card.Body>{content}</Card.Body></Card>","<Card><Card.Header><Card.Title>{title}</Card.Title><Card.Description>{desc}</Card.Description></Card.Header><Card.Body>{content}</Card.Body><Card.Footer>{actions}</Card.Footer></Card>"]},"contract":{"propsSummary":["variant: solid|soft|outline (default: solid)","tone: neutral|accent|warning|danger (default: neutral) - non-neutral paints the earned-moment capsule","padding: none|sm|md|lg (default: md) - none + Card.Header divided + Card.Body padding = panel","as: article|div|section (default: article) - card root element","onClick: (event) => void - click handler on root (adds role/button keyboard behavior)","Sub-components: Card.Header, Card.Title, Card.Description, Card.Body, Card.Footer","Card.Body padding: none|sm|md|lg - use for panel body spacing"],"a11yRules":["A11Y_CARD_HEADING","A11Y_CARD_INTERACTIVE"]},"matrix":{"axes":{"variant":"auto","tone":"auto","padding":"auto","theme":["light","dark"]},"forced":["hover","focus"],"worstCase":{"children":"A long localized heading and dense multi-line supporting content"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Card/index.tsx","exportName":"Card","performance":{"bundleSize":1127,"rawSize":2685,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Card (self)","bytes":2003,"percent":75}]}},"Chart":{"filePath":"src/components/Chart/index.tsx","meta":{"name":"Chart","description":"Plots your data with tooltips, legends, and colors that track the theme.","category":"display","tags":["chart","graph","data-visualization","recharts"],"status":"stable","dependencies":[{"name":"recharts","version":">=2.0.0 || >=3.0.0","reason":"Optional — powers Chart.Tooltip and Chart.Legend; both render nothing until it is installed."}]},"usage":{"when":["A trend over time is the point","Categories need comparing side by side","A whole splits into parts worth seeing"],"whenNot":["One number tells the story (use Text or Badge)","Distance to a goal (use Progress)","Readers need exact values (use Table)"],"guidelines":["Wrap every recharts chart in ChartContainer","Map each data key to a label and color in ChartConfig","Colors come from --fui-* variables so both themes stay readable","Pair with ChartTooltip and ChartLegend rather than recharts' own","Give the container a real height — recharts cannot measure zero"],"accessibility":["accessibilityLayer is on by default","ChartConfig labels are what screen readers read","Pass dataTable to offer the same numbers as text"]},"props":{"config":{"type":"object","description":"ChartConfig mapping data keys to labels/colors (optional icon per series)","required":true},"children":{"type":"element","description":"A recharts chart component (LineChart, BarChart, etc.)","required":true},"summary":{"type":"string","description":"Non-visual summary announced to assistive technology users","required":false},"dataTable":{"type":"node","description":"Optional accessible data table or textual fallback","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Card","relationship":"parent","note":"Charts are typically placed inside Cards"},{"component":"Progress","relationship":"alternative","note":"Use Progress for single-value completion"},{"component":"Table","relationship":"sibling","note":"Combine with Table for full data views"}],"variants":[{"name":"Line Chart","description":"Two series share one scale, so the gap between them reads instantly.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n users: { label: 'Users', color: 'var(--fui-color-info)' },\n }}\n >\n <LineChart data={monthlyData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"month\" />\n <YAxis />\n <ChartTooltip />\n <ChartLegend />\n <Line type=\"monotone\" dataKey=\"revenue\" stroke=\"var(--fui-color-accent)\" strokeWidth={2} dot={false} />\n <Line type=\"monotone\" dataKey=\"users\" stroke=\"var(--fui-color-info)\" strokeWidth={2} dot={false} />\n </LineChart>\n </ChartContainer>\n</div>"},{"name":"Bar Chart","description":"Fixed categories, compared by height — the safest default.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n sessions: { label: 'Sessions', color: 'var(--fui-color-accent)' },\n }}\n >\n <BarChart data={deviceData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"device\" />\n <YAxis />\n <ChartTooltip />\n <Bar dataKey=\"sessions\" fill=\"var(--fui-color-accent)\" radius={[4, 4, 0, 0]} />\n </BarChart>\n </ChartContainer>\n</div>"},{"name":"Area Chart","description":"The fill under the line stresses volume, not just direction.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n }}\n >\n <AreaChart data={monthlyData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"month\" />\n <YAxis />\n <ChartTooltip />\n <Area type=\"monotone\" dataKey=\"revenue\" stroke=\"var(--fui-color-accent)\" fill=\"var(--fui-color-accent)\" fillOpacity={0.15} strokeWidth={2} />\n </AreaChart>\n </ChartContainer>\n</div>"},{"name":"Pie Chart","description":"Parts of one whole — keep it under six slices or it stops reading.","code":"<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n Chrome: { label: 'Chrome', color: 'var(--fui-color-accent)' },\n Firefox: { label: 'Firefox', color: 'var(--fui-color-info)' },\n Safari: { label: 'Safari', color: 'var(--fui-color-success)' },\n Edge: { label: 'Edge', color: 'var(--fui-color-warning)' },\n }}\n >\n <PieChart>\n <ChartTooltip />\n <ChartLegend />\n <Pie\n data={browserData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={60}\n outerRadius={90}\n strokeWidth={2}\n >\n {browserData.map((entry) => (\n <Cell key={entry.name} fill={entry.color} />\n ))}\n </Pie>\n </PieChart>\n </ChartContainer>\n</div>"}],"contract":{"propsSummary":["config: ChartConfig - maps data keys to labels and theme colors","children: ReactElement - recharts chart component","Chart.Tooltip / Chart.Legend support custom content renderers for advanced overlays"],"a11yRules":["A11Y_CHART_LABEL"]},"propsSummary":["config: object (required)","children: element (required)","summary: string","dataTable: node","style: object"],"sourcePath":"src/components/Chart/index.tsx","exportName":"ChartContainer","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.043Z"},"ai":{"subComponents":["Root","Tooltip","TooltipContent","Legend","LegendContent","preload"],"compositionPattern":"compound"},"performance":{"bundleSize":2010,"rawSize":4575,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Chart (self)","bytes":3659,"percent":80},{"path":"src/utils/aria.ts","bytes":109,"percent":2},{"path":"src/utils/env.ts","bytes":92,"percent":2}]}},"Checkbox":{"filePath":"src/components/Checkbox/index.tsx","meta":{"name":"Checkbox","description":"Selects options that take effect when a form is submitted.","category":"inputs","tags":["checkbox","form","boolean","selection","input"],"status":"stable"},"usage":{"when":["Choices that apply only once the form is submitted","Picking several items from a list","Accepting terms","Filter and preference lists"],"whenNot":["Settings that apply instantly (use Switch)","One choice from a few (use RadioGroup)","Many options (use Select)"],"guidelines":["Always show a label","Add helperText when the consequence is not obvious","Keep related boxes together","Use indeterminate for a parent whose children are partly checked"],"accessibility":["Label is tied to the box","Space toggles it","Focus ring stays visible","Indeterminate is announced as mixed"]},"props":{"checked":{"type":"boolean","description":"Controlled checked state","required":false},"defaultChecked":{"type":"boolean","description":"Default checked state (uncontrolled)","required":false},"onCheckedChange":{"type":"function","description":"Called when checked state changes","required":false},"onChange":{"type":"function","description":"Alias for onCheckedChange: (checked: boolean) => void","required":false},"indeterminate":{"type":"boolean","description":"Indeterminate state (partial selection)","default":"false","required":false},"disabled":{"type":"boolean","description":"Disable the checkbox","default":"false","required":false},"required":{"type":"boolean","description":"Whether the checkbox is required","default":"false","required":false},"size":{"type":"enum","description":"Checkbox size","default":"\"md\"","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Chrome. Omit for the inline checkbox beside its label; 'outline' renders a full-width bordered surface with the checkbox tucked inside.","required":false,"values":["outline"]},"label":{"type":"string","description":"Label text","required":false},"helperText":{"type":"string","description":"Helper text shown below the label (preferred)","required":false},"description":{"type":"string","description":"Deprecated alias for helperText","required":false},"name":{"type":"string","description":"Name attribute for form submission","required":false},"value":{"type":"string","description":"Value attribute for form submission","required":false},"id":{"type":"string","description":"ID for the checkbox input","required":false},"controlClassName":{"type":"string","description":"Class name for the checkbox control element (stable styling target)","required":false},"contentClassName":{"type":"string","description":"Class name for the label/description content wrapper","required":false},"aria-label":{"type":"string","description":"Accessible label for icon-only mode","required":false},"aria-labelledby":{"type":"string","description":"Accessible labelled-by relationship for icon-only mode","required":false},"aria-describedby":{"type":"string","description":"Accessible described-by relationship","required":false},"form":{"type":"string","description":"ID of the form that owns the hidden input","required":false},"inputRef":{"type":"union","description":"Ref to the hidden input element","required":false},"parent":{"type":"boolean","description":"Whether this checkbox controls child checkboxes in a checkbox group","required":false},"readOnly":{"type":"boolean","description":"Whether the checkbox cannot be changed by the user","default":"false","required":false},"uncheckedValue":{"type":"string","description":"Value submitted when unchecked","required":false}},"relations":[{"component":"Switch","relationship":"alternative","note":"Use Switch for immediate-effect settings"},{"component":"Input","relationship":"sibling","note":"Checkbox handles boolean; Input handles text"}],"variants":[{"name":"Default","description":"One box, one label, off to start.","code":"<StatefulCheckbox label=\"Accept terms and conditions\" />"},{"name":"With Helper Text","description":"Second line spells out what opting in does.","code":"<StatefulCheckbox\n label=\"Email notifications\"\n helperText=\"Receive email updates about your account activity\"\n/>"},{"name":"Checked","description":"Starts on.","code":"<StatefulCheckbox defaultChecked label=\"Subscribe to newsletter\" />"},{"name":"Indeterminate","description":"A dash on the parent means only some children are on.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox indeterminate label=\"Select all\" />\n <div style={{ marginLeft: '24px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <StatefulCheckbox defaultChecked label=\"Option 1\" />\n <StatefulCheckbox label=\"Option 2\" />\n <StatefulCheckbox defaultChecked label=\"Option 3\" />\n </div>\n</div>"},{"name":"Sizes","description":"Three box sizes: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulCheckbox size=\"sm\" label=\"Small checkbox\" />\n <StatefulCheckbox size=\"md\" label=\"Medium checkbox\" />\n <StatefulCheckbox size=\"lg\" label=\"Large checkbox\" />\n</div>"},{"name":"Disabled","description":"Locked in both positions, on and off.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Checkbox disabled label=\"Disabled unchecked\" />\n <Checkbox disabled checked label=\"Disabled checked\" />\n</div>"},{"name":"Custom Styling Targets","description":"controlClassName styles the box, contentClassName the text.","code":"<Checkbox\n label=\"Styled checkbox\"\n helperText=\"Control and content wrappers can be targeted independently\"\n controlClassName=\"demo-checkbox-control\"\n contentClassName=\"demo-checkbox-content\"\n/>"}],"contract":{"propsSummary":["checked: boolean - controlled checked state","onCheckedChange: (checked) => void - change handler","onChange: (checked) => void - alias for onCheckedChange","indeterminate: boolean - partial selection state","variant: outline - full-width bordered surface; omit for the inline control","label: string - checkbox label","helperText: string - helper text (preferred)","description: string - deprecated alias for helperText","controlClassName/contentClassName - explicit styling targets for control and content"],"a11yRules":["A11Y_CHECKBOX_LABEL","A11Y_CHECKBOX_FOCUS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["checked: boolean","defaultChecked: boolean","onCheckedChange: function","onChange: function","indeterminate: boolean (default: false)","disabled: boolean (default: false)","required: boolean (default: false)","size: sm|md|lg (default: md)","variant: outline","label: string","helperText: string","description: string","name: string","value: string","id: string","controlClassName: string","contentClassName: string","aria-label: string","aria-labelledby: string","aria-describedby: string"],"sourcePath":"src/components/Checkbox/index.tsx","exportName":"Checkbox","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.226Z"},"performance":{"bundleSize":1384,"rawSize":3417,"complexity":"lightweight","budgetPercent":9,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Checkbox (self)","bytes":2508,"percent":73},{"path":"ComponentDefaults","bytes":198,"percent":6},{"path":"src/utils/aria.ts","bytes":110,"percent":3}]}},"Chip":{"filePath":"src/components/Chip/index.tsx","meta":{"name":"Chip","description":"Pill control for filtering, multi-select, and removable tags.","category":"inputs","tags":["chip","tag","filter","selection","multi-select","action"],"status":"stable"},"usage":{"when":["Filtering a list by tag or category","Multi-select from a compact set","Showing filters the user can dismiss"],"whenNot":["Read-only status — use Badge","Switching views — use Tabs","On/off state — use Switch","A main call to action — use Button"],"guidelines":["One to three words per chip","Chip.Group when chips share selection state","Keep xs for filters and tags; size up only to match a taller control track","onRemove only when the chip is genuinely dismissible","Pass an explicit value when children are custom JSX"],"accessibility":["Chips are buttons; selection is reported via aria-pressed","Add role and aria-label to Chip.Group when the set needs a name","Remove buttons carry the chip text in their aria-label","Disabled chips are skipped by keyboard and pointer"]},"props":{"children":{"type":"node","description":"Chip label text","required":true},"variant":{"type":"enum","description":"Chrome family. solid is the tinted pill; outline is hairline-bordered; soft is info-tinted for a suggestion","default":"solid","required":false,"values":["solid","outline","soft"]},"size":{"type":"enum","description":"Chip size","default":"\"xs\"","required":false,"values":["xs","sm","md","lg"]},"selected":{"type":"boolean","description":"Whether the chip is in a selected state","default":"false","required":false},"icon":{"type":"node","description":"Icon element rendered before the label","required":false},"avatar":{"type":"node","description":"Avatar element rendered before the label","required":false},"onRemove":{"type":"function","description":"Makes chip removable. Called when X is clicked.","required":false},"value":{"type":"string","description":"Value identifier used by Chip.Group for selection tracking","required":false},"disabled":{"type":"boolean","description":"","default":"false","required":false},"onClick":{"type":"function","description":"","required":false}},"relations":[{"component":"Badge","relationship":"sibling","note":"Badge is display-only; Chip is interactive"},{"component":"ToggleGroup","relationship":"alternative","note":"Use ToggleGroup for mutually exclusive options"},{"component":"Button","relationship":"alternative","note":"Use Button for primary actions, Chip for selection/filtering"}],"variants":[{"name":"Variants","description":"Tinted, hairline, and accent-soft chrome.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip variant=\"solid\">Solid</Chip>\n <Chip variant=\"outline\">Outline</Chip>\n <Chip variant=\"soft\">Soft</Chip>\n</Stack>"},{"name":"Sizes","description":"xs for filter rows; larger sizes match taller field tracks.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\" wrap>\n <Chip variant=\"outline\" size=\"xs\">Extra small</Chip>\n <Chip variant=\"outline\" size=\"sm\">Small</Chip>\n <Chip variant=\"outline\" size=\"md\">Medium</Chip>\n <Chip variant=\"outline\" size=\"lg\">Large</Chip>\n</Stack>"},{"name":"Selected","description":"All three variants share one selection treatment.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip selected>Solid</Chip>\n <Chip variant=\"outline\" selected>Outline</Chip>\n <Chip variant=\"soft\" selected>Soft</Chip>\n</Stack>"},{"name":"With Avatar","description":"Leading face, for people-shaped selections.","code":"<Chip avatar={<img src=\"https://i.pravatar.cc/32?u=chip\" alt=\"\" />}>\n Jane Doe\n</Chip>"},{"name":"With Remove","description":"Trailing dismiss button clears the tag.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip variant=\"outline\" onRemove={() => {}}>React</Chip>\n <Chip variant=\"outline\" selected onRemove={() => {}}>TypeScript</Chip>\n <Chip variant=\"soft\" onRemove={() => {}}>SCSS</Chip>\n</Stack>"},{"name":"Chip Group","description":"Selection state is held by the group, not each chip.","code":"<Chip.Group defaultValue={['react']}>\n <Chip value=\"react\">React</Chip>\n <Chip value=\"vue\">Vue</Chip>\n <Chip value=\"angular\">Angular</Chip>\n <Chip value=\"svelte\">Svelte</Chip>\n</Chip.Group>"},{"name":"Chip Group with Custom Labels","description":"Custom JSX children need an explicit value.","code":"<Chip.Group aria-label=\"Assignees\">\n <Chip value=\"jane\">\n <span>Jane Doe</span>\n </Chip>\n <Chip value=\"sam\">\n <span>Sam Lee</span>\n </Chip>\n</Chip.Group>"},{"name":"Disabled","description":"Dimmed and unreachable, selected or not.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" wrap>\n <Chip variant=\"outline\" disabled>Disabled</Chip>\n <Chip variant=\"outline\" disabled selected>Disabled selected</Chip>\n</Stack>"}],"contract":{"propsSummary":["children: ReactNode - chip label (required)","variant: solid|outline|soft - chrome family","size: xs|sm|md|lg - chip size (xs by default)","selected: boolean - selection state","icon/avatar: ReactNode - leading visual","onRemove: () => void - makes chip removable","value: string - identifier for Chip.Group","Chip.Group forwards DOM props (id, role, aria-*, data-*, handlers)","Chip.Group: non-string chip labels should set an explicit value"],"a11yRules":["A11Y_CHIP_SELECTION","A11Y_CHIP_DISMISS"]},"ai":{"compositionPattern":"compound","subComponents":["Group"]},"propsSummary":["children: node (required)","variant: solid|outline|soft (default: solid)","size: xs|sm|md|lg (default: xs)","selected: boolean (default: false)","icon: node","avatar: node","onRemove: function","value: string","disabled: boolean (default: false)","onClick: function"],"sourcePath":"src/components/Chip/index.tsx","exportName":"Chip","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:54.270Z"},"performance":{"bundleSize":1209,"rawSize":2417,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Chip (self)","bytes":1742,"percent":72},{"path":"src/utils/env.ts","bytes":89,"percent":4}]}},"CodeBlock":{"filePath":"src/components/CodeBlock/index.tsx","meta":{"name":"CodeBlock","description":"Shows code with syntax colors, a copy button, and diff or collapse when you need them.","category":"display","tags":["code","syntax","highlighting","documentation","developer","diff"],"status":"stable","dependencies":[{"name":"shiki","version":">=1.0.0","reason":"Optional — provides syntax highlighting; without it code renders unhighlighted."}]},"usage":{"when":["Code examples inside prose or docs","Install and config snippets","Showing what changed, as a diff"],"whenNot":["The user needs to edit it (use an editor)","A couple of words inline (use a code element)"],"guidelines":["Set language every time — wrong highlighting is worse than none","filename for a real file, title for a label, caption for the aside","Line numbers earn their keep once you need to point at a line","highlightLines for emphasis; addedLines and removedLines for diffs","maxHeight or collapsible keeps a long file from swallowing the page","CodeBlock.Tabbed groups the same snippet across languages"],"accessibility":["Renders as semantic pre and code","The copy button is labelled and keyboard reachable","The collapse toggle reports aria-expanded"]},"props":{"code":{"type":"string","description":"The code string to display","required":true},"language":{"type":"enum","description":"Programming language for syntax highlighting","default":"tsx","required":false,"values":["tsx","typescript","ts","javascript","js","jsx","bash","shell","css","scss","sass","json","html","xml","markdown","md","yaml","yml","python","py","ruby","go","rust","java","kotlin","swift","c","cpp","csharp","php","sql","graphql","diff","plaintext","text"]},"theme":{"type":"enum","description":"Syntax highlighting theme. css-variables maps spans onto --fui-code-token-* so both themes stay readable.","default":"css-variables","required":false,"values":["css-variables","synthwave-84","github-dark","github-light","one-dark-pro","dracula","nord","monokai","vitesse-dark","vitesse-light","min-dark","min-light"]},"showCopy":{"type":"boolean","description":"Whether to show the copy button","default":"true","required":false},"title":{"type":"string","description":"Optional title displayed above the code block (external label)","required":false},"filename":{"type":"string","description":"Optional filename shown in header bar inside code block","required":false},"caption":{"type":"string","description":"Optional caption displayed below the code block","required":false},"showLineNumbers":{"type":"boolean","description":"Whether to display line numbers","default":"false","required":false},"startLineNumber":{"type":"number","description":"Starting line number (useful for code excerpts)","default":"1","required":false},"highlightLines":{"type":"array","description":"Lines to highlight (e.g., [1, 3, \"5-7\"])","required":false},"addedLines":{"type":"array","description":"Lines marked as added in diff view (e.g., [2, \"4-6\"])","required":false},"removedLines":{"type":"array","description":"Lines marked as removed in diff view (e.g., [1, 3])","required":false},"wordWrap":{"type":"boolean","description":"Enable word wrapping for long lines","default":"false","required":false},"maxHeight":{"type":"number","description":"Maximum height in pixels (enables scrolling)","required":false},"collapsible":{"type":"boolean","description":"Allow collapsing/expanding the code block","default":"false","required":false},"defaultCollapsed":{"type":"boolean","description":"Initial collapsed state (only applies when collapsible is true)","default":"false","required":false},"collapsedLines":{"type":"number","description":"Number of lines to show when collapsed","default":"5","required":false},"collapseAction":{"type":"enum","description":"Collapse control copy: line-count bar, or a single Expand / Collapse control","default":"lines","required":false,"values":["lines","expand"]},"compact":{"type":"boolean","description":"Compact mode with reduced padding","default":"false","required":false},"persistentCopy":{"type":"boolean","description":"Show a persistent copy button that is always visible","default":"false","required":false},"copyPlacement":{"type":"enum","description":"Where to place the copy button when not using persistentCopy","default":"auto","required":false,"values":["auto","header","overlay"]},"bg":{"type":"string","description":"Custom background color for the code block (useful when the content area is pure black or dark gray)","required":false},"onCopy":{"type":"function","description":"Callback fired when the copy button is clicked and copy succeeds","required":false}},"relations":[{"component":"Card","relationship":"parent","note":"Can be wrapped in Card for additional context"},{"component":"Tabs","relationship":"child","note":"Use in Tabs for showing code in multiple languages"}],"variants":[{"name":"Default","description":"Pass code and language; highlighting and copy come free.","code":"<CodeBlock code={`import { Button } from '@usefragments/ui';\n\nfunction App() {\n return <Button>Click me</Button>;\n}`} language=\"tsx\" />"},{"name":"With Filename","description":"A header bar names the source file and holds the copy button.","code":"<CodeBlock filename=\"app.tsx\" code={`import { Button, Card } from '@usefragments/ui';\n\nfunction App() {\n return (\n <Card>\n <Card.Header>Welcome</Card.Header>\n <Card.Content>\n <Button>Get Started</Button>\n </Card.Content>\n </Card>\n );\n}`} language=\"tsx\" />"},{"name":"With Title","description":"A label above the block, outside the code surface.","code":"<CodeBlock title=\"Installation\" code=\"npm install @usefragments/ui\" language=\"bash\" />"},{"name":"With Caption","description":"A footer line for the aside that does not belong in the code.","code":"<CodeBlock\n code={`const API_URL = process.env.NEXT_PUBLIC_API_URL;`}\n language=\"typescript\"\n caption=\"Environment variables must be prefixed with NEXT_PUBLIC_ to be available in the browser.\"\n/>"},{"name":"With Line Numbers","description":"Turn these on once a snippet is long enough to point at.","code":"<CodeBlock code={`const greeting = \"Hello\";\nconst name = \"World\";\nconsole.log(\\`\\${greeting}, \\${name}!\\`);`} language=\"typescript\" showLineNumbers />"},{"name":"Custom Start Line","description":"Numbering starts where the excerpt actually starts in the file.","code":"<CodeBlock\n code={` return (\n <button onClick={() => setCount(c => c + 1)}>\n Count: {count}\n </button>\n );\n}`}\n language=\"tsx\"\n showLineNumbers\n startLineNumber={15}\n caption=\"Lines 15-20 from Counter.tsx\"\n/>"},{"name":"With Highlighted Lines","description":"Marks the lines the prose is talking about.","code":"<CodeBlock code={`import { useState } from 'react';\n\nfunction Counter() {\n const [count, setCount] = useState(0);\n\n return (\n <button onClick={() => setCount(c => c + 1)}>\n Count: {count}\n </button>\n );\n}`} language=\"tsx\" showLineNumbers highlightLines={[4, '7-9']} />"},{"name":"Diff View","description":"Added and removed lines, side by side with the rest.","code":"<CodeBlock\n code={`import { useState } from 'react';\nimport { useCallback } from 'react';\n\nfunction Counter() {\n const [count, setCount] = useState(0);\n const increment = () => setCount(c => c + 1);\n const increment = useCallback(() => setCount(c => c + 1), []);\n\n return <button onClick={increment}>Count: {count}</button>;\n}`}\n language=\"tsx\"\n showLineNumbers\n removedLines={[6]}\n addedLines={[2, 7]}\n/>"},{"name":"Custom Theme","description":"Any Shiki theme works — pass its name to theme.","code":"<CodeBlock\n code={`async function fetchUser(id: string) {\n const response = await fetch(\\`/api/users/\\${id}\\`);\n return response.json();\n}`}\n language=\"typescript\"\n theme=\"github-dark\"\n/>"},{"name":"Word Wrap","description":"Long lines break instead of scrolling sideways.","code":"<CodeBlock\n code={`const longString = \"This is a very long string that would normally cause horizontal scrolling, but with word wrap enabled it will break to the next line instead.\";`}\n language=\"typescript\"\n wordWrap\n/>"},{"name":"Max Height with Scroll","description":"Caps the height so one snippet cannot own the page.","code":"<CodeBlock\n code={`// This code block has a maximum height\nfunction processItems(items: string[]) {\n const results = [];\n for (const item of items) {\n if (item.startsWith('_')) {\n continue;\n }\n const processed = item.trim().toLowerCase();\n if (processed.length > 0) {\n results.push(processed);\n }\n }\n return results;\n}\n\nexport default processItems;`}\n language=\"typescript\"\n maxHeight={150}\n showLineNumbers\n/>"},{"name":"Collapsible","description":"Shows the opening lines and hides the rest behind a toggle.","code":"<CodeBlock\n code={`import React, { useState, useEffect } from 'react';\n\ninterface User {\n id: string;\n name: string;\n email: string;\n avatar?: string;\n}\n\nexport function UserProfile({ userId }: { userId: string }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n async function fetchUser() {\n try {\n setLoading(true);\n const response = await fetch(\\`/api/users/\\${userId}\\`);\n if (!response.ok) throw new Error('Failed to fetch');\n const data = await response.json();\n setUser(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error');\n } finally {\n setLoading(false);\n }\n }\n fetchUser();\n }, [userId]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div>Error: {error}</div>;\n if (!user) return null;\n\n return (\n <div>\n <h1>{user.name}</h1>\n <p>{user.email}</p>\n </div>\n );\n}`}\n language=\"tsx\"\n showLineNumbers\n collapsible\n defaultCollapsed\n collapsedLines={8}\n/>"},{"name":"JSON","description":"Config files highlight the same way source does.","code":"<CodeBlock title=\"package.json\" code={`{\n \"name\": \"my-app\",\n \"dependencies\": {\n \"@usefragments/ui\": \"^0.3.0\"\n }\n}`} language=\"json\" />"},{"name":"Without Copy Button","description":"Drop the copy button when the snippet is not meant to be reused.","code":"<CodeBlock code=\"const simple = true;\" language=\"typescript\" showCopy={false} />"}],"contract":{"propsSummary":["code: string - required code content","language: tsx|typescript|javascript|jsx|bash|shell|css|scss|sass|json|html|xml|markdown|md|yaml|yml|python|py|ruby|go|rust|java|kotlin|swift|c|cpp|csharp|php|sql|graphql|diff|plaintext","theme: css-variables|synthwave-84|github-dark|github-light|one-dark-pro|dracula|nord|monokai|vitesse-dark|vitesse-light|min-dark|min-light (default: css-variables)","showCopy: boolean (default: true)","copyPlacement: auto|header|overlay (default: auto)","title: string - optional external label","filename: string - optional filename in header bar","caption: string - optional footer caption","showLineNumbers: boolean (default: false)","startLineNumber: number (default: 1)","highlightLines: (number | string)[] - lines to emphasize","addedLines: (number | string)[] - diff added lines","removedLines: (number | string)[] - diff removed lines","wordWrap: boolean (default: false)","maxHeight: number - max height with scrolling","collapsible: boolean (default: false)","defaultCollapsed: boolean (default: false)","collapsedLines: number (default: 5)","CodeBlock.Tabbed: tabs[] plus optional defaultTab/value/onValueChange for multi-language snippets; collapsible/defaultCollapsed/collapsedLines forward to every panel"],"a11yRules":["A11Y_CODE_SEMANTIC","A11Y_BTN_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Tabbed"]},"propsSummary":["code: string (required)","language: tsx|typescript|ts|javascript|js|jsx|bash|shell|css|scss|sass|json|html|xml|markdown|md|yaml|yml|python|py|ruby|go|rust|java|kotlin|swift|c|cpp|csharp|php|sql|graphql|diff|plaintext|text (default: tsx)","theme: css-variables|synthwave-84|github-dark|github-light|one-dark-pro|dracula|nord|monokai|vitesse-dark|vitesse-light|min-dark|min-light (default: css-variables)","showCopy: boolean (default: true)","title: string","filename: string","caption: string","showLineNumbers: boolean (default: false)","startLineNumber: number (default: 1)","highlightLines: array","addedLines: array","removedLines: array","wordWrap: boolean (default: false)","maxHeight: number","collapsible: boolean (default: false)","defaultCollapsed: boolean (default: false)","collapsedLines: number (default: 5)","compact: boolean (default: false)","persistentCopy: boolean (default: false)","copyPlacement: auto|header|overlay (default: auto)","bg: string","onCopy: function"],"sourcePath":"src/components/CodeBlock/index.tsx","exportName":"CodeBlock","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.626Z"},"performance":{"bundleSize":5887,"rawSize":16360,"complexity":"moderate","budgetPercent":38,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"CodeBlock (self)","bytes":11366,"percent":69},{"path":"Button","bytes":2023,"percent":12},{"path":"Tabs","bytes":1653,"percent":10},{"path":"IconButton","bytes":689,"percent":4}]}},"Collapsible":{"filePath":"src/components/Collapsible/index.tsx","meta":{"name":"Collapsible","description":"Shows or hides one region of content behind a trigger.","category":"layout","tags":["collapsible","expandable","accordion","disclosure","toggle"],"status":"stable"},"usage":{"when":["Detail most readers do not need","Optional or advanced settings","Navigation sections that fold away","Building a disclosure the other components do not cover"],"whenNot":["Several sections that should coordinate (use Accordion)","Content that must overlay the page (use Dialog or Popover)","Action lists (use Menu)"],"guidelines":["The trigger should say what opens, not 'click here'","defaultOpen for content most users want on arrival","Keep the trigger to a short phrase","Keep the chevron direction consistent across the page"],"accessibility":["Trigger must have aria-expanded to indicate state","Content region needs aria-labelledby pointing to trigger","Keyboard: Enter/Space toggles open state","Focus should remain on trigger after toggle"]},"props":{"children":{"type":"node","description":"Collapsible.Trigger and Collapsible.Content components","required":true},"defaultOpen":{"type":"boolean","description":"Whether the collapsible is initially open (uncontrolled)","default":"false","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false},"onOpenChange":{"type":"function","description":"Callback when open state changes - (open: boolean) => void","required":false},"disabled":{"type":"boolean","description":"Whether the collapsible is disabled","default":"false","required":false}},"relations":[{"component":"Accordion","relationship":"alternative","note":"Use Accordion for multiple exclusive collapsible sections"},{"component":"Sidebar","relationship":"used-by","note":"Sidebar uses Collapsible for section expand/collapse"},{"component":"Menu","relationship":"alternative","note":"Use Menu for dropdown navigation with actions"}],"variants":[{"name":"Default","description":"Starts closed and opens on click.","code":"<Collapsible>\n <Collapsible.Trigger>Click to expand</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content is hidden by default and revealed when the trigger is clicked.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Default Open","description":"Starts open for content most users want.","code":"<Collapsible defaultOpen>\n <Collapsible.Trigger>Section Title</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content is visible by default. Click the trigger to collapse.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Chevron Start","description":"Marker leads the label instead of trailing it.","code":"<Collapsible>\n <Collapsible.Trigger chevronPosition=\"start\">Navigation</Collapsible.Trigger>\n <Collapsible.Content>\n <ul style={{ margin: 0, paddingLeft: '1.5rem' }}>\n <li>Dashboard</li>\n <li>Settings</li>\n <li>Profile</li>\n </ul>\n </Collapsible.Content>\n</Collapsible>"},{"name":"No Chevron","description":"Bare trigger when the surrounding layout signals enough.","code":"<Collapsible>\n <Collapsible.Trigger showChevron={false}>Show more details</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Hidden details that appear when triggered.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Disabled","description":"Locked shut and skipped by the keyboard.","code":"<Collapsible disabled>\n <Collapsible.Trigger>Cannot toggle (disabled)</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content cannot be shown because the collapsible is disabled.</p>\n </Collapsible.Content>\n</Collapsible>"},{"name":"Multiple Sections","description":"Independent regions that ignore each other.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n <Collapsible defaultOpen>\n <Collapsible.Trigger>Getting Started</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Introduction and setup instructions.</p>\n </Collapsible.Content>\n </Collapsible>\n <Collapsible>\n <Collapsible.Trigger>Advanced Usage</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Advanced configuration options.</p>\n </Collapsible.Content>\n </Collapsible>\n <Collapsible>\n <Collapsible.Trigger>API Reference</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Complete API documentation.</p>\n </Collapsible.Content>\n </Collapsible>\n</div>"}],"contract":{"propsSummary":["defaultOpen: boolean - initial open state (default: false)","open: boolean - controlled open state","onOpenChange: (open: boolean) => void - state change callback","disabled: boolean - prevents interaction"],"a11yRules":["A11Y_EXPANDED_STATE","A11Y_REGION_LABEL","A11Y_KEYBOARD_NAV"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Trigger","Content"],"commonPatterns":["<Collapsible>\n <Collapsible.Trigger>...</Collapsible.Trigger>\n <Collapsible.Content>...</Collapsible.Content>\n</Collapsible>"],"requiredChildren":["Trigger","Content"]},"propsSummary":["children: node (required)","defaultOpen: boolean (default: false)","open: boolean","onOpenChange: function","disabled: boolean (default: false)"],"sourcePath":"src/components/Collapsible/index.tsx","exportName":"Collapsible","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:52.800Z"},"performance":{"bundleSize":1511,"rawSize":3197,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Collapsible (self)","bytes":2508,"percent":78}]}},"ColorPicker":{"filePath":"src/components/ColorPicker/index.tsx","meta":{"name":"ColorPicker","description":"Selects a color through a visual picker and hexadecimal input.","category":"inputs","tags":["color","picker","input","hex","swatch","theme"],"status":"stable","dependencies":[{"name":"react-colorful","version":">=5.0.0","reason":"Optional — renders the visual picker surface; the swatch and hex input work without it."}]},"usage":{"when":["Theme and brand customisation","Any colour the user must pick freely","Design tool inputs"],"whenNot":["A fixed palette (use RadioGroup with swatches)","Showing a colour without editing it (use a tinted Badge)","Status colour that should come from a token"],"guidelines":["Label says what the colour is for","Use helperText for constraints, such as contrast rules","Offer presets next to the picker for the common choices","Validate the hex as #RRGGBB before accepting it"],"accessibility":["Label is tied to the hex input","The swatch button carries its own aria-label","The picker popup is reachable from the keyboard","Users can type a hex instead of dragging"]},"props":{"label":{"type":"string","description":"Label text above the picker","required":false},"value":{"type":"string","description":"Controlled color value in hex format (#RRGGBB)","required":false},"defaultValue":{"type":"string","description":"Default color for uncontrolled usage","default":"#000000","required":false},"onChange":{"type":"function","description":"Called with new color value when changed","required":false},"onValueChange":{"type":"function","description":"Alias for onChange (Radix convention)","required":false},"helperText":{"type":"string","description":"Helper text below the picker (preferred)","required":false},"description":{"type":"string","description":"Deprecated alias for helperText","required":false},"error":{"type":"boolean","description":"Show error styling","default":"false","required":false},"disabled":{"type":"boolean","description":"Disable the color picker","default":"false","required":false},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["sm","md","lg"]},"showInput":{"type":"boolean","description":"Show the hex input field","default":"true","required":false}},"relations":[{"component":"Input","relationship":"sibling","note":"ColorPicker is a specialized input for colors"},{"component":"RadioGroup","relationship":"alternative","note":"Use RadioGroup for predefined color choices"},{"component":"Field","relationship":"parent","note":"ColorPicker uses Field internally for structure"}],"variants":[{"name":"Default","description":"Swatch opens the picker; the hex field accepts typing.","code":"<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#3b82f6\"\n/>"},{"name":"With Helper Text","description":"Supporting line says where the colour will be used.","code":"<ColorPicker\n label=\"Primary Color\"\n defaultValue=\"#10b981\"\n helperText=\"This color will be used for buttons and links\"\n/>"},{"name":"Controlled","description":"The parent owns the value and sees every change.","code":"<ControlledColorPickerDemo />"},{"name":"Multiple Pickers","description":"A stacked set reads as one palette.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '240px' }}>\n <ColorPicker label=\"Primary\" defaultValue=\"#3b82f6\" />\n <ColorPicker label=\"Success\" defaultValue=\"#22c55e\" />\n <ColorPicker label=\"Warning\" defaultValue=\"#f59e0b\" />\n <ColorPicker label=\"Danger\" defaultValue=\"#ef4444\" />\n</div>"},{"name":"Compact","description":"showInput={false} drops the hex field, leaving a swatch row.","code":"<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <ColorPicker defaultValue=\"#ef4444\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#f59e0b\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#22c55e\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#3b82f6\" size=\"sm\" showInput={false} />\n</div>"},{"name":"Sizes","description":"Three swatch sizes: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '240px' }}>\n <ColorPicker label=\"Small\" defaultValue=\"#3b82f6\" size=\"sm\" />\n <ColorPicker label=\"Medium (default)\" defaultValue=\"#3b82f6\" size=\"md\" />\n <ColorPicker label=\"Large\" defaultValue=\"#3b82f6\" size=\"lg\" />\n</div>"},{"name":"Error State","description":"Red border on the hex field, and the reason below it.","code":"<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#7c3aed\"\n error\n helperText=\"This color fails contrast against the page background\"\n/>"},{"name":"Disabled","description":"Swatch will not open and the hex field will not accept typing.","code":"<ColorPicker\n label=\"Locked Color\"\n defaultValue=\"#64748b\"\n helperText=\"This color cannot be changed\"\n disabled\n/>"}],"contract":{"propsSummary":["value: string - controlled hex color (#RRGGBB)","defaultValue: string - initial color for uncontrolled usage","onChange: (color: string) => void - change handler","label: string - field label","helperText: string - helper text (preferred)","description: string - deprecated alias for helperText","error: boolean - error styling","disabled: boolean - disable interaction","size: sm|md|lg - size variant","showInput: boolean - show hex input field"],"a11yRules":["A11Y_LABEL_REQUIRED","A11Y_FOCUS_VISIBLE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root","preload"]},"propsSummary":["label: string","value: string","defaultValue: string (default: #000000)","onChange: function","onValueChange: function","helperText: string","description: string","error: boolean (default: false)","disabled: boolean (default: false)","size: sm|md|lg (default: md)","showInput: boolean (default: true)"],"sourcePath":"src/components/ColorPicker/index.tsx","exportName":"ColorPicker","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.238Z"},"performance":{"bundleSize":8354,"rawSize":22904,"complexity":"moderate","budgetPercent":54,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"react-colorful","bytes":14089,"percent":62},{"path":"Input","bytes":3081,"percent":13},{"path":"src/recipes/popup.ts","bytes":2532,"percent":11},{"path":"ColorPicker (self)","bytes":2154,"percent":9},{"path":"ComponentDefaults","bytes":199,"percent":1},{"path":"src/utils/env.ts","bytes":93,"percent":0}]}},"Combobox":{"filePath":"src/components/Combobox/index.tsx","meta":{"name":"Combobox","description":"Filters a list of options as the user types.","category":"inputs","tags":["combobox","autocomplete","search","select","typeahead","form","multiselect"],"status":"stable"},"usage":{"when":["Lists too long to scan by eye","The user roughly knows the value they want","Autocomplete or typeahead","Multi-select from a searchable list"],"whenNot":["Under five options (use Select or RadioGroup)","Free-form text with no known options (use Input)","Short list nobody needs to search (use Select)","Actions rather than values (use Menu)"],"guidelines":["Placeholder names what is searchable","Set label so the field is announced","helperText for guidance, error for the failure reason","Override the built-in \"No results found\" with Combobox.Empty when you have better wording","Group related options with Combobox.Group in long lists","Filtering keeps wrapper composition, so groups and fragments survive","Keep option text short and searchable","multiple turns selections into removable chips"],"accessibility":["Arrow keys, Enter, and Escape all work","Typing filters the list in place","Correct ARIA combobox roles and attributes","Filtered result counts are announced","Chips can be removed from the keyboard"]},"props":{"multiple":{"type":"boolean","description":"Allow multiple selections with chips","default":"false","required":false},"value":{"type":"union","description":"Controlled selected value (string for single, string[] for multiple)","required":false},"defaultValue":{"type":"union","description":"Default selected value (uncontrolled)","required":false},"onValueChange":{"type":"union","description":"Called when selection changes","required":false},"onChange":{"type":"union","description":"Alias for onValueChange","required":false},"children":{"type":"node","description":"Combobox input and content","required":true},"open":{"type":"boolean","description":"Controlled open state of the dropdown","required":false},"defaultOpen":{"type":"boolean","description":"Initial open state for uncontrolled usage","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when dropdown open state changes","required":false},"required":{"type":"boolean","description":"","required":false},"name":{"type":"string","description":"","required":false},"placeholder":{"type":"string","description":"Placeholder text for the input","required":false},"autoHighlight":{"type":"boolean","description":"Auto-highlight first matching item while filtering","default":"true","required":false},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"className":{"type":"string","description":"Wrapper class name","required":false},"label":{"type":"string","description":"Visible label text above the combobox","required":false},"helperText":{"type":"string","description":"Helper text shown below the combobox","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false},"disabled":{"type":"boolean","description":"Disable the combobox","default":"false","required":false},"autoComplete":{"type":"string","description":"","required":false},"form":{"type":"string","description":"","required":false},"inputRef":{"type":"union","description":"","required":false},"readOnly":{"type":"boolean","description":"","required":false}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select when search/filtering is not needed"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text entry"},{"component":"Listbox","relationship":"sibling","note":"Use Listbox for inline option lists"}],"variants":[{"name":"Default","description":"Type to narrow the list; unmatched queries show a no-results row.","code":"<StatefulCombobox placeholder=\"Select a fruit\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"apple\">Apple</Combobox.Item>\n <Combobox.Item value=\"banana\">Banana</Combobox.Item>\n <Combobox.Item value=\"orange\">Orange</Combobox.Item>\n <Combobox.Item value=\"grape\">Grape</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Multiple Selection","description":"Each pick becomes a removable chip in the field.","code":"<StatefulCombobox multiple placeholder=\"Select fruits...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"apple\">Apple</Combobox.Item>\n <Combobox.Item value=\"banana\">Banana</Combobox.Item>\n <Combobox.Item value=\"orange\">Orange</Combobox.Item>\n <Combobox.Item value=\"grape\">Grape</Combobox.Item>\n <Combobox.Item value=\"mango\">Mango</Combobox.Item>\n <Combobox.Item value=\"kiwi\">Kiwi</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"With Label and Helper Text","description":"Helper text tells the user the field is searchable.","code":"<StatefulCombobox\n label=\"Assignee\"\n placeholder=\"Search assignees...\"\n helperText=\"Type to filter the list of available assignees.\"\n>\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Empty>No matches</Combobox.Empty>\n <Combobox.Item value=\"alice\">Alice Johnson</Combobox.Item>\n <Combobox.Item value=\"bob\">Bob Chen</Combobox.Item>\n <Combobox.Item value=\"carol\">Carol Smith</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Error State","description":"Red border, and the message replaces helper text.","code":"<Combobox\n label=\"Reviewer\"\n placeholder=\"Search reviewers...\"\n error=\"Please select a reviewer\"\n>\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"alice\">Alice</Combobox.Item>\n </Combobox.Content>\n</Combobox>"},{"name":"With Groups","description":"Headed sections stay intact while filtering.","code":"<StatefulCombobox placeholder=\"Search countries...\">\n <Combobox.Input />\n <Combobox.Content>\n <>\n <Combobox.Group>\n <Combobox.GroupLabel>North America</Combobox.GroupLabel>\n <Combobox.Item value=\"us\">United States</Combobox.Item>\n <Combobox.Item value=\"ca\">Canada</Combobox.Item>\n <Combobox.Item value=\"mx\">Mexico</Combobox.Item>\n </Combobox.Group>\n <Combobox.Group>\n <Combobox.GroupLabel>Europe</Combobox.GroupLabel>\n <Combobox.Item value=\"uk\">United Kingdom</Combobox.Item>\n <Combobox.Item value=\"de\">Germany</Combobox.Item>\n <Combobox.Item value=\"fr\">France</Combobox.Item>\n </Combobox.Group>\n <Combobox.Empty>No matching country</Combobox.Empty>\n </>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"With Empty State","description":"Combobox.Empty replaces the default no-results wording.","code":"<StatefulCombobox placeholder=\"Filter languages...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Empty>No language matches that search</Combobox.Empty>\n <Combobox.Item value=\"js\">JavaScript</Combobox.Item>\n <Combobox.Item value=\"ts\">TypeScript</Combobox.Item>\n <Combobox.Item value=\"py\">Python</Combobox.Item>\n <Combobox.Item value=\"rs\">Rust</Combobox.Item>\n <Combobox.Item value=\"go\">Go</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Scrollable List","description":"Caps at four rows and half-shows the fifth as a scroll hint.","code":"<StatefulCombobox placeholder=\"Search languages...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Empty>No results found</Combobox.Empty>\n <Combobox.Item value=\"js\">JavaScript</Combobox.Item>\n <Combobox.Item value=\"ts\">TypeScript</Combobox.Item>\n <Combobox.Item value=\"py\">Python</Combobox.Item>\n <Combobox.Item value=\"rs\">Rust</Combobox.Item>\n <Combobox.Item value=\"go\">Go</Combobox.Item>\n <Combobox.Item value=\"rb\">Ruby</Combobox.Item>\n <Combobox.Item value=\"java\">Java</Combobox.Item>\n <Combobox.Item value=\"swift\">Swift</Combobox.Item>\n <Combobox.Item value=\"kt\">Kotlin</Combobox.Item>\n <Combobox.Item value=\"cpp\">C++</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Custom Max Visible Items","description":"maxVisibleItems raises the cap to six rows.","code":"<StatefulCombobox placeholder=\"Search cities...\">\n <Combobox.Input />\n <Combobox.Content maxVisibleItems={6}>\n <Combobox.Empty>No results found</Combobox.Empty>\n <Combobox.Item value=\"nyc\">New York</Combobox.Item>\n <Combobox.Item value=\"lon\">London</Combobox.Item>\n <Combobox.Item value=\"tok\">Tokyo</Combobox.Item>\n <Combobox.Item value=\"par\">Paris</Combobox.Item>\n <Combobox.Item value=\"syd\">Sydney</Combobox.Item>\n <Combobox.Item value=\"ber\">Berlin</Combobox.Item>\n <Combobox.Item value=\"tor\">Toronto</Combobox.Item>\n <Combobox.Item value=\"sin\">Singapore</Combobox.Item>\n <Combobox.Item value=\"dub\">Dubai</Combobox.Item>\n <Combobox.Item value=\"sao\">São Paulo</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"},{"name":"Disabled","description":"Dimmed and unfocusable.","code":"<Combobox disabled placeholder=\"Search...\">\n <Combobox.Input />\n <Combobox.Content>\n <Combobox.Item value=\"1\">Option 1</Combobox.Item>\n </Combobox.Content>\n</Combobox>"},{"name":"Explicit Trigger","description":"showTrigger={false} hands the open control to your own Combobox.Trigger.","code":"<StatefulCombobox placeholder=\"Search assignees...\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n <Combobox.Input showTrigger={false} />\n <Combobox.Trigger aria-label=\"Open assignee list\" />\n </div>\n <Combobox.Content>\n <Combobox.Item value=\"alice\">Alice</Combobox.Item>\n <Combobox.Item value=\"bob\">Bob</Combobox.Item>\n <Combobox.Item value=\"carol\">Carol</Combobox.Item>\n </Combobox.Content>\n</StatefulCombobox>"}],"contract":{"propsSummary":["value: string | string[] - controlled selected value","onValueChange: (value) => void - selection handler","onChange: (value) => void - alias for onValueChange","multiple: boolean - enable multi-select with chips","When multiple=true, value/defaultValue must be string[] (single mode uses string|null)","placeholder: string - input placeholder text","label: string - visible label text","helperText: string - helper text below field","error: boolean | string - error styling and message","disabled: boolean - disable combobox","size: sm|md|lg (default: md)","autoHighlight: boolean - auto-highlight first match","Combobox.Input showTrigger: boolean - hide built-in trigger when using Combobox.Trigger explicitly","maxVisibleItems: number - max visible options before scrolling (default 4)"],"a11yRules":["A11Y_COMBOBOX_KEYBOARD","A11Y_COMBOBOX_LABEL","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Input","Trigger","Content","Item","ItemIndicator","Empty","Group","GroupLabel"],"requiredChildren":["Input","Content"],"commonPatterns":["<Combobox placeholder=\"Search...\"><Combobox.Input /><Combobox.Content><Combobox.Item value=\"opt1\">{label1}</Combobox.Item><Combobox.Item value=\"opt2\">{label2}</Combobox.Item></Combobox.Content></Combobox>","<Combobox multiple placeholder=\"Select items...\"><Combobox.Input /><Combobox.Content><Combobox.Item value=\"opt1\">{label1}</Combobox.Item><Combobox.Item value=\"opt2\">{label2}</Combobox.Item></Combobox.Content></Combobox>","<Combobox placeholder=\"Search...\"><Combobox.Input showTrigger={false} /><Combobox.Trigger aria-label=\"Open\" /><Combobox.Content>...</Combobox.Content></Combobox>"]},"propsSummary":["multiple: boolean (default: false)","value: union","defaultValue: union","onValueChange: union","onChange: union","children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","required: boolean","name: string","placeholder: string","autoHighlight: boolean (default: true)","size: sm|md|lg (default: md)","className: string","label: string","helperText: string","error: union","disabled: boolean"],"sourcePath":"src/components/Combobox/index.tsx","exportName":"Combobox","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.524Z"},"performance":{"bundleSize":4328,"rawSize":11755,"complexity":"lightweight","budgetPercent":28,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Combobox (self)","bytes":7720,"percent":66},{"path":"src/recipes/popup.ts","bytes":2627,"percent":22},{"path":"src/utils/aria.ts","bytes":436,"percent":4},{"path":"ComponentDefaults","bytes":199,"percent":2}]}},"Command":{"filePath":"src/components/Command/index.tsx","meta":{"name":"Command","description":"Filters a list of actions as the user types.","category":"navigation","tags":["command","palette","search","spotlight","quick-actions","cmdk"],"status":"stable"},"usage":{"when":["A keyboard shortcut that jumps anywhere","Action lists too long to scan","Inline lists that need filtering","Search across everything the app can do"],"whenNot":["A handful of actions (use Menu)","Picking a value for a form (use Select or Combobox)","Fixed navigation (use Sidebar or Tabs)"],"guidelines":["Wrap in Dialog for the summon-anywhere palette","Group by category once the list gets long","Always supply Command.Empty","Add keywords so aliases and synonyms match","Label rows with a verb"],"accessibility":["Uses combobox + listbox ARIA pattern","Keyboard navigation with ArrowUp/ArrowDown, Enter to select","Home/End jump to first/last item","aria-activedescendant tracks focused item"]},"props":{"children":{"type":"node","description":"Command.Input, Command.List, and other sub-components","required":true},"search":{"type":"string","description":"Controlled search value","required":false},"defaultSearch":{"type":"string","description":"Default search value (uncontrolled)","default":"","required":false},"onSearchChange":{"type":"function","description":"Called when search input changes","required":false},"filter":{"type":"function","description":"Custom filter function. Return 0 to hide, >0 to show.","required":false},"loop":{"type":"boolean","description":"Whether to loop keyboard navigation","default":"true","required":false},"hosted":{"type":"boolean","description":"The Command sits inside another surface (a Popover, a Dialog) that draws the frame, so it draws none of its own","default":"false","required":false}},"relations":[{"component":"Dialog","relationship":"sibling","note":"Compose inside Dialog for modal command palette"},{"component":"Listbox","relationship":"sibling","note":"Command uses Listbox-like keyboard navigation internally"},{"component":"Combobox","relationship":"alternative","note":"Use Combobox for form field selection with search"}],"variants":[{"name":"Default","description":"Search field over a flat list.","code":"<div style={{ maxWidth: '400px', width: '100%' }}>\n <Command>\n <Command.Input placeholder=\"Type a command...\" />\n <Command.List>\n <Command.Item onItemSelect={() => {}}>Open File</Command.Item>\n <Command.Item onItemSelect={() => {}}>Save Document</Command.Item>\n <Command.Item onItemSelect={() => {}}>Print</Command.Item>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n</div>"},{"name":"Dialog Command Palette","description":"The same list summoned over the page.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"soft\">Open Command Palette</Button>\n </Dialog.Trigger>\n <Dialog.Content width=\"sm\">\n <Command>\n <Command.Input placeholder=\"Search commands...\" />\n <Command.List>\n <Command.Group heading=\"Actions\">\n <Command.Item onItemSelect={() => {}}>New File</Command.Item>\n <Command.Item onItemSelect={() => {}}>Open Recent</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Settings\">\n <Command.Item onItemSelect={() => {}}>Preferences</Command.Item>\n <Command.Item onItemSelect={() => {}}>Keyboard Shortcuts</Command.Item>\n </Command.Group>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n </Dialog.Content>\n</Dialog>"},{"name":"With Groups","description":"Category labels survive filtering.","code":"<div style={{ maxWidth: '400px', width: '100%' }}>\n <Command>\n <Command.Input placeholder=\"Search...\" />\n <Command.List>\n <Command.Group heading=\"Suggestions\">\n <Command.Item onItemSelect={() => {}}>Calendar</Command.Item>\n <Command.Item onItemSelect={() => {}}>Calculator</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Settings\">\n <Command.Item onItemSelect={() => {}}>Profile</Command.Item>\n <Command.Item onItemSelect={() => {}}>Billing</Command.Item>\n <Command.Item disabled onItemSelect={() => {}}>\n Team (coming soon)\n </Command.Item>\n </Command.Group>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n</div>"},{"name":"With Icons","description":"Leading glyphs speed up scanning.","code":"<div style={{ maxWidth: '400px', width: '100%' }}>\n <Command>\n <Command.Input placeholder=\"What do you need?\" />\n <Command.List>\n <Command.Item onItemSelect={() => {}}>\n <span style={{ marginRight: '0.5rem', fontSize: '1rem' }}>+</span> New Document\n </Command.Item>\n <Command.Item onItemSelect={() => {}}>\n <span style={{ marginRight: '0.5rem', fontSize: '1rem' }}>{'>'}</span> Open Folder\n </Command.Item>\n <Command.Item onItemSelect={() => {}}>\n <span style={{ marginRight: '0.5rem', fontSize: '1rem' }}>?</span> Search\n </Command.Item>\n <Command.Empty>No results found.</Command.Empty>\n </Command.List>\n </Command>\n</div>"}],"contract":{"propsSummary":["search: string - controlled search value","onSearchChange: (search) => void - search change handler","filter: (value, search, keywords?) => number - custom filter","loop: boolean - loop keyboard navigation (default: true)","Command.Item value: string - filter match value","Command.Item keywords: string[] - extra filter terms","Command.Item onItemSelect: (value, event) => void - selection handler"],"a11yRules":["A11Y_COMBOBOX_ROLE","A11Y_LISTBOX_ROLE","A11Y_ACTIVE_DESCENDANT"]},"ai":{"compositionPattern":"compound","subComponents":["Input","List","Item","Group","Empty","Separator"],"requiredChildren":["Input","List"],"commonPatterns":["<Dialog><Dialog.Trigger><Button>Open Palette</Button></Dialog.Trigger><Dialog.Content size=\"sm\"><Command><Command.Input placeholder=\"Search...\" /><Command.List><Command.Group heading=\"Actions\"><Command.Item onItemSelect={() => {}}>Action 1</Command.Item></Command.Group><Command.Empty>No results.</Command.Empty></Command.List></Command></Dialog.Content></Dialog>"]},"propsSummary":["children: node (required)","search: string","defaultSearch: string (default: )","onSearchChange: function","filter: function","loop: boolean (default: true)"],"sourcePath":"src/components/Command/index.tsx","exportName":"Command","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.723Z"},"performance":{"bundleSize":2650,"rawSize":6138,"complexity":"lightweight","budgetPercent":17,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Command (self)","bytes":5419,"percent":88}]}},"ComponentDefaults":{"filePath":"src/components/ComponentDefaults/index.tsx","meta":{"name":"ComponentDefaults","description":"Utility provider that sets the default control size for every control below it.","category":"utilities","tags":["provider","defaults","size","utility"],"status":"stable"},"usage":{"when":["A region needs every control at one size (dense table toolbars, compact sidebars)","A ThemeProvider subtree should default to sm or lg controls"],"whenNot":["Sizing a single control (pass its size prop)","Changing spacing or typography (use tokens, not control size)"],"guidelines":["Renders no chrome: it only supplies context read through useResolvedControlSize","Nest providers to override the size for a smaller region","An explicit size prop on a control always wins over the provider default","ThemeProvider componentDefaults wires this provider for you at the root"],"accessibility":["sm controls still meet the kit's minimum target size through the action recipe"]},"props":{"children":{"type":"node","description":"Subtree that inherits the defaults","required":true},"controlSize":{"type":"enum","description":"Default size for controls that do not pass their own size prop","required":false,"values":["sm","md","lg"]},"value":{"type":"object","description":"Full defaults object; explicit controlSize wins over value.controlSize","required":false}},"relations":[{"component":"Theme","relationship":"parent","note":"ThemeProvider accepts componentDefaults and mounts this provider"},{"component":"Button","relationship":"child","note":"Controls resolve their size through useResolvedControlSize"}],"variants":[{"name":"Dense Toolbar","description":"Every control in the toolbar defaults to sm without repeating the prop.","code":"<ComponentDefaultsProvider controlSize=\"sm\">\n <div style={{ display: 'flex', gap: '8px' }}>\n <Button variant=\"soft\">Filter</Button>\n <Button variant=\"ghost\">Export</Button>\n </div>\n</ComponentDefaultsProvider>"},{"name":"Nested Override","description":"A nested provider narrows the default for one region.","code":"<ComponentDefaultsProvider controlSize=\"lg\">\n <Button>Large by default</Button>\n <ComponentDefaultsProvider controlSize=\"sm\">\n <Button>Small in this region</Button>\n </ComponentDefaultsProvider>\n</ComponentDefaultsProvider>"}],"contract":{"propsSummary":["controlSize: sm|md|lg - default size for controls below the provider","value: { controlSize } - defaults object, explicit controlSize wins","useComponentDefaults() - read the merged defaults","useResolvedControlSize(explicit, fallback) - explicit > provider > fallback (md)"],"a11yRules":[]},"propsSummary":["children: node (required)","controlSize: sm|md|lg","value: { controlSize?: sm|md|lg }"],"sourcePath":"src/components/ComponentDefaults/index.tsx","exportName":"ComponentDefaultsProvider","provenance":{"source":"manual","verified":false,"frameworkSupport":"native","extractedAt":"2026-09-03T00:00:00.000Z"},"performance":{"bundleSize":296,"rawSize":537,"complexity":"lightweight","budgetPercent":2,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ComponentDefaults (self)","bytes":430,"percent":80}]}},"ConversationList":{"filePath":"src/components/ConversationList/index.tsx","meta":{"name":"ConversationList","description":"Stacks chat messages in a scroller that follows new arrivals.","category":"ai","tags":["conversation","chat","messages","scroll","ai","list"],"status":"stable"},"usage":{"when":["Chat interfaces holding many messages","Transcripts that should follow new arrivals","Paging back through older message history","Runs of messages grouped day by day"],"whenNot":["Plain item lists with no chat context (use List)","A single message (use Message directly)","Layouts that never scroll"],"guidelines":["autoScroll=\"smart\" follows only when the reader is already near the bottom","showAvatars={false} drops the avatar gutter and the inset that goes with it","Chrome stays on neutral surfaces; reserve accent for actions and semantic state","Implement onScrollTop to page in older messages","Your onScroll handler composes with the internal auto-scroll and history logic","Give new conversations an emptyState","Put a DateSeparator between messages from different days"],"accessibility":["Uses proper ARIA roles for separators","Typing indicator uses a status role with an aria-label","Smooth scroll respects reduced motion preferences","Keyboard navigation works within scrollable container"]},"props":{"children":{"type":"node","description":"Message components","required":true},"showAvatars":{"type":"boolean","description":"Show avatars for messages and typing indicators in this conversation","default":"true","required":false},"autoScroll":{"type":"union","description":"Auto-scroll behavior: true (always), false (never), or \"smart\" (only when near bottom)","default":"smart","required":false},"onScrollTop":{"type":"function","description":"Callback when user scrolls to top (for loading history). Receives the scroll event.","required":false},"loadingHistory":{"type":"boolean","description":"Show loading spinner at top when loading history","default":"false","required":false},"emptyState":{"type":"node","description":"Content to show when conversation is empty","required":false},"scrollTopThreshold":{"type":"number","description":"Pixels from top to trigger onScrollTop","default":"50","required":false},"scrollBottomThreshold":{"type":"number","description":"Pixels from bottom for smart auto-scroll","default":"100","required":false}},"relations":[{"component":"Message","relationship":"child","note":"ConversationList contains Message components"},{"component":"ThinkingIndicator","relationship":"child","note":"Show ThinkingIndicator at bottom while awaiting response"},{"component":"Prompt","relationship":"sibling","note":"Typically paired with Prompt for input"}],"variants":[{"name":"Basic","description":"Three turns stacked in reading order.","code":"<ConversationList>\n <Message role=\"user\">\n <Message.Content>Hello!</Message.Content>\n </Message>\n <Message role=\"assistant\">\n <Message.Content>Hi there! How can I help you today?</Message.Content>\n </Message>\n <Message role=\"user\">\n <Message.Content>Can you explain React hooks?</Message.Content>\n </Message>\n</ConversationList>"},{"name":"With Date Separators","description":"A labelled rule marks where one day ends.","code":"<ConversationList>\n <ConversationList.DateSeparator date={new Date(Date.now() - 86400000)} />\n <Message role=\"user\">\n <Message.Content>A message from yesterday</Message.Content>\n </Message>\n <ConversationList.DateSeparator date={new Date()} />\n <Message role=\"assistant\">\n <Message.Content>And a message from today!</Message.Content>\n </Message>\n</ConversationList>"},{"name":"Without Avatars","description":"Turns sit flush when nothing needs an avatar gutter.","code":"<ConversationList showAvatars={false}>\n <Message role=\"user\">\n <Message.Content>Hello!</Message.Content>\n </Message>\n <Message role=\"assistant\">\n <Message.Content>How can I help?</Message.Content>\n </Message>\n</ConversationList>"},{"name":"With Typing Indicator","description":"Animated dots hold the reply's place before it lands.","code":"<ConversationList>\n <Message role=\"user\">\n <Message.Content>What is TypeScript?</Message.Content>\n </Message>\n <ConversationList.TypingIndicator name=\"Assistant\" />\n</ConversationList>"},{"name":"Loading History","description":"A spinner pins to the top while older turns load.","code":"<ConversationList loadingHistory>\n <Message role=\"user\">\n <Message.Content>This is the latest message</Message.Content>\n </Message>\n</ConversationList>"},{"name":"Empty","description":"A fresh conversation shows its placeholder instead of blank space.","code":"<ConversationList\n emptyState={\n <EmptyState>\n <EmptyState.Title>No messages yet</EmptyState.Title>\n <EmptyState.Description>\n Ask a question to get started.\n </EmptyState.Description>\n </EmptyState>\n }\n/>"}],"contract":{"propsSummary":["children: ReactNode - Message components","showAvatars: boolean - show message and typing-indicator avatars (default: true)","autoScroll: boolean | \"smart\" - scroll behavior (default: \"smart\")","onScrollTop: (event?) => void - callback for loading history (receives scroll event)","loadingHistory: boolean - show history loading spinner","emptyState: ReactNode - empty conversation content"],"a11yRules":["A11Y_ARIA_ROLES","A11Y_MOTION_PREFERENCE"]},"propsSummary":["children: node (required)","showAvatars: boolean (default: true)","autoScroll: union (default: smart)","onScrollTop: function","loadingHistory: boolean (default: false)","emptyState: node","scrollTopThreshold: number (default: 50)","scrollBottomThreshold: number (default: 100)"],"sourcePath":"src/components/ConversationList/index.tsx","exportName":"ConversationList","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:53.889Z"},"ai":{"subComponents":["DateSeparator","TypingIndicator"],"compositionPattern":"compound"},"performance":{"bundleSize":2122,"rawSize":5480,"complexity":"lightweight","budgetPercent":14,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ConversationList (self)","bytes":2728,"percent":50},{"path":"Loading","bytes":2026,"percent":37}]}},"DataTable":{"filePath":"src/components/DataTable/DataTable.fragment.tsx","meta":{"name":"DataTable","description":"Interactive table — sort, select, expand, and click through rows of data.","category":"display","status":"stable","tags":["table","data","grid","list","sorting","tanstack"],"dependencies":[{"name":"@tanstack/react-table","version":">=8.0.0","reason":"Optional — powers sorting, selection, and expansion; without it DataTable renders a static, non-interactive table."}]},"guidance":{"when":["Rows need sorting, selection, or expansion","Users scan and compare several attributes per row","A row click opens the record behind it"],"whenNot":["The data is read-only and static (use Table)","Each item is a single line (use List)","Narrow screens where a card list reads better"],"dont":[{"reason":"Do not use DataTable for a simple static comparison.","bad":"<DataTable />","good":"<Table aria-label=\"Plan comparison\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Starter</Table.Cell>\n <Table.Cell>$0</Table.Cell>\n </Table.Row>\n </Table.Body>\n </Table>"}],"guidelines":["Cap visible columns near 5–7; push the rest behind a row click","Right-align numbers, left-align text","Always set emptyMessage — a bare grid reads as broken","Clickable rows need getRowProps for a role and an accessible name","Reach for density, not the deprecated size prop"],"accessibility":["Headers stay real th elements with scope","Sortable headers are buttons — reachable by keyboard","Selection checkboxes carry their own labels","Expand toggles report aria-expanded"]},"usage":{"when":["Rows need sorting, selection, or expansion","Users scan and compare several attributes per row","A row click opens the record behind it"],"whenNot":["The data is read-only and static (use Table)","Each item is a single line (use List)","Narrow screens where a card list reads better"],"dont":[{"reason":"Do not use DataTable for a simple static comparison.","bad":"<DataTable />","good":"<Table aria-label=\"Plan comparison\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Starter</Table.Cell>\n <Table.Cell>$0</Table.Cell>\n </Table.Row>\n </Table.Body>\n </Table>"}],"guidelines":["Cap visible columns near 5–7; push the rest behind a row click","Right-align numbers, left-align text","Always set emptyMessage — a bare grid reads as broken","Clickable rows need getRowProps for a role and an accessible name","Reach for density, not the deprecated size prop"],"accessibility":["Headers stay real th elements with scope","Sortable headers are buttons — reachable by keyboard","Selection checkboxes carry their own labels","Expand toggles report aria-expanded"]},"props":{"bordered":{"type":"boolean","description":"Wrap table in a bordered container","required":false},"caption":{"type":"string","description":"Visible caption for the table (recommended for accessibility)","required":false},"captionHidden":{"type":"boolean","description":"Hide the caption visually but keep it for screen readers","required":false},"columns":{"type":"array","description":"Column definitions","required":true},"data":{"type":"array","description":"Data array","required":true},"density":{"type":"enum","description":"Canonical row density. `condensed` is a deprecated alias for `compact`.","required":false,"values":["compact","regular","relaxed","condensed"]},"emptyMessage":{"type":"string","description":"Empty state message (plain text). Ignored if `emptyState` is set.","required":false},"emptyState":{"type":"node","description":"Rich empty-state slot (icon + copy + CTA) rendered when there's no data.","required":false},"expanded":{"type":"union","description":"Controlled expanded state","required":false},"getRowId":{"type":"function","description":"Unique key extractor for each row","required":false},"getRowProps":{"type":"function","description":"Props applied to each rendered data row. Use this for row-level ARIA labels, roles, and data attributes.","required":false},"getSubRows":{"type":"function","description":"Extract sub-rows from a row for expandable tree tables","required":false},"hideHeader":{"type":"boolean","description":"Hide the column header row (e.g. stacked per-group tables share one).","required":false},"loading":{"type":"boolean","description":"When true, render skeleton placeholder rows instead of data.","required":false},"onExpandedChange":{"type":"function","description":"Expanded state change handler","required":false},"onRowClick":{"type":"function","description":"Row click handler","required":false},"onRowSelectionChange":{"type":"function","description":"Selection change handler","required":false},"onSortingChange":{"type":"function","description":"Sorting change handler","required":false},"rowSelection":{"type":"object","description":"Controlled selection state","required":false},"selectable":{"type":"boolean","description":"Enable row selection","required":false},"showCheckbox":{"type":"boolean","description":"Show checkbox column for row selection","required":false},"size":{"type":"enum","description":"","required":false,"values":["sm","md"]},"skeletonRows":{"type":"number","description":"Number of skeleton rows to show while loading (default 6).","required":false},"sortable":{"type":"boolean","description":"Enable sorting","required":false},"sorting":{"type":"array","description":"Controlled sorting state","required":false},"striped":{"type":"boolean","description":"Show alternating row backgrounds","required":false},"wrapperClassName":{"type":"string","description":"Additional class name for the outer wrapper div","required":false},"wrapperProps":{"type":"object","description":"Props forwarded to the outer wrapper div","required":false}},"relations":[{"component":"Table","relationship":"alternative","note":"Use Table for simple semantic HTML tables"},{"component":"EmptyState","relationship":"sibling","note":"Use EmptyState for empty table states"},{"component":"Badge","relationship":"sibling","note":"Use Badge for status columns"},{"component":"Menu","relationship":"sibling","note":"Use Menu for filter dropdowns"},{"component":"Checkbox","relationship":"sibling","note":"Built-in checkbox selection via showCheckbox"}],"variants":[{"name":"Default","description":"Columns and data are the only required props; everything else is opt-in.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[\n { name: \"Ada Lovelace\", status: \"Active\" },\n { name: \"Grace Hopper\", status: \"Pending\" },\n ]}\n aria-label=\"Team members\"\n />","canonical":true},{"name":"Loading","description":"Skeleton rows hold the table's height so the page never jumps.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[]}\n loading\n skeletonRows={3}\n aria-label=\"Loading team members\"\n />"},{"name":"Rich Cells","description":"A cell renderer drops any component — avatar, badge — straight into the column.","code":"<DataTable\n columns={[\n {\n accessorKey: \"name\",\n header: \"Name\",\n cell: ({ row }) => (\n <Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <Avatar name={row.original.name} size=\"sm\" />\n <span>{row.original.name}</span>\n </Stack>\n ),\n },\n { accessorKey: \"role\", header: \"Role\" },\n {\n accessorKey: \"status\",\n header: \"Status\",\n cell: ({ row }) => (\n <Badge tone={row.original.status === \"Active\" ? \"success\" : \"warning\"}>\n {row.original.status}\n </Badge>\n ),\n },\n ]}\n data={[\n { name: \"Ada Lovelace\", role: \"Engineer\", status: \"Active\" },\n { name: \"Grace Hopper\", role: \"Admiral\", status: \"Pending\" },\n ]}\n bordered\n aria-label=\"Team members\"\n />"},{"name":"Sortable","description":"Click a header to sort; click it again to reverse.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"amount\", header: \"Amount\" },\n ]}\n data={[\n { name: \"Subscription\", amount: \"$24.00\" },\n { name: \"Usage\", amount: \"$12.00\" },\n ]}\n sortable\n bordered\n caption=\"Recent transactions\"\n captionHidden\n aria-label=\"Transactions\"\n />"},{"name":"Checkbox Selection","description":"The header checkbox toggles every row at once.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[\n { id: \"ada\", name: \"Ada Lovelace\", status: \"Active\" },\n { id: \"grace\", name: \"Grace Hopper\", status: \"Pending\" },\n ]}\n getRowId={(row) => row.id}\n selectable\n showCheckbox\n bordered\n aria-label=\"Team members\"\n />"},{"name":"Expandable Rows","description":"Children fold away under their parent, like a file tree.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"type\", header: \"Type\" },\n ]}\n data={[\n {\n id: \"src\",\n name: \"src\",\n type: \"folder\",\n subRows: [{ id: \"components\", name: \"components\", type: \"folder\", subRows: [] }],\n },\n { id: \"package\", name: \"package.json\", type: \"file\", subRows: [] },\n ]}\n getRowId={(row) => row.id}\n getSubRows={(row) => row.subRows}\n bordered\n density=\"compact\"\n aria-label=\"File tree\"\n />"},{"name":"With Filters","description":"Filter controls sit outside the table; you own the filtering.","code":"<Stack gap=\"sm\">\n <Input aria-label=\"Search users\" placeholder=\"Search...\" withFieldWrapper={false} />\n <DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[{ name: \"Ada Lovelace\", status: \"Active\" }]}\n sortable\n bordered\n emptyMessage=\"No users match the current filters\"\n aria-label=\"Filtered team members\"\n />\n </Stack>"},{"name":"Clickable Rows","description":"Mouse or keyboard opens the row; getRowProps supplies its name.","code":"<DataTable\n columns={[\n { accessorKey: \"method\", header: \"Method\" },\n { accessorKey: \"path\", header: \"Path\" },\n ]}\n data={[{ method: \"GET\", path: \"/v1/components\" }]}\n getRowProps={(row) => ({\n role: \"button\",\n \"aria-label\": `Open ${row.method} ${row.path}`,\n })}\n onRowClick={() => undefined}\n density=\"compact\"\n aria-label=\"API endpoints\"\n />"},{"name":"Striped","description":"Row tint alternates so tightly packed rows stay readable.","code":"<DataTable\n columns={[\n { accessorKey: \"method\", header: \"Method\" },\n { accessorKey: \"path\", header: \"Path\" },\n ]}\n data={[\n { method: \"GET\", path: \"/v1/components\" },\n { method: \"POST\", path: \"/v1/fragments\" },\n ]}\n striped\n density=\"compact\"\n sortable\n aria-label=\"API endpoints\"\n />"},{"name":"Empty State","description":"emptyMessage replaces the rows and keeps the headers in place.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Name\" },\n { accessorKey: \"status\", header: \"Status\" },\n ]}\n data={[]}\n emptyMessage=\"No users match your search criteria\"\n aria-label=\"Search results\"\n />"},{"name":"Long Cell Content","description":"Oversized values scroll inside the table instead of stretching the page.","code":"<DataTable\n columns={[\n { accessorKey: \"name\", header: \"Administrator\" },\n { accessorKey: \"status\", header: \"Recovery policy\" },\n ]}\n data={[\n {\n name: \"A very long localized administrator identity that remains distinguishable\",\n status:\n \"Pending confirmation of the detailed workspace recovery policy and notification workflow\",\n },\n ]}\n bordered\n aria-label=\"Long localized team member data\"\n />"}],"ai":{"compositionPattern":"simple","subComponents":["Root","Columns","preload"],"commonPatterns":["<DataTable columns={createColumns([{key:\"name\",header:\"Name\"},{key:\"status\",header:\"Status\"}])} data={[{name:\"Item 1\",status:\"Active\"}]} />"]},"contract":{"propsSummary":["columns: ColumnDef[] - column definitions","data: T[] - row data array","sortable: boolean - enable sorting","selectable: boolean - enable row selection","showCheckbox: boolean - add checkbox column","getSubRows: (row) => T[] - enable expandable rows","onRowClick: (row, event) => void - row activation handler with event access","getRowProps: (row) => HTMLAttributes<HTMLTableRowElement> - row-level ARIA, role, data, class, and event props","density: compact|regular|relaxed - row density (size is deprecated)","striped: boolean - alternating row backgrounds","bordered: boolean - bordered container","wrapperClassName / wrapperProps - style and configure the outer wrapper div"],"a11yRules":["A11Y_TABLE_HEADERS","A11Y_TABLE_SORT"]},"matrix":{"axes":{"size":"auto","theme":["light","dark"]},"forced":["loading","empty","focus"],"worstCase":{"data":"Long localized cell values and enough rows to require horizontal and vertical overflow handling"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/DataTable/index.tsx","exportName":"DataTable","performance":{"bundleSize":6263,"rawSize":17910,"complexity":"moderate","budgetPercent":41,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"DataTable (self)","bytes":11556,"percent":65},{"path":"Checkbox","bytes":2850,"percent":16},{"path":"src/recipes/table-chrome.ts","bytes":2782,"percent":16},{"path":"src/utils/env.ts","bytes":93,"percent":1}]}},"DatePicker":{"filePath":"src/components/DatePicker/index.tsx","meta":{"name":"DatePicker","description":"Selects a date or date range from a calendar.","category":"inputs","tags":["date","picker","calendar","range","form","input"],"status":"stable","dependencies":[{"name":"react-day-picker","version":">=9.0.0","reason":"Optional — renders the calendar popup; the trigger and form field work without it."}]},"usage":{"when":["A date the user picks off a calendar","A start and end date together","Filtering by date"],"whenNot":["Time on its own (use a dedicated TimePicker)","A handful of known dates (use Select)","Typed date entry (use Input with a date mask)"],"guidelines":["Pair range mode with numberOfMonths={2} so both ends are visible","size=\"sm\" lines the trigger up with other dense toolbar controls","Offer presets for the common ranges: Today, Last 7 days, Last 30 days","disabledDates blocks past or unavailable days before the user tries","Placeholder names the date, not the action","DatePicker.Trigger defaults to type=\"button\", so it is safe inside a form"],"accessibility":["The calendar grid is fully keyboard navigable","Arrow keys move between days","Escape closes the calendar","Focus returns to the trigger on close"]},"props":{"children":{"type":"node","description":"DatePicker trigger and content","required":true},"className":{"type":"string","description":"Wrapper class name","required":false},"mode":{"type":"enum","description":"Selection mode","default":"single","required":false,"values":["single","range"]},"selected":{"type":"object","description":"Controlled date (single mode). Type: Date | null","required":false},"selectedRange":{"type":"object","description":"Controlled range (range mode). Type: DateRange | null","required":false},"onSelect":{"type":"function","description":"Called when a single date is selected","required":false},"onChange":{"type":"function","description":"Alias for onSelect (consistent with Input/Select onChange convention)","required":false},"onRangeSelect":{"type":"function","description":"Called when a date range is selected","required":false},"numberOfMonths":{"type":"number","description":"Number of months displayed side-by-side","default":"1","required":false},"disabled":{"type":"boolean","description":"Disable the picker","default":"false","required":false},"size":{"type":"enum","description":"Trigger size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"disabledDates":{"type":"union","description":"Dates to disable (react-day-picker Matcher | Matcher[])","required":false},"placeholder":{"type":"string","description":"Trigger placeholder text","required":false},"locale":{"type":"object","description":"date-fns locale for i18n","required":false},"fixedWeeks":{"type":"boolean","description":"Always show 6 rows","default":"false","required":false},"formatDate":{"type":"function","description":"Custom trigger date formatter","required":false},"formatRange":{"type":"function","description":"Custom trigger range formatter","required":false},"open":{"type":"boolean","description":"Controlled popover open state","required":false},"onOpenChange":{"type":"function","description":"Popover open state change callback","required":false},"name":{"type":"string","description":"Hidden input name for forms","required":false},"label":{"type":"string","description":"Visible label text above the date picker","required":false},"helperText":{"type":"string","description":"Helper text shown below the date picker","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for choosing from a list of options"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text date entry"},{"component":"Popover","relationship":"composition","note":"DatePicker uses Popover for the calendar dropdown"}],"variants":[{"name":"Default","description":"Trigger opens one month; today is outlined.","code":"<StatefulDatePicker placeholder=\"Pick a date\">\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Small Trigger","description":"Matches the height of other sm toolbar controls.","code":"<StatefulDatePicker size=\"sm\" placeholder=\"Last scanned\">\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Date Range","description":"Two months side by side so both ends of the range are visible.","code":"<StatefulRangePicker placeholder=\"Select date range\" numberOfMonths={2}>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulRangePicker>"},{"name":"Multi-Month","description":"Three months at once, for dates far from today.","code":"<StatefulDatePicker placeholder=\"Pick a date\" numberOfMonths={3}>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Disabled Dates","description":"Everything before today is greyed out and unclickable.","code":"<StatefulDatePicker\n placeholder=\"Select a future date\"\n disabledDates={{ before: new Date() }}\n>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"With Presets","description":"Shortcut buttons beside the calendar skip the common ranges.","code":"<StatefulRangePicker placeholder=\"Select date range\" numberOfMonths={2}>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <div style={{ display: 'flex', gap: '1rem' }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', minWidth: '8rem' }}>\n <DatePicker.Preset range={{ from: today, to: today }}>Today</DatePicker.Preset>\n <DatePicker.Preset range={{ from: subDays(today, 7), to: today }}>Last 7 days</DatePicker.Preset>\n <DatePicker.Preset range={{ from: subDays(today, 30), to: today }}>Last 30 days</DatePicker.Preset>\n <DatePicker.Preset range={{ from: subDays(today, 90), to: today }}>Last 90 days</DatePicker.Preset>\n </div>\n <DatePicker.Calendar />\n </div>\n </DatePicker.Content>\n</StatefulRangePicker>"},{"name":"With Label and Helper Text","description":"Label above the trigger, supporting text below it.","code":"<StatefulDatePicker\n label=\"Renewal date\"\n placeholder=\"Pick a date\"\n helperText=\"Billing restarts on this day each month.\"\n>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"},{"name":"Error State","description":"Red border on the trigger, and the reason below it.","code":"<DatePicker\n label=\"Start Date\"\n placeholder=\"Pick a date\"\n error=\"Please select a start date\"\n>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</DatePicker>"},{"name":"Disabled","description":"Dimmed; the calendar will not open.","code":"<StatefulDatePicker placeholder=\"Pick a date\" disabled>\n <DatePicker.Trigger />\n <DatePicker.Content>\n <DatePicker.Calendar />\n </DatePicker.Content>\n</StatefulDatePicker>"}],"contract":{"propsSummary":["mode: \"single\" | \"range\" - selection mode","selected: Date - controlled date (single)","selectedRange: DateRange - controlled range","onSelect: (date) => void - single selection handler","onRangeSelect: (range) => void - range selection handler","numberOfMonths: number - months visible (default 1)","size: \"sm\" | \"md\" | \"lg\" - trigger size variant (default md)","label: string - visible label text","helperText: string - helper text below field","error: boolean | string - error styling and message","disabled: boolean - disable picker","disabledDates: Matcher - dates to disable","DatePicker.Trigger: button props supported (type defaults to \"button\")"],"a11yRules":["A11Y_DATEPICKER_KEYBOARD","A11Y_DATEPICKER_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Calendar","Preset","preload"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<DatePicker size=\"sm\" selected={date} onSelect={setDate}><DatePicker.Trigger placeholder=\"Pick a date\" /><DatePicker.Content><DatePicker.Calendar /></DatePicker.Content></DatePicker>","<DatePicker selected={date} onSelect={setDate}><DatePicker.Trigger placeholder=\"Pick a date\" /><DatePicker.Content><DatePicker.Calendar /></DatePicker.Content></DatePicker>"]},"propsSummary":["children: node (required)","className: string","mode: single|range (default: single)","selected: object","selectedRange: object","onSelect: function","onChange: function","onRangeSelect: function","numberOfMonths: number (default: 1)","disabled: boolean (default: false)","size: sm|md|lg (default: md)","disabledDates: union","placeholder: string","locale: object","fixedWeeks: boolean (default: false)","formatDate: function","formatRange: function","open: boolean","onOpenChange: function","name: string","label: string","helperText: string","error: union"],"sourcePath":"src/components/DatePicker/index.tsx","exportName":"DatePicker","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:54.712Z"},"performance":{"bundleSize":4239,"rawSize":10976,"complexity":"lightweight","budgetPercent":28,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"DatePicker (self)","bytes":7078,"percent":64},{"path":"src/recipes/popup.ts","bytes":2528,"percent":23},{"path":"src/utils/aria.ts","bytes":351,"percent":3},{"path":"ComponentDefaults","bytes":199,"percent":2},{"path":"src/utils/env.ts","bytes":93,"percent":1}]}},"Dialog":{"filePath":"src/components/Dialog/Dialog.fragment.tsx","meta":{"name":"Dialog","description":"Blocks the page with one focused task the user must finish or dismiss.","category":"overlays","status":"stable","tags":["modal","dialog","overlay","popup","confirmation"]},"guidance":{"when":["Confirming something irreversible","Collecting input the user must finish in one pass","Content that needs acknowledgment before continuing","Isolating a step in a longer workflow"],"whenNot":["A short hint (use Tooltip)","A list of actions (use Menu)","Contextual content that should not block (use Popover)","Feedback the user does not act on (use Toast or Alert)"],"dont":[{"reason":"Do not use a Dialog for a non-blocking notification.","bad":"<Dialog>Saved</Dialog>","good":"<Alert tone=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Changes saved</Alert.Title>\n <Alert.Content>Your settings are up to date.</Alert.Content>\n </Alert.Body>\n </Alert>"},{"reason":"Do not omit an accessible title and explicit close action from a Dialog.","bad":"<Dialog><Dialog.Content>Focused task</Dialog.Content></Dialog>","good":"<Dialog defaultOpen>\n <Dialog.Content>\n <Dialog.Title>Account settings</Dialog.Title>\n <Dialog.Body>Update your workspace preferences.</Dialog.Body>\n <Dialog.Close>Close</Dialog.Close>\n </Dialog.Content>\n </Dialog>"}],"guidelines":["One task per dialog","Title states the task; body states the consequence","Pair the primary action with an explicit cancel","Leave backdrop and Escape dismissal on unless the choice is destructive","Wrap the trigger with asChild around a real control — the bare trigger ships unstyled"],"accessibility":["Traps focus while open","Escape closes","Focus returns to the trigger on close","role=\"dialog\" with title and description wired to aria attributes"]},"usage":{"when":["Confirming something irreversible","Collecting input the user must finish in one pass","Content that needs acknowledgment before continuing","Isolating a step in a longer workflow"],"whenNot":["A short hint (use Tooltip)","A list of actions (use Menu)","Contextual content that should not block (use Popover)","Feedback the user does not act on (use Toast or Alert)"],"dont":[{"reason":"Do not use a Dialog for a non-blocking notification.","bad":"<Dialog>Saved</Dialog>","good":"<Alert tone=\"success\">\n <Alert.Icon />\n <Alert.Body>\n <Alert.Title>Changes saved</Alert.Title>\n <Alert.Content>Your settings are up to date.</Alert.Content>\n </Alert.Body>\n </Alert>"},{"reason":"Do not omit an accessible title and explicit close action from a Dialog.","bad":"<Dialog><Dialog.Content>Focused task</Dialog.Content></Dialog>","good":"<Dialog defaultOpen>\n <Dialog.Content>\n <Dialog.Title>Account settings</Dialog.Title>\n <Dialog.Body>Update your workspace preferences.</Dialog.Body>\n <Dialog.Close>Close</Dialog.Close>\n </Dialog.Content>\n </Dialog>"}],"guidelines":["One task per dialog","Title states the task; body states the consequence","Pair the primary action with an explicit cancel","Leave backdrop and Escape dismissal on unless the choice is destructive","Wrap the trigger with asChild around a real control — the bare trigger ships unstyled"],"accessibility":["Traps focus while open","Escape closes","Focus returns to the trigger on close","role=\"dialog\" with title and description wired to aria attributes"]},"props":{"children":{"type":"node","description":"","required":true},"defaultOpen":{"type":"boolean","description":"Default open state","required":false},"modal":{"type":"boolean","description":"Whether the dialog blocks interaction with the rest of the page.","default":"true","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for non-modal contextual content"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Alert","relationship":"sibling","note":"Use Alert for inline notifications"}],"variants":[{"name":"Default","description":"Header, body, and footer in the standard layout.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Dialog title</Dialog.Title>\n <Dialog.Description>Focused supporting content.</Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>Dialog body</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"soft\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>","canonical":true},{"name":"Confirmation","description":"Names the consequence before an irreversible action.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"solid\" tone=\"danger\">Delete item</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Delete item?</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>This action cannot be undone.</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"soft\">Cancel</Button>\n </Dialog.Close>\n <Dialog.Close asChild>\n <Button variant=\"solid\" tone=\"danger\">Delete</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Large","description":"Wider surface for denser content.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open large dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content width=\"lg\">\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>Detailed settings</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>Complex content</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"soft\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"No Initial Focus","description":"Skips autofocus when you place focus yourself.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button variant=\"soft\">Open settings</Button>\n </Dialog.Trigger>\n <Dialog.Content initialFocus={false}>\n <Dialog.Header>\n <Dialog.Title>Settings</Dialog.Title>\n <Dialog.Description>Choose a settings area to edit.</Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>Settings content</Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"soft\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"},{"name":"Long Title","description":"A wrapping title keeps the close control reachable.","code":"<Dialog>\n <Dialog.Trigger asChild>\n <Button>Open long title dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Close />\n <Dialog.Header>\n <Dialog.Title>\n Confirm the localized account recovery policy for every workspace administrator\n </Dialog.Title>\n <Dialog.Description>\n The title wraps while the close affordance and recovery action remain reachable.\n </Dialog.Description>\n </Dialog.Header>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"soft\">Close</Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","Header","Title","Description","Body","Footer"],"requiredChildren":["Content"],"commonPatterns":["<Dialog><Dialog.Trigger asChild><Button>Open</Button></Dialog.Trigger><Dialog.Content><Dialog.Header><Dialog.Title>{title}</Dialog.Title></Dialog.Header><Dialog.Body>{content}</Dialog.Body><Dialog.Footer><Dialog.Close asChild><Button variant=\"soft\">Cancel</Button></Dialog.Close><Button>Confirm</Button></Dialog.Footer></Dialog.Content></Dialog>","<Dialog><Dialog.Trigger asChild><Button variant=\"soft\">Open settings</Button></Dialog.Trigger><Dialog.Content initialFocus={false}>...</Dialog.Content></Dialog>"]},"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - open state handler","modal: boolean - blocks page interaction (default: true)","Dialog.Content initialFocus?: boolean - control auto-focus on open (default: true)","Dialog.Content width: sm|md|lg|xl|full - dialog width (default: md)"],"a11yRules":["A11Y_DIALOG_FOCUS","A11Y_DIALOG_ESCAPE","A11Y_DIALOG_LABEL"]},"matrix":{"axes":{"width":"auto","modal":["true","false"],"theme":["light","dark"]},"forced":["open","focus","reduced-motion"],"worstCase":{"title":"A long localized dialog title that wraps while the close affordance remains reachable"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Dialog/index.tsx","exportName":"Dialog","performance":{"bundleSize":1126,"rawSize":3005,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Dialog (self)","bytes":2254,"percent":75}]}},"Drawer":{"filePath":"src/components/Drawer/index.tsx","meta":{"name":"Drawer","description":"Slides a panel in from a screen edge and dims the page behind it.","category":"overlays","tags":["drawer","sheet","panel","sidebar","slide-over"],"status":"stable"},"usage":{"when":["Editing or creating alongside the page behind it","Touch-reachable action sheets","Navigation that slides in and back out","Detail views that overlay rather than replace"],"whenNot":["A centred task (use Dialog)","Navigation that stays on screen (use Sidebar)","A short list of actions (use Menu or Popover)","Feedback the user does not act on (use Toast)"],"guidelines":["Right for editing, left for navigation, bottom for touch","Always give the user a visible way out","One task per drawer","asChild on Trigger and Close needs a single element child","Set initialFocus={false} when you place focus yourself"],"accessibility":["Automatically traps focus within the drawer","Closes on Escape key press","Returns focus to trigger element on close","Uses role=\"dialog\" with proper aria attributes"]},"props":{"children":{"type":"node","description":"Drawer content (use Drawer.Content, Drawer.Header, etc.)","required":true},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"modal":{"type":"union","description":"Whether to render as modal (blocks interaction with rest of page)","default":"true","required":false},"disablePointerDismissal":{"type":"boolean","description":"Disable outside-click dismissal","required":false},"onOpenChangeComplete":{"type":"function","description":"Called after open/close animation completes","required":false},"snapPoints":{"type":"array","description":"Preset snap-point heights for bottom-sheet drawers","required":false},"swipeDirection":{"type":"enum","description":"Swipe direction to dismiss.","default":"derived from `side` prop on Content","required":false,"values":["up","down","left","right"]}},"relations":[{"component":"Dialog","relationship":"sibling","note":"Use Dialog for centered modal overlays"},{"component":"Sidebar","relationship":"alternative","note":"Use Sidebar for permanent side navigation"},{"component":"Popover","relationship":"alternative","note":"Use Popover for small contextual content"}],"variants":[{"name":"Default","description":"Enters from the right, the default for editing and forms.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button>Open Drawer</Button>\n </Drawer.Trigger>\n <Drawer.Content>\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Drawer Title</Drawer.Title>\n <Drawer.Description>\n A panel sliding in from the right.\n </Drawer.Description>\n </Drawer.Header>\n <Drawer.Body>\n <p>Drawer content goes here.</p>\n </Drawer.Body>\n <Drawer.Footer>\n <Drawer.Close asChild>\n <Button variant=\"soft\">Cancel</Button>\n </Drawer.Close>\n <Button variant=\"solid\">Save</Button>\n </Drawer.Footer>\n </Drawer.Content>\n</Drawer>"},{"name":"Left Side","description":"Enters from the left, where navigation belongs.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button variant=\"soft\">Open Left</Button>\n </Drawer.Trigger>\n <Drawer.Content side=\"left\">\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Navigation</Drawer.Title>\n </Drawer.Header>\n <Drawer.Body>\n <p>Left-side drawer for navigation or filters.</p>\n </Drawer.Body>\n </Drawer.Content>\n</Drawer>"},{"name":"Bottom Sheet","description":"Rises from the bottom for touch-reachable actions.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button variant=\"soft\">Open Bottom Sheet</Button>\n </Drawer.Trigger>\n <Drawer.Content side=\"bottom\" width=\"sm\">\n <Drawer.Header>\n <Drawer.Title>Actions</Drawer.Title>\n </Drawer.Header>\n <Drawer.Body>\n <p>Bottom sheet for mobile-style actions.</p>\n </Drawer.Body>\n </Drawer.Content>\n</Drawer>"},{"name":"With Form","description":"Fields in the body, submit and cancel pinned to the footer.","code":"<Drawer>\n <Drawer.Trigger asChild>\n <Button>Edit Settings</Button>\n </Drawer.Trigger>\n <Drawer.Content width=\"md\">\n <Drawer.Close />\n <Drawer.Header>\n <Drawer.Title>Settings</Drawer.Title>\n <Drawer.Description>Update your preferences.</Drawer.Description>\n </Drawer.Header>\n <Drawer.Body>\n <Stack gap=\"md\">\n <Input label=\"Display Name\" placeholder=\"Enter name\" />\n <Input label=\"Email\" type=\"email\" placeholder=\"you@example.com\" />\n </Stack>\n </Drawer.Body>\n <Drawer.Footer>\n <Drawer.Close asChild>\n <Button variant=\"soft\">Cancel</Button>\n </Drawer.Close>\n <Button variant=\"solid\">Save Changes</Button>\n </Drawer.Footer>\n </Drawer.Content>\n</Drawer>"}],"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - open state handler","modal: boolean - blocks page interaction (default: true)","Drawer.Content side: left|right|top|bottom - slide direction (default: right)","Drawer.Content width: sm|md|lg|xl|full - panel width, or height for top/bottom (default: md)","Drawer.Content initialFocus: boolean - auto-focus popup on open (default: true)"],"a11yRules":["A11Y_DIALOG_FOCUS","A11Y_DIALOG_ESCAPE","A11Y_DIALOG_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","SwipeArea","Header","Title","Description","Body","Footer"],"requiredChildren":["Content"],"commonPatterns":["<Drawer><Drawer.Trigger><Button>Open</Button></Drawer.Trigger><Drawer.Content><Drawer.Close /><Drawer.Header><Drawer.Title>{title}</Drawer.Title></Drawer.Header><Drawer.Body>{content}</Drawer.Body><Drawer.Footer><Drawer.Close asChild><Button variant=\"soft\">Cancel</Button></Drawer.Close><Button>Save</Button></Drawer.Footer></Drawer.Content></Drawer>"]},"propsSummary":["children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","modal: boolean (default: true)"],"sourcePath":"src/components/Drawer/index.tsx","exportName":"Drawer","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:55.637Z"},"performance":{"bundleSize":1519,"rawSize":4048,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Drawer (self)","bytes":3276,"percent":81}]}},"Editor":{"filePath":"src/components/Editor/index.tsx","meta":{"name":"Editor","description":"Edits rich text with formatting, autosave, and a word count.","category":"inputs","tags":["editor","rich-text","markdown","toolbar","writing","blog","content"],"status":"stable","dependencies":[{"name":"@tiptap/react","version":">=2.0.0","reason":"Optional — enables rich-text mode; without TipTap the editor falls back to a markdown textarea."},{"name":"@tiptap/starter-kit","version":">=2.0.0","reason":"Optional — TipTap extension bundle used by rich-text mode."},{"name":"@tiptap/extension-link","version":">=2.0.0","reason":"Optional — link formatting in rich-text mode."}]},"usage":{"when":["Blog posts and long-form articles","Text that needs formatting controls beside it","Drafts that autosave and report a word count","Markdown or WYSIWYG authoring"],"whenNot":["Single-line text (use Input)","Multi-line with no formatting (use Textarea)","Chat or AI prompt input (use Prompt)","Code editing (use CodeBlock)"],"guidelines":["Compose Editor.Toolbar and Editor.Content to control toolbar layout","Rich text needs @tiptap/react, @tiptap/starter-kit, and @tiptap/extension-link","Without TipTap it falls back to a markdown-aware textarea","onAutoSave may return a Promise; save status updates once it settles","size sets the minimum body height: sm 120px, md 200px, lg 400px","maxLength drives the counter's warning and over-limit states","Headings, blockquote, orderedList, undo, and redo are opt-in via formats","toolbarIcons swaps glyphs without changing labels or keyboard behavior"],"accessibility":["Toolbar has role=\"toolbar\" with aria-label","Format buttons use aria-pressed to indicate active state","Action buttons (undo/redo) omit aria-pressed since they are not toggles","Status indicator uses aria-live=\"polite\" for save status announcements","Keyboard shortcuts match standard text editor conventions (Ctrl+B, Ctrl+I, etc.)","Global shortcuts (e.g., Sidebar Ctrl+B) automatically yield when focus is inside the Editor","Focus ring appears on the editor container when any child element is focused"]},"props":{"children":{"type":"node","description":"","required":false},"value":{"type":"string","description":"Controlled editor value","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","default":"","required":false},"onValueChange":{"type":"function","description":"Called when content changes","required":false},"placeholder":{"type":"string","description":"Placeholder text shown when empty","default":"Start typing...","required":false},"disabled":{"type":"boolean","description":"Disable the editor","default":"false","required":false},"readOnly":{"type":"boolean","description":"Make the editor read-only","default":"false","required":false},"formats":{"type":"array","description":"Which format buttons to show in the toolbar","default":"[\"bold\", \"italic\", \"strikethrough\", \"link\", \"code\", \"bulletList\"]","required":false},"toolbar":{"type":"boolean","description":"Show default toolbar","default":"true","required":false},"statusBar":{"type":"boolean","description":"Show default status bar with word/character counts","default":"true","required":false},"onAutoSave":{"type":"function","description":"Auto-save callback, called at autoSaveInterval (may be async)","required":false},"autoSaveInterval":{"type":"number","description":"Auto-save interval in milliseconds","default":"30000","required":false},"size":{"type":"enum","description":"Editor size preset: \"sm\" (120px), \"md\" (200px), or \"lg\" (400px)","default":"md","required":false,"values":["sm","md","lg"]},"maxLength":{"type":"number","description":"Maximum character count. Shows counter in status bar with warning (90%) and error (over limit) states","required":false},"toolbarIcons":{"type":"object","description":"Optional toolbar icon overrides keyed by format/action (e.g. bold, italic, undo). Values can be React nodes or render functions.","required":false}},"relations":[{"component":"Prompt","relationship":"sibling","note":"Prompt is for AI/chat input; Editor is for long-form content editing"},{"component":"Textarea","relationship":"alternative","note":"Use Textarea for simple multi-line input without formatting toolbar"},{"component":"Input","relationship":"alternative","note":"Use Input for single-line text input"}],"variants":[{"name":"Default","description":"Toolbar and status bar you get with no configuration.","code":"<Editor placeholder=\"Start typing your masterpiece here...\" />"},{"name":"With Auto-Save and Publish","description":"Save state sits next to the primary action in the toolbar.","code":"<Editor\n placeholder=\"Start typing your masterpiece here...\"\n onValueChange={(v) => console.log(v)}\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n <Editor.ToolbarButton format=\"strikethrough\" />\n <Editor.ToolbarButton format=\"link\" />\n <Editor.ToolbarButton format=\"code\" />\n <Editor.ToolbarButton format=\"bulletList\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Actions\">\n <Editor.StatusIndicator status=\"saved\" />\n <Button variant=\"solid\" tone=\"accent\" size=\"sm\">\n Publish\n </Button>\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"Save Failed","description":"A failed autosave turns the status text red.","code":"<Editor defaultValue=\"This draft could not be saved.\">\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Status\">\n <Editor.StatusIndicator status=\"error\" />\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"Disabled","description":"Dimmed and inert, but the text stays readable.","code":"<Editor\n defaultValue=\"This content cannot be edited.\"\n disabled\n/>"},{"name":"Read Only","description":"Text can be selected and copied, but never changed.","code":"<Editor\n defaultValue=\"This content is read-only. You can select and copy text but cannot modify it.\"\n readOnly\n/>"},{"name":"Custom Toolbar","description":"Separators split the controls into labelled clusters.","code":"<Editor\n placeholder=\"Write your blog post...\"\n onValueChange={(v) => console.log(v)}\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"Basic formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Advanced formatting\">\n <Editor.ToolbarButton format=\"link\" />\n <Editor.ToolbarButton format=\"code\" />\n <Editor.ToolbarButton format=\"bulletList\" />\n </Editor.ToolbarGroup>\n <Editor.ToolbarGroup aria-label=\"Status\">\n <Editor.StatusIndicator status=\"saving\" />\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"Full Formatting","description":"Every opt-in format switched on, at the tallest preset.","code":"<Editor\n placeholder=\"Write an article...\"\n size=\"lg\"\n>\n <Editor.Toolbar>\n <Editor.ToolbarGroup aria-label=\"History\">\n <Editor.ToolbarButton format=\"undo\" />\n <Editor.ToolbarButton format=\"redo\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Headings\">\n <Editor.ToolbarButton format=\"heading1\" />\n <Editor.ToolbarButton format=\"heading2\" />\n <Editor.ToolbarButton format=\"heading3\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Text formatting\">\n <Editor.ToolbarButton format=\"bold\" />\n <Editor.ToolbarButton format=\"italic\" />\n <Editor.ToolbarButton format=\"strikethrough\" />\n <Editor.ToolbarButton format=\"code\" />\n </Editor.ToolbarGroup>\n <Editor.Separator />\n <Editor.ToolbarGroup aria-label=\"Block formatting\">\n <Editor.ToolbarButton format=\"bulletList\" />\n <Editor.ToolbarButton format=\"orderedList\" />\n <Editor.ToolbarButton format=\"blockquote\" />\n <Editor.ToolbarButton format=\"link\" />\n </Editor.ToolbarGroup>\n </Editor.Toolbar>\n <Editor.Content />\n <Editor.StatusBar showWordCount showCharCount />\n</Editor>"},{"name":"With Character Limit","description":"The counter warns near 280 characters and turns red past it.","code":"<Editor\n placeholder=\"Write a tweet-sized message...\"\n maxLength={280}\n size=\"sm\"\n formats={['bold', 'italic', 'link']}\n/>"},{"name":"Small Size","description":"A 120px body with a trimmed toolbar, for tight spaces.","code":"<Editor\n placeholder=\"Quick note...\"\n size=\"sm\"\n formats={['bold', 'italic', 'code']}\n/>"}],"contract":{"propsSummary":["value: string - controlled editor value","onValueChange: (value: string) => void - change callback","placeholder: string - hint text (default: \"Start typing...\")","disabled: boolean - disables interaction","readOnly: boolean - prevents editing","formats: EditorFormat[] - toolbar buttons (default: all 6)","toolbar: boolean - show default toolbar (default: true)","statusBar: boolean - show word/char counts (default: true)","onAutoSave: (value: string) => void | Promise<void> - auto-save handler","size: \"sm\" | \"md\" | \"lg\" - editor height preset (default: \"md\")","maxLength: number - character limit with visual indicator","toolbarIcons: Partial<Record<EditorFormat, ReactNode | (state) => ReactNode>> - custom toolbar icons"],"a11yRules":["A11Y_TOOLBAR_ROLE","A11Y_BUTTON_LABEL","A11Y_LIVE_REGION"]},"ai":{"compositionPattern":"compound","subComponents":["Toolbar","ToolbarGroup","ToolbarButton","Separator","StatusIndicator","Content","StatusBar","preload"]},"propsSummary":["children: node","value: string","defaultValue: string (default: )","onValueChange: function","placeholder: string (default: Start typing...)","disabled: boolean (default: false)","readOnly: boolean (default: false)","formats: array","toolbar: boolean (default: true)","statusBar: boolean (default: true)","onAutoSave: function","autoSaveInterval: number (default: 30000)","size: sm|md|lg (default: md)","maxLength: number","toolbarIcons: object"],"sourcePath":"src/components/Editor/index.tsx","exportName":"Editor","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:56.748Z"},"performance":{"bundleSize":138773,"rawSize":442459,"complexity":"heavy","budgetPercent":903,"overBudget":true,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"@tiptap/react","bytes":335208,"percent":76},{"path":"@phosphor-icons/react","bytes":34485,"percent":8},{"path":"@tiptap/starter-kit","bytes":32005,"percent":7},{"path":"@tiptap/extension-link","bytes":25654,"percent":6},{"path":"Editor (self)","bytes":10201,"percent":2},{"path":"src/utils/keyboard-shortcuts.ts","bytes":2656,"percent":1},{"path":"src/utils/env.ts","bytes":93,"percent":0}]}},"EmptyState":{"filePath":"src/components/EmptyState/index.tsx","meta":{"name":"EmptyState","description":"Explains why an area is blank and offers the next step.","category":"feedback","tags":["empty","placeholder","no-data","zero-state","blank-slate"],"status":"stable"},"usage":{"when":["Lists, tables, or search results with nothing to show","First-run screens before any content exists","Filtered views that matched nothing"],"whenNot":["Content still loading (use Skeleton)","Failures that need a retry (use Alert)","Transient confirmations (use Toast)"],"guidelines":["Say why the area is empty, not just that it is","Give one clear action out of the state","Keep to two actions at most, primary first","Match the icon to the cause — search, inbox, folder","Use size=\"sm\" inline and size=\"lg\" for full-page states"],"accessibility":["Empty state content is accessible to screen readers","Action buttons follow button accessibility guidelines"]},"props":{"children":{"type":"node","description":"EmptyState content - use EmptyState.Icon, EmptyState.Title, EmptyState.Description, EmptyState.Actions sub-components","required":true},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Chrome. `outline` draws a dashed hairline around the reserved region; `ghost` leaves framing to the surrounding surface.","default":"ghost","required":false,"values":["ghost","outline"]}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for error states with retry"},{"component":"Progress","relationship":"alternative","note":"Use Progress/Spinner for loading states"}],"variants":[{"name":"Default","description":"First-run state: nothing exists yet, so offer the create action.","code":"<EmptyState>\n <EmptyState.Icon><FolderIcon /></EmptyState.Icon>\n <EmptyState.Title>No projects yet</EmptyState.Title>\n <EmptyState.Description>Get started by creating your first project.</EmptyState.Description>\n <EmptyState.Actions>\n <Button>Create Project</Button>\n </EmptyState.Actions>\n</EmptyState>"},{"name":"No Results","description":"A filter or query matched nothing — offer a way back.","code":"<EmptyState>\n <EmptyState.Icon><SearchIcon /></EmptyState.Icon>\n <EmptyState.Title>No results found</EmptyState.Title>\n <EmptyState.Description>Try adjusting your search terms or filters.</EmptyState.Description>\n <EmptyState.Actions>\n <Button variant=\"soft\">Clear Filters</Button>\n </EmptyState.Actions>\n</EmptyState>"},{"name":"With Secondary Action","description":"One primary action plus a quieter alternative.","code":"<EmptyState>\n <EmptyState.Icon><InboxIcon /></EmptyState.Icon>\n <EmptyState.Title>Inbox is empty</EmptyState.Title>\n <EmptyState.Description>You have no new messages.</EmptyState.Description>\n <EmptyState.Actions>\n <Button>Compose Message</Button>\n <Button variant=\"soft\">View Archive</Button>\n </EmptyState.Actions>\n</EmptyState>"},{"name":"Small","description":"Compact size for inline panels; no icon, no action.","code":"<EmptyState size=\"sm\">\n <EmptyState.Title>No items</EmptyState.Title>\n <EmptyState.Description>Add items to see them here.</EmptyState.Description>\n</EmptyState>"},{"name":"Large","description":"Full-page size for a workspace or onboarding screen.","code":"<EmptyState size=\"lg\">\n <EmptyState.Icon><FolderIcon /></EmptyState.Icon>\n <EmptyState.Title>Welcome to your workspace</EmptyState.Title>\n <EmptyState.Description>\n This is where your projects will appear. Create your first project to get started.\n </EmptyState.Description>\n <EmptyState.Actions>\n <Button>Create Your First Project</Button>\n </EmptyState.Actions>\n</EmptyState>"}],"contract":{"propsSummary":["size: sm|md|lg (default: md)","Sub-components: EmptyState.Icon, EmptyState.Title, EmptyState.Description, EmptyState.Actions","Compound sub-components forward DOM props to their rendered elements"],"a11yRules":["A11Y_EMPTY_STATE_CONTENT"]},"ai":{"compositionPattern":"compound","subComponents":["Icon","Title","Description","Actions"],"requiredChildren":["Title"],"commonPatterns":["<EmptyState><EmptyState.Title>{title}</EmptyState.Title><EmptyState.Description>{description}</EmptyState.Description></EmptyState>","<EmptyState><EmptyState.Icon>{icon}</EmptyState.Icon><EmptyState.Title>{title}</EmptyState.Title><EmptyState.Description>{description}</EmptyState.Description><EmptyState.Actions><Button>{action}</Button></EmptyState.Actions></EmptyState>"]},"propsSummary":["children: node (required)","size: sm|md|lg (default: md)","variant: ghost|outline (default: ghost)"],"sourcePath":"src/components/EmptyState/index.tsx","exportName":"EmptyState","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:56.922Z"},"performance":{"bundleSize":813,"rawSize":1902,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"EmptyState (self)","bytes":1173,"percent":62}]}},"Field":{"filePath":"src/components/Field/index.tsx","meta":{"name":"Field","description":"Composes labels, descriptions, validation, and errors around a form control.","category":"inputs","tags":["form","field","validation","label","error","input","accessible"],"status":"stable"},"usage":{"when":["One error message per failure reason, not one catch-all","A custom control needs a real label and description","Server errors must land on the field that caused them","You need dirty and touched tracking"],"whenNot":["A plain input with a label and helper text (use Input's own props)","A Select or Textarea whose built-in error display is enough"],"guidelines":["Every Field gets a Field.Label","Wrap the control in Field.Control so it joins the field context","Give each Field.Error a match so the message fits the failure","Nest inside Form to route server errors by field name"],"accessibility":["Label links to the control via aria-labelledby","Description links via aria-describedby","Errors are announced when they appear","data-disabled and data-invalid are available for styling"]},"props":{"children":{"type":"node","description":"Field content (Label, Control, Description, Error)","required":true},"name":{"type":"string","description":"Field name, used for error distribution from Form","required":false},"disabled":{"type":"boolean","description":"Disables the field and its control","required":false},"invalid":{"type":"boolean","description":"Marks the field as invalid","required":false},"validate":{"type":"function","description":"Custom validation function returning error string(s) or null","required":false},"validationMode":{"type":"enum","description":"When to trigger validation","required":false,"values":["onSubmit","onBlur","onChange"]},"validationDebounceTime":{"type":"number","description":"Debounce time in ms for onChange validation","required":false},"size":{"type":"enum","description":"","required":false,"values":["sm","md","lg"]}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for simple fields with built-in label/error"},{"component":"Form","relationship":"parent","note":"Wrap in Form for server-side error distribution"},{"component":"Fieldset","relationship":"sibling","note":"Use Fieldset to group related fields"}],"variants":[{"name":"Single field","description":"Label, control and description wired together automatically.","code":"<Field name=\"email\">\n <Field.Label>Email address</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Description>We will never share your email.</Field.Description>\n</Field>"},{"name":"Two-column layout","description":"Grid places two short fields side by side and one full-width.","code":"<Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"typeMismatch\">Enter a valid email address</Field.Error>\n </Field>\n </Grid.Item>\n</Grid>"},{"name":"Invalid","description":"invalid marks the field failed and reveals Field.Error.","code":"<Field name=\"username\" invalid>\n <Field.Label>Username</Field.Label>\n <Field.Control>\n <Input value=\"ada lovelace\" error />\n </Field.Control>\n <Field.Error match>Usernames cannot contain spaces</Field.Error>\n</Field>"},{"name":"Custom validation","description":"validate runs on change and feeds Field.Error.","code":"<Field\n name=\"age\"\n validate={(value) => {\n const num = Number(value);\n if (isNaN(num) || num < 18) return 'Must be 18 or older';\n return null;\n }}\n validationMode=\"onChange\"\n validationDebounceTime={500}\n>\n <Field.Label>Age</Field.Label>\n <Field.Control>\n <Input type=\"number\" placeholder=\"18\" />\n </Field.Control>\n <Field.Description>You must be at least 18 years old.</Field.Description>\n <Field.Error match=\"customError\" />\n</Field>"}],"contract":{"propsSummary":["name: string - field name for error distribution","validate: (value) => string | null - custom validation","validationMode: onSubmit|onBlur|onChange - validation trigger","Field.Control: wraps any form component (Input, Textarea, etc.)","Field.Error match: valueMissing|typeMismatch|customError|... - granular errors"],"a11yRules":["A11Y_FIELD_LABEL","A11Y_FIELD_ERROR","A11Y_FIELD_DESCRIPTION"]},"ai":{"compositionPattern":"compound","subComponents":["Label","Control","Description","Error","Validity","Required"],"commonPatterns":["<Field>\n <Field.Label>...</Field.Label>\n <Field.Control>...</Field.Control>\n <Field.Description>...</Field.Description>\n</Field>"],"requiredChildren":["Label","Control"]},"propsSummary":["children: node (required)","name: string","disabled: boolean","invalid: boolean","validate: function","validationMode: onSubmit|onBlur|onChange","validationDebounceTime: number"],"sourcePath":"src/components/Field/index.tsx","exportName":"Field","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.733Z"},"performance":{"bundleSize":923,"rawSize":2253,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Field (self)","bytes":1348,"percent":60},{"path":"ComponentDefaults","bytes":193,"percent":9}]}},"Fieldset":{"filePath":"src/components/Fieldset/index.tsx","meta":{"name":"Fieldset","description":"Groups related form controls under an accessible legend.","category":"inputs","tags":["form","fieldset","group","legend","accessible"],"status":"stable"},"usage":{"when":["Fields that belong to one subject: address, billing, profile","Locking a whole section at once","Screen readers should hear the group name before each field"],"whenNot":["Grouping for looks alone (use Card)","Wrapping one control (use Field)"],"guidelines":["Every Fieldset gets a Fieldset.Legend","disabled on the Fieldset locks every control inside it","Put a Grid inside for multi-column layouts","Fieldset.Legend forwards DOM props for ids, ARIA, and data hooks"],"accessibility":["Renders a real fieldset element","Legend names the group","Disabled cascades to every child field"]},"props":{"children":{"type":"node","description":"Fieldset content including Fieldset.Legend and form fields","required":true},"disabled":{"type":"boolean","description":"Disables all fields within the fieldset","required":false}},"relations":[{"component":"Field","relationship":"sibling","note":"Contains Field components"},{"component":"Form","relationship":"parent","note":"Used within a Form"},{"component":"Card","relationship":"alternative","note":"Use Card for non-form visual grouping"}],"variants":[{"name":"Two-column layout","description":"A Grid inside the legend box pairs short fields on one row.","code":"<Fieldset>\n <Fieldset.Legend>Personal Information</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n</Fieldset>"},{"name":"Mixed controls","description":"Textarea, select and checkbox share one spacing rhythm.","code":"<Fieldset>\n <Fieldset.Legend>Preferences</Fieldset.Legend>\n <Field name=\"bio\">\n <Field.Label>Bio</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"Tell us about yourself\" rows={3} />\n </Field.Control>\n <Field.Description>Brief description for your profile.</Field.Description>\n </Field>\n <Field name=\"role\">\n <Field.Label>Role</Field.Label>\n <Field.Control>\n <Select placeholder=\"Select a role\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"admin\">Admin</Select.Item>\n <Select.Item value=\"editor\">Editor</Select.Item>\n <Select.Item value=\"viewer\">Viewer</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n <Field name=\"newsletter\">\n <Field.Control>\n <Checkbox label=\"Subscribe to newsletter\" />\n </Field.Control>\n </Field>\n</Fieldset>"},{"name":"With Description","description":"One sentence under the legend covers the whole group.","code":"<Fieldset>\n <Fieldset.Legend>Notification Settings</Fieldset.Legend>\n <Fieldset.Description>Choose how you want to be notified about updates.</Fieldset.Description>\n <Field name=\"emailNotif\">\n <Field.Control>\n <Checkbox label=\"Email notifications\" />\n </Field.Control>\n </Field>\n <Field name=\"smsNotif\">\n <Field.Control>\n <Checkbox label=\"SMS notifications\" />\n </Field.Control>\n </Field>\n</Fieldset>"},{"name":"Disabled","description":"One prop on the wrapper dims and locks every control inside.","code":"<Fieldset disabled>\n <Fieldset.Legend>Locked Section</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"lockedFirst\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input defaultValue=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lockedLast\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input defaultValue=\"Doe\" />\n </Field.Control>\n </Field>\n </Grid>\n <Field name=\"lockedCheck\">\n <Field.Control>\n <Checkbox label=\"Cannot toggle\" defaultChecked />\n </Field.Control>\n </Field>\n</Fieldset>"}],"contract":{"propsSummary":["disabled: boolean - disables all child fields","Fieldset.Legend: accessible group label","Fieldset.Legend forwards DOM props","Fieldset.Description: helper text below the legend"],"a11yRules":["A11Y_FIELDSET_LEGEND"]},"ai":{"compositionPattern":"compound","subComponents":["Legend","Description"],"commonPatterns":["<Fieldset>\n <Fieldset.Legend>...</Fieldset.Legend>\n</Fieldset>"],"requiredChildren":["Legend"]},"propsSummary":["children: node (required)","disabled: boolean"],"sourcePath":"src/components/Fieldset/index.tsx","exportName":"Fieldset","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:57.275Z"},"performance":{"bundleSize":610,"rawSize":1285,"complexity":"lightweight","budgetPercent":4,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Fieldset (self)","bytes":632,"percent":49}]}},"Form":{"filePath":"src/components/Form/index.tsx","meta":{"name":"Form","description":"Distributes server-side validation errors to its Field components.","category":"inputs","tags":["form","validation","errors","submit","server"],"status":"stable"},"usage":{"when":["The server rejects a submission and each reason must reach its own field","Client and server validation live in the same form"],"whenNot":["Client-side validation only (a native form plus Field is enough)","Layout without submission (use Grid or Card)"],"guidelines":["errors is keyed by field name: Record<string, string | string[]>","Clear a field's error in onClearErrors when the user edits it","Use onSubmit; onFormSubmit is a deprecated alias","A Field picks up its error by matching name","Leave Field.Error unmatched so it shows whatever the server sent","Put a Grid inside Form or Fieldset for multi-column layouts","Buttons go in Form.Actions so they stay right-aligned"],"accessibility":["Renders a real form element","Errors link back to their field via aria-describedby"]},"props":{"children":{"type":"node","description":"Form content","required":true},"errors":{"type":"object","description":"Server-side errors keyed by field name","required":false},"onSubmit":{"type":"function","description":"Form submission handler (preferred)","required":false},"onFormSubmit":{"type":"function","description":"Deprecated alias for onSubmit","required":false},"onClearErrors":{"type":"function","description":"Called with field name when errors should be cleared","required":false},"validationMode":{"type":"enum","description":"When field validation should run","required":false,"values":["onSubmit","onBlur","onChange"]}},"relations":[{"component":"Field","relationship":"sibling","note":"Contains Field components for error distribution"},{"component":"Fieldset","relationship":"sibling","note":"Use Fieldset to group fields within a Form"},{"component":"Button","relationship":"sibling","note":"Use Button type=\"submit\" for form submission"}],"variants":[{"name":"Sign up","description":"Paired name fields, then full-width rows and a right-aligned submit.","code":"<Form onSubmit={(e) => { e.preventDefault(); }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"firstName\">\n <Field.Label>First Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Jane\" />\n </Field.Control>\n </Field>\n <Field name=\"lastName\">\n <Field.Label>Last Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Doe\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"jane@example.com\" />\n </Field.Control>\n <Field.Error match=\"typeMismatch\">Enter a valid email address</Field.Error>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"password\">\n <Field.Label>Password</Field.Label>\n <Field.Control>\n <Input type=\"password\" placeholder=\"At least 8 characters\" />\n </Field.Control>\n <Field.Description>Must be at least 8 characters</Field.Description>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"terms\">\n <Field.Control>\n <Checkbox label=\"I agree to the terms and conditions\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n <Form.Actions>\n <Button type=\"submit\" variant=\"solid\">Create Account</Button>\n </Form.Actions>\n</Form>"},{"name":"Profile settings","description":"Fieldsets split a long form into sections the user can scan.","code":"<Form onSubmit={(e) => { e.preventDefault(); }}>\n <Fieldset>\n <Fieldset.Legend>Profile</Fieldset.Legend>\n <Grid columns={2} gap=\"md\">\n <Field name=\"displayName\">\n <Field.Label>Display Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"How others see you\" />\n </Field.Control>\n </Field>\n <Field name=\"timezone\">\n <Field.Label>Timezone</Field.Label>\n <Field.Control>\n <Select placeholder=\"Select timezone\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"utc\">UTC</Select.Item>\n <Select.Item value=\"est\">Eastern (EST)</Select.Item>\n <Select.Item value=\"pst\">Pacific (PST)</Select.Item>\n <Select.Item value=\"gmt\">GMT</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"bio\">\n <Field.Label>Bio</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"Tell us about yourself\" rows={3} maxLength={280} />\n </Field.Control>\n <Field.Description>Max 280 characters</Field.Description>\n </Field>\n </Grid.Item>\n </Grid>\n </Fieldset>\n <Fieldset>\n <Fieldset.Legend>Notifications</Fieldset.Legend>\n <Field name=\"emailNotifs\">\n <Field.Control>\n <Switch label=\"Email notifications\" />\n </Field.Control>\n </Field>\n <Field name=\"marketingEmails\">\n <Field.Control>\n <Switch label=\"Marketing emails\" />\n </Field.Control>\n </Field>\n <Field name=\"frequency\">\n <Field.Label>Digest frequency</Field.Label>\n <Field.Control>\n <RadioGroup name=\"frequency\" orientation=\"vertical\">\n <RadioGroup.Item value=\"daily\" label=\"Daily\" />\n <RadioGroup.Item value=\"weekly\" label=\"Weekly\" />\n <RadioGroup.Item value=\"monthly\" label=\"Monthly\" />\n </RadioGroup>\n </Field.Control>\n </Field>\n </Fieldset>\n <Form.Actions>\n <Button type=\"submit\" variant=\"solid\">Save Changes</Button>\n </Form.Actions>\n</Form>"},{"name":"Contact form","description":"Mixed control types in one submission flow.","code":"<Form onSubmit={(e) => { e.preventDefault(); }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"name\">\n <Field.Label>Name</Field.Label>\n <Field.Control>\n <Input placeholder=\"Your name\" />\n </Field.Control>\n </Field>\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" placeholder=\"you@example.com\" />\n </Field.Control>\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field name=\"subject\">\n <Field.Label>Subject</Field.Label>\n <Field.Control>\n <Select placeholder=\"What is this about?\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"general\">General Inquiry</Select.Item>\n <Select.Item value=\"support\">Technical Support</Select.Item>\n <Select.Item value=\"billing\">Billing</Select.Item>\n <Select.Item value=\"feedback\">Feedback</Select.Item>\n </Select.Content>\n </Select>\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"message\">\n <Field.Label>Message</Field.Label>\n <Field.Control>\n <Textarea placeholder=\"How can we help?\" rows={5} />\n </Field.Control>\n </Field>\n </Grid.Item>\n <Grid.Item colSpan=\"full\">\n <Field name=\"copy\">\n <Field.Control>\n <Checkbox label=\"Send me a copy\" />\n </Field.Control>\n </Field>\n </Grid.Item>\n </Grid>\n <Form.Actions>\n <Button type=\"submit\" variant=\"solid\">Send Message</Button>\n </Form.Actions>\n</Form>"},{"name":"With server errors","description":"Errors from the server land on the fields that caused them.","code":"<Form errors={{ username: 'Username is already taken', email: 'Email is already registered' }}>\n <Grid columns={2} gap=\"md\">\n <Field name=\"username\">\n <Field.Label>Username</Field.Label>\n <Field.Control>\n <Input defaultValue=\"janedoe\" />\n </Field.Control>\n <Field.Error />\n </Field>\n <Field name=\"email\">\n <Field.Label>Email</Field.Label>\n <Field.Control>\n <Input type=\"email\" defaultValue=\"jane@example.com\" />\n </Field.Control>\n <Field.Error />\n </Field>\n </Grid>\n <Form.Actions>\n <Button type=\"submit\" variant=\"solid\">Submit</Button>\n </Form.Actions>\n</Form>"}],"contract":{"propsSummary":["errors: Record<string, string | string[]> - server errors by field name","onSubmit: (event) => void - submission handler (preferred)","onFormSubmit: (event) => void - deprecated alias for onSubmit","onClearErrors: (name) => void - clear errors callback"],"a11yRules":["A11Y_FORM_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Actions"],"commonPatterns":["<Form>\n <Form.Actions>...</Form.Actions>\n</Form>"],"requiredChildren":["Actions"]},"propsSummary":["children: node (required)","errors: object","onSubmit: function","onFormSubmit: function","onClearErrors: function","validationMode: onSubmit|onBlur|onChange"],"sourcePath":"src/components/Form/index.tsx","exportName":"Form","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:57.100Z"},"performance":{"bundleSize":619,"rawSize":1139,"complexity":"lightweight","budgetPercent":4,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Form (self)","bytes":553,"percent":49}]}},"Grid":{"filePath":"src/components/Grid/index.tsx","meta":{"name":"Grid","description":"Arranges items into responsive columns with one shared gap.","category":"layout","tags":["grid","layout","columns","responsive"],"status":"stable"},"usage":{"when":["Cards, tiles, or media that reflow across breakpoints","Multi-column form layouts","Dashboard widget layouts"],"whenNot":["One-directional lists (use Stack)","Editorial mosaics with feature tiles (use BentoGrid)","Navigation bars (use Header)"],"guidelines":["columns=\"auto\" with minChildWidth adapts without breakpoints","Pass { base, md, lg } to columns for explicit per-breakpoint control","Numeric gaps (1-8) map to the same spacing scale as the tokens","Wrap a child in Grid.Item to span columns; colSpan=\"full\" spans the row","Keep source order equal to visual order — Grid does not reorder for screen readers"],"accessibility":["Grid is purely visual — it does not affect reading order or semantics","Ensure logical source order matches visual order for screen readers"]},"props":{"children":{"type":"node","description":"Grid items and content","required":false},"columns":{"type":"union","description":"Number of columns: a number (1-12), a responsive object { base, sm, md, lg, xl }, or \"auto\" for auto-fill","default":"1","required":false,"constraints":["Use \"auto\" with minChildWidth for fully fluid layouts","Use responsive object for explicit breakpoint control: { base: 1, md: 2, lg: 3 }"]},"minChildWidth":{"type":"string","description":"Minimum width for auto-fill columns (e.g., \"16rem\", \"250px\")","required":false,"constraints":["Only applies when columns=\"auto\""]},"gap":{"type":"union","description":"Gap between grid items. Accepts string tokens or numbers (1-8) mapped to the spacing scale","default":"md","required":false,"values":["none","xs","sm","md","lg","xl"]},"alignItems":{"type":"enum","description":"Vertical alignment of items within their cells","required":false,"values":["start","center","end","stretch"]},"justifyItems":{"type":"enum","description":"Horizontal alignment of items within their cells","required":false,"values":["start","center","end","stretch"]},"padding":{"type":"enum","description":"Internal padding of the grid container","default":"none","required":false,"values":["none","sm","md","lg"]},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false}},"relations":[{"component":"Card","relationship":"child","note":"Grid commonly contains Card components for dashboard and tile layouts"},{"component":"Separator","relationship":"sibling","note":"Use Separator between grid sections"}],"variants":[{"name":"Default","description":"A fixed count of equal columns.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns={3} gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">One</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Two</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Three</Box>\n </Grid>\n</Box>"},{"name":"Responsive","description":"Column count changes per breakpoint.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns={{ base: 1, md: 2, lg: 3 }} gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 1</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 2</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 3</Box>\n </Grid>\n</Box>"},{"name":"Auto-fill","description":"Columns fit themselves to a minimum child width — no breakpoints needed.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns=\"auto\" minChildWidth=\"10rem\" gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 1</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 2</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 3</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Card 4</Box>\n </Grid>\n</Box>"},{"name":"With Spanning","description":"Grid.Item stretches a child across columns.","code":"import { Box } from '@/components/Box';\nimport { Grid } from '@/components/Grid';\n\n<Box width=\"100%\">\n <Grid columns={4} gap=\"md\">\n <Grid.Item colSpan={2}>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Spans 2 columns</Box>\n </Grid.Item>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">1 col</Box>\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">1 col</Box>\n <Grid.Item colSpan=\"full\">\n <Box background=\"secondary\" rounded=\"sm\" padding=\"sm\">Full width</Box>\n </Grid.Item>\n </Grid>\n</Box>"},{"name":"Form Layout","description":"Paired fields with one full-width row.","code":"import { Box } from '@/components/Box';\nimport { Field } from '@/components/Field';\nimport { Grid } from '@/components/Grid';\nimport { Input } from '@/components/Input';\n\n<Box width=\"100%\">\n <Grid columns={{ base: 1, md: 2 }} gap=\"md\">\n <Field>\n <Field.Label>First name</Field.Label>\n <Input placeholder=\"Ada\" />\n </Field>\n <Field>\n <Field.Label>Last name</Field.Label>\n <Input placeholder=\"Lovelace\" />\n </Field>\n <Grid.Item colSpan=\"full\">\n <Field>\n <Field.Label>Email address</Field.Label>\n <Input type=\"email\" placeholder=\"ada@example.com\" />\n </Field>\n </Grid.Item>\n </Grid>\n</Box>"}],"contract":{"propsSummary":["columns: 1-12 | { base, sm, md, lg, xl } | \"auto\" (default: 1)","minChildWidth: string — min width for auto-fill (only with columns=\"auto\")","gap: none|xs|sm|md|lg|xl|number (default: md, number maps to space scale)","alignItems: start|center|end|stretch — vertical alignment","justifyItems: start|center|end|stretch — horizontal alignment","padding: none|sm|md|lg (default: none)","Pass-through DOM props supported on Grid and Grid.Item roots (id, role, aria-*, data-*, handlers)"]},"propsSummary":["children: node","columns: union (default: 1)","minChildWidth: string","gap: union (default: md)","alignItems: start|center|end|stretch","justifyItems: start|center|end|stretch","padding: none|sm|md|lg (default: none)","className: string","style: object"],"sourcePath":"src/components/Grid/index.tsx","exportName":"Grid","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:57.444Z"},"performance":{"bundleSize":2069,"rawSize":4663,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"src/utils/layout-spacing.ts","bytes":2475,"percent":53},{"path":"Grid (self)","bytes":1615,"percent":35}]}},"Header":{"filePath":"src/components/Header/index.tsx","meta":{"name":"Header","description":"Composes brand, navigation, search, and actions into one responsive app bar.","category":"layout","tags":["header","navigation","navbar","brand","layout","dropdown"],"status":"stable"},"usage":{"when":["Top-level navigation for an app or site","Inside AppShell.Header","Anywhere brand, nav, and actions share one row"],"whenNot":["Section headings inside a page (use a heading)","Toolbars scoped to one panel (use Toolbar)","Sidebar-only navigation (use Sidebar)"],"guidelines":["Header.Spacer pushes the actions cluster to the right","Omit Header.Brand when the sidebar already shows the logo","container=\"page\" caps the content at page width for marketing bars","elevatedOnScroll adds a bottom border once the page scrolls","Pair Header.Trigger with Header.MobileNav for small screens","Header.SkipLink should be the first child"],"accessibility":["Include Header.SkipLink for keyboard users","Navigation has aria-label for screen readers","Active nav items use aria-current=\"page\"","Mobile trigger has aria-expanded state","NavMenu dropdown opens with click and is keyboard navigable"]},"props":{"children":{"type":"node","description":"Header content (use Header.Brand, Header.Nav, etc.)","required":true},"height":{"type":"string","description":"Header height","default":"56px","required":false},"position":{"type":"enum","description":"Position behavior (usually controlled by AppShell)","default":"static","required":false,"values":["static","fixed","sticky"]},"elevatedOnScroll":{"type":"union","description":"Apply the elevated header border after scrolling. Object form accepts { threshold?: number }.","default":"false","required":false},"navAlign":{"type":"enum","description":"Navigation alignment inside the header","default":"start","required":false,"values":["start","center"]},"container":{"type":"enum","description":"Header content width","default":"full","required":false,"values":["full","page"]},"icons":{"type":"object","description":"Optional icon overrides for Header.Trigger (menu/close) and Header.NavMenu chevron","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"AppShell","relationship":"parent","note":"Header is typically used inside AppShell.Header"},{"component":"Sidebar","relationship":"sibling","note":"Header.Trigger toggles Sidebar on mobile"},{"component":"Theme","relationship":"child","note":"ThemeToggle is commonly placed in Header.Actions"},{"component":"NavigationMenu","relationship":"child","note":"Use NavigationMenu inside Header for rich dropdown nav with auto mobile drawer"}],"variants":[{"name":"For Default Layout","description":"Brand, nav, and actions for AppShell layout=\"default\".","code":"import { Box } from '@/components/Box';\nimport { Button } from '@/components/Button';\nimport { Header } from '@/components/Header';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/dashboard\" active>Dashboard</Header.NavItem>\n <Header.NavItem href=\"/projects\">Projects</Header.NavItem>\n <Header.NavItem href=\"/settings\">Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"soft\" size=\"sm\">Sign In</Button>\n </Header.Actions>\n </Header>\n</Box>"},{"name":"Marketing Header","description":"Sticky page-width bar that gains a border on scroll, with a mobile drawer.","code":"import { Box } from '@/components/Box';\nimport { Button } from '@/components/Button';\nimport { Header } from '@/components/Header';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header position=\"sticky\" elevatedOnScroll navAlign=\"center\" container=\"page\">\n <Header.SkipLink href=\"#main-content\" />\n <Header.Brand asChild>\n <a href=\"/\" aria-label=\"Home\">Logo</a>\n </Header.Brand>\n <Header.Nav aria-label=\"Main navigation\">\n <Header.NavItem href=\"/docs\">Docs</Header.NavItem>\n <Header.NavItem href=\"/pricing\">Pricing</Header.NavItem>\n </Header.Nav>\n <Header.Actions>\n <Button size=\"sm\">Start free</Button>\n </Header.Actions>\n <Header.Trigger />\n <Header.MobileNav>\n <Header.MobileNavLink href=\"/docs\">Docs</Header.MobileNavLink>\n <Header.MobileNavLink href=\"/pricing\">Pricing</Header.MobileNavLink>\n <Header.MobileNavActions>\n <Button size=\"sm\">Start free</Button>\n </Header.MobileNavActions>\n </Header.MobileNav>\n </Header>\n</Box>"},{"name":"With Dropdown Nav","description":"Header.NavMenu groups related links behind one trigger.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/components\" active>Components</Header.NavItem>\n <Header.NavItem href=\"/blocks\">Blocks</Header.NavItem>\n <Header.NavMenu label=\"Docs\">\n <Header.NavMenuItem href=\"/getting-started\">Getting Started</Header.NavMenuItem>\n <Header.NavMenuItem href=\"/cli\">CLI Reference</Header.NavMenuItem>\n <Header.NavMenuItem href=\"/mcp\">MCP Tools</Header.NavMenuItem>\n </Header.NavMenu>\n <Header.NavItem href=\"/blog\">Blog</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n</Box>"},{"name":"For Sidebar Layout","description":"No brand — the logo lives in the sidebar instead.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { Input } from '@/components/Input';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Search>\n <Input placeholder=\"Search...\" style={{ width: '240px' }} />\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n</Box>"},{"name":"Minimal","description":"Just the drawer trigger and actions.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.Trigger />\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n </Header.Actions>\n </Header>\n</Box>"},{"name":"With Skip Link","description":"Header.SkipLink gives keyboard users a jump to main content.","code":"import { Box } from '@/components/Box';\nimport { Header } from '@/components/Header';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.SkipLink href=\"#main-content\">Skip to content</Header.SkipLink>\n <Header.Brand>Accessible App</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/\" active>Home</Header.NavItem>\n <Header.NavItem href=\"/about\">About</Header.NavItem>\n </Header.Nav>\n </Header>\n</Box>"},{"name":"With NavigationMenu","description":"Rich dropdown panels with titles and descriptions.","code":"import { Box } from '@/components/Box';\nimport { Button } from '@/components/Button';\nimport { Header } from '@/components/Header';\nimport { NavigationMenu } from '@/components/NavigationMenu';\nimport { Stack } from '@/components/Stack';\nimport { ThemeToggle } from '@/components/Theme';\n\n<Box width=\"100%\" border rounded=\"md\" overflow=\"hidden\">\n <Header>\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <NavigationMenu aria-label=\"Site navigation\">\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"products\">\n <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <Box padding=\"xs\" style={{ minWidth: '200px' }}>\n <Stack gap=\"none\">\n <NavigationMenu.Link href=\"/analytics\" title=\"Analytics\" description=\"Track your metrics.\" />\n <NavigationMenu.Link href=\"/automation\" title=\"Automation\" description=\"Automate workflows.\" />\n </Stack>\n </Box>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/pricing\">Pricing</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n </NavigationMenu>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"solid\" size=\"sm\">Sign Up</Button>\n </Header.Actions>\n </Header>\n</Box>"}],"contract":{"propsSummary":["height: string - header height (default: 56px)","position: static|fixed|sticky - positioning behavior","elevatedOnScroll: boolean|{ threshold?: number } - scroll-elevated boundary","navAlign: start|center - nav placement inside the header","container: full|page - content width and gutter","icons: { menu?, close?, navMenuChevron? } - custom internal control icons (ReactNode or render function)","Header.Brand asChild composes custom link components","Header.Trigger composes click handler with Sidebar toggle behavior","Header.NavMenu provides dropdown groups via Base UI Menu","Header.MobileNavActions provides an action row inside the mobile drawer"],"a11yRules":["A11Y_HEADER_LANDMARK","A11Y_NAV_LABEL","A11Y_SKIP_LINK","A11Y_BUTTON_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["SkipLink","Trigger","Brand","Nav","NavItem","MobileNav","MobileNavLink","MobileNavActions","NavMenu","NavMenuItem","Search","Spacer","Actions"],"commonPatterns":["<Header><Header.Brand href=\"/\">{appName}</Header.Brand><Header.Nav><Header.NavItem href=\"/home\" active>Home</Header.NavItem></Header.Nav><Header.Spacer /><Header.Actions>{actions}</Header.Actions></Header>","<Header position=\"sticky\" elevatedOnScroll navAlign=\"center\" container=\"page\"><Header.Brand asChild>{link}</Header.Brand><Header.Nav>{links}</Header.Nav><Header.Actions>{actions}</Header.Actions><Header.Trigger /><Header.MobileNav>{mobileLinks}<Header.MobileNavActions>{mobileActions}</Header.MobileNavActions></Header.MobileNav></Header>","<Header><Header.Nav><Header.NavItem href=\"/home\">Home</Header.NavItem><Header.NavMenu label=\"Docs\" active><Header.NavMenuItem href=\"/cli\">CLI</Header.NavMenuItem><Header.NavMenuItem href=\"/mcp\">MCP</Header.NavMenuItem></Header.NavMenu></Header.Nav></Header>"]},"propsSummary":["children: node (required)","height: string (default: 56px)","position: static|fixed|sticky (default: static)","elevatedOnScroll: boolean|{ threshold?: number }","navAlign: start|center (default: start)","container: full|page (default: full)","icons: object","style: object"],"sourcePath":"src/components/Header/index.tsx","exportName":"Header","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:58.820Z"},"performance":{"bundleSize":11366,"rawSize":36934,"complexity":"moderate","budgetPercent":74,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Sidebar","bytes":17553,"percent":48},{"path":"Header (self)","bytes":7135,"percent":19},{"path":"@phosphor-icons/react","bytes":5528,"percent":15},{"path":"src/recipes/popup.ts","bytes":2532,"percent":7},{"path":"ScrollArea","bytes":2512,"percent":7},{"path":"src/utils/a11y.tsx","bytes":779,"percent":2}]}},"Icon":{"filePath":"src/components/Icon/index.tsx","meta":{"name":"Icon","description":"Sizes and colours any icon so it lines up with the text beside it.","category":"display","tags":["icon","visual","symbol","graphic"],"status":"stable"},"usage":{"when":["A symbol sits beside text, inside a button, or leads a list item","State needs a glanceable marker"],"whenNot":["Artwork or illustration (use Image)","Multi-color or animated graphics"],"guidelines":["Reserve the success, warning, and danger tones for real state","Hold one size per context","Match weight to the text weight beside it","iconProps reaches options the wrapper does not expose"],"accessibility":["Icons ship aria-hidden — they are decoration until you label them","An icon-only button needs VisuallyHidden text","Color alone never carries the message"]},"props":{"style":{"type":"object","description":"","required":false},"icon":{"type":"union","description":"Icon component to render","required":true},"size":{"type":"enum","description":"Icon size","default":"md","required":false,"values":["xs","sm","md","lg","xl"]},"weight":{"type":"string","description":"Optional icon style/weight hint (forwarded when supported by the icon component)","default":"regular","required":false,"values":["thin","light","regular","bold","fill","duotone"]},"tone":{"type":"enum","description":"Semantic colour. Reserve success, warning and danger for real state; omit to inherit currentColor","required":false,"values":["accent","info","success","warning","danger"]},"color":{"type":"enum","description":"Text-hierarchy colour, the same axis as Text color. tone wins when both are set","required":false,"values":["primary","secondary","tertiary"]},"iconProps":{"type":"object","description":"Additional props forwarded to the underlying icon component (typed from the icon prop in TypeScript)","required":false}},"relations":[{"component":"Button","relationship":"child","note":"Use inside icon-only buttons with VisuallyHidden label"},{"component":"VisuallyHidden","relationship":"sibling","note":"Pair with VisuallyHidden for accessible icon-only elements"},{"component":"Badge","relationship":"child","note":"Can be used as badge icon prop"}],"variants":[{"name":"Default","description":"Inherits the size and color of its surroundings.","code":"<Icon icon={Heart} />"},{"name":"Sizes","description":"Steps tuned to the type scale, so icons never float off the baseline.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Star} size=\"xs\" />\n <Icon icon={Star} size=\"sm\" />\n <Icon icon={Star} size=\"md\" />\n <Icon icon={Star} size=\"lg\" />\n <Icon icon={Star} size=\"xl\" />\n</div>"},{"name":"Tones","description":"Tone states carry meaning — never use them for decoration.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Check} tone=\"success\" />\n <Icon icon={Warning} tone=\"warning\" />\n <Icon icon={Warning} tone=\"danger\" />\n <Icon icon={Info} tone=\"accent\" />\n</div>"},{"name":"Hierarchy","description":"The text colour ladder, for glyphs that sit beside secondary or tertiary copy.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Heart} color=\"primary\" />\n <Icon icon={Heart} color=\"secondary\" />\n <Icon icon={Heart} color=\"tertiary\" />\n</div>"},{"name":"Weights","description":"Match the stroke to the text weight next to it.","code":"<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n <Icon icon={Heart} weight=\"thin\" />\n <Icon icon={Heart} weight=\"light\" />\n <Icon icon={Heart} weight=\"regular\" />\n <Icon icon={Heart} weight=\"bold\" />\n <Icon icon={Heart} weight=\"fill\" />\n <Icon icon={Heart} weight=\"duotone\" />\n</div>"},{"name":"Advanced Icon Props","description":"iconProps passes anything the underlying icon package supports.","code":"<Icon icon={Heart} iconProps={{ mirrored: true }} />"}],"contract":{"propsSummary":["icon: React component - icon component (required)","size: xs|sm|md|lg|xl - icon size","weight: string - optional style/weight hint for icons that support it","tone: accent|info|success|warning|danger - semantic colour","color: primary|secondary|tertiary - text-hierarchy colour","iconProps: typed from the passed icon component - advanced icon-specific props"],"a11yRules":["A11Y_ICON_LABEL","A11Y_COLOR_CONTRAST"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["style: object","icon: union (required)","size: xs|sm|md|lg|xl (default: md)","weight: string (default: regular)","tone: accent|info|success|warning|danger","color: primary|secondary|tertiary","iconProps: object"],"sourcePath":"src/components/Icon/index.tsx","exportName":"Icon","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:58.998Z"},"performance":{"bundleSize":1797,"rawSize":3847,"complexity":"lightweight","budgetPercent":12,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"src/measurements/index.ts","bytes":2491,"percent":65},{"path":"Icon (self)","bytes":770,"percent":20}]}},"IconButton":{"filePath":"src/components/IconButton/index.tsx","meta":{"name":"IconButton","description":"Runs an action from an icon alone, for toolbars and table rows.","category":"actions","tags":["action","button","icon","toolbar","interactive"],"status":"stable"},"usage":{"when":["Toolbars and top bars where text buttons crowd","Row actions too narrow for a label","Toggle actions that show a pressed state"],"whenNot":["The action needs a visible label — use Button","It flips a persistent setting — use Switch","The icon is decorative — use Icon"],"guidelines":["aria-label or aria-labelledby is required, every time","ghost for ordinary toolbar actions; outline when it needs separation","pressed only for real toggle state, not selection","Keep icon meaning obvious, or pair it with a Tooltip"],"accessibility":["Name the action, not the icon: \"Delete row\", not \"Trash\"","Pressed state is exposed via aria-pressed","Hit target stays at least 24px even at size=\"sm\""]},"props":{"children":{"type":"node","description":"Icon element rendered inside the button","required":true},"variant":{"type":"enum","description":"Visual treatment for the icon-only action","default":"ghost","required":false,"values":["ghost","soft","outline"]},"size":{"type":"enum","description":"Control size aligned with adjacent fields and toolbar actions","default":"\"md\"","required":false,"values":["sm","md","lg"]},"pressed":{"type":"boolean","description":"Marks a toggle-style action as pressed and sets aria-pressed","required":false},"aria-label":{"type":"string","description":"Accessible action name when no labelled-by relationship is available","required":false},"aria-labelledby":{"type":"string","description":"ID reference for an external accessible action label","required":false},"type":{"type":"enum","description":"","default":"button","required":false,"values":["submit","reset","button"]}},"relations":[{"component":"Button","relationship":"sibling","note":"Use Button when the action should have a visible text label or broader layout variants"},{"component":"Icon","relationship":"complementary","note":"Icon supplies the visual glyph rendered inside IconButton"}],"variants":[{"name":"Toolbar action","description":"Icon carries the action; the label lives in aria-label.","code":"import { Plus as PlusIcon } from '@phosphor-icons/react';\n\n<IconButton aria-label=\"Add item\">\n <PlusIcon aria-hidden />\n</IconButton>"},{"name":"Variants","description":"Rising chrome: transparent, tinted, then bordered.","code":"import { Plus as PlusIcon } from '@phosphor-icons/react';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <IconButton aria-label=\"Add item\" variant=\"ghost\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"soft\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"outline\">\n <PlusIcon aria-hidden />\n </IconButton>\n</Stack>"},{"name":"Sizes","description":"sm for table rows, lg for primary chrome.","code":"import { Plus as PlusIcon } from '@phosphor-icons/react';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <IconButton aria-label=\"Add item\" variant=\"outline\" size=\"sm\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"outline\" size=\"md\">\n <PlusIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Add item\" variant=\"outline\" size=\"lg\">\n <PlusIcon aria-hidden />\n </IconButton>\n</Stack>"},{"name":"Pressed state","description":"Toggle that stays on, reported through aria-pressed.","code":"import { PushPin as PinIcon } from '@phosphor-icons/react';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\" align=\"center\">\n <IconButton aria-label=\"Pin item\" variant=\"outline\">\n <PinIcon aria-hidden />\n </IconButton>\n <IconButton aria-label=\"Unpin item\" variant=\"outline\" pressed>\n <PinIcon aria-hidden />\n </IconButton>\n</Stack>"},{"name":"Disabled","description":"Unavailable action, out of the tab order.","code":"import { Trash as TrashIcon } from '@phosphor-icons/react';\n\n<IconButton aria-label=\"Delete row\" variant=\"outline\" disabled>\n <TrashIcon aria-hidden />\n</IconButton>"}],"contract":{"propsSummary":["children: ReactNode - icon element (required)","variant: ghost|soft|outline - visual treatment","size: sm|md|lg - square control size","pressed: boolean - toggle state exposed with aria-pressed","aria-label or aria-labelledby - required accessible name"],"a11yRules":["A11Y_BTN_LABEL","A11Y_BTN_FOCUS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","variant: ghost|soft|outline (default: ghost)","size: sm|md|lg (default: md)","pressed: boolean","aria-label: string","aria-labelledby: string"],"sourcePath":"src/components/IconButton/index.tsx","exportName":"IconButton","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-07-14T00:00:00.000Z"},"performance":{"bundleSize":818,"rawSize":1552,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"IconButton (self)","bytes":678,"percent":44},{"path":"ComponentDefaults","bytes":193,"percent":12},{"path":"src/utils/env.ts","bytes":89,"percent":6}]}},"Image":{"filePath":"src/components/Image/index.tsx","meta":{"name":"Image","description":"Renders a picture at a fixed shape with a built-in fallback when loading fails.","category":"display","tags":["image","media","photo","picture","visual"],"status":"stable"},"usage":{"when":["Product shots, thumbnails, and hero art","Uploads you do not control and cannot trust to load"],"whenNot":["A person (use Avatar)","A symbol (use Icon)","Pure decoration behind content (use a CSS background)"],"guidelines":["Set aspectRatio so a grid holds its shape before the file arrives","objectFit=\"contain\" for logos, \"cover\" for photography","Always give fallback something to say","imgProps, onImageLoad, and onImageError expose the raw img when you need it"],"accessibility":["alt is required — describe what the picture shows","Decoration takes alt=\"\"","Words baked into an image must be repeated in alt"]},"props":{"src":{"type":"string","description":"Image source URL","required":true},"alt":{"type":"string","description":"Alt text for accessibility (required)","required":true},"aspectRatio":{"type":"enum","description":"Aspect ratio of the image container","default":"auto","required":false,"values":["1:1","4:3","16:9","21:9","auto"]},"objectFit":{"type":"enum","description":"How the image fits within its container","default":"cover","required":false,"values":["cover","contain","fill","none"]},"width":{"type":"union","description":"Width of the image container","required":false},"height":{"type":"union","description":"Height of the image container","required":false},"rounded":{"type":"enum","description":"Border radius","default":"none","required":false,"values":["none","sm","md","lg","full"]},"fallback":{"type":"node","description":"Content to show while loading or on error","required":false},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false},"imgProps":{"type":"object","description":"Additional props for the underlying img element (except src/alt/size/style/events)","required":false},"onImageLoad":{"type":"function","description":"Called when the underlying img element loads","required":false},"onImageError":{"type":"function","description":"Called when the underlying img element fails to load","required":false}},"relations":[{"component":"Card","relationship":"child","note":"Common pattern to use Image at top of product cards"},{"component":"Avatar","relationship":"alternative","note":"Use Avatar for user profile pictures"}],"variants":[{"name":"Default","description":"src plus alt — the shape follows the file.","code":"<Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=400&h=300&fit=crop\"\n alt=\"Code on a screen\"\n width={300}\n/>"},{"name":"Aspect Ratios","description":"Lock the frame so a grid stays even whatever the file is.","code":"<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=200&fit=crop\"\n alt=\"Square image\"\n aspectRatio=\"1:1\"\n width={100}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=200&h=150&fit=crop\"\n alt=\"4:3 image\"\n aspectRatio=\"4:3\"\n width={120}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=320&h=180&fit=crop\"\n alt=\"16:9 image\"\n aspectRatio=\"16:9\"\n width={160}\n />\n</div>"},{"name":"Rounded Corners","description":"Rounding softens the frame; match it to the surface it sits on.","code":"<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"No rounding\"\n rounded=\"none\"\n width={80}\n height={80}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"Medium rounding\"\n rounded=\"md\"\n width={80}\n height={80}\n />\n <Image\n src=\"https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=100&h=100&fit=crop\"\n alt=\"Full rounding\"\n rounded=\"full\"\n width={80}\n height={80}\n />\n</div>"},{"name":"With Fallback","description":"A dead URL shows this instead of a broken-image glyph.","code":"<Image\n src=\"https://invalid-url.example/image.jpg\"\n alt=\"Image that will fail\"\n width={200}\n height={150}\n rounded=\"md\"\n fallback={\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', background: 'var(--fui-color-surface-secondary)' }}>\n <span style={{ color: 'var(--fui-color-text-tertiary)' }}>No image</span>\n </div>\n }\n/>"}],"contract":{"propsSummary":["src: string - image URL (required)","alt: string - accessibility text (required)","aspectRatio: 1:1|4:3|16:9|21:9|auto - container ratio","objectFit: cover|contain|fill|none - image fitting","rounded: none|sm|md|lg|full - border radius","fallback: ReactNode - loading/error content","imgProps/onImageLoad/onImageError - low-level img customization and events"],"a11yRules":["A11Y_IMG_ALT","A11Y_IMG_DECORATIVE"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["src: string (required)","alt: string (required)","aspectRatio: 1:1|4:3|16:9|21:9|auto (default: auto)","objectFit: cover|contain|fill|none (default: cover)","width: union","height: union","rounded: none|sm|md|lg|full (default: none)","fallback: node","className: string","style: object","imgProps: object","onImageLoad: function","onImageError: function"],"sourcePath":"src/components/Image/index.tsx","exportName":"Image","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.379Z"},"performance":{"bundleSize":972,"rawSize":1781,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Image (self)","bytes":1194,"percent":67}]}},"Input":{"filePath":"src/components/Input/index.tsx","meta":{"name":"Input","description":"Collects a single line of user-entered text.","category":"inputs","tags":["form","input","text"],"status":"stable"},"usage":{"when":["Single-line answers: name, email, password, phone, URL","Search fields","Short free-form values a list cannot cover"],"whenNot":["Multi-line text (use Textarea)","Selecting from predefined options (use Select)","Boolean input (use Checkbox or Switch)","Date/time input (use DatePicker)"],"guidelines":["Give every field a label","Match type to the data — it drives validation and mobile keyboards","Placeholder shows format; it never replaces the label","Pair error with helperText so the reason is announced","Use the shortcut prop for kbd hints instead of custom markup","shortcut is display-only; shortcutBehavior=\"focus-input\" adds the global hotkey"],"accessibility":["Label is programmatically tied to the input","Error text is announced to screen readers","Required fields are marked"]},"props":{"value":{"type":"string","description":"Current input value (controlled)","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","required":false},"placeholder":{"type":"string","description":"Placeholder text shown when empty","required":false,"constraints":["Use for format hints only, not as a replacement for labels"]},"type":{"type":"enum","description":"HTML input type for validation and keyboard","default":"text","required":false,"values":["number","text","email","password","tel","url"]},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Whether the input is interactive","default":"false","required":false},"error":{"type":"boolean","description":"Whether to show error styling","default":"false","required":false},"label":{"type":"string","description":"Label text displayed above input","required":false},"required":{"type":"boolean","description":"Whether the field is required (shows asterisk)","default":"false","required":false},"helperText":{"type":"string","description":"Helper or error message below input","required":false},"startAdornment":{"type":"node","description":"Content rendered before the input (icon or prefix text)","required":false},"endAdornment":{"type":"node","description":"Content rendered after the input (icon or suffix text)","required":false},"shortcut":{"type":"string","description":"Keyboard shortcut hint displayed as a visual kbd token inside the input","required":false},"shortcutBehavior":{"type":"enum","description":"Whether shortcut hint is visual only or also registers a global focus hotkey","default":"display-only","required":false,"values":["display-only","focus-input"]},"onChange":{"type":"function","description":"Called with new value on change","required":false},"onValueChange":{"type":"function","description":"Value-first change callback alias: (value: string) => void","required":false},"onBlur":{"type":"function","description":"","required":false},"onFocus":{"type":"function","description":"","required":false},"onKeyDown":{"type":"function","description":"","required":false},"rootProps":{"type":"object","description":"HTML attributes applied to the wrapper element","required":false},"inputStyle":{"type":"object","description":"Inline styles applied directly to the input element","required":false},"inputClassName":{"type":"string","description":"Class name applied directly to the input element","required":false},"withFieldWrapper":{"type":"boolean","description":"Render built-in label/helper wrapper (set false for Field composition or bare input rendering)","default":"true","required":false},"className":{"type":"string","description":"Wrapper class name","required":false},"style":{"type":"object","description":"Wrapper styles","required":false}},"relations":[{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line text input"},{"component":"Select","relationship":"alternative","note":"Use Select when choosing from predefined options"},{"component":"Field","relationship":"parent","note":"Use Field for advanced form composition and custom controls"}],"variants":[{"name":"Default","description":"Label plus a placeholder that hints the format.","code":"<Input label=\"Name\" placeholder=\"Enter your name\" />"},{"name":"With Value","description":"Starts with a value already in the field.","code":"<Input label=\"Email\" type=\"email\" value=\"user@example.com\" />"},{"name":"With Helper","description":"Supporting text sits under the field.","code":"<Input\n label=\"Password\"\n type=\"password\"\n placeholder=\"Create a password\"\n helperText=\"Must be at least 8 characters\"\n/>"},{"name":"Error State","description":"Red border, and helperText becomes the reason.","code":"<Input\n label=\"Email\"\n type=\"email\"\n value=\"invalid-email\"\n error\n helperText=\"Please enter a valid email address\"\n/>"},{"name":"Disabled","description":"Dimmed, unfocusable, still shows its value.","code":"<Input label=\"Username\" value=\"ada.lovelace\" disabled />"},{"name":"Required","description":"Asterisk marks the field as mandatory.","code":"<Input\n label=\"Email\"\n type=\"email\"\n placeholder=\"user@example.com\"\n required\n/>"},{"name":"Sizes","description":"Three heights: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '300px' }}>\n <Input label=\"Small\" size=\"sm\" placeholder=\"Small input\" />\n <Input label=\"Medium\" size=\"md\" placeholder=\"Medium input\" />\n <Input label=\"Large\" size=\"lg\" placeholder=\"Large input\" />\n</div>"},{"name":"Bare Input (Field Composition)","description":"Drops the built-in label wrapper so Field owns the layout.","code":"<Input\n withFieldWrapper={false}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n rootProps={{ 'data-demo': 'bare-input-wrapper' }}\n/>"},{"name":"Search With Shortcut","description":"Leading icon and a ⌘K hint that focuses the field.","code":"<Input\n aria-label=\"Search findings\"\n placeholder=\"Search findings...\"\n shortcut=\"⌘K\"\n shortcutBehavior=\"focus-input\"\n startAdornment={<MagnifyingGlass aria-hidden=\"true\" />}\n withFieldWrapper={false}\n/>"},{"name":"With Start Adornment","description":"Prefix sits inside the field, before the text.","code":"<Input\n label=\"Price\"\n placeholder=\"0.00\"\n startAdornment={<span>$</span>}\n/>"},{"name":"With End Adornment","description":"Suffix sits inside the field, after the text.","code":"<Input\n label=\"Weight\"\n placeholder=\"0\"\n endAdornment={<span>kg</span>}\n/>"}],"contract":{"propsSummary":["type: text|email|password|number|tel|url (default: text)","value: string - controlled input value","label: string - accessible label text","placeholder: string - format hint only","disabled: boolean - disables interaction","required: boolean - required field indicator","error: boolean - shows error styling","startAdornment: ReactNode - content before the input (icon or prefix)","endAdornment: ReactNode - content after the input (icon or suffix)","shortcut: string - visual kbd hint inside the input; do not hand-roll extra kbd markup","helperText: string - helper/error message","onValueChange: (value: string) => void - value-first change callback alias","rootProps: HTMLAttributes<HTMLDivElement> - wrapper element props","withFieldWrapper: boolean - toggle built-in wrapper/label rendering (default: true)","shortcutBehavior: display-only|focus-input (default: display-only)","...native input attributes are supported (autoComplete, required, inputMode, pattern, etc.)"],"a11yRules":["A11Y_INPUT_LABEL","A11Y_INPUT_ERROR","A11Y_INPUT_REQUIRED"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["value: string","defaultValue: string","placeholder: string","type: number|text|email|password|tel|url (default: text)","size: sm|md|lg (default: md)","disabled: boolean (default: false)","error: boolean (default: false)","label: string","required: boolean (default: false)","helperText: string","startAdornment: node","endAdornment: node","shortcut: string","shortcutBehavior: display-only|focus-input (default: display-only)","onChange: function","onValueChange: function","onBlur: function","onFocus: function","onKeyDown: function","rootProps: object","inputStyle: object","inputClassName: string","withFieldWrapper: boolean (default: true)","className: string","style: object"],"sourcePath":"src/components/Input/index.tsx","exportName":"Input","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.208Z"},"performance":{"bundleSize":1695,"rawSize":3826,"complexity":"lightweight","budgetPercent":11,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Input (self)","bytes":2916,"percent":76},{"path":"ComponentDefaults","bytes":198,"percent":5},{"path":"src/utils/aria.ts","bytes":110,"percent":3}]}},"Link":{"filePath":"src/components/Link/index.tsx","meta":{"name":"Link","description":"Navigates somewhere else, inline or in chrome, with real link semantics.","category":"navigation","tags":["link","anchor","navigation","href","url"],"status":"stable"},"usage":{"when":["Inline links inside body text","Footer and sidebar navigation","\"Forgot password?\" and \"Sign up\" in forms","Pointing out to docs or external resources"],"whenNot":["A main call to action — use Button","Switching views in place — use Tabs","Dropdown items — use Menu"],"guidelines":["Name the destination; never \"click here\"","external sets target and rel — add your own \"opens in a new tab\" cue","tone=\"neutral\" for secondary links; add color=\"tertiary\" for metadata and footers","Links must stay distinguishable from surrounding text","asChild composes handlers with the child rather than replacing them"],"accessibility":["The link text alone should make sense out of context","Say when a link opens a new window","Focus ring must stay visible","A link that looks like a button still needs link semantics"]},"props":{"children":{"type":"node","description":"Link text content","required":true},"tone":{"type":"enum","description":"Colour. accent is the link ink; neutral reads as body text until hovered","default":"accent","required":false,"values":["accent","neutral"]},"color":{"type":"enum","description":"Text-hierarchy colour for a neutral link (Text color axis); tertiary is the quietest link","required":false,"values":["primary","secondary","tertiary"]},"underline":{"type":"enum","description":"Underline behavior","default":"hover","required":false,"values":["always","hover","none","dotted"]},"external":{"type":"boolean","description":"Opens in new tab with noopener noreferrer","default":"false","required":false},"asChild":{"type":"boolean","description":"Render as child element (polymorphic). Merges link props/classes and composes event handlers onto the single child (e.g. Next.js Link).","default":"false","required":false},"className":{"type":"string","description":"Additional class name","required":false},"style":{"type":"object","description":"Inline styles","required":false},"target":{"type":"union","description":"","required":false},"rel":{"type":"string","description":"","required":false}},"relations":[{"component":"Button","relationship":"alternative","note":"Use Button for primary actions, Link for navigation"},{"component":"Text","relationship":"parent","note":"Links often appear within Text components"}],"variants":[{"name":"Default","description":"Accent text that underlines on hover.","code":"<Link href=\"#\">Learn more about our services</Link>"},{"name":"Tones","description":"Accent, then neutral, then the quietest neutral.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\" align=\"center\" wrap>\n <Link href=\"#\" tone=\"accent\">Accent</Link>\n <Link href=\"#\" tone=\"neutral\">Neutral</Link>\n <Link href=\"#\" tone=\"neutral\" color=\"tertiary\">Tertiary</Link>\n</Stack>"},{"name":"Underline Styles","description":"Four rules for when the line shows.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\" align=\"center\" wrap>\n <Link href=\"#\" underline=\"always\">Always underlined</Link>\n <Link href=\"#\" underline=\"hover\">Underline on hover</Link>\n <Link href=\"#\" underline=\"dotted\">Dotted underline</Link>\n <Link href=\"#\" underline=\"none\">No underline</Link>\n</Stack>"},{"name":"External Link","description":"Sets target and rel; you still supply the visible cue.","code":"<Link href=\"https://example.com\" external>\n View documentation ↗\n</Link>"},{"name":"As Child (Polymorphic)","description":"Paints Link styling onto a router link and keeps both click handlers.","code":"<Link asChild tone=\"neutral\" onClick={() => {}}>\n <a href=\"#pricing\" onClick={() => {}}>\n Client-side navigation\n </a>\n</Link>"}],"contract":{"propsSummary":["children: ReactNode - link text (required)","href: string - destination URL","tone: accent|neutral - colour","color: primary|secondary|tertiary - hierarchy colour on a neutral link","underline: always|hover|none|dotted - underline behavior","external: boolean - opens in new tab","asChild: boolean - polymorphic child rendering with merged styles and composed event handlers"],"a11yRules":["A11Y_LINK_TEXT","A11Y_LINK_FOCUS"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","tone: accent|neutral (default: accent)","color: primary|secondary|tertiary","underline: always|hover|none|dotted (default: hover)","external: boolean (default: false)","asChild: boolean (default: false)","className: string","style: object","target: union","rel: string"],"sourcePath":"src/components/Link/index.tsx","exportName":"Link","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.546Z"},"performance":{"bundleSize":892,"rawSize":1618,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Link (self)","bytes":1045,"percent":65}]}},"List":{"filePath":"src/components/List/index.tsx","meta":{"name":"List","description":"Stacks items down the page with evenly spaced bullets, numbers, or icons.","category":"display","tags":["list","items","bullet","ordered","unordered"],"status":"stable"},"usage":{"when":["Steps, instructions, or anything with an order","Feature and benefit lists","Plain stacks of links in a sidebar"],"whenNot":["Items are pickable (use Menu or Select)","Items have columns (use Table)","Items need their own surface (use Card in a Grid)"],"guidelines":["Order matters? Use as=\"ol\" so the numbers are real","Keep one icon meaning per list — mixing icons reads as noise","Write items in parallel grammar; scanning depends on it","Stop nesting at two levels"],"accessibility":["Real ul/ol markup means screen readers announce the item count","Icons are decorative — the text has to carry the meaning"]},"props":{"children":{"type":"node","description":"List.Item components","required":true},"as":{"type":"enum","description":"List type","default":"ul","required":false,"values":["ul","ol"]},"marker":{"type":"enum","description":"Marker drawn before each item","default":"disc","required":false,"values":["none","disc","decimal","icon"]},"gap":{"type":"enum","description":"Spacing between items","default":"sm","required":false,"values":["none","xs","sm","md","lg","xl"]},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Icon","relationship":"child","note":"Use Icon as List.Item icon prop"},{"component":"Stack","relationship":"alternative","note":"Use Stack for non-semantic vertical lists"}],"variants":[{"name":"Bullet List","description":"The default marker — reach for it when order does not matter.","code":"<List marker=\"disc\">\n <List.Item>First item</List.Item>\n <List.Item>Second item</List.Item>\n <List.Item>Third item</List.Item>\n</List>"},{"name":"Numbered List","description":"as=\"ol\" makes the sequence real, not just visual.","code":"<List as=\"ol\" marker=\"decimal\">\n <List.Item>Create your account</List.Item>\n <List.Item>Configure your settings</List.Item>\n <List.Item>Start building</List.Item>\n</List>"},{"name":"Icon List","description":"Each item takes its own icon — checkmarks sell a feature list.","code":"<List marker=\"icon\">\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Unlimited projects\n </List.Item>\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Priority support\n </List.Item>\n <List.Item icon={<Check weight=\"bold\" color=\"var(--fui-color-success)\" />}>\n Advanced analytics\n </List.Item>\n</List>"},{"name":"No Style","description":"No markers, wider gap — the shape for stacked nav links.","code":"<List marker=\"none\" gap=\"md\">\n <List.Item>Dashboard</List.Item>\n <List.Item>Settings</List.Item>\n <List.Item>Profile</List.Item>\n</List>"}],"contract":{"propsSummary":["children: List.Item[] - list items (required)","as: ul|ol - list type","marker: none|disc|decimal|icon - marker before each item","gap: none|xs|sm|md|lg|xl - item spacing"],"a11yRules":["A11Y_LIST_SEMANTIC","A11Y_LIST_NESTING"]},"ai":{"compositionPattern":"compound","subComponents":["Item"],"commonPatterns":["<List>\n <List.Item>...</List.Item>\n</List>"],"requiredChildren":["Item"]},"propsSummary":["children: node (required)","as: ul|ol (default: ul)","marker: none|disc|decimal|icon (default: disc)","gap: none|xs|sm|md|lg|xl (default: sm)","style: object"],"sourcePath":"src/components/List/index.tsx","exportName":"List","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:18:59.915Z"},"performance":{"bundleSize":749,"rawSize":1458,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"List (self)","bytes":824,"percent":57}]}},"Listbox":{"filePath":"src/components/Listbox/index.tsx","meta":{"name":"Listbox","description":"Shows a keyboard-navigable list of options with no trigger of its own.","category":"inputs","tags":["listbox","search","autocomplete","combobox","command","dropdown"],"status":"stable"},"usage":{"when":["Results under a search field","Autocomplete suggestions","Command palette results","Any list the user drives with arrow keys"],"whenNot":["A list nobody selects from (use List)","Actions behind a button (use Menu)","A form field (use Select)","Navigation (use Sidebar or Tabs)"],"guidelines":["You own open state — drive it from the input's focus and query","Arrows, Home, End, Enter, and Space are handled for you","Always supply Listbox.Empty","Group once the list draws from more than one source"],"accessibility":["Uses listbox and option ARIA roles","aria-selected indicates current selection","aria-disabled for non-interactive items","Connect to input with aria-controls for full combobox pattern"]},"props":{"children":{"type":"node","description":"Listbox.Item, Listbox.Group, or Listbox.Empty components","required":true},"style":{"type":"object","description":"","required":false},"tabIndex":{"type":"number","description":"","required":false},"onFocus":{"type":"function","description":"","required":false},"onKeyDown":{"type":"function","description":"","required":false}},"relations":[{"component":"Input","relationship":"sibling","note":"Pair with Input for search/autocomplete patterns"},{"component":"Menu","relationship":"alternative","note":"Use Menu when you need a trigger button"},{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"List","relationship":"alternative","note":"Use List for static, non-interactive lists"}],"variants":[{"name":"Default","description":"Plain options, one selectable at a time.","code":"<Listbox aria-label=\"Options\">\n <Listbox.Item selected>First option</Listbox.Item>\n <Listbox.Item>Second option</Listbox.Item>\n <Listbox.Item>Third option</Listbox.Item>\n</Listbox>"},{"name":"Search Results","description":"Trailing metadata explains each match.","code":"<Listbox aria-label=\"Search results\">\n <Listbox.Item selected>\n <span style={{ fontWeight: 500 }}>Button</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Components</span>\n </Listbox.Item>\n <Listbox.Item>\n <span style={{ fontWeight: 500 }}>Badge</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Components</span>\n </Listbox.Item>\n <Listbox.Item>\n <span style={{ fontWeight: 500 }}>Box</span>\n <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--fui-text-tertiary)' }}>Layout</span>\n </Listbox.Item>\n</Listbox>"},{"name":"With Groups","description":"Labels split the list by source.","code":"<Listbox aria-label=\"Commands\">\n <Listbox.Group label=\"Recent\">\n <Listbox.Item selected>Open file...</Listbox.Item>\n <Listbox.Item>Save as...</Listbox.Item>\n </Listbox.Group>\n <Listbox.Group label=\"Actions\">\n <Listbox.Item>Copy</Listbox.Item>\n <Listbox.Item>Paste</Listbox.Item>\n <Listbox.Item disabled>Cut</Listbox.Item>\n </Listbox.Group>\n</Listbox>"},{"name":"Empty State","description":"Says so when nothing matches.","code":"<Listbox aria-label=\"Search results\">\n <Listbox.Empty>No results found</Listbox.Empty>\n</Listbox>"},{"name":"With Disabled Items","description":"Unavailable rows stay visible but inert.","code":"<Listbox aria-label=\"Options\">\n <Listbox.Item>Available option</Listbox.Item>\n <Listbox.Item disabled>Disabled option</Listbox.Item>\n <Listbox.Item>Another option</Listbox.Item>\n</Listbox>"}],"contract":{"propsSummary":["children: ReactNode - Listbox.Item components (required)","aria-label: string - accessible label","Listbox.Item selected: boolean - highlight state","Listbox.Item disabled: boolean - non-interactive"],"a11yRules":["A11Y_LISTBOX_ROLE","A11Y_OPTION_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Group","Empty"],"requiredChildren":["Item"],"commonPatterns":["<Listbox aria-label=\"Search results\">{results.map(item => <Listbox.Item key={item.id} selected={item.id === selectedId} onClick={() => onSelect(item)}>{item.label}</Listbox.Item>)}</Listbox>"]},"propsSummary":["children: node (required)","style: object","tabIndex: number","onFocus: function","onKeyDown: function"],"sourcePath":"src/components/Listbox/index.tsx","exportName":"Listbox","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.924Z"},"performance":{"bundleSize":1661,"rawSize":3896,"complexity":"lightweight","budgetPercent":11,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Listbox (self)","bytes":3237,"percent":83}]}},"Loading":{"filePath":"src/components/Loading/index.tsx","meta":{"name":"Loading","description":"Signals that something is happening when you cannot say how long it will take.","category":"feedback","tags":["loading","spinner","progress","feedback","indicator","async"],"status":"stable"},"usage":{"when":["Fetching or processing content","Waiting on an async action to come back","Buttons, forms, and page sections mid-request","The first paint of an app or page"],"whenNot":["You know the percentage — use Progress","You know the page shape — use Skeleton","AI reasoning states — use ThinkingIndicator"],"guidelines":["spinner for general waits","dots for chat and messaging","pulse for quiet ambient waiting","Always pass a label describing what is loading","Loading.Screen for first page load, Loading.Inline to sit inside a sentence"],"accessibility":["Announced through role=\"status\" with aria-live=\"polite\"","label is what a screen reader reads — make it specific","Animation stops for prefers-reduced-motion"]},"props":{"size":{"type":"enum","description":"Size of the loading indicator","default":"md","required":false,"values":["sm","md","lg","xl"]},"kind":{"type":"enum","description":"Which animation plays","default":"spinner","required":false,"values":["spinner","dots","pulse"]},"label":{"type":"string","description":"Accessible label for screen readers","default":"Loading...","required":false},"centered":{"type":"boolean","description":"Whether to center the loading indicator in its container","default":"false","required":false},"fill":{"type":"boolean","description":"Whether to fill the parent container","default":"false","required":false},"overlay":{"type":"boolean","description":"Whether to show with a backdrop overlay","default":"false","required":false},"color":{"type":"enum","description":"Colour. accent uses the theme accent, current inherits the surrounding text colour","default":"accent","required":false,"values":["accent","current","muted"]}},"relations":[],"variants":[{"name":"Default","description":"Spinner at medium size, accent coloured.","code":"<Loading label=\"Loading content\" />"},{"name":"Sizes","description":"sm inside controls, xl for a whole page.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"lg\" align=\"center\">\n <Loading size=\"sm\" label=\"Loading\" />\n <Loading size=\"md\" label=\"Loading\" />\n <Loading size=\"lg\" label=\"Loading\" />\n <Loading size=\"xl\" label=\"Loading\" />\n</Stack>"},{"name":"Dots","description":"Three bouncing dots, at home in a message thread.","code":"<Loading kind=\"dots\" label=\"Sending message\" />"},{"name":"Pulse","description":"One breathing dot for ambient background work.","code":"<Loading kind=\"pulse\" label=\"Syncing\" />"},{"name":"Colors","description":"Accent, muted, or whatever the surrounding text is.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"lg\" align=\"center\">\n <Loading color=\"accent\" label=\"Loading\" />\n <Loading color=\"muted\" label=\"Loading\" />\n <span style={{ color: 'var(--fui-color-info)' }}>\n <Loading color=\"current\" label=\"Loading\" />\n </span>\n</Stack>"},{"name":"Inline","description":"Sits on the text baseline mid-sentence.","code":"<p style={{ margin: 0 }}>\n Processing your request <Loading.Inline label=\"Processing\" /> please wait…\n</p>"},{"name":"Centered","description":"Fills its container and centres in it.","code":"<div\n style={{\n width: '200px',\n height: '100px',\n border: '1px dashed var(--fui-border)',\n borderRadius: 'var(--fui-radius-md)',\n }}\n>\n <Loading centered fill label=\"Loading section\" />\n</div>"},{"name":"Screen","description":"Covers the surface it sits on and names the wait.","code":"<div\n style={{\n position: 'relative',\n contain: 'layout',\n width: '300px',\n height: '200px',\n border: '1px solid var(--fui-border)',\n borderRadius: 'var(--fui-radius-md)',\n overflow: 'hidden',\n }}\n>\n <Loading.Screen size=\"lg\" label=\"Loading application…\" showLabel />\n</div>"}],"contract":{"propsSummary":["size: sm|md|lg|xl (default: md)","kind: spinner|dots|pulse (default: spinner)","label: string (default: Loading...)","centered: boolean (default: false)","fill: boolean (default: false)","overlay: boolean (default: false)","color: accent|current|muted (default: accent)"]},"ai":{"compositionPattern":"compound","subComponents":["Inline","Screen"]},"propsSummary":["size: sm|md|lg|xl (default: md)","kind: spinner|dots|pulse (default: spinner)","label: string (default: Loading...)","centered: boolean (default: false)","fill: boolean (default: false)","overlay: boolean (default: false)","color: accent|current|muted (default: accent)"],"sourcePath":"src/components/Loading/index.tsx","exportName":"Loading","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.576Z"},"performance":{"bundleSize":1129,"rawSize":2670,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Loading (self)","bytes":2026,"percent":76}]}},"Main":{"filePath":"src/components/Main/index.tsx","meta":{"name":"Main","description":"Owns a page's gutters, reading measure, and vertical rhythm.","category":"layout","tags":["main","page","layout","compound"],"status":"stable"},"usage":{"when":["Laying out a page's header, description, content, and footer","Giving a page one consistent gutter and measure"],"whenNot":["Shell-level navigation chrome (use AppShell)","Arbitrary spacing inside a component (use Stack or Box)"],"guidelines":["One Main per page owns the gutters — do not nest them","measure=\"narrow\" caps content for reading; \"full\" uses the whole canvas","Compose regions with Main.Header, Main.Description, Main.Content, Main.Footer","Main.Description caps itself at 68ch regardless of measure"],"accessibility":["Use the default main element unless an existing shell already owns the main landmark"]},"props":{"children":{"type":"node","description":"Page regions composed from Main.Header, Main.Description, Main.Content, and Main.Footer","required":true},"measure":{"type":"enum","description":"Maximum width applied to the page composition","default":"full","required":false,"values":["full","narrow"]},"as":{"type":"enum","description":"Semantic HTML element rendered by the root","default":"main","required":false,"values":["div","section","nav","article","aside","header","footer","main","ul","ol"]}},"relations":[],"variants":[{"name":"Full Measure","description":"Content fills the canvas, inset only by the page gutter.","code":"import { Box } from '@/components/Box';\nimport { Main } from '@/components/Main';\n\n<Box width=\"100%\" border rounded=\"md\">\n <Main measure=\"full\">\n <Main.Header>Findings</Main.Header>\n <Main.Description>\n Every governance finding raised against this repository, newest first.\n </Main.Description>\n <Main.Content>\n Content stretches edge to edge, inset only by the page gutter.\n </Main.Content>\n <Main.Footer>Export report</Main.Footer>\n </Main>\n</Box>"},{"name":"Narrow Measure","description":"Caps content at the reading measure and centres it on wide screens.","code":"import { Box } from '@/components/Box';\nimport { Main } from '@/components/Main';\n\n<Box width=\"100%\" border rounded=\"md\">\n <Main measure=\"narrow\">\n <Main.Header>Settings</Main.Header>\n <Main.Description>\n Manage the workspace contract, canonical components, and token files.\n </Main.Description>\n <Main.Content>\n Content is capped at the reading measure and centred, so long prose stays\n comfortable to read on wide displays.\n </Main.Content>\n <Main.Footer>Save changes</Main.Footer>\n </Main>\n</Box>"}],"contract":{"propsSummary":["children: node (required)","measure: full|narrow (default: full)","as: semantic element (default: main)"]},"ai":{"compositionPattern":"compound","subComponents":["Header","Description","Content","Footer"],"commonPatterns":["<Main>\n <Main.Header>...</Main.Header>\n <Main.Description>...</Main.Description>\n <Main.Content>...</Main.Content>\n <Main.Footer>...</Main.Footer>\n</Main>"],"requiredChildren":["Header","Description","Content","Footer"]},"propsSummary":["children: node (required)","measure: full|narrow (default: full)","as: semantic element (default: main)"],"sourcePath":"src/components/Main/index.tsx","exportName":"Main","provenance":{"source":"manual","verified":true,"frameworkSupport":"native"},"performance":{"bundleSize":2508,"rawSize":6182,"complexity":"lightweight","budgetPercent":16,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Stack","bytes":4469,"percent":72},{"path":"Main (self)","bytes":1139,"percent":18}]}},"Markdown":{"filePath":"src/components/Markdown/index.tsx","meta":{"name":"Markdown","description":"Turns a Markdown string into styled headings, lists, tables, code, and quotes.","category":"display","tags":["markdown","prose","content","text","ai","chat"],"status":"stable","dependencies":[{"name":"react-markdown","version":">=9.0.0","reason":"Optional — parses markdown; without it content renders as plain paragraphs."},{"name":"remark-gfm","version":">=4.0.0","reason":"Optional — adds GitHub-flavored markdown (tables, strikethrough, task lists)."}]},"usage":{"when":["Rendering an LLM reply","Showing text a user wrote in Markdown","Docs or readme content inside the app"],"whenNot":["The string has no formatting (use Text)","The user needs to edit it (use an editor)"],"guidelines":["react-markdown and remark-gfm are peer dependencies — install both","The parser loads on demand, so the first frame is plain text; call Markdown.preload() at startup to skip it","Without react-markdown installed it degrades to plain paragraphs","components overrides how any element renders","react-markdown sanitises the content for you"],"accessibility":["Output is real headings, lists, and tables","Links render as anchors, images keep their alt text"]},"props":{"content":{"type":"string","description":"Markdown string to render","required":true},"components":{"type":"object","description":"Override map for markdown element components (e.g., { h1: MyHeading }). Accepts custom renderer component signatures used by react-markdown","required":false},"className":{"type":"string","description":"Additional CSS class name","required":false}},"relations":[{"component":"Text","relationship":"alternative","note":"Use Text for plain, non-markdown text"},{"component":"CodeBlock","relationship":"complementary","note":"CodeBlock can be used via components prop for syntax highlighting"},{"component":"Message","relationship":"parent","note":"Message wraps Markdown when markdown prop is true"}],"variants":[{"name":"Default","description":"Headings, emphasis, lists, and quotes all pick up the type scale.","code":"<Markdown content={`# Hello World\n\nThis is a paragraph with **bold text** and *italic text*.\n\nHere is some \\`inline code\\` within a sentence.\n\n- First item\n- Second item\n- Third item\n\n> A blockquote for emphasis.\n`} />"},{"name":"GFM Table","description":"remark-gfm adds tables and checkbox items on top of the basics.","code":"<Markdown content={`## Data Overview\n\n| Feature | Status | Priority |\n|------------|-----------|----------|\n| Markdown | Done | High |\n| Tables | Done | Medium |\n| Task Lists | Planned | Low |\n\nNotes:\n- [x] Support GFM tables\n- [x] Support task lists\n- [ ] Syntax highlighting\n`} />"},{"name":"Code Block","description":"Fenced blocks get the same code surface as CodeBlock.","code":"<Markdown content={`## Code Example\n\nHere is a JavaScript function:\n\n```js\nfunction greet(name) {\n return 'Hello, ' + name;\n}\n```\n\nAnd some inline code: \\`const x = 42;\\``} />"},{"name":"Mixed Content","description":"A realistic document — the worst case worth checking.","code":"<Markdown content={`# Project Update\n\n## Summary\n\nThe project is progressing well. Here are the **key highlights**:\n\n1. Completed the *design system* components\n2. Added markdown rendering support\n3. Integrated with the documentation site\n\n### Performance Metrics\n\n| Metric | Before | After |\n|-------------|--------|-------|\n| Bundle Size | 142kb | 98kb |\n| Load Time | 1.2s | 0.8s |\n| Lighthouse | 72 | 95 |\n\n> These improvements were achieved through tree-shaking and code splitting.\n\n### Next Steps\n\n- [ ] Add syntax highlighting\n- [ ] Support custom themes\n- [x] GFM table support\n`} />"}],"contract":{"propsSummary":["content: string - Markdown string to render","components: object - Override map for element components (react-markdown renderer components)","className: string - Additional CSS class","Forwards standard HTML div attributes to the wrapper element"],"a11yRules":["A11Y_SEMANTIC_HTML"]},"ai":{"compositionPattern":"compound","subComponents":["Root","preload"]},"propsSummary":["content: string (required)","components: object","className: string"],"sourcePath":"src/components/Markdown/index.tsx","exportName":"Markdown","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.091Z"},"performance":{"bundleSize":50235,"rawSize":162771,"complexity":"heavy","budgetPercent":327,"overBudget":true,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"react-markdown","bytes":120667,"percent":74},{"path":"remark-gfm","bytes":40158,"percent":25},{"path":"Markdown (self)","bytes":1101,"percent":1},{"path":"src/utils/env.ts","bytes":93,"percent":0}]}},"Menu":{"filePath":"src/components/Menu/index.tsx","meta":{"name":"Menu","description":"Drops a list of actions below a trigger, driveable entirely by keyboard.","category":"overlays","tags":["menu","dropdown","actions","context-menu","commands","submenu"],"status":"stable"},"usage":{"when":["Actions that do not fit in the toolbar","Right-click context actions","Account and profile actions","Related actions that read better grouped"],"whenNot":["Picking a value for a form (use Select)","Moving between pages or views (use Tabs or NavigationMenu)","One of a few visible choices (use RadioGroup)"],"guidelines":["Group related actions and separate the rest","Show the keyboard shortcut where one exists","Mark destructive actions with the danger variant","Past a dozen rows, reach for Command instead","Nest at most one level of submenu","asChild on Trigger needs a single element child"],"accessibility":["Full keyboard navigation with arrow keys","Type-ahead search for items","Focus returns to trigger on close","Proper ARIA menu roles","ArrowRight opens submenus, ArrowLeft closes them"]},"props":{"children":{"type":"node","description":"Menu trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"modal":{"type":"boolean","description":"Whether menu is modal","default":"true","required":false}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for form field selection"},{"component":"Popover","relationship":"alternative","note":"Use Popover for rich non-action content"}],"variants":[{"name":"Default","description":"Plain actions, one per row.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"soft\">Actions</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>Edit</Menu.Item>\n <Menu.Item onSelect={() => {}}>Duplicate</Menu.Item>\n <Menu.Separator />\n <Menu.Item danger onSelect={() => {}}>Delete</Menu.Item>\n </Menu.Content>\n</Menu>"},{"name":"With Shortcuts","description":"Trailing keys teach the faster path.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"soft\">Edit</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item shortcut=\"Ctrl+Z\" onSelect={() => {}}>Undo</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+Y\" onSelect={() => {}}>Redo</Menu.Item>\n <Menu.Separator />\n <Menu.Item shortcut=\"Ctrl+C\" onSelect={() => {}}>Copy</Menu.Item>\n <Menu.Item shortcut=\"Ctrl+V\" onSelect={() => {}}>Paste</Menu.Item>\n </Menu.Content>\n</Menu>"},{"name":"With Groups","description":"Labels separate unrelated actions.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"soft\">Options</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Group>\n <Menu.GroupLabel>View</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Zoom In</Menu.Item>\n <Menu.Item onSelect={() => {}}>Zoom Out</Menu.Item>\n </Menu.Group>\n <Menu.Separator />\n <Menu.Group>\n <Menu.GroupLabel>Layout</Menu.GroupLabel>\n <Menu.Item onSelect={() => {}}>Grid View</Menu.Item>\n <Menu.Item onSelect={() => {}}>List View</Menu.Item>\n </Menu.Group>\n </Menu.Content>\n</Menu>"},{"name":"With Checkboxes","description":"Rows that stay open while you toggle them.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"soft\">Display</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.CheckboxItem defaultChecked>Show Grid</Menu.CheckboxItem>\n <Menu.CheckboxItem defaultChecked>Show Rulers</Menu.CheckboxItem>\n <Menu.CheckboxItem>Show Guides</Menu.CheckboxItem>\n </Menu.Content>\n</Menu>"},{"name":"With Checked Items","description":"Ticks mark which filters are on.","code":"<CheckedItemsMenuDemo />"},{"name":"With Submenu","description":"Secondary options nest one level deep.","code":"<Menu>\n <Menu.Trigger asChild>\n <Button variant=\"soft\">File</Button>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>New File</Menu.Item>\n <Menu.Item onSelect={() => {}}>Open</Menu.Item>\n <Menu.Separator />\n <Menu.Submenu>\n <Menu.SubmenuTrigger>Export As</Menu.SubmenuTrigger>\n <Menu.Content side=\"right\" align=\"start\">\n <Menu.Item onSelect={() => {}}>PNG</Menu.Item>\n <Menu.Item onSelect={() => {}}>SVG</Menu.Item>\n <Menu.Item onSelect={() => {}}>PDF</Menu.Item>\n </Menu.Content>\n </Menu.Submenu>\n <Menu.Separator />\n <Menu.Item danger onSelect={() => {}}>Delete</Menu.Item>\n </Menu.Content>\n</Menu>"},{"name":"Link Trigger","description":"asChild lets a link open it.","code":"<Menu>\n <Menu.Trigger asChild>\n <a href=\"#menu-actions\">Open menu</a>\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onSelect={() => {}}>Inspect</Menu.Item>\n <Menu.Item onSelect={() => {}}>Rename</Menu.Item>\n </Menu.Content>\n</Menu>"}],"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - state handler","Menu.Trigger asChild supports non-button trigger elements","Menu.Item onSelect: (event) => void - selection callback receives click event","Menu.Item danger: boolean - destructive styling","Menu.Item shortcut: string - keyboard shortcut text","Menu.Item checked: boolean - check indicator for selection state"],"a11yRules":["A11Y_MENU_KEYBOARD","A11Y_MENU_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Item","CheckboxItem","RadioGroup","RadioItem","Group","GroupLabel","Separator","Submenu","SubmenuTrigger"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Menu><Menu.Trigger asChild><Button>Actions</Button></Menu.Trigger><Menu.Content><Menu.Item>{action1}</Menu.Item><Menu.Separator /><Menu.Item danger>{delete}</Menu.Item></Menu.Content></Menu>"]},"propsSummary":["children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","modal: boolean (default: true)"],"sourcePath":"src/components/Menu/index.tsx","exportName":"Menu","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:00.159Z"},"performance":{"bundleSize":2660,"rawSize":7277,"complexity":"lightweight","budgetPercent":17,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Menu (self)","bytes":3945,"percent":54},{"path":"src/recipes/popup.ts","bytes":2527,"percent":35}]}},"Message":{"filePath":"src/components/Message/index.tsx","meta":{"name":"Message","description":"Shows one chat message, styled by who sent it.","category":"ai","tags":["message","chat","ai","conversation","bubble"],"status":"stable"},"usage":{"when":["Individual turns in a chat transcript","AI assistant and chatbot interfaces","User and assistant turns that must read differently","Turns carrying copy, regenerate, or feedback actions"],"whenNot":["Plain text with no chat context (use Text)","Notifications (use Alert or Toast)","Threads with nested replies (use Card with a custom layout)"],"guidelines":["Always set role — it drives alignment, avatar, and chrome","status covers pending, streaming, and error","Hide avatars with avatar={null}, or showAvatars={false} on ConversationList","User bubbles cap at 80% of the inline measure so the two sides stay distinct","Chrome stays on neutral surfaces; reserve accent for actions and semantic state","Add timestamps once a conversation runs long","Give assistant turns hover actions such as copy and regenerate"],"accessibility":["Uses semantic HTML for message structure","Role-based styling has sufficient color contrast","Actions are keyboard accessible","Streaming indicator respects reduced motion preferences"]},"props":{"role":{"type":"enum","description":"Message role determines styling and alignment","required":true,"values":["user","assistant","system"]},"children":{"type":"node","description":"Message content","required":true},"status":{"type":"enum","description":"Message state","default":"complete","required":false,"values":["pending","streaming","complete","error"]},"timestamp":{"type":"object","description":"When the message was sent","required":false},"avatar":{"type":"node","description":"Custom avatar override (null to hide)","required":false},"actions":{"type":"node","description":"Hover actions (copy, regenerate)","required":false}},"relations":[{"component":"ConversationList","relationship":"parent","note":"Messages are typically used within ConversationList"},{"component":"Avatar","relationship":"child","note":"Use Avatar component for custom avatar content"},{"component":"ThinkingIndicator","relationship":"sibling","note":"Show ThinkingIndicator while awaiting assistant response"}],"variants":[{"name":"User Message","description":"Right-aligned and capped at 80% of the available width.","code":"<Message role=\"user\">\n <Message.Content>\n Hello! Can you help me with a coding question?\n </Message.Content>\n</Message>"},{"name":"Assistant Message","description":"Left-aligned with an avatar and a wider measure.","code":"<Message role=\"assistant\">\n <Message.Content>\n Of course! I'd be happy to help. What would you like to know?\n </Message.Content>\n</Message>"},{"name":"System Message","description":"Centred and quiet, for context rather than conversation.","code":"<Message role=\"system\">\n <Message.Content>\n Conversation started. Model: GPT-4\n </Message.Content>\n</Message>"},{"name":"Streaming","description":"A blinking caret trails the text as it arrives.","code":"<Message role=\"assistant\" status=\"streaming\">\n <Message.Content>\n I'm currently generating a response for you\n </Message.Content>\n</Message>"},{"name":"With Timestamp","description":"A relative send time sits beneath the bubble.","code":"<Message role=\"assistant\" timestamp={new Date(Date.now() - 300000)}>\n <Message.Content>\n This message was sent 5 minutes ago.\n </Message.Content>\n <Message.Timestamp />\n</Message>"},{"name":"Error State","description":"A failed send turns the bubble and its border red.","code":"<Message role=\"user\" status=\"error\">\n <Message.Content>\n This message failed to send.\n </Message.Content>\n</Message>"},{"name":"Custom Avatars","description":"Photos replace the default glyphs on both sides.","code":"<>\n <Message\n role=\"user\"\n avatar={<Message.Avatar src=\"https://i.pravatar.cc/64?u=user\" alt=\"Jane\" />}\n >\n <Message.Content>\n Can you help me understand this error?\n </Message.Content>\n </Message>\n <Message\n role=\"assistant\"\n avatar={<Message.Avatar src=\"https://i.pravatar.cc/64?u=bot\" alt=\"AI Assistant\" />}\n >\n <Message.Content>\n Sure! Let me take a look at that for you.\n </Message.Content>\n </Message>\n</>"},{"name":"With Actions","description":"Controls stay hidden until the pointer enters the row.","code":"<Message\n role=\"assistant\"\n actions={\n <>\n <Button variant=\"ghost\" size=\"sm\">\n Copy\n </Button>\n <Button variant=\"ghost\" size=\"sm\">\n Regenerate\n </Button>\n </>\n }\n>\n <Message.Content>\n Hover over this message to see the actions.\n </Message.Content>\n</Message>"}],"contract":{"propsSummary":["role: \"user\" | \"assistant\" | \"system\" - determines styling","children: ReactNode - message content","status: \"pending\" | \"streaming\" | \"complete\" | \"error\" - message state","timestamp: Date - when message was sent","avatar: ReactNode - custom avatar (null to hide)","actions: ReactNode - hover actions","Avatar.src: string - image URL for avatar","Avatar.alt: string - alt text for image avatar"],"a11yRules":["A11Y_COLOR_CONTRAST","A11Y_MOTION_PREFERENCE"]},"ai":{"compositionPattern":"compound","subComponents":["Content","Actions","Timestamp","Avatar"],"commonPatterns":["<Message>\n <Message.Content>...</Message.Content>\n</Message>"],"requiredChildren":["Content"]},"propsSummary":["role: user|assistant|system (required)","children: node (required)","status: pending|streaming|complete|error (default: complete)","timestamp: object","avatar: node","actions: node"],"sourcePath":"src/components/Message/index.tsx","exportName":"Message","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:00.333Z"},"performance":{"bundleSize":54088,"rawSize":174091,"complexity":"heavy","budgetPercent":352,"overBudget":true,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Markdown","bytes":162039,"percent":93},{"path":"ConversationList","bytes":4734,"percent":3},{"path":"Avatar","bytes":3348,"percent":2},{"path":"Message (self)","bytes":3092,"percent":2}]}},"NavigationMenu":{"filePath":"src/components/NavigationMenu/index.tsx","meta":{"name":"NavigationMenu","description":"Site navigation whose dropdowns become a drawer on small screens.","category":"navigation","tags":["navigation","menu","header","dropdown","navbar","mobile","responsive","drawer"],"status":"stable"},"usage":{"when":["Header navigation with more than links","Dropdowns carrying titles, descriptions, or icons","Navigation that must survive a phone screen","Several sections that animate between each other"],"whenNot":["Flat links with no dropdowns (use Header.Nav)","Application actions like cut and paste (use Menu)","Persistent side navigation (use Sidebar)","Showing where the user already is (use Breadcrumbs)"],"guidelines":["Place it inside Header for site-level navigation","Add Viewport to animate between panels","Use MobileContent for sections that only make sense in the drawer","Title plus description for rich panels, plain Link for the rest","asChild on Link composes your handler and honours preventDefault()","Desktop triggers open on hover after a configurable delay","Point icons at your own icon package to replace the chevrons","Set mobileBreakpoint=\"lg\" when the shell drops its sidebar below 1024px"],"accessibility":["Uses disclosure pattern (not menu role) per W3C guidance","Keyboard: Arrow keys navigate between triggers, Enter/Space toggles, Escape closes","Content panels have role=\"region\" with aria-labelledby pointing to trigger","Mobile drawer has focus trap, Escape to close, and aria-modal","Supports prefers-reduced-motion for all animations"]},"props":{"children":{"type":"node","description":"NavigationMenu.List, NavigationMenu.Viewport, and optionally NavigationMenu.MobileContent","required":true},"value":{"type":"string","description":"Controlled open item value","required":false},"defaultValue":{"type":"string","description":"Default open item value","default":"''","required":false},"onValueChange":{"type":"function","description":"Callback when open item changes","required":false},"orientation":{"type":"enum","description":"'horizontal' | 'vertical'","default":"horizontal","required":false,"values":["horizontal","vertical"]},"delayDuration":{"type":"number","description":"Hover delay before opening (ms)","default":"200","required":false},"skipDelayDuration":{"type":"number","description":"Duration after close during which moving to another trigger opens instantly (ms)","default":"300","required":false},"icons":{"type":"object","description":"Optional icon overrides for triggerChevron, mobileMenu, mobileClose, and drawerClose controls","required":false},"mobileBreakpoint":{"type":"enum","description":"Viewport breakpoint below which the mobile drawer replaces desktop navigation","default":"md","required":false,"values":["md","lg"]}},"relations":[{"component":"Header","relationship":"sibling","note":"Place NavigationMenu inside Header for site navigation"},{"component":"Sidebar","relationship":"alternative","note":"Use Sidebar for persistent side navigation, NavigationMenu for header dropdowns"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action menus (role=menu), NavigationMenu for site navigation (disclosure pattern)"},{"component":"Breadcrumbs","relationship":"sibling","note":"Use Breadcrumbs for hierarchical page trail, NavigationMenu for site-level navigation"}],"variants":[{"name":"Default","description":"Two dropdowns beside one plain link.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"products\">\n <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <NavigationMenu.Link href=\"/analytics\" title=\"Analytics\" description=\"Track your metrics and KPIs.\" />\n <NavigationMenu.Link href=\"/automation\" title=\"Automation\" description=\"Automate your workflows.\" />\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"resources\">\n <NavigationMenu.Trigger>Resources</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <NavigationMenu.Link href=\"/docs\" title=\"Documentation\" description=\"Comprehensive API reference.\" />\n <NavigationMenu.Link href=\"/blog\" title=\"Blog\" description=\"Latest news and updates.\" />\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/pricing\">Pricing</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"With Rich Content","description":"A grid of icons, titles, and descriptions.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"platform\">\n <NavigationMenu.Trigger>Platform</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px', padding: '8px', minWidth: '400px' }}>\n <NavigationMenu.Link\n href=\"/dashboard\"\n title=\"Dashboard\"\n description=\"Overview of your project metrics.\"\n />\n <NavigationMenu.Link\n href=\"/analytics\"\n title=\"Analytics\"\n description=\"Deep dive into your data.\"\n />\n <NavigationMenu.Link\n href=\"/reports\"\n title=\"Reports\"\n description=\"Generate custom reports.\"\n />\n <NavigationMenu.Link\n href=\"/settings\"\n title=\"Settings\"\n description=\"Configure your workspace.\"\n />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"With Simple Links","description":"Link lists where descriptions would be noise.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"company\">\n <NavigationMenu.Trigger>Company</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'flex', flexDirection: 'column', padding: '4px', minWidth: '160px' }}>\n <NavigationMenu.Link href=\"/about\">About</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/careers\">Careers</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/contact\">Contact</NavigationMenu.Link>\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/blog\">Blog</NavigationMenu.Link>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/docs\">Docs</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"With Featured Card","description":"One promoted item leads the panel.","code":"<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"learn\">\n <NavigationMenu.Trigger>Learn</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', padding: '8px', minWidth: '420px' }}>\n <NavigationMenu.Link\n href=\"/quickstart\"\n title=\"Quick Start\"\n description=\"Get up and running in 5 minutes with our getting started guide.\"\n featured\n />\n <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n <NavigationMenu.Link href=\"/docs\" title=\"Documentation\" description=\"API reference and guides.\" />\n <NavigationMenu.Link href=\"/examples\" title=\"Examples\" description=\"Browse example projects.\" />\n </div>\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"},{"name":"Vertical","description":"Panels open to the side instead of below.","code":"<div style={{ display: 'flex' }}>\n <NavigationMenu orientation=\"vertical\">\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"overview\">\n <NavigationMenu.Trigger>Overview</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ padding: '8px', minWidth: '200px' }}>\n <NavigationMenu.Link href=\"/intro\" title=\"Introduction\" description=\"Learn the basics.\" />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"guides\">\n <NavigationMenu.Trigger>Guides</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ padding: '8px', minWidth: '200px' }}>\n <NavigationMenu.Link href=\"/install\" title=\"Installation\" description=\"Get started quickly.\" />\n <NavigationMenu.Link href=\"/config\" title=\"Configuration\" description=\"Customize your setup.\" />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n </NavigationMenu>\n</div>"}],"contract":{"propsSummary":["value: string — controlled open item","onValueChange: (value) => void — open state handler","orientation: horizontal | vertical — layout direction","delayDuration: number — hover open delay (default: 200ms)","icons: { triggerChevron?, mobileMenu?, mobileClose?, drawerClose? } — custom internal control icons","mobileBreakpoint: md | lg — mobile drawer breakpoint (default: md)","NavigationMenu.Link: title + description + icon for structured links, or children for simple links","NavigationMenu.Link asChild: composes child and menu click handlers (preventDefault keeps menu open)","NavigationMenu.MobileContent: slot for extra mobile-only sections"],"a11yRules":["A11Y_DISCLOSURE_PATTERN","A11Y_KEYBOARD_NAV","A11Y_FOCUS_TRAP"]},"ai":{"compositionPattern":"compound","subComponents":["List","Item","Trigger","Content","Link","Indicator","Viewport","MobileBrand","MobileContent","MobileSection"],"requiredChildren":["List"],"commonPatterns":["<NavigationMenu><NavigationMenu.List><NavigationMenu.Item value=\"docs\"><NavigationMenu.Trigger>Docs</NavigationMenu.Trigger><NavigationMenu.Content><NavigationMenu.Link href=\"/guides\" title=\"Guides\" description=\"Learn the basics\" /></NavigationMenu.Content></NavigationMenu.Item></NavigationMenu.List><NavigationMenu.Viewport /></NavigationMenu>"]},"propsSummary":["children: node (required)","value: string","defaultValue: string","onValueChange: function","orientation: horizontal|vertical (default: horizontal)","delayDuration: number (default: 200)","skipDelayDuration: number (default: 300)","icons: object","mobileBreakpoint: md|lg (default: md)"],"sourcePath":"src/components/NavigationMenu/index.tsx","exportName":"NavigationMenu","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:01.458Z"},"performance":{"bundleSize":7933,"rawSize":25748,"complexity":"moderate","budgetPercent":52,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"NavigationMenu (self)","bytes":12903,"percent":50},{"path":"@phosphor-icons/react","bytes":5518,"percent":21},{"path":"Collapsible","bytes":2538,"percent":10},{"path":"ScrollArea","bytes":2504,"percent":10},{"path":"src/utils/a11y.tsx","bytes":1358,"percent":5}]}},"Pagination":{"filePath":"src/components/Pagination/index.tsx","meta":{"name":"Pagination","description":"Steps through content split across numbered pages.","category":"navigation","tags":["pagination","paging","pages","navigation"],"status":"stable"},"usage":{"when":["Data sets served a page at a time","Tables and lists with a known total","Search results past the first screen"],"whenNot":["Everything already fits on one page","Content that loads as the user scrolls","Switching between panels (use Tabs)","Steps in an order (use Stepper)"],"guidelines":["Sit it directly below what it pages","edgeCount keeps the first and last pages reachable","siblingCount sets how many neighbours show","The current page uses a neutral surface, not the brand accent","The root forwards id, aria-*, data-*, and handlers to <nav>","Your onClick runs first — call preventDefault() to stop the change"],"accessibility":["Uses nav element with aria-label=\"Pagination\"","aria-current=\"page\" marks the active page","Previous/Next buttons have descriptive aria-labels","Disabled buttons at boundaries prevent invalid navigation"]},"props":{"children":{"type":"node","description":"","required":true},"totalPages":{"type":"number","description":"Total number of pages","required":true},"page":{"type":"number","description":"Controlled current page (1-indexed)","required":false},"defaultPage":{"type":"number","description":"Default page (uncontrolled)","default":"1","required":false},"onPageChange":{"type":"function","description":"Called when page changes","required":false},"edgeCount":{"type":"number","description":"Number of pages shown at edges","default":"1","required":false},"siblingCount":{"type":"number","description":"Number of pages shown around current","default":"1","required":false},"size":{"type":"enum","description":"Visible action size. Resolves through ComponentDefaults when omitted.","required":false,"values":["sm","md","lg"]}},"relations":[{"component":"Table","relationship":"sibling","note":"Commonly paired for table pagination"},{"component":"Listbox","relationship":"alternative","note":"Use Listbox for small sets of options"}],"variants":[{"name":"Default","description":"Neighbours around the current page, ends always reachable.","code":"<Pagination totalPages={10} defaultPage={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"},{"name":"With Edge Pages","description":"Two pages pinned at each end.","code":"<Pagination totalPages={20} defaultPage={10} edgeCount={2} siblingCount={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"},{"name":"Compact","description":"Drops the neighbours when space is tight.","code":"<Pagination totalPages={20} defaultPage={10} siblingCount={0}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"},{"name":"Controlled","description":"You hold the page number in state.","code":"<Pagination totalPages={5} page={3}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"}],"contract":{"propsSummary":["totalPages: number - total page count (required)","page: number - controlled current page (1-indexed)","defaultPage: number - initial page (default: 1)","onPageChange: (page) => void - page change handler","edgeCount: number - pages at edges (default: 1)","siblingCount: number - pages around current (default: 1)","Forwards standard HTML nav attributes to the root element"],"a11yRules":["A11Y_NAV_LABEL","A11Y_CURRENT_PAGE"]},"ai":{"compositionPattern":"compound","subComponents":["Previous","Next","Items","Item","Ellipsis"],"requiredChildren":["Items"],"commonPatterns":["<Pagination totalPages={totalPages} page={currentPage} onPageChange={setPage}><Pagination.Previous /><Pagination.Items /><Pagination.Next /></Pagination>"]},"propsSummary":["children: node (required)","totalPages: number (required)","page: number","defaultPage: number (default: 1)","onPageChange: function","edgeCount: number (default: 1)","siblingCount: number (default: 1)"],"sourcePath":"src/components/Pagination/index.tsx","exportName":"Pagination","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:01.648Z"},"performance":{"bundleSize":1855,"rawSize":4918,"complexity":"lightweight","budgetPercent":12,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Pagination (self)","bytes":4002,"percent":81},{"path":"ComponentDefaults","bytes":194,"percent":4}]}},"Popover":{"filePath":"src/components/Popover/index.tsx","meta":{"name":"Popover","description":"Anchors interactive content to a trigger without blocking the page.","category":"overlays","tags":["popover","overlay","dropdown","floating","contextual"],"status":"stable"},"usage":{"when":["Editing a value in place","Previews richer than a line of text","Filter and picker panels","Content that outgrows a tooltip"],"whenNot":["A short hint (use Tooltip)","A list of actions (use Menu)","Anything that must block the page (use Dialog)","Feedback the user does not act on (use Toast or Alert)"],"guidelines":["One job per panel","Always give the user a visible way out","Pick a side that does not cover what the user just clicked","Add the arrow when the trigger is not obvious","asChild on Trigger and Close needs a single element child"],"accessibility":["Focus is moved to popover content on open","Closes on Escape key","Focus returns to trigger on close"]},"props":{"children":{"type":"node","description":"Popover trigger and content","required":true},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"modal":{"type":"boolean","description":"Whether to block page interaction","default":"false","required":false}},"relations":[{"component":"Tooltip","relationship":"alternative","note":"Use Tooltip for brief, non-interactive hints"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action lists"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for blocking interactions"}],"variants":[{"name":"Default","description":"Title, body, and a close control.","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"soft\">Open Popover</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Close />\n <Popover.Title>Popover Title</Popover.Title>\n <Popover.Description>\n This is a popover with some content. It can contain text, forms, or other elements.\n </Popover.Description>\n </Popover.Content>\n</Popover>"},{"name":"With Form","description":"Enough room to edit a value in place.","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"soft\">Edit Name</Button>\n </Popover.Trigger>\n <Popover.Content size=\"sm\">\n <Popover.Close />\n <Popover.Title>Edit Name</Popover.Title>\n <Popover.Body>\n <Input label=\"Display Name\" placeholder=\"Enter name\" />\n </Popover.Body>\n <Popover.Footer>\n <Popover.Close asChild>\n <Button variant=\"soft\" size=\"sm\">Cancel</Button>\n </Popover.Close>\n <Button variant=\"solid\" size=\"sm\">Save</Button>\n </Popover.Footer>\n </Popover.Content>\n</Popover>"},{"name":"With Arrow","description":"The arrow ties the panel back to its trigger.","code":"<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"soft\">Info</Button>\n </Popover.Trigger>\n <Popover.Content arrow>\n <Popover.Title>Quick Tip</Popover.Title>\n <Popover.Description>\n This popover has an arrow pointing to its trigger element.\n </Popover.Description>\n </Popover.Content>\n</Popover>"},{"name":"Positions","description":"Flips to the opposite side when space runs out.","code":"<div style={{ display: 'flex', gap: '16px', padding: '60px' }}>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"soft\">Top</Button>\n </Popover.Trigger>\n <Popover.Content side=\"top\" size=\"sm\">\n <Popover.Description>Popover on top</Popover.Description>\n </Popover.Content>\n </Popover>\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"soft\">Bottom</Button>\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" size=\"sm\">\n <Popover.Description>Popover on bottom</Popover.Description>\n </Popover.Content>\n </Popover>\n</div>"},{"name":"Link Trigger","description":"asChild lets a link open it.","code":"<Popover>\n <Popover.Trigger asChild>\n <a href=\"#popover-help\">Open help</a>\n </Popover.Trigger>\n <Popover.Content size=\"sm\">\n <Popover.Description>Popover trigger can be an anchor when using asChild.</Popover.Description>\n </Popover.Content>\n</Popover>"}],"contract":{"propsSummary":["open: boolean - controlled open state","onOpenChange: (open) => void - state handler","modal: boolean - blocks page interaction (default: false)","Popover.Trigger / Popover.Close asChild support non-button children","Popover.Content side: top|bottom|left|right - position"],"a11yRules":["A11Y_POPOVER_FOCUS","A11Y_POPOVER_ESCAPE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Close","Title","Description","Body","Footer"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Popover><Popover.Trigger asChild><Button>Open</Button></Popover.Trigger><Popover.Content><Popover.Close /><Popover.Title>{title}</Popover.Title><Popover.Description>{description}</Popover.Description></Popover.Content></Popover>","<Popover><Popover.Trigger asChild><a href=\"#help\">Open help</a></Popover.Trigger><Popover.Content>...</Popover.Content></Popover>"]},"propsSummary":["children: node (required)","open: boolean","defaultOpen: boolean","onOpenChange: function","modal: boolean (default: false)"],"sourcePath":"src/components/Popover/index.tsx","exportName":"Popover","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.154Z"},"performance":{"bundleSize":1344,"rawSize":3486,"complexity":"lightweight","budgetPercent":9,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Popover (self)","bytes":2744,"percent":79}]}},"Progress":{"filePath":"src/components/Progress/index.tsx","meta":{"name":"Progress","description":"Shows how far along a task is, as a bar or a ring.","category":"feedback","tags":["progress","loading","indicator","percentage","status"],"status":"stable"},"usage":{"when":["Upload and download progress","Percentage of a task finished","How much of a form is filled in","Waits where you know the duration"],"whenNot":["You cannot say how long — use Loading","Discrete steps — use a stepper","Status with no number — use Badge"],"guidelines":["Pass a value when you know the percentage; pass null when you do not","Add a label whenever the bar alone leaves the purpose unclear","success, warning, and danger carry state, not decoration","tone=\"neutral\" with role=\"meter\" for a magnitude where full is not success","Values outside min and max are clamped before display"],"accessibility":["Reports role=\"progressbar\" with aria-valuenow","role=\"meter\" is accepted for scalar readings inside a known range","The label is tied to the bar","Value changes are announced as they happen"]},"props":{"value":{"type":"number","description":"Current progress value (0-100). Null for indeterminate.","default":"null","required":false},"min":{"type":"number","description":"Minimum value","default":"0","required":false},"max":{"type":"number","description":"Maximum value","default":"100","required":false},"size":{"type":"enum","description":"Size of the progress bar","default":"md","required":false,"values":["sm","md","lg"]},"tone":{"type":"enum","description":"Colour. accent is the plain bar; neutral reads as a meter whose maximum is not a success; success, warning and danger carry state.","default":"accent","required":false,"values":["accent","neutral","success","warning","danger"]},"label":{"type":"string","description":"Label text above the progress bar","required":false},"showValue":{"type":"boolean","description":"Show percentage value","default":"false","required":false},"formatValue":{"type":"function","description":"Custom formatter for displayed progress value","required":false},"role":{"type":"union","description":"","required":false}},"relations":[{"component":"Badge","relationship":"alternative","note":"Use Badge for status without percentage"},{"component":"Alert","relationship":"sibling","note":"Use Alert for completion messages"}],"variants":[{"name":"Default","description":"Determinate bar with its percentage spelled out.","code":"<Progress value={60} label=\"Uploading…\" showValue />"},{"name":"Tones","description":"Colour carries state: normal, done, tight, critical.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <Progress value={75} tone=\"accent\" label=\"Processing\" showValue />\n <Progress value={100} tone=\"success\" label=\"Complete\" showValue />\n <Progress value={80} tone=\"warning\" label=\"Almost full\" showValue />\n <Progress value={95} tone=\"danger\" label=\"Storage critical\" showValue />\n</Stack>"},{"name":"Meter","description":"A reading where hitting the top is not a win.","code":"<Progress\n value={42}\n tone=\"neutral\"\n role=\"meter\"\n label=\"Seats used\"\n showValue\n/>"},{"name":"Sizes","description":"Thin for table rows, thick when the bar is the point.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <Progress value={50} size=\"sm\" label=\"Small\" />\n <Progress value={50} size=\"md\" label=\"Medium\" />\n <Progress value={50} size=\"lg\" label=\"Large\" />\n</Stack>"},{"name":"Indeterminate","description":"value={null} sweeps instead of filling.","code":"<Progress value={null} label=\"Loading…\" />"},{"name":"Circular","description":"Same value in a ring, for tiles and compact chrome.","code":"import { CircularProgress } from '@/components/Progress';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"lg\" align=\"center\">\n <CircularProgress value={25} size=\"sm\" />\n <CircularProgress value={50} size=\"md\" showValue />\n <CircularProgress value={75} size=\"lg\" showValue tone=\"success\" />\n <CircularProgress value={null} size=\"md\" />\n</Stack>"}],"contract":{"propsSummary":["value: number|null - progress percentage (null for indeterminate)","size: sm|md|lg - bar thickness","tone: accent|neutral|success|warning|danger - colour","label: string - descriptive label","showValue: boolean - display percentage","Determinate display values are clamped (and invalid min/max ranges render as 0%)"],"a11yRules":["A11Y_PROGRESS_ROLE","A11Y_PROGRESS_VALUE"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Circular"]},"propsSummary":["value: number (default: null)","min: number (default: 0)","max: number (default: 100)","size: sm|md|lg (default: md)","tone: accent|neutral|success|warning|danger (default: accent)","role: progressbar|meter (default: progressbar)","label: string","showValue: boolean (default: false)","formatValue: function"],"sourcePath":"src/components/Progress/index.tsx","exportName":"Progress","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.339Z"},"performance":{"bundleSize":2599,"rawSize":6473,"complexity":"lightweight","budgetPercent":17,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Progress (self)","bytes":5859,"percent":91}]}},"Prompt":{"filePath":"src/components/Prompt/index.tsx","meta":{"name":"Prompt","description":"Collects multi-line input for AI and chat interfaces.","category":"ai","tags":["prompt","chat","ai","input","textarea","form"],"status":"stable"},"usage":{"when":["Chat and AI assistant interfaces","Multi-line input with a submit action","Toolbars carrying attachments or a model picker"],"whenNot":["Single-line text (use Input)","Multi-line with no toolbar (use Textarea)","Search-only fields (use Input with the search variant)"],"guidelines":["Always pass an onSubmit handler","Set loading while the request is in flight to block duplicate sends","Prompt.Textarea forwards native textarea props and composes your own handlers","variant=\"ghost\" floats the controls on the writing surface instead of a footer","Seamless secondary controls stay transparent; only Prompt.Submit keeps a filled shape","Prompt.Submit uses a neutral inverse surface, never semantic brand color","Prompt.ModeButton toggles a setting; Prompt.Select picks one from a list","Wire onFiles once — the attach button, paste, and drop all route through it","Render Prompt.Attachments above Prompt.Textarea; they are part of the message"],"accessibility":["Enter submits, Shift+Enter for newline","Submit button is keyboard accessible","Loading state prevents duplicate submissions"]},"props":{"children":{"type":"node","description":"Prompt composition using Prompt sub-components","required":true},"value":{"type":"string","description":"Controlled input value","required":false},"defaultValue":{"type":"string","description":"Uncontrolled default value","default":"","required":false},"onChange":{"type":"function","description":"Called when value changes","required":false},"onSubmit":{"type":"function","description":"Called on form submission","required":false},"placeholder":{"type":"string","description":"Placeholder text for the textarea","default":"Ask, Search or Chat...","required":false},"disabled":{"type":"boolean","description":"Disable the entire prompt","default":"false","required":false},"loading":{"type":"boolean","description":"Show loading state","default":"false","required":false},"minRows":{"type":"number","description":"Minimum number of visible rows","default":"1","required":false},"maxRows":{"type":"number","description":"Maximum number of visible rows","default":"8","required":false},"autoResize":{"type":"boolean","description":"Enable auto-resize based on content","default":"true","required":false},"submitOnEnter":{"type":"boolean","description":"Submit on Enter (Shift+Enter for newline)","default":"true","required":false},"placement":{"type":"enum","description":"Where the card sits: inline in the flow, fixed to the viewport bottom, or sticky to the content area (offset by --fui-prompt-inset-left)","default":"inline","required":false,"values":["inline","fixed","sticky"]},"onFiles":{"type":"function","description":"Called with files added by the attach button, a paste, or a drop anywhere on the card. Providing it enables all three.","required":false},"accept":{"type":"string","description":"accept filter for the attach button's picker, e.g. \"image/*\"","required":false},"variant":{"type":"enum","description":"Card chrome. \"outline\" keeps the toolbar as a filled footer under a rule; \"ghost\" makes the whole card one writing surface with the controls floating on it.","default":"outline","required":false,"values":["outline","ghost"]}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for simple single-line text input"},{"component":"Textarea","relationship":"alternative","note":"Use Textarea for multi-line without toolbar"}],"variants":[{"name":"Basic","description":"A textarea and a submit button, nothing else.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions />\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"With Actions","description":"Attach and mode controls sit to the left of submit.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"With Usage","description":"A quota readout sits beside the submit button.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton active>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"Agent Composer","description":"Controls float on the writing surface instead of a footer.","code":"<Prompt\n variant=\"ghost\"\n submitOnEnter={false}\n minRows={3}\n onSubmit={(value) => console.log(value)}\n>\n <Prompt.Textarea placeholder=\"What should be true when this is done?\" />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.Select\n aria-label=\"Model\"\n defaultValue=\"claude-opus-4-8\"\n options={[{ value: 'claude-opus-4-8', label: 'Opus 4.8' }, { value: 'claude-sonnet-5', label: 'Sonnet 5' }]}\n />\n <Prompt.ModeButton>Plan</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"With Attachments","description":"Staged files list above the text they belong to.","code":"<Prompt onSubmit={(value) => console.log(value)}>\n <Prompt.Attachments\n items={[\n { id: '1', name: 'findings-export.csv', size: 20480 },\n { id: '2', name: 'dashboard.png', size: 153600 },\n ]}\n onRemove={(id) => console.log(id)}\n />\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"Loading State","description":"Input locks and submit spins while the request runs.","code":"<Prompt\n onSubmit={(value) => console.log(value)}\n loading\n defaultValue=\"Tell me about the weather...\"\n>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n <Prompt.ModeButton>Auto</Prompt.ModeButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Usage>52% used</Prompt.Usage>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"},{"name":"Disabled","description":"Everything dims and stops responding to input.","code":"<Prompt onSubmit={(value) => console.log(value)} disabled>\n <Prompt.Textarea />\n <Prompt.Toolbar>\n <Prompt.Actions>\n <Prompt.ActionButton aria-label=\"Add attachment\">\n +\n </Prompt.ActionButton>\n </Prompt.Actions>\n <Prompt.Info>\n <Prompt.Submit />\n </Prompt.Info>\n </Prompt.Toolbar>\n</Prompt>"}],"contract":{"propsSummary":["value: string - controlled input value","onSubmit: (value: string) => void - submission handler","placeholder: string - hint text (default: \"Ask, Search or Chat...\")","disabled: boolean - disables interaction","loading: boolean - shows loading state","minRows/maxRows: number - row constraints (default: 1/8)","submitOnEnter: boolean - Enter key behavior (default: true)","Prompt.Textarea accepts native textarea props and optional aria-label override"],"a11yRules":["A11Y_TEXTAREA_LABEL","A11Y_BUTTON_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Textarea","Toolbar","Tabs","Tab","Actions","Info","ActionButton","ModeButton","Select","Attach","Attachments","Usage","Submit"],"commonPatterns":["<Prompt>\n <Prompt.Textarea>...</Prompt.Textarea>\n <Prompt.Toolbar>...</Prompt.Toolbar>\n <Prompt.Actions>...</Prompt.Actions>\n <Prompt.Info>...</Prompt.Info>\n <Prompt.Submit>...</Prompt.Submit>\n</Prompt>"],"requiredChildren":["Textarea","Toolbar","Actions","Info","Submit"]},"propsSummary":["children: node (required)","value: string","defaultValue: string (default: )","onChange: function","onSubmit: function","placeholder: string (default: Ask, Search or Chat...)","disabled: boolean (default: false)","loading: boolean (default: false)","minRows: number (default: 1)","maxRows: number (default: 8)","autoResize: boolean (default: true)","submitOnEnter: boolean (default: true)","placement: inline|fixed|sticky (default: inline)","variant: outline|ghost (default: outline)","onFiles: function","accept: string"],"sourcePath":"src/components/Prompt/index.tsx","exportName":"Prompt","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.513Z"},"performance":{"bundleSize":6525,"rawSize":18885,"complexity":"moderate","budgetPercent":42,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Select","bytes":8162,"percent":43},{"path":"Prompt (self)","bytes":7771,"percent":41},{"path":"Loading","bytes":2050,"percent":11}]}},"RadioGroup":{"filePath":"src/components/RadioGroup/index.tsx","meta":{"name":"RadioGroup","description":"Selects one option from a mutually exclusive set.","category":"inputs","tags":["form","radio","selection","options"],"status":"stable"},"usage":{"when":["Exactly one answer out of two to five","Options rule each other out","Every option should be visible without opening anything"],"whenNot":["Several answers allowed (use a Checkbox group)","Long lists (use Select)","A single on/off (use Switch)","Options need searching (use Combobox)"],"guidelines":["Pre-select a sensible default whenever one exists","Order options predictably: alphabetical, by frequency, or by cost","Keep labels short","Put the trade-off in each item's helperText"],"accessibility":["The group carries its own label","Arrow keys move between options","The selected option reads as checked"]},"props":{"value":{"type":"string","description":"Controlled selected value","required":false},"defaultValue":{"type":"string","description":"Default value (uncontrolled)","required":false},"onValueChange":{"type":"function","description":"Callback when selection changes","required":false},"onChange":{"type":"function","description":"Alias for onValueChange","required":false},"orientation":{"type":"enum","description":"Layout orientation","default":"vertical","required":false,"values":["horizontal","vertical"]},"disabled":{"type":"boolean","description":"Disable all options","default":"false","required":false},"name":{"type":"string","description":"Form field name","required":false},"label":{"type":"string","description":"Group label","required":false},"helperText":{"type":"string","description":"Helper text shown below the group","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false},"size":{"type":"enum","description":"Size variant","default":"md","required":false,"values":["sm","md","lg"]},"variant":{"type":"enum","description":"Chrome. Omit for the inline radio beside its label; 'outline' renders each item as a full-width bordered surface with the radio tucked inside.","required":false,"values":["outline"]},"wrapperClassName":{"type":"string","description":"Class name for the outer wrapper element","required":false},"groupClassName":{"type":"string","description":"Class name for the inner radio group element","required":false},"groupId":{"type":"string","description":"ID for the inner element with role=radiogroup; the inherited id remains on the outer field wrapper","required":false},"children":{"type":"node","description":"RadioGroup.Item elements","required":true},"form":{"type":"string","description":"ID of the form that owns the radio inputs","required":false},"inputRef":{"type":"union","description":"Ref to the hidden input element","required":false},"readOnly":{"type":"boolean","description":"Whether the selected value cannot be changed by the user","default":"false","required":false},"required":{"type":"boolean","description":"Whether the user must choose a value before submitting a form","default":"false","required":false}},"relations":[{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox for multiple selections"},{"component":"Select","relationship":"alternative","note":"Use Select for many options or limited space"},{"component":"Switch","relationship":"alternative","note":"Use Switch for binary on/off choices"}],"variants":[{"name":"Default","description":"Three options stacked, the first already chosen.","code":"<RadioGroup defaultValue=\"option1\" label=\"Select an option\">\n <RadioGroup.Item value=\"option1\" label=\"Option 1\" />\n <RadioGroup.Item value=\"option2\" label=\"Option 2\" />\n <RadioGroup.Item value=\"option3\" label=\"Option 3\" />\n</RadioGroup>"},{"name":"With Helper Text","description":"Each option carries the trade-off under its label.","code":"<RadioGroup defaultValue=\"standard\" label=\"Shipping Method\">\n <RadioGroup.Item\n value=\"standard\"\n label=\"Standard\"\n helperText=\"5-7 business days\"\n />\n <RadioGroup.Item\n value=\"express\"\n label=\"Express\"\n helperText=\"2-3 business days\"\n />\n <RadioGroup.Item\n value=\"overnight\"\n label=\"Overnight\"\n helperText=\"Next business day\"\n />\n</RadioGroup>"},{"name":"Horizontal","description":"One row — good for short labels like sizes.","code":"<RadioGroup orientation=\"horizontal\" defaultValue=\"small\" label=\"Size\">\n <RadioGroup.Item value=\"small\" label=\"S\" />\n <RadioGroup.Item value=\"medium\" label=\"M\" />\n <RadioGroup.Item value=\"large\" label=\"L\" />\n <RadioGroup.Item value=\"xlarge\" label=\"XL\" />\n</RadioGroup>"},{"name":"With Group Helper Text","description":"One note under the whole group instead of per option.","code":"<RadioGroup defaultValue=\"standard\" label=\"Plan\" helperText=\"You can change your plan at any time\">\n <RadioGroup.Item value=\"free\" label=\"Free\" />\n <RadioGroup.Item value=\"standard\" label=\"Standard\" />\n <RadioGroup.Item value=\"pro\" label=\"Pro\" />\n</RadioGroup>"},{"name":"With Error","description":"Passing a string to error tints the group and prints the reason.","code":"<RadioGroup label=\"Required selection\" error=\"Please select an option\">\n <RadioGroup.Item value=\"a\" label=\"Option A\" />\n <RadioGroup.Item value=\"b\" label=\"Option B\" />\n</RadioGroup>"},{"name":"Disabled","description":"The choice stays visible but nothing can change it.","code":"<RadioGroup disabled defaultValue=\"locked\" label=\"Locked selection\">\n <RadioGroup.Item value=\"locked\" label=\"This is locked\" />\n <RadioGroup.Item value=\"other\" label=\"Cannot select\" />\n</RadioGroup>"},{"name":"Styling Targets","description":"Named class hooks for the wrapper, the group, and each item.","code":"<RadioGroup\n defaultValue=\"a\"\n label=\"Display mode\"\n wrapperClassName=\"demo-radio-wrapper\"\n groupClassName=\"demo-radio-group\"\n>\n <RadioGroup.Item value=\"a\" label=\"Compact\" controlClassName=\"demo-radio-control\" contentClassName=\"demo-radio-content\" />\n <RadioGroup.Item value=\"b\" label=\"Comfortable\" />\n</RadioGroup>"}],"contract":{"propsSummary":["value: string - selected value","onValueChange: (value: string) => void","onChange: (value: string) => void - alias for onValueChange","orientation: horizontal|vertical (default: vertical)","size: sm|md|lg (default: md)","variant: outline - each item a full-width bordered surface; omit for the inline control","label: string - group label","helperText: string - helper text below the group","error: boolean | string - error styling and message","disabled: boolean - disable all options","wrapperClassName/groupClassName - explicit styling targets for wrapper and group","groupId: string - ID forwarded to the inner radiogroup while id remains on the wrapper","RadioGroup.Item supports helperText (preferred) and description (legacy alias) plus controlClassName/contentClassName for item-level styling","RadioGroup.Item trailing: ReactNode - a short value (price, count) at the end of the row on the label's line; pairs with variant=outline for plan pickers"],"a11yRules":["A11Y_RADIO_GROUP","A11Y_LABEL_REQUIRED","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Item"],"commonPatterns":["<RadioGroup>\n <RadioGroup.Item>...</RadioGroup.Item>\n</RadioGroup>"],"requiredChildren":["Item"]},"propsSummary":["value: string","defaultValue: string","onValueChange: function","onChange: function","orientation: horizontal|vertical (default: vertical)","disabled: boolean (default: false)","name: string","label: string","helperText: string","error: union","size: sm|md|lg (default: md)","variant: outline","wrapperClassName: string","groupClassName: string","groupId: string","children: node (required)"],"sourcePath":"src/components/RadioGroup/index.tsx","exportName":"RadioGroup","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.692Z"},"performance":{"bundleSize":1556,"rawSize":4091,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"RadioGroup (self)","bytes":2863,"percent":70},{"path":"src/utils/aria.ts","bytes":433,"percent":11},{"path":"ComponentDefaults","bytes":198,"percent":5}]}},"ScrollArea":{"filePath":"src/components/ScrollArea/index.tsx","meta":{"name":"ScrollArea","description":"Scrolls overflowing content with a slim scrollbar and optional edge fades.","category":"layout","tags":["scroll","overflow","scrollbar","container","layout"],"status":"stable"},"usage":{"when":["Content that overflows a fixed-size container","Tab bars or chip rows that may run past the edge","Scrollable panels, sidebars, and menu content"],"whenNot":["Whole-page scrolling (use the native body scroll)","Content that can never overflow"],"guidelines":["orientation constrains which axis can scroll","showFades hints at hidden content when nothing else does","scrollbarVisibility=\"hover\" hides the thumb without shifting layout","The container needs a fixed height or the area cannot scroll"],"accessibility":["Preserves native scroll behavior and keyboard support across both axes","Scrollbar is visible on focus for keyboard users","Respects prefers-reduced-motion for fade transitions"]},"props":{"children":{"type":"node","description":"Scrollable content","required":true},"orientation":{"type":"enum","description":"Scroll direction","default":"vertical","required":false,"values":["horizontal","vertical","both"]},"scrollbarVisibility":{"type":"enum","description":"When to show the scrollbar","default":"auto","required":false,"values":["auto","always","hover"]},"showFades":{"type":"boolean","description":"Show gradient fade indicators at scroll edges","default":"false","required":false},"className":{"type":"string","description":"Additional class name","required":false},"dir":{"type":"string","description":"","required":false}},"relations":[],"variants":[{"name":"Vertical","description":"Scrolls down with a thin, always-visible thumb.","code":"import { Box } from '@/components/Box';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <ScrollArea style={{ height: '200px' }}>\n <Box padding=\"sm\">\n <Stack gap=\"sm\">\n <Text>Row 1</Text>\n <Text>Row 2</Text>\n <Text>Row 3</Text>\n <Text>Row 4</Text>\n <Text>Row 5</Text>\n <Text>Row 6</Text>\n <Text>Row 7</Text>\n <Text>Row 8</Text>\n <Text>Row 9</Text>\n <Text>Row 10</Text>\n <Text>Row 11</Text>\n <Text>Row 12</Text>\n </Stack>\n </Box>\n </ScrollArea>\n</Box>"},{"name":"Horizontal","description":"Keeps an overflowing row of chips on one line.","code":"import { Box } from '@/components/Box';\nimport { Chip } from '@/components/Chip';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\n\n<Box width=\"100%\">\n <ScrollArea orientation=\"horizontal\">\n <Stack direction=\"row\" gap=\"sm\">\n <Chip>React</Chip>\n <Chip>TypeScript</Chip>\n <Chip>Accessibility</Chip>\n <Chip>Docs</Chip>\n <Chip>Playground</Chip>\n <Chip>CLI</Chip>\n <Chip>Tokens</Chip>\n <Chip>Governance</Chip>\n <Chip>Contracts</Chip>\n <Chip>Registry</Chip>\n </Stack>\n </ScrollArea>\n</Box>"},{"name":"With Fades","description":"Edge fades signal there is more content each way.","code":"import { Box } from '@/components/Box';\nimport { Chip } from '@/components/Chip';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\n\n<Box width=\"100%\">\n <ScrollArea orientation=\"horizontal\" showFades>\n <Stack direction=\"row\" gap=\"sm\">\n <Chip>React</Chip>\n <Chip>TypeScript</Chip>\n <Chip>Accessibility</Chip>\n <Chip>Docs</Chip>\n <Chip>Playground</Chip>\n <Chip>CLI</Chip>\n <Chip>Tokens</Chip>\n <Chip>Governance</Chip>\n <Chip>Contracts</Chip>\n <Chip>Registry</Chip>\n </Stack>\n </ScrollArea>\n</Box>"},{"name":"Hover Scrollbar","description":"Thumb stays invisible until hover or keyboard focus.","code":"import { Box } from '@/components/Box';\nimport { ScrollArea } from '@/components/ScrollArea';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <ScrollArea scrollbarVisibility=\"hover\" style={{ height: '200px' }}>\n <Box padding=\"sm\">\n <Stack gap=\"sm\">\n <Text>Row 1</Text>\n <Text>Row 2</Text>\n <Text>Row 3</Text>\n <Text>Row 4</Text>\n <Text>Row 5</Text>\n <Text>Row 6</Text>\n <Text>Row 7</Text>\n <Text>Row 8</Text>\n <Text>Row 9</Text>\n <Text>Row 10</Text>\n <Text>Row 11</Text>\n <Text>Row 12</Text>\n </Stack>\n </Box>\n </ScrollArea>\n</Box>"}],"contract":{"propsSummary":["orientation: horizontal|vertical|both - scroll direction","scrollbarVisibility: auto|always|hover - scrollbar display mode","showFades: boolean - gradient edge indicators"]},"ai":{"compositionPattern":"compound","subComponents":["Root"],"commonPatterns":["<ScrollArea orientation=\"horizontal\"><div style={{ display: \"flex\", gap: 8 }}>{items}</div></ScrollArea>","<ScrollArea style={{ height: 300 }}>{longContent}</ScrollArea>"]},"propsSummary":["children: node (required)","orientation: horizontal|vertical|both (default: vertical)","scrollbarVisibility: auto|always|hover (default: auto)","showFades: boolean (default: false)","className: string"],"sourcePath":"src/components/ScrollArea/index.tsx","exportName":"ScrollArea","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:02.867Z"},"performance":{"bundleSize":1519,"rawSize":3074,"complexity":"lightweight","budgetPercent":10,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ScrollArea (self)","bytes":2482,"percent":81}]}},"Select":{"filePath":"src/components/Select/Select.fragment.tsx","meta":{"name":"Select","description":"Opens a list and returns the single option the user picks.","category":"inputs","status":"stable","tags":["select","dropdown","form","options","picker"]},"guidance":{"when":["Picking one value from a known list","More than 4-5 options — radios would crowd the form","Tight forms where the list should stay collapsed"],"whenNot":["Two or three options (use RadioGroup)","Users may type their own value (use Combobox)","Multiple selections (use a Checkbox group)","Actions rather than values (use Menu)"],"dont":[{"reason":"Do not use Select for a list of actions.","bad":"<Select>Delete</Select>","good":"<Select label=\"Choose a value\" options={[{ value: \"design\", label: \"Design\" }]} />"}],"guidelines":["Placeholder names the decision, e.g. \"Choose a team\"","Set label so the field is announced","helperText for guidance, error for the failure reason","Group related options with Select.Group","Keep option text short","Order options predictably: alphabetical, by frequency, or by category"],"accessibility":["Full keyboard navigation","Type-ahead jumps to matching options","Trigger and list carry the right ARIA roles"]},"usage":{"when":["Picking one value from a known list","More than 4-5 options — radios would crowd the form","Tight forms where the list should stay collapsed"],"whenNot":["Two or three options (use RadioGroup)","Users may type their own value (use Combobox)","Multiple selections (use a Checkbox group)","Actions rather than values (use Menu)"],"dont":[{"reason":"Do not use Select for a list of actions.","bad":"<Select>Delete</Select>","good":"<Select label=\"Choose a value\" options={[{ value: \"design\", label: \"Design\" }]} />"}],"guidelines":["Placeholder names the decision, e.g. \"Choose a team\"","Set label so the field is announced","helperText for guidance, error for the failure reason","Group related options with Select.Group","Keep option text short","Order options predictably: alphabetical, by frequency, or by category"],"accessibility":["Full keyboard navigation","Type-ahead jumps to matching options","Trigger and list carry the right ARIA roles"]},"props":{"autoComplete":{"type":"string","description":"Browser autofill hint for the hidden input","required":false},"children":{"type":"node","description":"","required":false},"className":{"type":"string","description":"Wrapper class name","required":false},"defaultOpen":{"type":"boolean","description":"Default open state","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","required":false},"disabled":{"type":"boolean","description":"Whether the field is disabled","required":false},"error":{"type":"union","description":"Show error styling. When a string is provided, it is displayed as an error message.","required":false},"form":{"type":"string","description":"ID of the form that owns the hidden input","required":false},"helperText":{"type":"string","description":"Helper text shown below the field","required":false},"inputRef":{"type":"union","description":"Ref to the hidden input element","required":false},"label":{"type":"string","description":"Visible label text","required":false},"name":{"type":"string","description":"Form field name","required":false},"onChange":{"type":"function","description":"Alias for onValueChange","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"onValueChange":{"type":"function","description":"Called when selection changes","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false},"options":{"type":"array","description":"Convenience API for simple selects (renders Select.Item entries when children are omitted)","required":false},"placeholder":{"type":"string","description":"Placeholder text when no value is selected","required":false},"readOnly":{"type":"boolean","description":"Whether the user cannot choose a different option","required":false},"required":{"type":"boolean","description":"Whether a selection is required","required":false},"size":{"type":"enum","description":"Size variant.","default":"\"md\"","required":false,"values":["sm","md","lg"]},"value":{"type":"string","description":"Controlled selected value","required":false},"variant":{"type":"enum","description":"Chrome. `outline` is the bordered field shell; `ghost` drops it for a\ncompact, borderless control — for toolbars and dense rows, where a bordered\nfield reads as a form. Pair with `size=\"sm\"`.","default":"outline","required":false,"values":["outline","ghost"]}},"relations":[{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based dropdowns"},{"component":"Input","relationship":"sibling","note":"Use Input for free-form text entry"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox group for multiple selections"}],"variants":[{"name":"Default","description":"Label, placeholder, three options.","code":"<Select label=\"Team\" placeholder=\"Choose a team\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"design\">Design</Select.Item>\n <Select.Item value=\"engineering\">Engineering</Select.Item>\n <Select.Item value=\"product\">Product</Select.Item>\n </Select.Content>\n </Select>","canonical":true},{"name":"With Groups","description":"Headed sections separate related options.","code":"<Select placeholder=\"Choose a country\">\n <Select.Trigger />\n <Select.Content>\n <Select.Group>\n <Select.GroupLabel>Americas</Select.GroupLabel>\n <Select.Item value=\"us\">United States</Select.Item>\n <Select.Item value=\"ca\">Canada</Select.Item>\n </Select.Group>\n <Select.Group>\n <Select.GroupLabel>Europe</Select.GroupLabel>\n <Select.Item value=\"uk\">United Kingdom</Select.Item>\n <Select.Item value=\"de\">Germany</Select.Item>\n </Select.Group>\n </Select.Content>\n </Select>"},{"name":"With Label and Helper Text","description":"Helper text explains what the choice affects.","code":"<Select label=\"Timezone\" helperText=\"Used for reminders and calendar notifications.\">\n <Select.Trigger placeholder=\"Select a timezone\" />\n <Select.Content>\n <Select.Item value=\"pt\">Pacific Time</Select.Item>\n <Select.Item value=\"mt\">Mountain Time</Select.Item>\n <Select.Item value=\"ct\">Central Time</Select.Item>\n <Select.Item value=\"et\">Eastern Time</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Error State","description":"Red border, and the message replaces helper text.","code":"<Select label=\"Team\" placeholder=\"Choose a team\" error=\"Choose a team before continuing\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"design\">Design</Select.Item>\n <Select.Item value=\"engineering\">Engineering</Select.Item>\n </Select.Content>\n </Select>"},{"name":"With Disabled Options","description":"Unavailable options stay visible but cannot be picked.","code":"<Select placeholder=\"Select a plan\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"free\">Free</Select.Item>\n <Select.Item value=\"pro\">Pro</Select.Item>\n <Select.Item value=\"enterprise\" disabled>\n Enterprise (contact sales)\n </Select.Item>\n </Select.Content>\n </Select>"},{"name":"Scrollable List","description":"Caps at four rows and half-shows the fifth as a scroll hint.","code":"<Select placeholder=\"Select a timezone\">\n <Select.Trigger />\n <Select.Content maxVisibleItems={4}>\n <Select.Item value=\"utc-8\">Pacific Time (UTC-8)</Select.Item>\n <Select.Item value=\"utc-7\">Mountain Time (UTC-7)</Select.Item>\n <Select.Item value=\"utc-6\">Central Time (UTC-6)</Select.Item>\n <Select.Item value=\"utc-5\">Eastern Time (UTC-5)</Select.Item>\n <Select.Item value=\"utc-4\">Atlantic Time (UTC-4)</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Custom Max Visible Items","description":"maxVisibleItems raises the cap to six rows.","code":"<Select placeholder=\"Select a color\">\n <Select.Trigger />\n <Select.Content maxVisibleItems={6}>\n <Select.Item value=\"red\">Red</Select.Item>\n <Select.Item value=\"orange\">Orange</Select.Item>\n <Select.Item value=\"yellow\">Yellow</Select.Item>\n <Select.Item value=\"green\">Green</Select.Item>\n <Select.Item value=\"blue\">Blue</Select.Item>\n <Select.Item value=\"indigo\">Indigo</Select.Item>\n <Select.Item value=\"violet\">Violet</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Ghost","description":"Ghost drops the field shell for toolbars and dense rows.","code":"<Select variant=\"ghost\" size=\"sm\" aria-label=\"Sort order\" defaultValue=\"newest\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"newest\">Newest first</Select.Item>\n <Select.Item value=\"oldest\">Oldest first</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Disabled","description":"Dimmed and cannot be opened.","code":"<Select disabled placeholder=\"Select an option\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"one\">Option 1</Select.Item>\n </Select.Content>\n </Select>"},{"name":"Options Prop","description":"The options array replaces hand-written Select.Item children.","code":"<Select\n placeholder=\"Select a team\"\n options={[\n { value: \"engineering\", label: \"Engineering\" },\n { value: \"design\", label: \"Design\" },\n { value: \"product\", label: \"Product\" },\n ]}\n />"},{"name":"Long Localized Option","description":"The trigger grows to fit a long label instead of clipping it.","code":"<Select label=\"Workspace region\" placeholder=\"Choose a workspace region\">\n <Select.Trigger />\n <Select.Content>\n <Select.Item value=\"eu-central\">\n Central European workspace with localized administrator recovery requirements\n </Select.Item>\n <Select.Item value=\"us-east\">United States East</Select.Item>\n </Select.Content>\n </Select>"}],"ai":{"compositionPattern":"compound","subComponents":["Trigger","Content","Item","Group","GroupLabel"],"requiredChildren":["Trigger","Content"],"commonPatterns":["<Select placeholder=\"Select option\" options={[{ value: 'opt1', label: 'Option 1' }, { value: 'opt2', label: 'Option 2' }]} />","<Select placeholder=\"Select option\"><Select.Trigger /><Select.Content><Select.Item value=\"opt1\">{label1}</Select.Item><Select.Item value=\"opt2\">{label2}</Select.Item></Select.Content></Select>"]},"contract":{"propsSummary":["value: string | null - controlled selected value","onValueChange: (value: string | null) => void - selection handler","onChange: (value: string | null) => void - alias for onValueChange","label: string - visible label text","helperText: string - helper text below field","error: boolean | string - error styling and message","placeholder: string - placeholder text","disabled: boolean - disable select","size: sm|md|lg (default: md)","variant: outline|ghost (default: outline) - ghost is borderless, for toolbars","options: SelectOption[] - convenience API for simple option lists","maxVisibleItems: number - max visible options before scrolling (default 4)","Select.Trigger accepts an icon prop for a leading adornment"],"a11yRules":["A11Y_SELECT_KEYBOARD","A11Y_SELECT_LABEL"]},"matrix":{"axes":{"size":"auto","variant":"auto","theme":["light","dark"]},"forced":["open","focus","disabled","error"],"worstCase":{"options":"A long localized option label that remains readable inside the bounded list"}},"preview":{"providers":[],"dynamicRegions":[]},"provenance":{"source":"extracted","verified":true},"sourcePath":"src/components/Select/index.tsx","exportName":"Select","performance":{"bundleSize":3534,"rawSize":8857,"complexity":"lightweight","budgetPercent":23,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Select (self)","bytes":4884,"percent":55},{"path":"src/recipes/popup.ts","bytes":2625,"percent":30},{"path":"src/utils/aria.ts","bytes":433,"percent":5},{"path":"ComponentDefaults","bytes":198,"percent":2}]}},"Separator":{"filePath":"src/components/Separator/index.tsx","meta":{"name":"Separator","description":"Draws a rule between sections of related content.","category":"layout","tags":["separator","divider","hr","line","layout"],"status":"stable"},"usage":{"when":["Dividing sections that spacing alone cannot separate","Labelled breaks such as an Or divider","Splitting items inside a toolbar or row"],"whenNot":["Whenever spacing already reads as a break","Decorative rules (use a border)","Building layout structure (use Grid)"],"guidelines":["Use sparingly — stacked rules read as noise","soft halves the rule's weight for quieter breaks","orientation=\"vertical\" needs a parent with a set height","Add aria-hidden when the rule is purely decorative"],"accessibility":["Uses role=\"separator\" for semantic meaning","Decorative separators should be aria-hidden"]},"props":{"orientation":{"type":"enum","description":"Direction of the separator","default":"horizontal","required":false,"values":["horizontal","vertical"]},"gap":{"type":"enum","description":"Breathing room around the rule","default":"none","required":false,"values":["none","xs","sm","md","lg","xl"]},"soft":{"type":"boolean","description":"Softer, lighter appearance","default":"false","required":false},"label":{"type":"string","description":"Optional text label (horizontal only)","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Card","relationship":"sibling","note":"Cards provide stronger visual grouping"}],"variants":[{"name":"Default","description":"Standard and soft weights, one above the other.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <Text>Standard weight</Text>\n <Separator gap=\"md\" />\n <Text>Soft weight</Text>\n <Separator soft gap=\"md\" />\n <Text>Below</Text>\n</Box>"},{"name":"With Label","description":"A label sits inside the rule for a major break.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <Text>First section</Text>\n <Separator label=\"Or\" gap=\"md\" />\n <Text>Second section</Text>\n</Box>"},{"name":"Vertical","description":"Divides items sitting in a row.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Stack direction=\"row\" align=\"center\" gap=\"md\" style={{ height: '40px' }}>\n <Text>Item 1</Text>\n <Separator orientation=\"vertical\" />\n <Text>Item 2</Text>\n <Separator orientation=\"vertical\" />\n <Text>Item 3</Text>\n</Stack>"},{"name":"Gap Options","description":"gap sets the breathing room around the rule.","code":"import { Box } from '@/components/Box';\nimport { Separator } from '@/components/Separator';\nimport { Text } from '@/components/Text';\n\n<Box width=\"100%\">\n <Text>none</Text>\n <Separator gap=\"none\" />\n <Text>sm</Text>\n <Separator gap=\"sm\" />\n <Text>md</Text>\n <Separator gap=\"md\" />\n <Text>lg</Text>\n <Separator gap=\"lg\" />\n <Text>End</Text>\n</Box>"}],"contract":{"propsSummary":["orientation: horizontal|vertical - direction","gap: none|xs|sm|md|lg|xl - breathing room","soft: boolean - lighter appearance","label: string - centered label text"],"a11yRules":["A11Y_SEPARATOR_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["orientation: horizontal|vertical (default: horizontal)","gap: none|xs|sm|md|lg|xl (default: none)","soft: boolean (default: false)","label: string","style: object"],"sourcePath":"src/components/Separator/index.tsx","exportName":"Separator","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:03.327Z"},"performance":{"bundleSize":760,"rawSize":1560,"complexity":"lightweight","budgetPercent":5,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Separator (self)","bytes":969,"percent":62}]}},"Sidebar":{"filePath":"src/components/Sidebar/index.tsx","meta":{"name":"Sidebar","description":"Collapsible navigation panel that turns into a drawer on mobile.","category":"layout","tags":["sidebar","navigation","drawer","menu","layout"],"status":"stable"},"usage":{"when":["Primary navigation for an app shell","Navigation that must collapse to icons or hide entirely","Grouped destinations with active state"],"whenNot":["Top-level horizontal navigation (use Header)","Temporary side panels for one task (use Drawer)","In-page section links (use a list of links)"],"guidelines":["Give every item an icon so the collapsed rail stays readable","collapsible=\"icon\" shrinks to a rail; \"offcanvas\" hides it completely","Wrap in SidebarProvider only when something outside must toggle it","An explicit collapsed prop overrides any surrounding provider","Sidebar.Rail and Sidebar.CollapseToggle are alternative toggles — pick one","Use Sidebar.MenuSkeleton while navigation data loads"],"accessibility":["Uses semantic <nav> element with aria-label","aria-current=\"page\" on active items","aria-expanded on items with submenus","Escape key closes mobile drawer","Cmd/Ctrl+B keyboard shortcut toggles sidebar (when using SidebarProvider)","Focus trap in mobile drawer mode","Minimum 44px touch targets"]},"props":{"children":{"type":"node","description":"Sidebar content (use Sidebar.Header, Sidebar.Nav, Sidebar.Section, etc.)","required":true},"collapsed":{"type":"boolean","description":"Icon-only mode for desktop (controlled)","required":false},"defaultCollapsed":{"type":"boolean","description":"Initial collapsed state (uncontrolled)","default":"false","required":false},"onCollapsedChange":{"type":"function","description":"Called when collapsed state changes","required":false},"open":{"type":"boolean","description":"Mobile drawer open state (controlled)","required":false},"defaultOpen":{"type":"boolean","description":"Initial open state (uncontrolled)","default":"false","required":false},"onOpenChange":{"type":"function","description":"Called when open state changes","required":false},"width":{"type":"string","description":"Width of expanded sidebar","default":"240px","required":false},"collapsedWidth":{"type":"string","description":"Width when collapsed","default":"var(--fui-navigation-sidebar-collapsed-width, 56px)","required":false},"position":{"type":"enum","description":"Sidebar position","default":"left","required":false,"values":["left","right"]},"collapsible":{"type":"enum","description":"Collapse behavior mode","default":"icon","required":false,"values":["icon","offcanvas","none"]},"activeIndicator":{"type":"enum","description":"Placement of the active-item affordance","default":"start","required":false,"values":["start","end"]},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Tabs","relationship":"alternative","note":"Use Tabs for in-page section navigation"},{"component":"Menu","relationship":"composition","note":"Use Menu for contextual actions within sidebar"}],"variants":[{"name":"Default","description":"Sections group items; active marks the current page.","code":"<Sidebar>\n <Sidebar.Header>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />}>Team</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n <Sidebar.Section label=\"Settings\">\n <Sidebar.Item icon={<GearIcon />}>Preferences</Sidebar.Item>\n <Sidebar.Item icon={<HelpIcon />}>Help</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n</Sidebar>"},{"name":"Collapsed","description":"Icon-only rail; labels move into hover tooltips.","code":"function App() {\n const [collapsed, setCollapsed] = useState(true);\n\n return (\n <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed}>\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n );\n}"},{"name":"With Badges","description":"Trailing counts for unread or pending work.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />} badge=\"3\">Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />} badge=\"12\">Team</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Submenu","description":"Nested items; defaultExpanded sets the opening state.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />}>Dashboard</Sidebar.Item>\n {/* Use defaultExpanded for uncontrolled mode - no state needed! */}\n <Sidebar.Item icon={<FolderIcon />} hasSubmenu defaultExpanded>\n Projects\n </Sidebar.Item>\n <Sidebar.Submenu>\n <Sidebar.SubItem active>Website Redesign</Sidebar.SubItem>\n <Sidebar.SubItem>Mobile App</Sidebar.SubItem>\n <Sidebar.SubItem>API Integration</Sidebar.SubItem>\n </Sidebar.Submenu>\n {/* Multiple submenus work without tracking separate state */}\n <Sidebar.Item icon={<UsersIcon />} hasSubmenu>\n Team\n </Sidebar.Item>\n <Sidebar.Submenu>\n <Sidebar.SubItem>Engineering</Sidebar.SubItem>\n <Sidebar.SubItem>Design</Sidebar.SubItem>\n </Sidebar.Submenu>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Disabled Items","description":"Items switched off by permissions or feature flags.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<UsersIcon />} disabled>\n Team (Coming Soon)\n </Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />} disabled>\n Projects (Upgrade)\n </Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Provider & External Trigger","description":"useSidebar drives the sidebar from anywhere, plus Cmd/Ctrl+B.","code":"function App() {\n return (\n <SidebarProvider>\n <Stack direction=\"row\" gap=\"lg\" align=\"start\">\n <Sidebar>\n <Sidebar.Header>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n </Sidebar>\n <MainContent />\n </Stack>\n </SidebarProvider>\n );\n}\n\nfunction MainContent() {\n const { toggleSidebar, state } = useSidebar();\n\n return (\n <Stack gap=\"sm\" align=\"start\">\n <Text scale=\"sm\" color=\"secondary\">State: {state}</Text>\n <Button size=\"sm\" variant=\"soft\" onClick={toggleSidebar}>\n Toggle sidebar\n </Button>\n </Stack>\n );\n}"},{"name":"With asChild (Polymorphic)","description":"Render items as your router's link component.","code":"import Link from 'next/link';\n\n<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active asChild>\n <Link href=\"/dashboard\">Dashboard</Link>\n </Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />} asChild>\n <Link href=\"/analytics\">Analytics</Link>\n </Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Section Action","description":"A section header can carry one quick action.","code":"<Sidebar>\n <Sidebar.Nav>\n <Sidebar.Section\n label=\"Projects\"\n action={\n <Sidebar.SectionAction aria-label=\"Add project\" onClick={handleAdd}>\n <PlusIcon />\n </Sidebar.SectionAction>\n }\n >\n <Sidebar.Item icon={<FolderIcon />}>Website Redesign</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Mobile App</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Loading Skeleton","description":"Placeholder rows to show while navigation data loads.","code":"<Sidebar>\n <Sidebar.Header>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.MenuSkeleton count={6} />\n </Sidebar.Nav>\n</Sidebar>"},{"name":"With Rail Toggle","description":"Drag-handle toggle on the sidebar edge — hover to reveal, click to collapse.","code":"function App() {\n const [collapsed, setCollapsed] = useState(false);\n\n return (\n <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed}>\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n <Sidebar.Item icon={<FolderIcon />}>Projects</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Rail />\n </Sidebar>\n );\n}"},{"name":"Offcanvas Collapsed","description":"Hides the panel entirely, leaving a floating re-open button.","code":"function App() {\n const [collapsed, setCollapsed] = useState(true);\n\n return (\n <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed} collapsible=\"offcanvas\">\n <Sidebar.Header collapsedContent={<Logo />}>\n <Logo />\n <span>Acme App</span>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section>\n <Sidebar.Item icon={<HomeIcon />} active>Dashboard</Sidebar.Item>\n <Sidebar.Item icon={<ChartIcon />}>Analytics</Sidebar.Item>\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Sidebar.CollapseToggle />\n </Sidebar.Footer>\n </Sidebar>\n );\n}"}],"contract":{"propsSummary":["collapsed: boolean - icon-only desktop mode","open: boolean - mobile drawer state","width: string - expanded width (default: 240px)","position: left|right - sidebar position","active: boolean - set on Sidebar.Item to mark current page (app-controlled)","Sidebar.Item/SubItem onClick: (event) => void - click handler receives mouse event"],"a11yRules":["A11Y_NAV_LANDMARK","A11Y_FOCUS_TRAP","A11Y_ESCAPE_CLOSE"]},"ai":{"compositionPattern":"compound","subComponents":["Header","Nav","Section","SectionAction","Item","SubItem","Submenu","Footer","Trigger","Overlay","CollapseToggle","Rail","MenuSkeleton"],"requiredChildren":["Nav"],"commonPatterns":["<Sidebar><Sidebar.Header>{logo}</Sidebar.Header><Sidebar.Nav><Sidebar.Section><Sidebar.Item icon={icon} active>{label}</Sidebar.Item></Sidebar.Section></Sidebar.Nav><Sidebar.Footer><Sidebar.CollapseToggle /></Sidebar.Footer></Sidebar>"]},"propsSummary":["children: node (required)","collapsed: boolean","defaultCollapsed: boolean (default: false)","onCollapsedChange: function","open: boolean","defaultOpen: boolean (default: false)","onOpenChange: function","width: string (default: 240px)","collapsedWidth: string (default: 56px)","position: left|right (default: left)","collapsible: icon|offcanvas|none (default: icon)","activeIndicator: start|end (default: start)","style: object"],"sourcePath":"src/components/Sidebar/index.tsx","exportName":"Sidebar","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:03.784Z"},"performance":{"bundleSize":8828,"rawSize":26613,"complexity":"moderate","budgetPercent":57,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Sidebar (self)","bytes":11967,"percent":45},{"path":"src/utils/keyboard-shortcuts.ts","bytes":3887,"percent":15},{"path":"Collapsible","bytes":2544,"percent":10},{"path":"ScrollArea","bytes":2508,"percent":9},{"path":"Tooltip","bytes":1461,"percent":5},{"path":"Skeleton","bytes":1275,"percent":5},{"path":"Badge","bytes":1228,"percent":5},{"path":"src/utils/a11y.tsx","bytes":779,"percent":3}]}},"Skeleton":{"filePath":"src/components/Skeleton/index.tsx","meta":{"name":"Skeleton","description":"Holds the shape of content that has not arrived yet.","category":"feedback","tags":["loading","placeholder","skeleton","shimmer"],"status":"stable"},"usage":{"when":["Content is still being fetched","You want to stop the layout jumping when it lands","Making a wait feel shorter than it is"],"whenNot":["Waits under about 300ms","A spinner says it better","Work the user cannot see anyway"],"guidelines":["Match the shape and size of the real content","Prefer the text, heading, and avatar shapes over hand-rolled boxes","Give Skeleton.Text an ancestor with a real width — percentage lines collapse without one","A few big shapes beat many small ones","Skeleton and Skeleton.Text forward id, aria-*, data-* and handlers"],"accessibility":["Skeletons are decoration — hide them with aria-hidden","Announce the loading state separately if it matters","Keep the pulse subtle but visible against the surface"]},"props":{"shape":{"type":"enum","description":"Semantic shape that auto-sizes","default":"rect","required":false,"values":["text","heading","avatar","button","input","rect"]},"size":{"type":"enum","description":"Size for avatar/button shapes","default":"md","required":false,"values":["sm","md","lg"]},"width":{"type":"union","description":"Custom width (string or number)","required":false},"height":{"type":"union","description":"Custom height (string or number)","required":false},"fill":{"type":"boolean","description":"Fill parent container","default":"false","required":false},"radius":{"type":"enum","description":"Border radius override","required":false,"values":["sm","md","lg","none","full"]},"static":{"type":"boolean","description":"Disable skeleton animation","default":"false","required":false}},"relations":[{"component":"Progress","relationship":"alternative","note":"Use Progress for determinate loading"}],"variants":[{"name":"Default","description":"One rectangle at an explicit size.","code":"<Skeleton width={200} height={20} />"},{"name":"Text Lines","description":"Stacked lines that fill the width they are given.","code":"<div style={{ width: 260 }}>\n <Skeleton.Text lines={3} />\n</div>"},{"name":"Semantic Shapes","description":"Heading sits taller than the body lines under it.","code":"<div\n style={{\n width: 260,\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--fui-space-2)',\n }}\n>\n <Skeleton shape=\"heading\" width={200} />\n <Skeleton shape=\"text\" width=\"100%\" />\n <Skeleton shape=\"text\" width=\"80%\" />\n</div>"},{"name":"Avatar Skeleton","description":"Circles matching the three avatar sizes.","code":"<div style={{ display: 'flex', gap: 'var(--fui-space-1)', alignItems: 'center' }}>\n <Skeleton.Circle size=\"sm\" />\n <Skeleton.Circle size=\"md\" />\n <Skeleton.Circle size=\"lg\" />\n</div>"},{"name":"Card Skeleton","description":"Media, title, then body — the card before it loads.","code":"<div\n style={{\n width: 300,\n padding: 'var(--fui-space-2)',\n border: '1px solid var(--fui-border)',\n borderRadius: 'var(--fui-radius-lg)',\n }}\n>\n <Skeleton shape=\"rect\" height={120} radius=\"md\" />\n <div style={{ marginTop: 'var(--fui-space-2)' }}>\n <Skeleton shape=\"heading\" width=\"60%\" />\n </div>\n <div style={{ marginTop: 'var(--fui-space-1)' }}>\n <Skeleton.Text lines={2} />\n </div>\n</div>"}],"contract":{"propsSummary":["shape: text|heading|avatar|button|input|rect","size: sm|md|lg (for avatar/button)","width/height: custom dimensions","fill: boolean - fill parent","Skeleton / Skeleton.Text forward div DOM props"]},"ai":{"compositionPattern":"compound","subComponents":["Text","Circle"]},"propsSummary":["shape: text|heading|avatar|button|input|rect (default: rect)","size: sm|md|lg (default: md)","width: union","height: union","fill: boolean (default: false)","radius: sm|md|lg|none|full","static: boolean (default: false)"],"sourcePath":"src/components/Skeleton/index.tsx","exportName":"Skeleton","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:03.952Z"},"performance":{"bundleSize":943,"rawSize":1839,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Skeleton (self)","bytes":1262,"percent":69}]}},"Slider":{"filePath":"src/components/Slider/index.tsx","meta":{"name":"Slider","description":"Selects a numeric value within a defined range.","category":"inputs","tags":["slider","range","input","number","control"],"status":"stable"},"usage":{"when":["Any value along a range, where roughly right is good enough","Volume, brightness, opacity","Price and range filters","The effect is visible as the user drags"],"whenNot":["An exact number matters (use Input type=\"number\")","A handful of fixed choices (use RadioGroup or Select)","On or off (use Switch)"],"guidelines":["Label what the track controls","Turn on showValue whenever the number matters","Set min and max to the real limits, not 0-100 by habit","Pick a step the user can actually land on"],"accessibility":["Label is tied to the track","Arrow keys move the thumb","The current value is announced","Native slider semantics throughout"]},"props":{"label":{"type":"string","description":"Label text","required":false},"helperText":{"type":"string","description":"Helper text shown below the slider","required":false},"error":{"type":"boolean","description":"Show error styling","default":"false","required":false},"value":{"type":"number","description":"Controlled value","required":false},"defaultValue":{"type":"number","description":"Default value for uncontrolled usage","required":false},"onChange":{"type":"function","description":"Called with new value when changed","required":false},"onValueChange":{"type":"function","description":"Alias for onChange (Radix convention): (value: number) => void","required":false},"min":{"type":"number","description":"Minimum value","default":"0","required":false},"max":{"type":"number","description":"Maximum value","default":"100","required":false},"step":{"type":"number","description":"Step interval","default":"1","required":false},"showValue":{"type":"boolean","description":"Display current value","default":"false","required":false},"showValueOnDrag":{"type":"boolean","description":"Show current value in a floating bubble while dragging the thumb","default":"false","required":false},"valueSuffix":{"type":"string","description":"Suffix after value (e.g., \"%\", \"px\")","default":"","required":false},"disabled":{"type":"boolean","description":"Disable the slider","default":"false","required":false},"name":{"type":"string","description":"","required":false},"aria-label":{"type":"string","description":"Accessible label when visible label is omitted","required":false},"aria-labelledby":{"type":"string","description":"Accessible labelled-by relationship","required":false},"aria-describedby":{"type":"string","description":"Accessible described-by relationship","required":false},"id":{"type":"string","description":"","required":false},"form":{"type":"string","description":"ID of the form that owns the hidden slider input","required":false},"largeStep":{"type":"number","description":"Larger step used for Page Up/Page Down and shift-arrow keyboard input","required":false},"onValueCommitted":{"type":"function","description":"Callback when the user commits a slider value","required":false},"thumbAlignment":{"type":"enum","description":"How the thumb is aligned at the minimum and maximum edges","required":false,"values":["center","edge","edge-client-only"]}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for precise numeric entry"},{"component":"Progress","relationship":"sibling","note":"Similar visual, but Progress is read-only"}],"variants":[{"name":"Default","description":"0-100 with no number shown.","code":"<div style={{ width: '300px' }}>\n <Slider label=\"Volume\" defaultValue={50} />\n</div>"},{"name":"With Value Display","description":"showValue prints the number opposite the label.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Brightness\"\n defaultValue={75}\n showValue\n valueSuffix=\"%\"\n />\n</div>"},{"name":"Custom Range","description":"min, max and step bound the track to real-world units.","code":"<div style={{ width: '300px', display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Slider\n label=\"Temperature\"\n min={60}\n max={80}\n step={1}\n defaultValue={72}\n showValue\n valueSuffix=\"°F\"\n />\n <Slider\n label=\"Font Size\"\n min={12}\n max={32}\n step={2}\n defaultValue={16}\n showValue\n valueSuffix=\"px\"\n />\n</div>"},{"name":"Controlled","description":"The parent owns the value and can react to every move.","code":"<ControlledSliderDemo />"},{"name":"Drag Value Bubble","description":"The number floats above the thumb only while dragging.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Mix\"\n defaultValue={40}\n showValueOnDrag\n valueSuffix=\"%\"\n />\n</div>"},{"name":"With Helper Text","description":"A line below the track explains the trade-off.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Quality\"\n defaultValue={80}\n showValue\n valueSuffix=\"%\"\n helperText=\"Higher quality increases file size\"\n />\n</div>"},{"name":"Disabled","description":"Dimmed; the thumb will not move.","code":"<div style={{ width: '300px' }}>\n <Slider\n label=\"Locked Setting\"\n defaultValue={30}\n showValue\n disabled\n />\n</div>"}],"contract":{"propsSummary":["value: number - controlled value","defaultValue: number - initial value","onChange: (value: number) => void - change handler (or onValueChange)","min/max: number - range bounds","step: number - increment size","label: string - field label","helperText: string - helper text below slider","error: boolean - error styling","showValue: boolean - display value","showValueOnDrag: boolean - show value bubble during drag","valueSuffix: string - unit suffix"],"a11yRules":["A11Y_LABEL_REQUIRED","A11Y_KEYBOARD_ACCESSIBLE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["label: string","helperText: string","error: boolean (default: false)","value: number","defaultValue: number","onChange: function","onValueChange: function","min: number (default: 0)","max: number (default: 100)","step: number (default: 1)","showValue: boolean (default: false)","showValueOnDrag: boolean (default: false)","valueSuffix: string (default: )","disabled: boolean (default: false)","name: string","aria-label: string","aria-labelledby: string","aria-describedby: string","id: string"],"sourcePath":"src/components/Slider/index.tsx","exportName":"Slider","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.141Z"},"performance":{"bundleSize":1217,"rawSize":2657,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Slider (self)","bytes":2065,"percent":78}]}},"Stack":{"filePath":"src/components/Stack/index.tsx","meta":{"name":"Stack","description":"Stacks children in a row or column with one consistent gap.","category":"layout","tags":["stack","layout","flex","spacing","responsive"],"status":"stable"},"usage":{"when":["Spacing a short row or column of elements","Any one-directional flexbox arrangement","Layouts that flip direction at a breakpoint"],"whenNot":["Two-dimensional layouts (use Grid)","Grouping buttons into one control (use ButtonGroup)","Page shell regions (use AppShell)"],"guidelines":["Set gap once on the parent instead of margins on children","Numeric gaps (1-8) map to the same spacing scale as the tokens","direction, gap, and align all accept per-breakpoint objects","Use as=\"nav\" or as=\"ul\" so the markup stays semantic","separator draws dividers without extra elements"],"accessibility":["Use semantic elements (nav, section, etc.) via \"as\" prop","Maintains source order for screen readers","No accessibility concerns with visual arrangement"]},"props":{"children":{"type":"node","description":"Elements to arrange","required":true},"direction":{"type":"union","description":"Stack direction: \"row\", \"column\", or responsive object","default":"column","required":false},"gap":{"type":"union","description":"Spacing between items: \"none\"|\"xs\"|\"sm\"|\"md\"|\"lg\"|\"xl\", a number (1-8) for space scale, or responsive object","default":"md","required":false},"align":{"type":"enum","description":"Cross-axis alignment","required":false,"values":["start","center","end","stretch","baseline"]},"justify":{"type":"enum","description":"Main-axis alignment","required":false,"values":["start","center","end","between"]},"wrap":{"type":"boolean","description":"Allow items to wrap","default":"false","required":false},"separator":{"type":"node","description":"Render a separator between children. true = default 1px line, or pass a ReactNode for custom separators.","required":false},"as":{"type":"enum","description":"HTML element to render","default":"div","required":false,"values":["div","section","nav","article","aside","header","footer","main","ul","ol"]},"className":{"type":"string","description":"","required":false},"style":{"type":"object","description":"","required":false}},"relations":[{"component":"Grid","relationship":"alternative","note":"Use Grid for complex 2D layouts"},{"component":"ButtonGroup","relationship":"sibling","note":"ButtonGroup is specialized for buttons"},{"component":"Box","relationship":"sibling","note":"Box for single-element styling"}],"variants":[{"name":"Vertical Stack","description":"Children flow top to bottom — the default.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack gap=\"sm\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">One</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Two</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Three</Box>\n</Stack>"},{"name":"Horizontal Stack","description":"Children flow left to right.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"sm\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">One</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Two</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">Three</Box>\n</Stack>"},{"name":"Gap Sizes","description":"One spacing token sets every gap in the stack.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack gap=\"lg\">\n <Stack direction=\"row\" gap=\"xs\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">xs</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">xs</Box>\n </Stack>\n <Stack direction=\"row\" gap=\"sm\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">sm</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">sm</Box>\n </Stack>\n <Stack direction=\"row\" gap=\"md\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">md</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">md</Box>\n </Stack>\n <Stack direction=\"row\" gap=\"lg\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">lg</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"md\" paddingY=\"sm\">lg</Box>\n </Stack>\n</Stack>"},{"name":"Alignment","description":"justify positions children along the main axis.","code":"import { Box } from '@/components/Box';\nimport { Stack } from '@/components/Stack';\n\n<Stack gap=\"md\">\n <Box width=\"240px\" border rounded=\"sm\" padding=\"sm\">\n <Stack direction=\"row\" gap=\"sm\" justify=\"between\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">Start</Box>\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">End</Box>\n </Stack>\n </Box>\n <Box width=\"240px\" border rounded=\"sm\" padding=\"sm\">\n <Stack direction=\"row\" gap=\"sm\" justify=\"center\">\n <Box background=\"secondary\" rounded=\"sm\" paddingX=\"sm\" paddingY=\"xs\">Centered</Box>\n </Stack>\n </Box>\n</Stack>"},{"name":"Responsive","description":"Swap direction and gap per breakpoint with an object value.","code":"<Stack\n direction={{ base: 'column', md: 'row' }}\n gap={{ base: 'sm', md: 'lg' }}\n>\n <Button variant=\"soft\">First</Button>\n <Button variant=\"soft\">Second</Button>\n <Button variant=\"soft\">Third</Button>\n</Stack>"},{"name":"With Separator","description":"Draws a divider between each child.","code":"import { Stack } from '@/components/Stack';\nimport { Text } from '@/components/Text';\n\n<Stack gap=\"md\" separator>\n <Text>Section one</Text>\n <Text>Section two</Text>\n <Text>Section three</Text>\n</Stack>"},{"name":"Semantic Element","description":"The as prop renders a real nav, section, or list element.","code":"<Stack as=\"nav\" direction=\"row\" gap=\"md\">\n <Button variant=\"ghost\" size=\"sm\">Home</Button>\n <Button variant=\"ghost\" size=\"sm\">About</Button>\n <Button variant=\"ghost\" size=\"sm\">Contact</Button>\n</Stack>"}],"contract":{"propsSummary":["direction: row|column|{responsive} - stack direction","gap: none|xs|sm|md|lg|xl|number|{responsive} - spacing (number maps to space scale)","align: start|center|end|stretch|baseline - cross-axis","justify: start|center|end|between - main-axis","wrap: boolean - allow wrapping","separator: boolean|ReactNode - divider between children","as: string - HTML element","Pass-through DOM props supported on the root (id, role, aria-*, data-*, handlers)"],"a11yRules":["A11Y_SEMANTIC_ELEMENTS"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","direction: union (default: column)","gap: union (default: md)","align: start|center|end|stretch|baseline","justify: start|center|end|between","wrap: boolean (default: false)","separator: node","as: div|section|nav|article|aside|header|footer|main|ul|ol (default: div)","className: string","style: object"],"sourcePath":"src/components/Stack/index.tsx","exportName":"Stack","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.310Z"},"performance":{"bundleSize":2214,"rawSize":5045,"complexity":"lightweight","budgetPercent":14,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"src/utils/layout-spacing.ts","bytes":2475,"percent":49},{"path":"Stack (self)","bytes":1995,"percent":40}]}},"Switch":{"filePath":"src/components/Switch/index.tsx","meta":{"name":"Switch","description":"Toggles a setting that takes effect immediately.","category":"inputs","tags":["switch","toggle","boolean","settings","preference"],"status":"stable"},"usage":{"when":["Settings that apply the moment they change","Turning a feature on or off in a settings panel","The result is visible straight away"],"whenNot":["Choices that only apply on submit (use Checkbox)","Several options at once (use a Checkbox group)","Yes/no questions in a form (use RadioGroup)","More than two states (use Select or RadioGroup)"],"guidelines":["The label names what is being turned on","On always means enabled, never the reverse","Apply the change immediately — no save button","Add helperText when the label alone is ambiguous","Stack related switches together"],"accessibility":["role=\"switch\" with aria-checked","Every switch has a label, visible or aria-label","Focus ring stays visible","Flipping it is announced"]},"props":{"checked":{"type":"boolean","description":"Whether the switch is in the on state","default":"false","required":false},"defaultChecked":{"type":"boolean","description":"Default checked state (uncontrolled)","required":false},"onCheckedChange":{"type":"function","description":"Called when the switch is toggled: (checked: boolean) => void","required":false},"onChange":{"type":"function","description":"Alias for onCheckedChange: (checked: boolean) => void","required":false},"label":{"type":"string","description":"Visible label text","required":false},"helperText":{"type":"string","description":"Helper text shown below the label (preferred)","required":false},"description":{"type":"string","description":"Deprecated alias for helperText","required":false},"disabled":{"type":"boolean","description":"Whether the switch is non-interactive","default":"false","required":false},"size":{"type":"enum","description":"Switch track size","default":"md","required":false,"values":["sm","md","lg"]},"className":{"type":"string","description":"","required":false},"name":{"type":"string","description":"","required":false},"id":{"type":"string","description":"","required":false},"aria-label":{"type":"string","description":"","required":false},"aria-labelledby":{"type":"string","description":"","required":false},"aria-describedby":{"type":"string","description":"","required":false},"form":{"type":"string","description":"","required":false},"inputRef":{"type":"union","description":"","required":false},"readOnly":{"type":"boolean","description":"","default":"false","required":false},"required":{"type":"boolean","description":"","default":"false","required":false},"uncheckedValue":{"type":"string","description":"","required":false},"value":{"type":"string","description":"","required":false}},"relations":[{"component":"Input","relationship":"sibling","note":"Input handles text/number entry; Switch handles boolean state"},{"component":"Checkbox","relationship":"alternative","note":"Use Checkbox when change requires form submission"}],"variants":[{"name":"Default Off","description":"Nothing happens until the user flips it.","code":"<StatefulSwitch label=\"Email notifications\" />","args":{"label":"Email notifications"}},{"name":"Checked","description":"Starts on; the track fills with the accent colour.","code":"<StatefulSwitch defaultChecked label=\"Dark mode\" />","args":{"defaultChecked":true,"label":"Dark mode"}},{"name":"With Helper Text","description":"Second line says what the setting actually does.","code":"<StatefulSwitch\n defaultChecked\n label=\"Auto-save\"\n helperText=\"Automatically save changes as you type\"\n/>","args":{"defaultChecked":true,"label":"Auto-save","helperText":"Automatically save changes as you type"}},{"name":"Sizes","description":"Three track sizes: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulSwitch size=\"sm\" defaultChecked label=\"Small switch\" />\n <StatefulSwitch size=\"md\" defaultChecked label=\"Medium switch (default)\" />\n <StatefulSwitch size=\"lg\" defaultChecked label=\"Large switch\" />\n</div>"},{"name":"Disabled States","description":"Locked off and locked on, both dimmed.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Switch disabled label=\"Premium feature (upgrade required)\" />\n <Switch disabled checked label=\"System managed (read-only)\" />\n</div>"},{"name":"Settings Panel","description":"Stacked switches sharing one rhythm and helper column.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>\n <StatefulSwitch\n defaultChecked\n label=\"Push notifications\"\n helperText=\"Receive push notifications on your device\"\n />\n <StatefulSwitch\n defaultChecked\n label=\"Email digest\"\n helperText=\"Weekly summary of your activity\"\n />\n <StatefulSwitch\n label=\"Marketing emails\"\n helperText=\"Product updates and promotional offers\"\n />\n</div>"}],"contract":{"propsSummary":["checked: boolean - on/off state","onCheckedChange: (checked) => void - state change handler","onChange: (checked) => void - alias for onCheckedChange","label: string - visible label text","helperText: string - helper text below label (preferred)","description: string - deprecated alias for helperText","disabled: boolean - non-interactive state","size: sm|md|lg - switch size"],"a11yRules":["A11Y_SWITCH_ROLE","A11Y_SWITCH_LABEL","A11Y_SWITCH_FOCUS","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["checked: boolean","defaultChecked: boolean","onCheckedChange: function","onChange: function","label: string","helperText: string","description: string","disabled: boolean (default: false)","size: sm|md|lg (default: md)","className: string","name: string","id: string","aria-label: string","aria-labelledby: string","aria-describedby: string"],"sourcePath":"src/components/Switch/index.tsx","exportName":"Switch","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.429Z"},"performance":{"bundleSize":1033,"rawSize":2130,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Switch (self)","bytes":1238,"percent":58},{"path":"ComponentDefaults","bytes":194,"percent":9},{"path":"src/utils/aria.ts","bytes":109,"percent":5}]}},"Table":{"filePath":"src/components/Table/index.tsx","meta":{"name":"Table","description":"Renders tabular data as a real HTML table — headers, rows, footer.","category":"display","tags":["table","semantic","html","layout"],"status":"stable"},"usage":{"when":["The data is static — read it, do not interact with it","You need real thead/tbody/tfoot semantics","The table needs a caption or a totals footer"],"whenNot":["Rows need sorting, selection, or clicking (use DataTable)","Content is a single column of items (use List)"],"guidelines":["Header cells go in Table.HeaderCell — it sets scope=\"col\" for you","Give every table a caption or aria-label; visuallyHidden keeps it off screen","Reach for density, not the deprecated size prop","Narrow viewports scroll the table sideways — keep column count low"],"accessibility":["Semantic HTML table elements (thead, tbody, tfoot, th, td)","Column headers have scope=\"col\" by default","Caption provides table description for screen readers","Supports visually-hidden caption for screen-reader-only labels"]},"props":{"size":{"type":"enum","description":"Table density","default":"md","required":false,"values":["sm","md","compact"]},"striped":{"type":"boolean","description":"Show alternating row backgrounds","default":"false","required":false},"bordered":{"type":"boolean","description":"Wrap table in a bordered container","default":"false","required":false},"wrapperClassName":{"type":"string","description":"Class name for the outer scroll/wrapper container","required":false},"wrapperProps":{"type":"object","description":"HTML attributes for the outer scroll/wrapper container","required":false},"children":{"type":"node","description":"","required":false},"density":{"type":"enum","description":"Canonical row density.","required":false,"values":["compact","regular","relaxed"]}},"relations":[{"component":"DataTable","relationship":"alternative","note":"Use DataTable for sorting, selection, and TanStack features"}],"variants":[{"name":"Default","description":"Header row plus body rows, no extra styling.","code":"<Table aria-label=\"Team members\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Role</Table.HeaderCell>\n <Table.HeaderCell>Status</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Alice Johnson</Table.Cell>\n <Table.Cell>Engineer</Table.Cell>\n <Table.Cell>Active</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Bob Smith</Table.Cell>\n <Table.Cell>Designer</Table.Cell>\n <Table.Cell>Active</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Carol Williams</Table.Cell>\n <Table.Cell>PM</Table.Cell>\n <Table.Cell>Away</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Empty","description":"Keep the headers and fill one full-width cell so the layout holds.","code":"<Table aria-label=\"Team members\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Role</Table.HeaderCell>\n <Table.HeaderCell>Status</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell colSpan={3}>No team members yet.</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Striped","description":"Row tint alternates so the eye tracks across wide rows.","code":"<Table striped aria-label=\"Inventory\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Item</Table.HeaderCell>\n <Table.HeaderCell>Category</Table.HeaderCell>\n <Table.HeaderCell>Qty</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Widget A</Table.Cell>\n <Table.Cell>Hardware</Table.Cell>\n <Table.Cell>120</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget B</Table.Cell>\n <Table.Cell>Software</Table.Cell>\n <Table.Cell>85</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget C</Table.Cell>\n <Table.Cell>Hardware</Table.Cell>\n <Table.Cell>200</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget D</Table.Cell>\n <Table.Cell>Software</Table.Cell>\n <Table.Cell>50</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Bordered","description":"A border wraps the data so it reads as one block on a busy page.","code":"<Table bordered aria-label=\"Pricing\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n <Table.HeaderCell>Features</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Basic</Table.Cell>\n <Table.Cell>$9/mo</Table.Cell>\n <Table.Cell>5 projects</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Pro</Table.Cell>\n <Table.Cell>$29/mo</Table.Cell>\n <Table.Cell>Unlimited</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Compact","description":"Tighter rows fit more data in the same height.","code":"<Table density=\"compact\" aria-label=\"Shortcuts\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Key</Table.HeaderCell>\n <Table.HeaderCell>Action</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Ctrl+S</Table.Cell>\n <Table.Cell>Save</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+Z</Table.Cell>\n <Table.Cell>Undo</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+C</Table.Cell>\n <Table.Cell>Copy</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"With Caption","description":"A visible caption titles the data for every reader.","code":"<Table aria-label=\"Q1 results\">\n <Table.Caption>Quarterly Results (Q1 2026)</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Metric</Table.HeaderCell>\n <Table.HeaderCell>Value</Table.HeaderCell>\n <Table.HeaderCell>Change</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Revenue</Table.Cell>\n <Table.Cell>$1.2M</Table.Cell>\n <Table.Cell>+15%</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Users</Table.Cell>\n <Table.Cell>24,500</Table.Cell>\n <Table.Cell>+8%</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"Screen Reader Caption","description":"The caption reaches screen readers only; the layout stays tight.","code":"<Table aria-label=\"API keys\">\n <Table.Caption visuallyHidden>API keys and last-used timestamps</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Prefix</Table.HeaderCell>\n <Table.HeaderCell>Last Used</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Deploy</Table.Cell>\n <Table.Cell>frg_live_...</Table.Cell>\n <Table.Cell>2 hours ago</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>CI</Table.Cell>\n <Table.Cell>frg_test_...</Table.Cell>\n <Table.Cell>Yesterday</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"},{"name":"With Footer","description":"Totals sit in a footer that stays separate from the data.","code":"<Table bordered aria-label=\"Expenses\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Category</Table.HeaderCell>\n <Table.HeaderCell>Amount</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Marketing</Table.Cell>\n <Table.Cell>$12,000</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Engineering</Table.Cell>\n <Table.Cell>$45,000</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Operations</Table.Cell>\n <Table.Cell>$8,000</Table.Cell>\n </Table.Row>\n </Table.Body>\n <Table.Footer>\n <Table.Row>\n <Table.Cell>Total</Table.Cell>\n <Table.Cell>$65,000</Table.Cell>\n </Table.Row>\n </Table.Footer>\n</Table>"}],"contract":{"propsSummary":["size: sm|md - table density","striped: boolean - alternating row backgrounds","bordered: boolean - bordered container","Table.Head, Table.Body, Table.Footer - section wrappers","Table.Row - table row with optional selected prop","Table.HeaderCell - th with scope=\"col\"","Table.Cell - td element","wrapperClassName/wrapperProps - customize outer scroll wrapper","Table.Caption - caption with visuallyHidden prop (hidden is deprecated alias)"],"a11yRules":["A11Y_TABLE_HEADERS","A11Y_TABLE_CAPTION"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Head","Body","Footer","Row","Cell","HeaderCell","Caption"],"commonPatterns":["<Table><Table.Head><Table.Row><Table.HeaderCell>Name</Table.HeaderCell></Table.Row></Table.Head><Table.Body><Table.Row><Table.Cell>Alice</Table.Cell></Table.Row></Table.Body></Table>"],"requiredChildren":["Head","Body","Row","Cell","HeaderCell"]},"propsSummary":["size: sm|md (default: md)","striped: boolean (default: false)","bordered: boolean (default: false)","wrapperClassName: string","wrapperProps: object","children: node"],"sourcePath":"src/components/Table/index.tsx","exportName":"Table","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.484Z"},"performance":{"bundleSize":2079,"rawSize":5160,"complexity":"lightweight","budgetPercent":14,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"src/recipes/table-chrome.ts","bytes":2772,"percent":54},{"path":"Table (self)","bytes":1801,"percent":35}]}},"TableOfContents":{"filePath":"src/components/TableOfContents/index.tsx","meta":{"name":"TableOfContents","description":"Indexes a long page and marks the section currently in view.","category":"navigation","tags":["toc","table-of-contents","navigation","sidebar","scroll-spy","headings","tree","hierarchy"],"status":"stable"},"usage":{"when":["Docs, articles, and other long reads","Reference pages with many sections","Filterable sidebars grouped by category","Anything past three headings"],"whenNot":["Pages with one or two sections","Site navigation (use Sidebar or Header)","Steps in an order (use Stepper)"],"guidelines":["Drive the active item from an IntersectionObserver scroll spy","Sub-items show by default — pass hideSubItems for a compact index","Group nests items under a labelled, optionally collapsible parent","Item ids must match the real heading ids","Items smooth-scroll — call preventDefault() in onClick to take over","Group is uncontrolled and open by default; pass open and onOpenChange to drive it","The legacy indent boolean still works; prefer Group in new code"],"accessibility":["Uses <nav aria-label=\"Table of contents\"> for landmark navigation","Active item is marked with aria-current=\"location\"","All items are links with smooth scroll behavior","Group toggle is a real <button> with aria-expanded reflecting open state","Focus-visible ring on keyboard navigation"]},"props":{"children":{"type":"node","description":"TableOfContents.Item or TableOfContents.Group elements","required":true},"label":{"type":"string","description":"Accessible label for the nav landmark","default":"Table of contents","required":false},"title":{"type":"string","description":"Visible title above the list","default":"On This Page","required":false},"hideTitle":{"type":"boolean","description":"Hide the visible title","default":"false","required":false},"hideSubItems":{"type":"boolean","description":"Hide indented items and nested groups","default":"false","required":false}},"relations":[{"component":"Breadcrumbs","relationship":"complementary","note":"Breadcrumbs show hierarchy, TOC shows page sections"},{"component":"Sidebar","relationship":"complementary","note":"Sidebar for site nav, TOC for in-page nav"},{"component":"Tabs","relationship":"alternative","note":"Tabs for switching views, TOC for scrolling to sections"}],"variants":[{"name":"Default","description":"Sections and their subsections, indented.","code":"<TableOfContents>\n <TableOfContents.Item id=\"introduction\">Introduction</TableOfContents.Item>\n <TableOfContents.Item id=\"getting-started\">Getting Started</TableOfContents.Item>\n <TableOfContents.Item id=\"installation\" indent>Installation</TableOfContents.Item>\n <TableOfContents.Item id=\"configuration\" indent>Configuration</TableOfContents.Item>\n <TableOfContents.Item id=\"api-reference\">API Reference</TableOfContents.Item>\n <TableOfContents.Item id=\"examples\">Examples</TableOfContents.Item>\n</TableOfContents>"},{"name":"Top-level Only","description":"Drops subsections when the index would crowd.","code":"<TableOfContents hideSubItems>\n <TableOfContents.Item id=\"overview\">Overview</TableOfContents.Item>\n <TableOfContents.Item id=\"basic-usage\" indent>Basic usage</TableOfContents.Item>\n <TableOfContents.Item id=\"advanced-usage\" indent>Advanced usage</TableOfContents.Item>\n <TableOfContents.Item id=\"accessibility\">Accessibility</TableOfContents.Item>\n</TableOfContents>"},{"name":"Nested Groups","description":"Collapsible categories with counts.","code":"<TableOfContents title=\"Components\">\n <TableOfContents.Item id=\"all\" active>All</TableOfContents.Item>\n <TableOfContents.Group label=\"Primitives\" trailing={<span>3</span>}>\n <TableOfContents.Item id=\"button\">Button</TableOfContents.Item>\n <TableOfContents.Item id=\"card\">Card</TableOfContents.Item>\n <TableOfContents.Item id=\"input\">Input</TableOfContents.Item>\n </TableOfContents.Group>\n <TableOfContents.Group label=\"Custom\" defaultOpen={false}>\n <TableOfContents.Item id=\"features\">Features</TableOfContents.Item>\n <TableOfContents.Item id=\"plans\">Plans</TableOfContents.Item>\n </TableOfContents.Group>\n</TableOfContents>"},{"name":"With Active Item","description":"The current section stays marked while you read.","code":"<TableOfContents>\n <TableOfContents.Item id=\"overview\">Overview</TableOfContents.Item>\n <TableOfContents.Item id=\"setup\" active>Setup</TableOfContents.Item>\n <TableOfContents.Item id=\"usage\" indent>Basic Usage</TableOfContents.Item>\n <TableOfContents.Item id=\"advanced\" indent>Advanced</TableOfContents.Item>\n <TableOfContents.Item id=\"props\">Props</TableOfContents.Item>\n <TableOfContents.Item id=\"accessibility\">Accessibility</TableOfContents.Item>\n</TableOfContents>"},{"name":"Custom Title","description":"Any heading in place of the default.","code":"<TableOfContents title=\"Contents\">\n <TableOfContents.Item id=\"chapter-1\">Chapter 1: The Beginning</TableOfContents.Item>\n <TableOfContents.Item id=\"chapter-2\">Chapter 2: The Middle</TableOfContents.Item>\n <TableOfContents.Item id=\"chapter-3\">Chapter 3: The End</TableOfContents.Item>\n</TableOfContents>"},{"name":"No Title","description":"Bare list where the surrounding layout already says enough.","code":"<TableOfContents hideTitle>\n <TableOfContents.Item id=\"section-a\">Section A</TableOfContents.Item>\n <TableOfContents.Item id=\"section-b\" active>Section B</TableOfContents.Item>\n <TableOfContents.Item id=\"section-c\">Section C</TableOfContents.Item>\n</TableOfContents>"}],"contract":{"propsSummary":["title: string - visible heading (default \"On This Page\")","hideTitle: boolean - hide the title","hideSubItems: boolean - hide indented items and nested groups (default false)","label: string - aria-label for nav landmark","TableOfContents.Item id: string - heading ID to link to","TableOfContents.Item active: boolean - highlight the current item with ink and weight","TableOfContents.Item indent: boolean - legacy depth=1 indent for flat lists; prefer Group for new code","TableOfContents.Item leading/trailing: node - optional adornments before/after the label","TableOfContents.Group label: node - header text for the group","TableOfContents.Group defaultOpen / open / onOpenChange - uncontrolled or controlled open state (default open)","TableOfContents.Group collapsible: boolean - render as a static label (default true)","TableOfContents.Group trailing/leading: node - optional adornments on the group header row","Forwards standard nav/anchor DOM props; TableOfContents.Item onClick can prevent default smooth scroll"],"a11yRules":["A11Y_NAV_LANDMARK","A11Y_ARIA_CURRENT","A11Y_ARIA_EXPANDED"]},"ai":{"compositionPattern":"compound","subComponents":["Item","Group"],"requiredChildren":["Item","Group"],"commonPatterns":["<TableOfContents>{headings.map(h => <TableOfContents.Item key={h.id} id={h.id} active={activeId === h.id} indent={h.level === 3}>{h.text}</TableOfContents.Item>)}</TableOfContents>","<TableOfContents>{groups.map(g => <TableOfContents.Group key={g.label} label={g.label} trailing={g.count}>{g.items.map(i => <TableOfContents.Item key={i.id} id={i.id} active={activeId === i.id}>{i.label}</TableOfContents.Item>)}</TableOfContents.Group>)}</TableOfContents>"]},"propsSummary":["children: node (required)","label: string (default: Table of contents)","title: string (default: On This Page)","hideTitle: boolean (default: false)","hideSubItems: boolean (default: false)"],"sourcePath":"src/components/TableOfContents/index.tsx","exportName":"TableOfContents","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.685Z"},"performance":{"bundleSize":2038,"rawSize":4560,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"TableOfContents (self)","bytes":2953,"percent":65},{"path":"Text","bytes":933,"percent":20}]}},"Tabs":{"filePath":"src/components/Tabs/index.tsx","meta":{"name":"Tabs","description":"Swaps between sibling panels without leaving the page.","category":"navigation","tags":["tabs","navigation","panels","content-switcher"],"status":"stable"},"usage":{"when":["Sibling sections of equal weight","Cutting scroll on a long page","Settings split by category","One data set seen several ways"],"whenNot":["Moving between pages (use Sidebar or header navigation)","Steps in an order (use Stepper)","Content the user compares side by side","More options than fit in a row (use Select)"],"guidelines":["One or two words per label","Order by how often each panel is used","Past five or six tabs, split the page instead","Keep panels comparable in depth","Soft rails inside cards, ghost at page level"],"accessibility":["Keyboard navigation with arrow keys","Tab panels are properly labeled","Focus management follows WAI-ARIA tabs pattern"]},"props":{"children":{"type":"node","description":"Tab list and panels (use Tabs.List, Tabs.Tab, Tabs.Panel)","required":true},"defaultValue":{"type":"string","description":"Initially active tab (uncontrolled)","required":false},"value":{"type":"string","description":"Controlled active tab value","required":false},"onValueChange":{"type":"function","description":"Called when active tab changes","required":false},"orientation":{"type":"enum","description":"Tab list orientation","default":"horizontal","required":false,"values":["horizontal","vertical"]},"variant":{"type":"enum","description":"Default chrome for Tabs.List (can be overridden on Tabs.List): ghost draws a rule under the active tab, soft is a filled rail with a selected segment","default":"ghost","required":false,"values":["ghost","soft"]},"size":{"type":"enum","description":"Tab control size. Defaults to the component-default control size.","required":false,"values":["sm","md","lg"]}},"relations":[{"component":"Select","relationship":"alternative","note":"Use Select for many options in compact space"},{"component":"Menu","relationship":"alternative","note":"Use Menu for action-based navigation"}],"variants":[{"name":"Ghost","description":"A rule tracks the active panel.","code":"<Tabs defaultValue=\"overview\" variant=\"ghost\">\n <Tabs.List>\n <Tabs.Tab value=\"overview\">Overview</Tabs.Tab>\n <Tabs.Tab value=\"analytics\">Analytics</Tabs.Tab>\n <Tabs.Tab value=\"settings\">Settings</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"overview\">\n <p>Overview content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"analytics\">\n <p>Analytics content goes here.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"settings\">\n <p>Settings content goes here.</p>\n </Tabs.Panel>\n</Tabs>"},{"name":"Soft","description":"A filled rail suits panels inside a card.","code":"<Tabs defaultValue=\"all\" variant=\"soft\">\n <Tabs.List>\n <Tabs.Tab value=\"all\">All</Tabs.Tab>\n <Tabs.Tab value=\"active\">Active</Tabs.Tab>\n <Tabs.Tab value=\"archived\">Archived</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"all\">\n <p>Showing all items.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"active\">\n <p>Showing active items only.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"archived\">\n <p>Showing archived items.</p>\n </Tabs.Panel>\n</Tabs>"},{"name":"With Disabled","description":"An unavailable panel stays visible but unreachable.","code":"<Tabs defaultValue=\"general\" variant=\"ghost\">\n <Tabs.List>\n <Tabs.Tab value=\"general\">General</Tabs.Tab>\n <Tabs.Tab value=\"security\">Security</Tabs.Tab>\n <Tabs.Tab value=\"billing\" disabled>Billing</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"general\">\n <p>General settings panel.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"security\">\n <p>Security settings panel.</p>\n </Tabs.Panel>\n</Tabs>"},{"name":"List Variant Override","description":"One list can opt out of the root's style.","code":"<Tabs defaultValue=\"overview\" variant=\"soft\">\n <Tabs.List variant=\"ghost\">\n <Tabs.Tab value=\"overview\">Overview</Tabs.Tab>\n <Tabs.Tab value=\"activity\">Activity</Tabs.Tab>\n </Tabs.List>\n <Tabs.Panel value=\"overview\">\n <p>Root sets soft, but this list overrides to ghost.</p>\n </Tabs.Panel>\n <Tabs.Panel value=\"activity\">\n <p>Per-list variant override example.</p>\n </Tabs.Panel>\n</Tabs>"}],"contract":{"propsSummary":["value: string - controlled active tab","defaultValue: string - initial active tab","onValueChange: (value) => void - tab change handler","variant: ghost|soft - default chrome for Tabs.List","Tabs.List variant?: ghost|soft - optional per-list override"],"a11yRules":["A11Y_TABS_KEYBOARD","A11Y_TABS_LABELS"]},"ai":{"compositionPattern":"compound","subComponents":["List","Tab","Panel"],"requiredChildren":["List","Panel"],"commonPatterns":["<Tabs defaultValue=\"tab1\"><Tabs.List><Tabs.Tab value=\"tab1\">{label1}</Tabs.Tab><Tabs.Tab value=\"tab2\">{label2}</Tabs.Tab></Tabs.List><Tabs.Panel value=\"tab1\">{content1}</Tabs.Panel><Tabs.Panel value=\"tab2\">{content2}</Tabs.Panel></Tabs>"]},"propsSummary":["children: node (required)","defaultValue: string","value: string","onValueChange: function","orientation: horizontal|vertical (default: horizontal)","variant: ghost|soft (default: ghost)"],"sourcePath":"src/components/Tabs/index.tsx","exportName":"Tabs","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:04.871Z"},"performance":{"bundleSize":1040,"rawSize":2471,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Tabs (self)","bytes":1640,"percent":66},{"path":"ComponentDefaults","bytes":193,"percent":8}]}},"Text":{"filePath":"src/components/Text/index.tsx","meta":{"name":"Text","description":"Applies the type scale to any text element, without hand-rolling font rules.","category":"display","tags":["text","typography","heading","paragraph","font"],"status":"stable"},"usage":{"when":["Any text that should sit on the type scale","Headings and paragraphs that need real tags","Text that must truncate or clamp"],"whenNot":["Rich or authored content (use Markdown)","Code (use CodeBlock)","Anything clickable (use Link or Button)"],"guidelines":["Pick the tag with as, the look with role (or scale) — they are separate decisions","Never skip heading levels to get a smaller heading","Color is for hierarchy and state, not decoration","Truncated text needs the full string in title or a tooltip"],"accessibility":["as keeps the document outline intact for screen readers","Clamped text still exposes its full content to assistive tech"]},"props":{"children":{"type":"node","description":"Text content","required":true},"as":{"type":"enum","description":"HTML element to render","default":"span","required":false,"values":["h1","h2","h3","h4","h5","h6","p","span","label","div","strong","em","small","mark","del","ins","sub","sup","time","address","blockquote","cite","code","abbr"]},"role":{"type":"enum","description":"Typography role: one named setting of size, weight, line height and tracking. section-label is the small list heading; eyebrow is the small semibold label above a statement. A role owns the whole setting, so scale, weight, font and letterSpacing are unavailable beside it.","required":false,"values":["caption","ui-compact","ui-standard","body-compact","body-relaxed","title-sm","title-md","title-lg","display","code","section-label","eyebrow"]},"scale":{"type":"enum","description":"Type-scale step for text with no role. 2xs (10), xs (12), sm/base (14), md (15 prose body), lg (20), xl (24), 2xl (30), 3xl (36 page title), 4xl (48 hero).","required":false,"values":["2xs","xs","sm","base","md","lg","xl","2xl","3xl","4xl"]},"weight":{"type":"enum","description":"Font weight","default":"\"normal\"","required":false,"values":["normal","medium","semibold","bold"]},"color":{"type":"enum","description":"Text color (muted is an alias for tertiary; success/warning/danger are for a run of text that carries a state on its own — prefer Badge or Alert when the state deserves a container)","default":"\"primary\"","required":false,"values":["primary","secondary","tertiary","muted","accent","success","warning","danger"]},"font":{"type":"enum","description":"Font family","default":"sans","required":false,"values":["sans","mono"]},"truncate":{"type":"boolean","description":"Truncate with ellipsis on overflow","required":false},"lineClamp":{"type":"number","description":"Number of lines before truncating (requires truncate)","required":false},"style":{"type":"object","description":"","required":false},"letterSpacing":{"type":"enum","description":"Letter-spacing preset. `\"tight\"` suits dense UI chrome labels (-0.01em);\n`\"tighter\"` suits headings and stat values (-0.02em); `\"tightest\"` suits\ndisplay numerics (-0.025em). Omit for the font's default tracking.","required":false,"values":["normal","tight","tighter","tightest"]},"tabularNums":{"type":"boolean","description":"Use tabular (fixed-width) numerals so digits align in columns. Ideal for\nstat values, tables, timestamps, and any updating number.","required":false}},"relations":[{"component":"Link","relationship":"sibling","note":"Use Link for clickable text"},{"component":"CodeBlock","relationship":"alternative","note":"Use CodeBlock for code display"},{"component":"Badge","relationship":"sibling","note":"Use Badge for labels/tags"}],"variants":[{"name":"Scale","description":"Ten steps from caption to hero, all on the same scale.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text scale=\"2xs\">Extra extra small (2xs — 10px)</Text>\n <Text scale=\"xs\">Extra small (xs — 12px)</Text>\n <Text scale=\"sm\">Small (sm — 14px)</Text>\n <Text scale=\"base\">Base size (14px)</Text>\n <Text scale=\"md\">Medium prose body (md — 15px)</Text>\n <Text scale=\"lg\">Large (lg — 20px)</Text>\n <Text scale=\"xl\">Extra large (xl — 24px)</Text>\n <Text scale=\"2xl\">Extra extra large (2xl — 30px)</Text>\n <Text scale=\"3xl\">Page title (3xl — 36px)</Text>\n <Text scale=\"4xl\">Hero display (4xl — 48px)</Text>\n</div>"},{"name":"Weights","description":"Four weights — reach past semibold only for real emphasis.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text weight=\"normal\">Normal weight</Text>\n <Text weight=\"medium\">Medium weight</Text>\n <Text weight=\"semibold\">Semibold weight</Text>\n <Text weight=\"bold\">Bold weight</Text>\n</div>"},{"name":"Colors","description":"Dimmer tones push text back; success and danger carry state.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text color=\"primary\">Primary color (default)</Text>\n <Text color=\"secondary\">Secondary color</Text>\n <Text color=\"tertiary\">Tertiary color</Text>\n <Text color=\"muted\">Muted color (alias for tertiary)</Text>\n</div>"},{"name":"Semantic Elements","description":"The as prop picks the tag, so the outline stays correct.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Text as=\"h1\" scale=\"3xl\" weight=\"semibold\">Heading 1</Text>\n <Text as=\"h2\" scale=\"xl\" weight=\"semibold\">Heading 2</Text>\n <Text as=\"h3\" scale=\"lg\" weight=\"semibold\">Heading 3</Text>\n <Text as=\"p\" scale=\"md\" color=\"secondary\">\n This is a paragraph of text that demonstrates the Text component\n with semantic paragraph element.\n </Text>\n</div>"},{"name":"Monospace","description":"Fixed width for IDs, keys, and anything meant to be compared.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <Text font=\"mono\" scale=\"sm\">const greeting = \"Hello, World!\";</Text>\n <Text font=\"mono\" scale=\"sm\" color=\"secondary\">npm install @usefragments/ui</Text>\n</div>"},{"name":"Truncation","description":"One line with an ellipsis, or clamp to a set number of lines.","code":"<div style={{ width: '200px', display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Text truncate>\n This is a very long text that will be truncated with an ellipsis when it overflows.\n </Text>\n <Text truncate lineClamp={2}>\n This text will be clamped to two lines. Any content beyond two lines\n will be hidden and replaced with an ellipsis at the end.\n </Text>\n</div>"}],"contract":{"propsSummary":["as: string - HTML element","role: caption|ui-compact|ui-standard|body-compact|body-relaxed|title-sm|title-md|title-lg|code|section-label|eyebrow - typography role (owns size, weight, line height, tracking)","scale: 2xs|xs|sm|base|md|lg|xl|2xl|3xl|4xl - type-scale step for text with no role (px: 10/12/14/14/15/20/24/30/36/48)","weight: normal|medium|semibold|bold - font weight","color: primary|secondary|tertiary|muted|accent|success|warning|danger - text color (muted = tertiary; accent = brand spend; semantic colours for inline state)","font: sans|mono - font family","truncate: boolean - enable truncation","lineClamp: number - max lines"],"a11yRules":["A11Y_HEADING_HIERARCHY","A11Y_SEMANTIC_ELEMENTS"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","as: h1|h2|h3|h4|h5|h6|p|span|label|div|strong|em|small|mark|del|ins|sub|sup|time|address|blockquote|cite|code|abbr (default: span)","role: caption|ui-compact|ui-standard|body-compact|body-relaxed|title-sm|title-md|title-lg|code|section-label|eyebrow","scale: 2xs|xs|sm|base|md|lg|xl|2xl|3xl|4xl","weight: normal|medium|semibold|bold (default: \"normal\")","color: primary|secondary|tertiary|muted|accent|success|warning|danger (default: \"primary\")","font: sans|mono (default: sans)","truncate: boolean","lineClamp: number","style: object"],"sourcePath":"src/components/Text/index.tsx","exportName":"Text","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.045Z"},"performance":{"bundleSize":847,"rawSize":1506,"complexity":"lightweight","budgetPercent":6,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Text (self)","bytes":844,"percent":56},{"path":"src/utils/env.ts","bytes":89,"percent":6}]}},"Textarea":{"filePath":"src/components/Textarea/index.tsx","meta":{"name":"Textarea","description":"Collects multi-line text for longer form content.","category":"inputs","tags":["input","text","form","multiline"],"status":"stable"},"usage":{"when":["Collecting multi-line text (comments, descriptions)","Free-form text input that may span multiple lines","Message composition fields","Code or content editing"],"whenNot":["Single-line input (use Input)","Rich text editing (use rich text editor)","Selecting from predefined options (use Select)"],"guidelines":["Set rows to match the expected answer length","Placeholder shows an example, not the label","Pair maxLength with showCharCount so the limit is visible","Use resize=\"none\" only when the layout truly cannot flex"],"accessibility":["Give every textarea a visible label","Put format hints in helperText, not the placeholder","Error text says what to fix, not just that it failed"]},"props":{"value":{"type":"string","description":"Controlled value","required":false},"defaultValue":{"type":"string","description":"Default value for uncontrolled usage","required":false},"placeholder":{"type":"string","description":"Placeholder text","required":false},"rows":{"type":"number","description":"Number of visible text rows","default":"3","required":false},"minRows":{"type":"number","description":"Minimum number of rows when auto-resizing","required":false},"maxRows":{"type":"number","description":"Maximum number of rows when auto-resizing","required":false},"resize":{"type":"enum","description":"Resize behavior","default":"vertical","required":false,"values":["none","vertical","horizontal","both"]},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"disabled":{"type":"boolean","description":"Disabled state","default":"false","required":false},"error":{"type":"boolean","description":"Error state","default":"false","required":false},"showCharCount":{"type":"boolean","description":"Show character counter when maxLength is set","default":"false","required":false},"label":{"type":"string","description":"Label text above the textarea","required":false},"helperText":{"type":"string","description":"Helper text below the textarea","required":false},"onChange":{"type":"function","description":"Called when the textarea value changes","required":false},"onValueChange":{"type":"function","description":"Value-first change callback alias: (value: string) => void","required":false},"onBlur":{"type":"function","description":"Called when textarea loses focus","required":false},"onFocus":{"type":"function","description":"Called when textarea receives focus","required":false},"name":{"type":"string","description":"Form field name","required":false},"maxLength":{"type":"number","description":"Maximum character length","required":false},"required":{"type":"boolean","description":"Required field","required":false},"aria-label":{"type":"string","description":"Accessible label for no-visible-label usage","required":false},"aria-labelledby":{"type":"string","description":"Accessible labelled-by relationship","required":false},"aria-describedby":{"type":"string","description":"Accessible described-by relationship","required":false},"rootProps":{"type":"object","description":"HTML attributes applied to the wrapper element","required":false},"className":{"type":"string","description":"Wrapper class name","required":false},"style":{"type":"object","description":"Wrapper styles","required":false}},"relations":[{"component":"Input","relationship":"alternative","note":"Use Input for single-line text"}],"variants":[{"name":"Default","description":"Three rows, draggable from the bottom-right corner.","code":"<Textarea\n label=\"Description\"\n placeholder=\"Enter a description...\"\n/>"},{"name":"With Helper Text","description":"Supporting text sits under the box.","code":"<Textarea\n label=\"Bio\"\n placeholder=\"Tell us about yourself...\"\n helperText=\"Max 500 characters\"\n maxLength={500}\n/>"},{"name":"Error State","description":"Red border, and helperText becomes the reason.","code":"<Textarea\n label=\"Comments\"\n placeholder=\"Add your comments...\"\n error\n helperText=\"This field is required\"\n/>"},{"name":"Disabled","description":"Dimmed and unfocusable.","code":"<Textarea\n label=\"Notes\"\n placeholder=\"Cannot edit...\"\n disabled\n/>"},{"name":"Custom Rows","description":"rows={6} doubles the visible height before scrolling.","code":"<Textarea\n label=\"Long Description\"\n placeholder=\"Enter detailed information...\"\n rows={6}\n/>"},{"name":"Sizes","description":"Three heights: sm, md, lg.","code":"<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '400px' }}>\n <Textarea label=\"Small\" size=\"sm\" placeholder=\"Small textarea\" />\n <Textarea label=\"Medium\" size=\"md\" placeholder=\"Medium textarea\" />\n <Textarea label=\"Large\" size=\"lg\" placeholder=\"Large textarea\" />\n</div>"},{"name":"Fixed Height","description":"resize=\"none\" removes the drag handle so the box stays put.","code":"<Textarea\n label=\"Notes\"\n placeholder=\"Add notes...\"\n resize=\"none\"\n/>"},{"name":"With Character Counter","description":"Live count against maxLength sits below the box.","code":"<Textarea\n label=\"Bio\"\n placeholder=\"Tell us about yourself...\"\n maxLength={200}\n showCharCount\n/>"}],"contract":{"propsSummary":["value: string - controlled value","rows: number - visible rows (default: 3)","label: string - label text","size: sm|md|lg (default: md)","error: boolean - error state","showCharCount: boolean - show character counter (requires maxLength)","disabled: boolean - disabled state","resize: none|vertical|horizontal|both","onValueChange: (value: string) => void - value-first change callback alias","rootProps: HTMLAttributes<HTMLDivElement> - wrapper element props","...native textarea attributes are supported (readOnly, autoComplete, maxLength, onKeyDown, etc.)"],"a11yRules":["A11Y_LABEL_REQUIRED"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["value: string","defaultValue: string","placeholder: string","rows: number (default: 3)","minRows: number","maxRows: number","resize: none|vertical|horizontal|both (default: vertical)","size: sm|md|lg (default: md)","disabled: boolean (default: false)","error: boolean (default: false)","showCharCount: boolean (default: false)","label: string","helperText: string","onChange: function","onValueChange: function","onBlur: function","onFocus: function","name: string","maxLength: number","required: boolean","aria-label: string","aria-labelledby: string","aria-describedby: string","rootProps: object","className: string","style: object"],"sourcePath":"src/components/Textarea/index.tsx","exportName":"Textarea","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.217Z"},"performance":{"bundleSize":1260,"rawSize":2623,"complexity":"lightweight","budgetPercent":8,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Textarea (self)","bytes":1725,"percent":66},{"path":"ComponentDefaults","bytes":198,"percent":8},{"path":"src/utils/aria.ts","bytes":110,"percent":4}]}},"Theme":{"filePath":"src/components/Theme/index.tsx","meta":{"name":"Theme","description":"Utility provider that gives everything below it a light, dark, or system color mode.","category":"utilities","tags":["theme","dark-mode","light-mode","provider","toggle"],"status":"stable"},"usage":{"when":["An app needs light and dark modes","The user's choice should survive a reload","You want to honour the OS setting by default"],"whenNot":["Recoloring one component (use its props)","A single one-off color swap (use a CSS variable)"],"guidelines":["ThemeProvider goes at the root, once","useTheme reads and sets the mode anywhere below it","storageKey renames the localStorage entry","attribute=\"class\" if your CSS keys off .dark instead of data-theme","ThemeProvider renders no chrome of its own; Theme.Toggle is the segmented light/dark/system control and Theme.Button the single icon button for tight toolbars"],"accessibility":["The toggle's label names the mode it is in","System mode follows prefers-color-scheme"]},"props":{"children":{"type":"node","description":"Application content","required":true},"defaultMode":{"type":"enum","description":"Default theme mode for uncontrolled usage","default":"system","required":false,"values":["light","dark","system"]},"defaultTheme":{"type":"enum","description":"","required":false,"values":["light","dark","system"]},"mode":{"type":"enum","description":"Controlled theme mode","required":false,"values":["light","dark","system"]},"onModeChange":{"type":"function","description":"Callback when mode changes","required":false},"storageKey":{"type":"string","description":"localStorage key for persistence","default":"fui-theme","required":false},"attribute":{"type":"enum","description":"How to apply theme to DOM","default":"data-theme","required":false,"values":["data-theme","class"]},"componentDefaults":{"type":"object","description":"Default primitive component behavior for the subtree.","required":false}},"relations":[{"component":"AppShell","relationship":"sibling","note":"ThemeProvider typically wraps AppShell"}],"variants":[{"name":"Default","description":"Wrap the app once; every token below resolves to the active mode.","code":"<ThemeProvider defaultMode=\"system\">\n <div\n style={{\n padding: '16px',\n borderRadius: '8px',\n background: 'var(--fui-bg-elevated)',\n color: 'var(--fui-text-primary)',\n }}\n >\n Everything inside follows the system color scheme.\n </div>\n</ThemeProvider>"},{"name":"With Toggle","description":"The toggle cycles light, dark, then back to system.","code":"<ThemeProvider defaultMode=\"light\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n <ThemeToggle />\n <span>Click to cycle themes</span>\n </div>\n</ThemeProvider>"},{"name":"Toggle Sizes","description":"Three sizes so the control fits whatever bar holds it.","code":"<ThemeProvider defaultMode=\"light\">\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n <ThemeToggle size=\"sm\" />\n <ThemeToggle size=\"md\" />\n <ThemeToggle size=\"lg\" />\n </div>\n</ThemeProvider>"},{"name":"Theme Button","description":"A single icon button for toolbars with no room to spare.","code":"<ThemeProvider defaultMode=\"system\">\n <ThemeButton aria-label=\"Switch color mode\" />\n</ThemeProvider>"}],"contract":{"propsSummary":["defaultMode: light|dark|system - initial theme mode","mode: light|dark|system - controlled mode","onModeChange: (mode) => void - change handler","attribute: data-theme|class - DOM theme attribute","Theme.Toggle size: sm|md|lg - segmented light/dark/system control","Theme.Toggle forwards div DOM props to the button group root","Theme.Button size: sm|md|lg - single ghost icon button that flips light and dark, built on IconButton"],"a11yRules":["A11Y_TARGET_SIZE_MIN"]},"propsSummary":["children: node (required)","defaultMode: light|dark|system","defaultTheme: light|dark|system","mode: light|dark|system","onModeChange: function","storageKey: string (default: fui-theme)","attribute: data-theme|class (default: data-theme)","Theme.Toggle size: sm|md|lg","Theme.Button size: sm|md|lg"],"sourcePath":"src/components/Theme/index.tsx","exportName":"ThemeProvider","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.406Z"},"ai":{"subComponents":["Root","Provider","Toggle","Button","useTheme"],"compositionPattern":"compound"},"performance":{"bundleSize":3396,"rawSize":8460,"complexity":"lightweight","budgetPercent":22,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ThemeToggle (self)","bytes":3950,"percent":47},{"path":"(other)","bytes":3237,"percent":38},{"path":"ComponentDefaults","bytes":393,"percent":5},{"path":"Theme","bytes":192,"percent":2}]}},"ThinkingIndicator":{"filePath":"src/components/ThinkingIndicator/index.tsx","meta":{"name":"ThinkingIndicator","description":"Shows that an AI response is being generated.","category":"ai","tags":["thinking","loading","ai","processing","indicator","animation"],"status":"stable"},"usage":{"when":["A model is working on a request","Async AI work that would otherwise look frozen","Multi-stage tasks worth showing stage by stage","The moment before streaming starts"],"whenNot":["Ordinary loading (use Progress or Skeleton)","Form submission (use the Button loading state)","Whole-page loading (use Progress or Skeleton)"],"guidelines":["active controls whether it shows at all","dots suits chat; spinner suits a discrete action","Turn on showElapsed once waits run past a few seconds","Use steps for tool calls, research, and other staged work"],"accessibility":["Uses role=\"status\" and aria-live=\"polite\"","Provides aria-label for screen readers","Animations respect prefers-reduced-motion","Elapsed time uses tabular numbers for stability"]},"props":{"active":{"type":"boolean","description":"Whether thinking is active","default":"true","required":false},"label":{"type":"string","description":"Status text","default":"Thinking...","required":false},"kind":{"type":"enum","description":"Animation style","default":"dots","required":false,"values":["dots","pulse","spinner"]},"showElapsed":{"type":"boolean","description":"Show elapsed time","default":"false","required":false},"steps":{"type":"array","description":"Multi-step progress array","required":false}},"relations":[{"component":"Message","relationship":"sibling","note":"Show ThinkingIndicator while waiting for assistant message"},{"component":"ConversationList","relationship":"parent","note":"Typically placed at bottom of ConversationList"},{"component":"Progress","relationship":"alternative","note":"Use Progress for determinate progress"}],"variants":[{"name":"Dots (Default)","description":"Three dots bounce in sequence; the quietest option.","code":"<ThinkingIndicator kind=\"dots\" label=\"Thinking...\" />"},{"name":"Pulse","description":"A single ring breathes in place.","code":"<ThinkingIndicator kind=\"pulse\" label=\"Processing...\" />"},{"name":"Spinner","description":"A rotating arc, for work with a definite end.","code":"<ThinkingIndicator kind=\"spinner\" label=\"Loading...\" />"},{"name":"With Elapsed Time","description":"A live counter reassures the reader during long waits.","code":"<ThinkingIndicator\n kind=\"dots\"\n label=\"Generating response...\"\n showElapsed\n/>"},{"name":"Multi-Step Progress","description":"Finished, running, and queued stages read at a glance.","code":"<ThinkingIndicator\n kind=\"spinner\"\n label=\"Working...\"\n steps={[\n { id: '1', label: 'Analyzing request', status: 'complete' },\n { id: '2', label: 'Searching knowledge base', status: 'pending' },\n { id: '3', label: 'Generating response', status: 'idle' },\n ]}\n/>"},{"name":"With Error Step","description":"A failed stage turns red while the next one retries.","code":"<ThinkingIndicator\n kind=\"spinner\"\n label=\"Retrying...\"\n steps={[\n { id: '1', label: 'Connecting to API', status: 'complete' },\n { id: '2', label: 'Fetching data', status: 'error' },\n { id: '3', label: 'Retrying with fallback', status: 'pending' },\n ]}\n/>"},{"name":"Custom Label","description":"Name the actual task instead of a generic status.","code":"<ThinkingIndicator\n kind=\"dots\"\n label=\"Claude is writing code...\"\n/>"}],"contract":{"propsSummary":["active: boolean - whether indicator is visible (default: true)","label: string - status text (default: \"Thinking...\")","kind: \"dots\" | \"pulse\" | \"spinner\" - animation style","steps[].status: \"idle\" | \"pending\" | \"streaming\" | \"complete\" | \"error\" - shared lifecycle axis","showElapsed: boolean - show elapsed time","steps: ThinkingStep[] - multi-step progress"],"a11yRules":["A11Y_ARIA_LIVE","A11Y_MOTION_PREFERENCE"]},"ai":{"compositionPattern":"compound","subComponents":["Steps","Step"]},"propsSummary":["active: boolean (default: true)","label: string (default: Thinking...)","kind: dots|pulse|spinner (default: dots)","showElapsed: boolean (default: false)","steps: array"],"sourcePath":"src/components/ThinkingIndicator/index.tsx","exportName":"ThinkingIndicator","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:05.747Z"},"performance":{"bundleSize":1922,"rawSize":5284,"complexity":"lightweight","budgetPercent":13,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ThinkingIndicator (self)","bytes":2560,"percent":48},{"path":"Loading","bytes":2026,"percent":38}]}},"Toast":{"filePath":"src/components/Toast/index.tsx","meta":{"name":"Toast","description":"Briefly reports what just happened, without blocking the page.","category":"feedback","tags":["notification","alert","message","feedback"],"status":"stable"},"usage":{"when":["Confirming an action landed","Reporting whether an operation worked","News the user does not have to act on","Messages that can disappear on their own"],"whenNot":["Errors the user must resolve — use Dialog","Anything that must stay on screen — use Alert","Field-level validation — use form error states","Site-wide notices — use a banner"],"guidelines":["One sentence, plus a title if it helps","Match the tone to what actually happened","Auto-dismiss in three to five seconds","Anything with an action needs a manual dismiss too","Two or three on screen at once, no more","useToast() helpers take (title, description) or an options object for action, duration, and id"],"accessibility":["role=\"alert\" for anything the user must not miss","Leave enough time to read it","Never let colour be the only signal","Give the dismiss button a real label"]},"props":{"onDismiss":{"type":"function","description":"Callback when toast should be dismissed","required":false},"title":{"type":"string","description":"Toast title","required":false},"description":{"type":"string","description":"Additional message content","required":false},"tone":{"type":"enum","description":"Colour on the shared status ramp; neutral is the plain notification. The useToast().error helper sets tone=\"danger\".","default":"neutral","required":false,"values":["neutral","success","danger","warning","info"]},"duration":{"type":"number","description":"Auto-dismiss duration in ms (0 = no auto-dismiss)","default":8000,"required":false},"action":{"type":"object","description":"Optional action button { label, onClick }","required":false},"id":{"type":"string","description":"","required":false},"onPause":{"type":"function","description":"Callback when auto-dismiss timer should pause","required":false},"onResume":{"type":"function","description":"Callback when auto-dismiss timer should resume","required":false}},"relations":[{"component":"Alert","relationship":"alternative","note":"Use Alert for persistent inline messages"},{"component":"Dialog","relationship":"alternative","note":"Use Dialog for messages requiring user action"}],"variants":[{"name":"Default","description":"Neutral message with a title and one line under it.","code":"<Toast\n title=\"Draft saved\"\n description=\"We will keep it until you publish.\"\n/>"},{"name":"Tones","description":"Icon and colour together carry the outcome.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"sm\">\n <Toast\n title=\"Success!\"\n description=\"Your changes have been saved.\"\n tone=\"success\"\n />\n <Toast\n title=\"Error\"\n description=\"Failed to save changes. Please try again.\"\n tone=\"danger\"\n />\n <Toast\n title=\"Warning\"\n description=\"This action cannot be undone.\"\n tone=\"warning\"\n />\n <Toast\n title=\"New update\"\n description=\"Version 2.0 is now available.\"\n tone=\"info\"\n />\n</Stack>"},{"name":"With Action","description":"One-tap way back from something destructive.","code":"<Toast\n title=\"File deleted\"\n description=\"The file has been moved to trash.\"\n action={{\n label: 'Undo',\n onClick: () => {},\n }}\n/>"},{"name":"Dismissible","description":"onDismiss adds a close button for longer messages.","code":"<Toast\n title=\"Export running\"\n description=\"We will email you when the file is ready.\"\n tone=\"info\"\n onDismiss={() => {}}\n/>"}],"contract":{"propsSummary":["title: string - toast title","description: string - additional message","tone: neutral|success|danger|warning|info","duration: number - ms before auto-dismiss","action: { label, onClick } - optional action","ToastInput (useToast): optional id for deterministic creation/replacement flows","useToast().success/error/warning/info: (title, description?) or ({ title, description, action, duration, id })"],"a11yRules":["A11Y_ALERT_ROLE","A11Y_TARGET_SIZE_MIN"]},"ai":{"compositionPattern":"compound","subComponents":["Provider"]},"propsSummary":["onDismiss: function","title: string","description: string","tone: neutral|success|danger|warning|info (default: neutral)","duration: number","action: object","id: string","onPause: function","onResume: function"],"sourcePath":"src/components/Toast/index.tsx","exportName":"Toast","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.259Z"},"performance":{"bundleSize":3236,"rawSize":8780,"complexity":"lightweight","budgetPercent":21,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Toast (self)","bytes":5496,"percent":63},{"path":"Button","bytes":1967,"percent":22},{"path":"IconButton","bytes":682,"percent":8}]}},"ToggleGroup":{"filePath":"src/components/ToggleGroup/index.tsx","meta":{"name":"ToggleGroup","description":"Picks exactly one option from a short row of toggle buttons.","category":"actions","tags":["toggle","group","fragmented","control","tabs","switch"],"status":"stable"},"usage":{"when":["Switching between mutually exclusive views or modes","Choosing one of two to five options","View switchers and segmented filters"],"whenNot":["More than one can be picked — use a Checkbox group","More than five options — use Select or RadioGroup","Moving between pages — use Tabs","A single on/off — use Switch"],"guidelines":["Two to five items","Labels short enough to scan in one pass","Icons work for well-known modes like grid and list","soft for an inset tonal rail, ghost for an open filter cluster, outline for connected segments","Keep targets at least 24px on touch"],"accessibility":["The group is a radiogroup; each item is a radio with aria-checked","Arrow keys move between items, Tab enters and leaves the group","Icon-only items still need an aria-label","Focus stays visible on the selected item"]},"props":{"value":{"type":"string","description":"Currently selected value","required":false},"defaultValue":{"type":"string","description":"Initial selected value (uncontrolled)","required":false},"onChange":{"type":"function","description":"Called with new value when selection changes","required":false},"onValueChange":{"type":"function","description":"Alias for onChange (Radix convention): (value: string) => void","required":false},"children":{"type":"node","description":"ToggleGroup.Item components","required":true},"variant":{"type":"enum","description":"Chrome: soft is the filled rail, ghost the open pill cluster, outline the connected bordered segments","default":"soft","required":false,"values":["soft","ghost","outline"]},"size":{"type":"enum","description":"Size variant","default":"\"md\"","required":false,"values":["sm","md","lg"]},"gap":{"type":"enum","description":"Gap between items in the ghost variant. Connected variants intentionally ignore gaps.","required":false,"values":["sm","none","xs"]},"selectionMode":{"type":"enum","description":"Selection behavior","default":"single","required":false,"values":["single"]}},"relations":[{"component":"RadioGroup","relationship":"alternative","note":"RadioGroup for form-style single selection"},{"component":"Tabs","relationship":"alternative","note":"Tabs for content panel switching"},{"component":"Switch","relationship":"sibling","note":"Switch for single on/off control"}],"variants":[{"name":"Default","description":"Inset tonal rail; the selected segment lifts.","code":"<ToggleGroup value={value} onChange={setValue}>\n <ToggleGroup.Item value=\"left\">Left</ToggleGroup.Item>\n <ToggleGroup.Item value=\"center\">Center</ToggleGroup.Item>\n <ToggleGroup.Item value=\"right\">Right</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Ghost","description":"Detached rounded buttons for open filter clusters.","code":"<ToggleGroup value={value} onChange={setValue} variant=\"ghost\">\n <ToggleGroup.Item value=\"all\">All</ToggleGroup.Item>\n <ToggleGroup.Item value=\"active\">Active</ToggleGroup.Item>\n <ToggleGroup.Item value=\"completed\">Completed</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Outline","description":"Bordered segments sharing one continuous edge.","code":"<ToggleGroup value={value} onChange={setValue} variant=\"outline\">\n <ToggleGroup.Item value=\"day\">Day</ToggleGroup.Item>\n <ToggleGroup.Item value=\"week\">Week</ToggleGroup.Item>\n <ToggleGroup.Item value=\"month\">Month</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Uncontrolled","description":"defaultValue when nothing outside needs the selection.","code":"<ToggleGroup defaultValue=\"list\">\n <ToggleGroup.Item value=\"grid\">Grid</ToggleGroup.Item>\n <ToggleGroup.Item value=\"list\">List</ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Sizes","description":"sm for toolbars, lg where the rail anchors a page.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\" align=\"start\">\n <ToggleGroup defaultValue=\"a\" size=\"sm\">\n <ToggleGroup.Item value=\"a\">Small</ToggleGroup.Item>\n <ToggleGroup.Item value=\"b\">Rail</ToggleGroup.Item>\n </ToggleGroup>\n <ToggleGroup defaultValue=\"a\" size=\"md\">\n <ToggleGroup.Item value=\"a\">Medium</ToggleGroup.Item>\n <ToggleGroup.Item value=\"b\">Rail</ToggleGroup.Item>\n </ToggleGroup>\n <ToggleGroup defaultValue=\"a\" size=\"lg\">\n <ToggleGroup.Item value=\"a\">Large</ToggleGroup.Item>\n <ToggleGroup.Item value=\"b\">Rail</ToggleGroup.Item>\n </ToggleGroup>\n</Stack>"},{"name":"View Switcher","description":"Icon-only modes, each named for screen readers.","code":"import { SquaresFour as GridIcon, ListBullets as ListIcon } from '@phosphor-icons/react';\n\n<ToggleGroup value={view} onChange={setView} size=\"sm\">\n <ToggleGroup.Item value=\"grid\" aria-label=\"Grid view\">\n <GridIcon aria-hidden />\n </ToggleGroup.Item>\n <ToggleGroup.Item value=\"list\" aria-label=\"List view\">\n <ListIcon aria-hidden />\n </ToggleGroup.Item>\n</ToggleGroup>"},{"name":"Disabled Item","description":"One option locked out; the rest stay reachable.","code":"<ToggleGroup value={value} onChange={setValue}>\n <ToggleGroup.Item value=\"basic\">Basic</ToggleGroup.Item>\n <ToggleGroup.Item value=\"pro\">Pro</ToggleGroup.Item>\n <ToggleGroup.Item value=\"enterprise\" disabled>Enterprise</ToggleGroup.Item>\n</ToggleGroup>"}],"contract":{"propsSummary":["value?: string - controlled selected value","defaultValue?: string - initial selected value (uncontrolled)","onChange: (value: string) => void - change handler (or onValueChange)","children: ToggleGroup.Item[] - toggle items","variant: soft|ghost|outline - chrome (soft rail, ghost cluster, outline segments)","size: sm|md|lg - size variant","gap: none|xs|sm - ghost spacing (xs by default; connected variants remain gapless)","selectionMode: single (default: single)"],"a11yRules":["A11Y_GROUP_ROLE","A11Y_KEYBOARD_ACCESSIBLE"]},"ai":{"compositionPattern":"compound","subComponents":["Item"],"commonPatterns":["<ToggleGroup>\n <ToggleGroup.Item>...</ToggleGroup.Item>\n</ToggleGroup>"],"requiredChildren":["Item"]},"propsSummary":["value: string","defaultValue: string","onChange: function","onValueChange: function","children: node (required)","variant: soft|ghost|outline (default: soft)","size: sm|md|lg (default: md)","gap: sm|none|xs (default: xs for ghost; none otherwise)","selectionMode: single (default: single)"],"sourcePath":"src/components/ToggleGroup/index.tsx","exportName":"ToggleGroup","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:07.233Z"},"performance":{"bundleSize":1431,"rawSize":2911,"complexity":"lightweight","budgetPercent":9,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"ToggleGroup (self)","bytes":2056,"percent":71},{"path":"ComponentDefaults","bytes":193,"percent":7}]}},"Tooltip":{"filePath":"src/components/Tooltip/index.tsx","meta":{"name":"Tooltip","description":"Shows a one-line hint when a control is hovered or focused.","category":"overlays","tags":["tooltip","hint","help","hover","contextual"],"status":"stable"},"usage":{"when":["Naming icon-only buttons","Showing text that had to be truncated","Surfacing a keyboard shortcut","One line of help, no more"],"whenNot":["Help longer than a line — use Popover","Anything the user must not miss — use Alert","Content they need to click — use Popover or Menu","Touch-first screens, where there is no hover"],"guidelines":["Under 80 characters","Sentence case, no trailing period","Never just repeat the visible label","Always leave a non-hover path to the same information","contentProps sets attributes and styling on the popup"],"accessibility":["Opens on keyboard focus, not only hover","The open delay stops tooltips flashing while the pointer crosses the screen","Do not put anything critical here — treat it as a hint, not a label"]},"props":{"children":{"type":"element","description":"The element that triggers the tooltip","required":true},"content":{"type":"node","description":"Content to display in the tooltip","required":true},"side":{"type":"enum","description":"Which side to show the tooltip","default":"top","required":false,"values":["top","bottom","left","right"]},"align":{"type":"enum","description":"Alignment along the side","default":"center","required":false,"values":["start","center","end"]},"sideOffset":{"type":"number","description":"Distance from trigger in pixels","default":"6","required":false},"delay":{"type":"number","description":"Delay before showing (ms)","default":"400","required":false},"closeDelay":{"type":"number","description":"Delay before hiding (ms)","default":"0","required":false},"disabled":{"type":"boolean","description":"Disable the tooltip","default":"false","required":false},"arrow":{"type":"boolean","description":"Show arrow pointing to trigger","default":"true","required":false},"open":{"type":"boolean","description":"Controlled open state","required":false},"defaultOpen":{"type":"boolean","description":"Default open state","default":"false","required":false},"onOpenChange":{"type":"function","description":"Callback when open state changes","required":false},"contentProps":{"type":"object","description":"Props forwarded to the tooltip popup element (preferred way to pass popup attrs/className/style)","required":false},"style":{"type":"object","description":"","required":false},"closeOnClick":{"type":"boolean","description":"Whether clicking the trigger closes the tooltip.","default":"false","required":false}},"relations":[{"component":"Popover","relationship":"alternative","note":"Use Popover for interactive or longer content"},{"component":"Alert","relationship":"alternative","note":"Use Alert for critical information that must be visible"}],"variants":[{"name":"Default","description":"Appears after a short delay above the trigger.","code":"<Tooltip content=\"Save your changes\">\n <Button>Save</Button>\n</Tooltip>"},{"name":"Positions","description":"Four sides; it flips if the edge is too close.","code":"import { Stack } from '@/components/Stack';\n\n<Stack direction=\"row\" gap=\"md\" align=\"center\" wrap>\n <Tooltip content=\"Top tooltip\" side=\"top\">\n <Button variant=\"soft\">Top</Button>\n </Tooltip>\n <Tooltip content=\"Bottom tooltip\" side=\"bottom\">\n <Button variant=\"soft\">Bottom</Button>\n </Tooltip>\n <Tooltip content=\"Left tooltip\" side=\"left\">\n <Button variant=\"soft\">Left</Button>\n </Tooltip>\n <Tooltip content=\"Right tooltip\" side=\"right\">\n <Button variant=\"soft\">Right</Button>\n </Tooltip>\n</Stack>"},{"name":"With Shortcut","description":"Spells out the key combination the icon implies.","code":"<Tooltip content=\"Undo (Ctrl+Z)\">\n <Button variant=\"ghost\">Undo</Button>\n</Tooltip>"},{"name":"No Arrow","description":"Drops the pointer for tooltips packed into dense chrome.","code":"<Tooltip content=\"No arrow on this one\" arrow={false}>\n <Button variant=\"soft\">Arrowless</Button>\n</Tooltip>"},{"name":"With Content Props","description":"contentProps lands on the popup element itself.","code":"<Tooltip\n content=\"Styled through contentProps\"\n contentProps={{ id: 'custom-tooltip-popup' }}\n>\n <Button variant=\"soft\">Custom popup</Button>\n</Tooltip>"}],"contract":{"propsSummary":["content: ReactNode - tooltip content","side: top|bottom|left|right - position","delay: number - show delay in ms (default: 400)","arrow: boolean - show arrow (default: true)","contentProps: HTMLAttributes<HTMLDivElement> - popup element props"],"a11yRules":["A11Y_TOOLTIP_FOCUS","A11Y_TOOLTIP_ROLE"]},"ai":{"compositionPattern":"compound","subComponents":["Root","Provider"]},"propsSummary":["children: element (required)","content: node (required)","side: top|bottom|left|right (default: top)","align: start|center|end (default: center)","sideOffset: number (default: 6)","delay: number","closeDelay: number","disabled: boolean (default: false)","arrow: boolean (default: true)","open: boolean","defaultOpen: boolean","onOpenChange: function","contentProps: object","style: object"],"sourcePath":"src/components/Tooltip/index.tsx","exportName":"Tooltip","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:07.058Z"},"performance":{"bundleSize":1069,"rawSize":2053,"complexity":"lightweight","budgetPercent":7,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"Tooltip (self)","bytes":1443,"percent":70}]}},"VisuallyHidden":{"filePath":"src/components/VisuallyHidden/index.tsx","meta":{"name":"VisuallyHidden","description":"Keeps text in the accessibility tree while taking it off the screen.","category":"utilities","tags":["accessibility","a11y","screen-reader","hidden","sr-only"],"status":"stable"},"usage":{"when":["An icon-only control needs a name","A link's text is vague out of context","A skip link needs to hide until focused"],"whenNot":["Nobody should see or hear it (render nothing)","The content is just collapsed (use aria-expanded)"],"guidelines":["Every icon-only button gets one","Say the action, not the icon: \"Search\", not \"magnifier\"","Keep it short — it is read aloud","Visible text beats hidden text whenever there is room"],"accessibility":["Screen readers announce it; the layout never moves","Focusable children inside still receive focus","Required for WCAG 2.1 on icon-only controls"]},"props":{"children":{"type":"node","description":"Content to hide visually","required":true},"as":{"type":"enum","description":"HTML element to render","default":"span","required":false,"values":["span","div"]}},"relations":[{"component":"Button","relationship":"child","note":"Use inside icon-only buttons for accessible labels"},{"component":"Icon","relationship":"sibling","note":"Pair with icons to provide text alternatives"}],"variants":[{"name":"Icon Button Label","description":"The only thing telling a screen reader what this button does.","code":"<button style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n border: '1px solid var(--fui-border-default)',\n borderRadius: '8px',\n background: 'var(--fui-color-surface-primary)',\n cursor: 'pointer'\n}}>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n <VisuallyHidden>Search</VisuallyHidden>\n</button>"},{"name":"Supplementary Text","description":"Gives a vague link the context sighted readers get from layout.","code":"<a href=\"#\" style={{ color: 'var(--fui-color-accent)' }}>\n Read more\n <VisuallyHidden> about our accessibility features</VisuallyHidden>\n</a>"},{"name":"Skip Link","description":"Hidden until focused, then it jumps keyboard users past the nav.","code":"<div>\n <VisuallyHidden as=\"div\">\n <a\n href=\"#main-content\"\n style={{\n position: 'absolute',\n padding: '8px 16px',\n background: 'var(--fui-color-accent)',\n color: 'white'\n }}\n >\n Skip to main content\n </a>\n </VisuallyHidden>\n <p style={{ color: 'var(--fui-color-text-tertiary)', fontSize: '14px' }}>\n (Screen reader only: \"Skip to main content\" link)\n </p>\n</div>"}],"contract":{"propsSummary":["children: ReactNode - hidden text (required)","as: span|div - HTML element","Forwards standard DOM props (id, aria-*, data-*, className, handlers)"],"a11yRules":["A11Y_SR_ONLY","A11Y_ICON_LABEL"]},"ai":{"compositionPattern":"compound","subComponents":["Root"]},"propsSummary":["children: node (required)","as: span|div (default: span)"],"sourcePath":"src/components/VisuallyHidden/index.tsx","exportName":"VisuallyHidden","provenance":{"source":"migrated","verified":false,"frameworkSupport":"native","extractedAt":"2026-03-13T23:19:06.625Z"},"performance":{"bundleSize":535,"rawSize":894,"complexity":"lightweight","budgetPercent":3,"overBudget":false,"measuredAt":"2026-09-07T16:46:04.054Z","imports":[{"path":"VisuallyHidden (self)","bytes":311,"percent":35}]}}},"blocks":{"Activity Feed":{"filePath":"src/blocks/ActivityFeed.block.ts","name":"Activity Feed","description":"Timeline of user activities with avatars and timestamps","category":"dashboard","components":["Card","Stack","Text","Avatar"],"code":"const activities = [\n { id: 1, user: 'Alice Chen', action: 'created a new project', time: '2 minutes ago', initials: 'AC' },\n { id: 2, user: 'Bob Smith', action: 'commented on your post', time: '15 minutes ago', initials: 'BS' },\n { id: 3, user: 'Carol Davis', action: 'shared a document', time: '1 hour ago', initials: 'CD' },\n { id: 4, user: 'Dan Wilson', action: 'completed a task', time: '3 hours ago', initials: 'DW' },\n];\n\n<Card>\n <Card.Header>\n <Card.Title>Recent Activity</Card.Title>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n {activities.map((activity) => (\n <Stack key={activity.id} direction=\"row\" gap=\"md\" align=\"center\">\n <Avatar size=\"sm\" initials={activity.initials} />\n <Stack gap=\"xs\" style={{ flex: 1 }}>\n <Text>\n <Text weight=\"semibold\">{activity.user}</Text> {activity.action}\n </Text>\n <Text scale=\"sm\" color=\"tertiary\">{activity.time}</Text>\n </Stack>\n </Stack>\n ))}\n </Stack>\n </Card.Body>\n</Card>","tags":["activity","feed","timeline","notifications"]},"Dashboard Layout":{"filePath":"src/blocks/DashboardLayout.block.ts","name":"Dashboard Layout","description":"Full application shell with sidebar navigation, header, and metrics grid","category":"dashboard","components":["AppShell","Header","Sidebar","Stack","Grid","Card","Text","Badge","Input","ThemeToggle","Avatar"],"code":"const navItems = [\n { label: 'Dashboard', active: true },\n { label: 'Analytics', active: false },\n { label: 'Projects', active: false },\n { label: 'Settings', active: false },\n];\n\nconst metrics = [\n { label: 'Total Users', value: '12,847', change: '+12%' },\n { label: 'Revenue', value: '$48,352', change: '+8%' },\n { label: 'Active Projects', value: '23', change: '+3' },\n];\n\n<AppShell>\n <AppShell.Header>\n <Header>\n <Header.Trigger />\n <Header.Search>\n <Input placeholder=\"Search...\" style={{ width: '240px' }} />\n </Header.Search>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"sm\" />\n <Avatar size=\"sm\" initials=\"JD\" />\n </Header.Actions>\n </Header>\n </AppShell.Header>\n <AppShell.Sidebar width=\"220px\" collapsible=\"offcanvas\">\n <Sidebar.Header>\n <Text weight=\"semibold\" scale=\"lg\">Acme Inc</Text>\n </Sidebar.Header>\n <Sidebar.Nav>\n <Sidebar.Section label=\"Main\">\n {navItems.map((item) => (\n <Sidebar.Item key={item.label} active={item.active}>\n {item.label}\n </Sidebar.Item>\n ))}\n </Sidebar.Section>\n </Sidebar.Nav>\n <Sidebar.Footer>\n <Text scale=\"sm\" color=\"tertiary\">v2.0.0</Text>\n </Sidebar.Footer>\n </AppShell.Sidebar>\n <AppShell.Main padding=\"lg\">\n <Stack gap=\"lg\">\n <Stack gap=\"xs\">\n <Text scale=\"xl\" weight=\"semibold\">Dashboard</Text>\n <Text color=\"tertiary\">Welcome back! Here's an overview of your metrics.</Text>\n </Stack>\n <Grid columns={{ base: 1, md: 3 }} gap=\"md\">\n {metrics.map((metric) => (\n <Card key={metric.label}>\n <Card.Body>\n <Stack gap=\"sm\">\n <Text scale=\"sm\" color=\"tertiary\">{metric.label}</Text>\n <Stack direction=\"row\" justify=\"between\" align=\"baseline\">\n <Text scale=\"2xl\" weight=\"semibold\">{metric.value}</Text>\n <Badge tone=\"success\">{metric.change}</Badge>\n </Stack>\n </Stack>\n </Card.Body>\n </Card>\n ))}\n </Grid>\n </Stack>\n </AppShell.Main>\n</AppShell>","tags":["dashboard","layout","sidebar","app-shell","navigation"]},"Login Form":{"filePath":"src/blocks/LoginForm.block.ts","name":"Login Form","description":"Email/password authentication form with card layout and footer links","category":"authentication","components":["Card","Stack","Input","Button","Text","Link"],"code":"<Card variant=\"solid\">\n <Card.Header>\n <Card.Title>Sign In</Card.Title>\n <Card.Description>Welcome back! Please enter your details.</Card.Description>\n </Card.Header>\n <Card.Body>\n <Stack gap=\"md\">\n <Input label=\"Email\" type=\"email\" placeholder=\"Enter your email\" />\n <Input label=\"Password\" type=\"password\" placeholder=\"Enter your password\" />\n <Link href=\"#\" tone=\"neutral\"><Text scale=\"sm\">Forgot password?</Text></Link>\n <Button variant=\"solid\" fullWidth>Sign In</Button>\n </Stack>\n </Card.Body>\n <Card.Footer>\n <Text scale=\"sm\" color=\"tertiary\">Don't have an account? <Link href=\"#\">Sign up</Link></Text>\n </Card.Footer>\n</Card>","tags":["auth","login","signin","form"]},"Stats Card":{"filePath":"src/blocks/StatsCard.block.ts","name":"Stats Card","description":"Metric card with value, change indicator and icon","category":"dashboard","components":["Card","Stack","Text","Badge","Icon"],"code":"<Card>\n <Card.Body>\n <Stack direction=\"row\" justify=\"between\" align=\"start\">\n <Stack gap=\"xs\">\n <Text scale=\"sm\" color=\"tertiary\">Total Revenue</Text>\n <Text scale=\"2xl\" weight=\"semibold\">$45,231</Text>\n <Stack direction=\"row\" gap=\"xs\" align=\"center\">\n <Badge tone=\"success\">+12.5%</Badge>\n <Text scale=\"sm\" color=\"tertiary\">from last month</Text>\n </Stack>\n </Stack>\n <Icon icon={TrendUp} size=\"lg\" tone=\"success\" />\n </Stack>\n </Card.Body>\n</Card>","tags":["stats","metrics","kpi","dashboard","card"]}},"tokens":{"prefix":"--","total":787,"categories":{"other":[{"name":"--_alert-tint","value":"var(--fui-color-info-bg, #{$fui-color-info-bg})"},{"name":"--_alert-ink","value":"var(--fui-color-info-text, #{$fui-color-info-text})"},{"name":"--_alert-line","value":"var(--fui-color-info-border, #{$fui-color-info-border})"},{"name":"--_badge-tint","value":"var(--fui-bg-tertiary, #{$fui-bg-tertiary})"},{"name":"--_badge-ink","value":"var(--fui-text-secondary, #{$fui-text-secondary})"},{"name":"--_badge-line","value":"var(--fui-border-strong, #{$fui-border-strong})"},{"name":"$_tint-light","value":"24%"},{"name":"$_tint-dark","value":"28%"},{"name":"--_tone-ink","value":"var(--fui-button-neutral-color, var(--fui-text-primary, #{$fui-text-primary}))"},{"name":"--_tone-soft","value":"var(--fui-button-neutral-bg, var(--fui-bg-tertiary, #{$fui-bg-tertiary}))"},{"name":"--_tone-soft-hover","value":"var(--fui-button-neutral-bg-hover, var(--fui-bg-hover, #{$fui-bg-hover}))"},{"name":"--_tone-soft-active","value":"var(--fui-button-neutral-bg-active, var(--fui-bg-active, #{$fui-bg-active}))"},{"name":"--_tone-wash","value":"var(--fui-bg-hover, #{$fui-bg-hover})"},{"name":"--_tone-wash-active","value":"var(--fui-bg-active, #{$fui-bg-active})"},{"name":"--_tone-line","value":"var(--fui-button-neutral-border, var(--fui-border-strong, #{$fui-border-strong}))"},{"name":"--_tone-line-hover","value":"var(--fui-color-accent, #{$fui-color-accent})"},{"name":"--fui-card-consumer-fixture","value":"1"},{"name":"--shiki-token-keyword","value":"#9a3412"},{"name":"--shiki-token-string","value":"light-dark(#166534, #7dcea0)"},{"name":"--shiki-token-string-expression","value":"light-dark(#166534, #7dcea0)"},{"name":"--shiki-token-comment","value":"#5c5348"},{"name":"--shiki-token-function","value":"#1e3a8a"},{"name":"--shiki-token-constant","value":"light-dark(#92400e, #e8b86d)"},{"name":"--shiki-token-parameter","value":"#3d3429"},{"name":"--shiki-token-punctuation","value":"#3d3429"},{"name":"--shiki-token-link","value":"var(--fui-link-ink, #{$fui-link-ink})"},{"name":"$rows","value":"5"},{"name":"--_cols","value":"1"},{"name":"--beam-angle","value":"0deg"},{"name":"--_gutter","value":"var(--fui-space-3, #{$fui-space-3})"},{"name":"--_fui-scrollarea-inline-fade","value":"calc(1 * 48px))"},{"name":"--_fui-scrollarea-block-fade","value":"calc(1 * 32px))"},{"name":"--_fui-scrollarea-inline-mask","value":"linear-gradient(black, black)"},{"name":"--_fui-scrollarea-block-mask","value":"linear-gradient(black, black)"},{"name":"$_inline-fade","value":"measurements.raw-space(48)"},{"name":"$_block-fade","value":"measurements.raw-space(32)"},{"name":"$_mask-none","value":"linear-gradient(black, black)"},{"name":"$_gutter","value":"navigation.gutter()"},{"name":"$_leading-box","value":"navigation.leading-box()"},{"name":"$_active-rail","value":"navigation.active-rail()"},{"name":"$_switch-travel-md","value":"calc(#{boolean.switch-inline-size(\"md\")} - #{boolean.switch-block-size(\"md\")})"},{"name":"$_track","value":"field.track(\"md\")"},{"name":"--_toast-tint","value":"var(--fui-bg-elevated, #{$fui-bg-elevated})"},{"name":"--_toast-line","value":"var(--fui-border, #{$fui-border})"},{"name":"--_toast-ink","value":"var(--fui-text-primary, #{$fui-text-primary})"},{"name":"--_toast-ink-soft","value":"var(--fui-text-secondary, #{$fui-text-secondary})"},{"name":"--_fui-action-type-line","value":"#{typography.line-height(\"ui-compact\")}"},{"name":"--_fui-action-type-weight","value":"#{typography.weight(\"ui-compact\")}"},{"name":"--_fui-action-type-tracking","value":"#{typography.tracking(\"ui-compact\")}"},{"name":"--_fui-action-type-family","value":"#{typography.font-family(\"ui-compact\")}"},{"name":"--_fui-action-track","value":"#{track($role)}"},{"name":"$icon-role","value":"null"},{"name":"--_fui-switch-travel","value":"calc(var(--_fui-switch-inline-size) - var(--_fui-switch-block-size))"},{"name":"$type-role","value":"\"ui-standard\""},{"name":"--_fui-feedback-empty-title-line","value":"#{typography.line-height(\"ui-standard\")}"},{"name":"--_fui-feedback-empty-title-weight","value":"#{typography.weight(\"ui-standard\")}"},{"name":"--_fui-feedback-empty-title-tracking","value":"#{typography.tracking(\"ui-standard\")}"},{"name":"--_fui-feedback-empty-copy-line","value":"#{typography.line-height(\"caption\")}"},{"name":"--_fui-feedback-empty-copy-weight","value":"#{typography.weight(\"caption\")}"},{"name":"--_fui-feedback-empty-copy-tracking","value":"#{typography.tracking(\"caption\")}"},{"name":"$top","value":"var( --fui-feedback-viewport-inset-top, max(calc(1 * 16px), env(safe-area-inset-top)) )"},{"name":"$bottom","value":"var( --fui-feedback-viewport-inset-bottom, max(calc(1 * 16px), env(safe-area-inset-bottom)) )"},{"name":"$left","value":"var( --fui-feedback-viewport-inset-left, max(calc(1 * 16px), env(safe-area-inset-left)) )"},{"name":"$right","value":"var( --fui-feedback-viewport-inset-right, max(calc(1 * 16px), env(safe-area-inset-right)) )"},{"name":"--_fui-field-track","value":"#{track($size)}"},{"name":"--fui-navigation-row-track","value":"calc(1 * 32px))"},{"name":"--fui-navigation-section-track","value":"calc(1 * 24px))"},{"name":"--fui-navigation-gutter","value":"navigation.gutter()"},{"name":"--fui-navigation-leading-box","value":"navigation.leading-box()"},{"name":"--fui-navigation-active-rail","value":"navigation.active-rail()"},{"name":"--fui-navigation-active-dot","value":"_navigation(\"sidebarDot\")"},{"name":"--fui-navigation-label-optical-y","value":"#{_navigation(\"sidebarLabelOffset\")}"},{"name":"$_row-track","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$_section-track","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$_active-dot","value":"_navigation(\"sidebarDot\")"},{"name":"--fui-popup-row-pitch","value":"calc(1 * 32px))"},{"name":"--fui-popup-indicator-box","value":"calc(1 * 16px)})"},{"name":"--fui-popup-offset","value":"calc(1 * 4px)})"},{"name":"--fui-popup-viewport-rows","value":"4.5"},{"name":"--_fui-popup-effective-row-pitch","value":"calc(1 * 32px)))"},{"name":"$_row-pitch","value":"measurements.raw-space(32)"},{"name":"$_viewport-rows","value":"4.5"},{"name":"$step","value":"null"},{"name":"--_fui-segmented-track","value":"#{action.track($size)}"},{"name":"--fui-table-row-track-compact","value":"calc(1 * 32px)})"},{"name":"--fui-table-row-track-regular","value":"calc(1 * 40px)})"},{"name":"--fui-table-row-track-relaxed","value":"calc(1 * 48px)})"},{"name":"--fui-table-tree-indent-step","value":"calc(1 * 24px))"},{"name":"--_fui-table-row-track","value":"#{row-track($density)}"},{"name":"$_tree-indent-step","value":"measurements.raw-space(24)"},{"name":"$_validated-role","value":"measurements.typography-value($role, \"size\")"},{"name":"--fui-line-clamp","value":"2"},{"name":"--fui-navmenu-viewport-left","value":"0px"},{"name":"--fui-table-tree-depth","value":"0"},{"name":"--fui-progress-diameter","value":"calc(1 * 48px)"},{"name":"--fui-progress-dash-full","value":"0"},{"name":"--fui-progress-dash-quarter","value":"0"},{"name":"--fui-control-track-micro","value":"calc(1 * 24px)"},{"name":"--fui-control-track-sm","value":"calc(1 * 28px)"},{"name":"--fui-control-track-md","value":"calc(1 * 32px)"},{"name":"--fui-control-track-lg","value":"calc(1 * 40px)"},{"name":"--fui-field-track-sm","value":"calc(1 * 28px)"},{"name":"--fui-field-track-md","value":"calc(1 * 32px)"},{"name":"--fui-field-track-lg","value":"calc(1 * 40px)"},{"name":"--fui-icon-xs","value":"calc(1 * 12px)"},{"name":"--fui-icon-sm","value":"calc(1 * 14px)"},{"name":"--fui-icon-md","value":"calc(1 * 16px)"},{"name":"--fui-icon-lg","value":"calc(1 * 20px)"},{"name":"--fui-icon-xl","value":"calc(1 * 24px)"},{"name":"--fui-icon-2xl","value":"calc(1 * 32px)"},{"name":"--fui-layout-measure-inline-floor","value":"calc(1 * 56px)"},{"name":"--fui-layout-measure-compact-content","value":"calc(1 * 168px)"},{"name":"--fui-layout-measure-grid-cell","value":"calc(1 * 224px)"},{"name":"--fui-layout-measure-composer-item","value":"calc(1 * 210px)"},{"name":"--fui-layout-measure-page-narrow","value":"calc(1 * 800px)"},{"name":"--fui-overlay-popover-sm","value":"calc(1 * 256px)"},{"name":"--fui-overlay-popover-md","value":"calc(1 * 384px)"},{"name":"--fui-overlay-popover-lg","value":"calc(1 * 512px)"},{"name":"--fui-overlay-dialog-sm","value":"calc(1 * 384px)"},{"name":"--fui-overlay-dialog-md","value":"calc(1 * 448px)"},{"name":"--fui-overlay-dialog-lg","value":"calc(1 * 576px)"},{"name":"--fui-overlay-dialog-xl","value":"calc(1 * 768px)"},{"name":"--fui-overlay-drawer-sm","value":"calc(1 * 320px)"},{"name":"--fui-overlay-drawer-md","value":"calc(1 * 384px)"},{"name":"--fui-overlay-drawer-lg","value":"calc(1 * 512px)"},{"name":"--fui-overlay-drawer-xl","value":"calc(1 * 768px)"},{"name":"--fui-type-caption-line","value":"16px"},{"name":"--fui-type-caption-weight","value":"400"},{"name":"--fui-type-caption-tracking","value":"0"},{"name":"--fui-type-ui-compact-line","value":"16px"},{"name":"--fui-type-ui-compact-weight","value":"500"},{"name":"--fui-type-ui-compact-tracking","value":"-0.01em"},{"name":"--fui-type-ui-standard-line","value":"20px"},{"name":"--fui-type-ui-standard-weight","value":"500"},{"name":"--fui-type-ui-standard-tracking","value":"-0.01em"},{"name":"--fui-type-body-compact-line","value":"20px"},{"name":"--fui-type-body-compact-weight","value":"400"},{"name":"--fui-type-body-compact-tracking","value":"0"},{"name":"--fui-type-body-relaxed-line","value":"24px"},{"name":"--fui-type-body-relaxed-weight","value":"400"},{"name":"--fui-type-body-relaxed-tracking","value":"0"},{"name":"--fui-type-display-line","value":"40px"},{"name":"--fui-type-display-weight","value":"600"},{"name":"--fui-type-display-tracking","value":"-0.02em"},{"name":"--fui-type-title-sm-line","value":"24px"},{"name":"--fui-type-title-sm-weight","value":"600"},{"name":"--fui-type-title-sm-tracking","value":"-0.01em"},{"name":"--fui-type-title-md-line","value":"28px"},{"name":"--fui-type-title-md-weight","value":"600"},{"name":"--fui-type-title-md-tracking","value":"-0.02em"},{"name":"--fui-type-title-lg-line","value":"32px"},{"name":"--fui-type-title-lg-weight","value":"600"},{"name":"--fui-type-title-lg-tracking","value":"-0.02em"},{"name":"--fui-type-code-line","value":"20px"},{"name":"--fui-type-code-weight","value":"400"},{"name":"--fui-type-code-tracking","value":"0"},{"name":"--fui-navigation-sidebar-gutter","value":"calc(1 * 8px)"},{"name":"--fui-navigation-sidebar-leading-box","value":"calc(1 * 16px)"},{"name":"--fui-navigation-sidebar-dot","value":"calc(1 * 6px)"},{"name":"--fui-navigation-sidebar-rail","value":"2px"},{"name":"--fui-navigation-sidebar-label-offset","value":"1px"},{"name":"--fui-seed-brand","value":"#{$fui-color-accent}"},{"name":"--fui-seed-danger","value":"#{$fui-color-danger}"},{"name":"--fui-seed-success","value":"#{$fui-color-success}"},{"name":"--fui-seed-warning","value":"#{$fui-color-warning}"},{"name":"--fui-seed-info","value":"#{$fui-color-info}"},{"name":"--fui-skeleton","value":"color-mix(in srgb, var(--fui-border-default) 62%, var(--fui-bg-secondary))"},{"name":"--fui-skeleton-hi","value":"color-mix(in srgb, var(--fui-border-default) 24%, var(--fui-bg-secondary))"},{"name":"--fui-link-ink","value":"light-dark(#{$fui-link-ink}, #{$fui-dark-link-ink})"},{"name":"--fui-sidebar-item-active-indicator","value":"transparent"}],"bentogrid-item":[{"name":"--_col-span","value":"1"},{"name":"--_row-span","value":"1"}],"colors":[{"name":"--_button-bg","value":"transparent"},{"name":"--_button-color","value":"var(--fui-text-primary, #{$fui-text-primary})"},{"name":"--_tone-fill","value":"var(--fui-bg-inverse, #{$fui-bg-inverse})"},{"name":"--_tone-fill-line","value":"var(--_tone-fill, var(--fui-bg-inverse, #{$fui-bg-inverse}))"},{"name":"--_tone-fill-line-hover","value":"var(--_tone-fill-hover, var(--fui-bg-inverse, #{$fui-bg-inverse}))"},{"name":"--_tone-on-fill","value":"var(--fui-text-inverse, #{$fui-text-inverse})"},{"name":"--shiki-color-text","value":"var(--fui-code-text, var(--fui-text-primary, #{$fui-text-primary}))"},{"name":"--shiki-color-background","value":"var(--fui-code-bg, #{$fui-code-bg})"},{"name":"$fui-colorpicker-size","value":"200px"},{"name":"$fui-colorpicker-hue-height","value":"$fui-target-size-min"},{"name":"$fui-colorpicker-pointer-size","value":"$fui-target-size-min"},{"name":"--fui-data-table-bg","value":"transparent)"},{"name":"--fui-sidebar-hover-bg","value":"var(--fui-sidebar-item-hover-bg, var(--fui-bg-hover, #{$fui-bg-hover}))"},{"name":"--fui-table-row-bg","value":"var(--fui-table-row-base-bg)"},{"name":"--fui-table-row-base-bg","value":"var(--fui-table-subrow-bg, var(--fui-bg-subtle, #{$fui-bg-subtle}))"},{"name":"$_stroke","value":"field.stroke()"},{"name":"--_fui-field-stroke","value":"#{stroke()}"},{"name":"--fui-chart-marker-stroke","value":"2px"},{"name":"--fui-stroke-hairline","value":"1px"},{"name":"--fui-stroke-default","value":"2px"},{"name":"--fui-stroke-strong","value":"calc(1 * 3px)"},{"name":"--fui-color-accent","value":"light-dark(#{$fui-color-accent}, #{$fui-dark-color-accent})"},{"name":"--fui-color-on-accent","value":"light-dark(#{$fui-color-on-accent}, #{$fui-dark-color-on-accent})"},{"name":"--fui-color-danger","value":"#{$fui-color-danger}"},{"name":"--fui-color-danger-hover","value":"#{$fui-color-danger-hover}"},{"name":"--fui-color-success","value":"#{$fui-color-success}"},{"name":"--fui-color-warning","value":"#{$fui-color-warning}"},{"name":"--fui-color-info","value":"#{$fui-color-info}"},{"name":"--fui-selection-color","value":"var(--fui-text-primary)"},{"name":"--fui-control-selected-bg","value":"color-mix(in srgb, var(--fui-text-primary) 9%, transparent)"},{"name":"--fui-control-checked-bg","value":"var(--fui-color-accent)"},{"name":"--fui-control-checked-bg-hover","value":"var(--fui-color-accent-hover)"},{"name":"--fui-control-checked-color","value":"var(--fui-color-on-accent)"},{"name":"--fui-field-selection-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-field-selection-bg-hover","value":"color-mix(in srgb, var(--fui-text-primary) 11%, transparent)"},{"name":"--fui-field-selection-color","value":"var(--fui-text-primary)"},{"name":"--fui-form-group-bg","value":"color-mix(in srgb, var(--fui-bg-secondary) 48%, var(--fui-bg-primary))"},{"name":"--fui-kbd-bg","value":"color-mix(in srgb, var(--fui-text-primary) 4%, transparent)"},{"name":"--fui-kbd-color","value":"var(--fui-text-tertiary)"},{"name":"--fui-card-accent-bg","value":"var(--fui-bg-tertiary)"},{"name":"--fui-app-canvas-bg","value":"var(--fui-body-bg)"},{"name":"--fui-app-main-bg","value":"var(--fui-body-bg)"},{"name":"--fui-app-sidebar-bg","value":"var(--fui-bg-tertiary)"},{"name":"--fui-sidebar-bg","value":"var(--fui-app-sidebar-bg)"},{"name":"--fui-sidebar-item-color","value":"var(--fui-text-secondary)"},{"name":"--fui-sidebar-item-icon-color","value":"var(--fui-text-tertiary)"},{"name":"--fui-sidebar-item-hover-bg","value":"var(--fui-bg-hover)"},{"name":"--fui-sidebar-item-hover-color","value":"var(--fui-text-primary)"},{"name":"--fui-sidebar-item-active-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-sidebar-item-active-color","value":"var(--fui-text-primary)"},{"name":"--fui-badge-dot-color","value":"currentColor"},{"name":"--fui-card-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 92%, transparent)"},{"name":"--fui-card-header-bg","value":"var(--fui-bg-subtle)"},{"name":"--fui-card-hover-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 88%, var(--fui-text-primary) 4%)"},{"name":"--fui-card-stat-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 74%, transparent)"},{"name":"--fui-panel-bg","value":"color-mix(in srgb, var(--fui-bg-elevated) 74%, transparent)"},{"name":"--fui-table-bg","value":"transparent"},{"name":"--fui-table-header-bg","value":"color-mix(in srgb, var(--fui-text-primary) 5%, transparent)"},{"name":"--fui-table-row-hover-bg","value":"var(--fui-bg-hover)"},{"name":"--fui-table-row-active-bg","value":"var(--fui-bg-active)"},{"name":"--fui-table-row-selected-bg","value":"var(--fui-control-selected-bg)"},{"name":"--fui-table-subrow-bg","value":"color-mix(in srgb, var(--fui-bg-secondary) 62%, transparent)"},{"name":"--fui-tabs-pills-bg","value":"color-mix(in srgb, var(--fui-text-primary) 5%, transparent)"},{"name":"--fui-tabs-pill-hover-bg","value":"transparent"},{"name":"--fui-color-accent-hover","value":"#{$_rt-dark-accent-hover}"},{"name":"--fui-color-accent-active","value":"#{$_rt-dark-accent-active}"},{"name":"--fui-color-danger-bg","value":"color-mix(in oklch, var(--fui-seed-danger) 24%, black)"},{"name":"--fui-color-success-bg","value":"color-mix(in oklch, var(--fui-seed-success) 24%, black)"},{"name":"--fui-color-warning-bg","value":"color-mix(in oklch, var(--fui-seed-warning) 24%, black)"},{"name":"--fui-color-info-bg","value":"color-mix(in oklch, var(--fui-seed-info) 24%, black)"},{"name":"--fui-color-danger-text","value":"color-mix(in oklch, var(--fui-seed-danger) 78%, white 22%)"},{"name":"--fui-color-success-text","value":"color-mix(in oklch, var(--fui-seed-success) 78%, white 22%)"},{"name":"--fui-color-warning-text","value":"color-mix(in oklch, var(--fui-seed-warning) 78%, white 22%)"},{"name":"--fui-color-info-text","value":"color-mix(in oklch, var(--fui-seed-info) 78%, white 22%)"}],"surfaces":[{"name":"--_button-bg-hover","value":"var(--fui-bg-hover, #{$fui-bg-hover})"},{"name":"--_button-bg-active","value":"var(--fui-bg-active, #{$fui-bg-active})"},{"name":"--fui-bg-primary","value":"light-dark(#{$fui-bg-primary}, #{$fui-dark-bg-primary})"},{"name":"--fui-bg-secondary","value":"light-dark(#{$fui-bg-secondary}, #{$fui-dark-bg-secondary})"},{"name":"--fui-bg-tertiary","value":"light-dark(#{$fui-bg-tertiary}, #{$fui-dark-bg-tertiary})"},{"name":"--fui-bg-elevated","value":"light-dark(#{$fui-bg-elevated}, #{$fui-dark-bg-elevated})"},{"name":"--fui-bg-subtle","value":"light-dark(#{$fui-bg-subtle}, #{$fui-dark-bg-subtle})"},{"name":"--fui-bg-hover","value":"light-dark(#{$fui-bg-hover}, #{$fui-dark-bg-hover})"},{"name":"--fui-bg-active","value":"light-dark(#{$fui-bg-active}, #{$fui-dark-bg-active})"},{"name":"--fui-body-bg","value":"light-dark(#{$fui-body-bg}, #{$fui-dark-body-bg})"},{"name":"--fui-main-bg","value":"light-dark(#{$fui-main-bg}, #{$fui-dark-main-bg})"},{"name":"--fui-bg-inverse","value":"light-dark(#{$fui-bg-inverse}, #{$fui-dark-bg-inverse})"},{"name":"--fui-bg-highlight","value":"color-mix(in srgb, var(--fui-text-primary) 7%, transparent)"}],"borders":[{"name":"--_button-border","value":"transparent"},{"name":"--_button-border-hover","value":"transparent"},{"name":"--fui-sidebar-active-border","value":"transparent"},{"name":"--fui-border","value":"light-dark(#{$fui-border}, #{$fui-dark-border})"},{"name":"--fui-border-default","value":"light-dark(#{$fui-border-default}, #{$fui-dark-border-default})"},{"name":"--fui-border-strong","value":"light-dark(#{$fui-border-strong}, #{$fui-dark-border-strong})"},{"name":"--fui-border-subtle","value":"color-mix(in srgb, var(--fui-border-default) 68%, transparent)"},{"name":"--fui-control-selected-border","value":"transparent"},{"name":"--fui-control-checked-border","value":"var(--fui-color-accent)"},{"name":"--fui-control-checked-border-hover","value":"var(--fui-color-accent-hover)"},{"name":"--fui-field-selection-border","value":"var(--fui-border-strong)"},{"name":"--fui-form-group-border","value":"var(--fui-border-default)"},{"name":"--fui-kbd-border","value":"color-mix(in srgb, var(--fui-border-strong) 72%, transparent)"},{"name":"--fui-card-accent-border","value":"color-mix(in srgb, var(--fui-color-accent) 30%, var(--fui-border))"},{"name":"--fui-sidebar-border","value":"var(--fui-border-default)"},{"name":"--fui-sidebar-item-active-border","value":"transparent"},{"name":"--fui-sidebar-footer-border","value":"color-mix(in srgb, var(--fui-border-default) 68%, transparent)"},{"name":"--fui-card-border","value":"color-mix(in srgb, var(--fui-border-default) 86%, transparent)"},{"name":"--fui-card-outlined-border","value":"var(--fui-card-border)"},{"name":"--fui-card-hover-border","value":"color-mix(in srgb, var(--fui-border-strong) 86%, transparent)"},{"name":"--fui-card-stat-border","value":"color-mix(in srgb, var(--fui-border-default) 78%, transparent)"},{"name":"--fui-panel-border","value":"color-mix(in srgb, var(--fui-border-default) 78%, transparent)"},{"name":"--fui-table-border","value":"var(--fui-border-default)"},{"name":"--fui-table-header-border","value":"var(--fui-border-strong)"},{"name":"--fui-table-row-selected-border","value":"var(--fui-border-strong)"},{"name":"--fui-tabs-pills-border","value":"var(--fui-border-default)"}],"shadows":[{"name":"--_button-shadow","value":"none"},{"name":"--_button-shadow-hover","value":"none"},{"name":"--_button-shadow-active","value":"none"},{"name":"--fui-card-active-shadow","value":"inset 0 1px 2px color-mix(in srgb, black 12%, transparent)"},{"name":"--fui-card-panel-shadow","value":"var(--fui-card-shadow)"},{"name":"--fui-card-stat-shadow","value":"var(--fui-card-shadow)"},{"name":"--fui-shadow-sm","value":"#{$fui-shadow-sm}"},{"name":"--fui-shadow-md","value":"#{$fui-shadow-md}"},{"name":"--fui-shadow-lg","value":"#{$fui-shadow-lg}"}],"padding":[{"name":"--_card-root-requested-inset","value":"#{surface.inset(\"panel\")}"}],"spacing":[{"name":"--_card-body-inset","value":"#{surface.inset(\"panel\")}"},{"name":"--_control-padding","value":"var(--fui-space-2, #{$fui-space-2})"},{"name":"--_chip-padding","value":"var(--fui-space-1, #{$fui-space-1})"},{"name":"$_block-inset","value":"calc(1 * 8px)})"},{"name":"--_fui-action-gap","value":"#{gap($role)}"},{"name":"--_fui-action-inline-inset","value":"#{inline-inset($role)}"},{"name":"--_fui-boolean-label-gap","value":"#{label-gap($size)}"},{"name":"--_fui-switch-inset","value":"2px})"},{"name":"--_fui-field-inline-inset","value":"#{inline-inset($size)}"},{"name":"--fui-field-label-gap","value":"calc(1 * 6px))"},{"name":"--fui-field-message-gap","value":"calc(1 * 4px))"},{"name":"$_label-gap","value":"measurements.raw-space(6)"},{"name":"$_message-gap","value":"measurements.raw-space(4)"},{"name":"--fui-navigation-inline-inset","value":"navigation.gutter()"},{"name":"--fui-navigation-content-gap","value":"navigation.gutter()"},{"name":"--fui-popup-container-inset","value":"calc(1 * 4px))"},{"name":"--fui-popup-row-block-inset","value":"calc(1 * 8px))"},{"name":"--fui-popup-row-inline-inset","value":"calc(1 * 8px))"},{"name":"--fui-popup-row-content-gap","value":"calc(1 * 8px))"},{"name":"--fui-popup-separator-gap","value":"calc(1 * 4px))"},{"name":"$_container-inset","value":"measurements.raw-space(4)"},{"name":"$_row-inset","value":"measurements.raw-space(8)"},{"name":"$_separator-gap","value":"measurements.raw-space(4)"},{"name":"--_fui-chart-tooltip-item-gap","value":"#{_raw(8)}"},{"name":"--_fui-segmented-inline-inset","value":"#{action.inline-inset($size)}"},{"name":"--_fui-segmented-gap","value":"#{action.gap($size)}"},{"name":"--fui-table-cell-inline-inset-compact","value":"calc(1 * 8px)})"},{"name":"--fui-table-cell-inline-inset-regular","value":"calc(1 * 12px)})"},{"name":"--fui-table-cell-inline-inset-relaxed","value":"calc(1 * 16px)})"},{"name":"--fui-table-cell-block-inset-compact","value":"calc(1 * 4px)})"},{"name":"--fui-table-cell-block-inset-regular","value":"calc(1 * 10px)})"},{"name":"--fui-table-cell-block-inset-relaxed","value":"calc(1 * 12px)})"},{"name":"--fui-table-header-block-inset-compact","value":"calc(1 * 4px)})"},{"name":"--fui-table-header-block-inset-regular","value":"calc(1 * 8px)})"},{"name":"--fui-table-header-block-inset-relaxed","value":"calc(1 * 12px)})"},{"name":"--_fui-table-cell-inline-inset","value":"#{cell-inline-inset($density)}"},{"name":"--_fui-table-cell-block-inset","value":"#{cell-block-inset($density)}"},{"name":"--_fui-table-header-block-inset","value":"#{header-block-inset($density)}"},{"name":"$_cell-inline-inset","value":"cell-inline-inset(\"regular\")"},{"name":"$_cell-block-inset","value":"cell-block-inset(\"regular\")"},{"name":"--fui-feedback-text-gap","value":"calc(1 * 4px)"},{"name":"--fui-feedback-transient-gap","value":"calc(1 * 8px)"},{"name":"--fui-feedback-viewport-inset-top","value":"max(calc(1 * 16px), env(safe-area-inset-top))"},{"name":"--fui-feedback-viewport-inset-right","value":"max(calc(1 * 16px), env(safe-area-inset-right))"},{"name":"--fui-feedback-viewport-inset-bottom","value":"max(calc(1 * 16px), env(safe-area-inset-bottom))"},{"name":"--fui-feedback-viewport-inset-left","value":"max(calc(1 * 16px), env(safe-area-inset-left))"},{"name":"--fui-overlay-close-inset","value":"calc(1 * 12px)"},{"name":"--fui-overlay-section-gap","value":"calc(1 * 8px)"},{"name":"--fui-prompt-inset-left","value":"0px"},{"name":"--fui-stack-gap","value":"0"},{"name":"--fui-stack-gap-sm","value":"0"},{"name":"--fui-stack-gap-md","value":"0"},{"name":"--fui-stack-gap-lg","value":"0"},{"name":"--fui-stack-gap-xl","value":"0"},{"name":"--fui-raw-space-0","value":"0"},{"name":"--fui-raw-space-2","value":"2px"},{"name":"--fui-raw-space-4","value":"calc(1 * 4px)"},{"name":"--fui-raw-space-6","value":"calc(1 * 6px)"},{"name":"--fui-raw-space-8","value":"calc(1 * 8px)"},{"name":"--fui-raw-space-10","value":"calc(1 * 10px)"},{"name":"--fui-raw-space-12","value":"calc(1 * 12px)"},{"name":"--fui-raw-space-16","value":"calc(1 * 16px)"},{"name":"--fui-raw-space-20","value":"calc(1 * 20px)"},{"name":"--fui-raw-space-24","value":"calc(1 * 24px)"},{"name":"--fui-raw-space-32","value":"calc(1 * 32px)"},{"name":"--fui-raw-space-40","value":"calc(1 * 40px)"},{"name":"--fui-raw-space-48","value":"calc(1 * 48px)"},{"name":"--fui-raw-space-64","value":"calc(1 * 64px)"},{"name":"--fui-field-inline-inset-sm","value":"calc(1 * 10px)"},{"name":"--fui-field-inline-inset-md","value":"calc(1 * 12px)"},{"name":"--fui-field-inline-inset-lg","value":"calc(1 * 16px)"},{"name":"--fui-surface-inset-panel","value":"0"},{"name":"--fui-surface-inset-compact","value":"calc(1 * 12px)"},{"name":"--fui-surface-inset-default","value":"calc(1 * 16px)"},{"name":"--fui-surface-inset-roomy","value":"calc(1 * 24px)"},{"name":"--fui-space-px","value":"#{$fui-space-px}"},{"name":"--fui-space-0-5","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-0-5})"},{"name":"--fui-space-0-75","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-0-75})"},{"name":"--fui-space-1","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-1})"},{"name":"--fui-space-2","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-2})"},{"name":"--fui-space-3","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-3})"},{"name":"--fui-space-4","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-4})"},{"name":"--fui-space-5","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-5})"},{"name":"--fui-space-6","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-6})"},{"name":"--fui-space-8","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-8})"},{"name":"--fui-space-10","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-10})"},{"name":"--fui-space-12","value":"calc(var(--fui-scale, #{$fui-scale}) * #{$fui-space-12})"},{"name":"--fui-popup-padding","value":"#{$fui-popup-padding}"},{"name":"--fui-popup-row-gap","value":"1px"},{"name":"--fui-popup-item-padding-block","value":"#{$fui-popup-item-padding-block}"},{"name":"--fui-popup-item-padding-inline","value":"#{$fui-popup-item-padding-inline}"},{"name":"--fui-kbd-padding-x","value":"var(--fui-space-0-75)"},{"name":"--fui-kbd-gap","value":"calc(var(--fui-space-px) * 2)"}],"code":[{"name":"--_fui-code-inline-inset","value":"calc(1 * 16px)})"},{"name":"--fui-code-bg","value":"#{$fui-code-bg}"},{"name":"--fui-code-selection-bg","value":"#{$fui-code-selection-bg}"},{"name":"--fui-code-text","value":"var(--fui-text-primary)"},{"name":"--fui-code-token-string","value":"light-dark(#166534, #7dcea0)"},{"name":"--fui-code-token-number","value":"light-dark(#92400e, #e8b86d)"}],"sizing":[{"name":"--_day-size","value":"#{action.track(\"md\")}"},{"name":"--_loading-inline-size","value":"0.875em"},{"name":"--_chip-height","value":"#{action.track(\"sm\")}"},{"name":"--_fui-scrollarea-track-size","value":"calc(1 * 6px))"},{"name":"$_track-size","value":"measurements.raw-space(6)"},{"name":"--_fui-target-hit-size","value":"#{target.hit-size(\"touch\")}"},{"name":"--_fui-action-type-size","value":"#{typography.font-size(\"ui-compact\")}"},{"name":"--_fui-action-icon-size","value":"#{icon-size($role)}"},{"name":"--_fui-boolean-mark-size","value":"#{mark-size($size)}"},{"name":"--_fui-switch-inline-size","value":"#{switch-inline-size($size)}"},{"name":"--_fui-switch-block-size","value":"#{switch-block-size($size)}"},{"name":"--_fui-switch-thumb-size","value":"#{switch-thumb-size($size)}"},{"name":"--_fui-feedback-empty-icon-size","value":"calc(1 * 24px)"},{"name":"--_fui-feedback-empty-max-inline","value":"240px"},{"name":"--_fui-feedback-empty-title-size","value":"#{typography.font-size(\"ui-standard\")}"},{"name":"--_fui-feedback-empty-copy-size","value":"#{typography.font-size(\"caption\")}"},{"name":"--fui-popup-separator-size","value":"1px)"},{"name":"$_separator-size","value":"measurements.target-value(\"stroke\", \"hairline\")"},{"name":"--_fui-activity-size","value":"#{activity-size($size)}"},{"name":"--_fui-segmented-icon-size","value":"#{action.icon-size($size)}"},{"name":"--fui-table-divider-size","value":"1px)"},{"name":"$_divider-size","value":"measurements.target-value(\"stroke\", \"hairline\")"},{"name":"--fui-grid-min-child-width","value":"calc(1 * 224px)"},{"name":"--fui-navmenu-viewport-height","value":"0px"},{"name":"--fui-navmenu-viewport-width","value":"0px"},{"name":"--fui-overlay-arrow-size","value":"calc(1 * 10px)"},{"name":"--fui-select-max-items","value":"4.5"},{"name":"--fui-layout-measure-field-minimum","value":"calc(1 * 140px)"},{"name":"--fui-layout-measure-menu-min","value":"calc(1 * 192px)"},{"name":"--fui-overlay-popover-min","value":"calc(1 * 192px)"},{"name":"--fui-overlay-tooltip-max","value":"calc(1 * 320px)"},{"name":"--fui-type-caption-size","value":"12px"},{"name":"--fui-type-ui-compact-size","value":"12px"},{"name":"--fui-type-ui-standard-size","value":"14px"},{"name":"--fui-type-body-compact-size","value":"14px"},{"name":"--fui-type-body-relaxed-size","value":"16px"},{"name":"--fui-type-display-size","value":"32px"},{"name":"--fui-type-title-sm-size","value":"16px"},{"name":"--fui-type-title-md-size","value":"20px"},{"name":"--fui-type-title-lg-size","value":"24px"},{"name":"--fui-type-code-size","value":"14px"},{"name":"--fui-navigation-app-shell-header-height","value":"calc(1 * 56px)"},{"name":"--fui-navigation-sidebar-collapsed-width","value":"calc(1 * 56px)"},{"name":"--fui-kbd-height","value":"1.286rem","description":"18px at 14px root"},{"name":"--fui-kbd-min-width","value":"1.714rem","description":"24px"},{"name":"--fui-kbd-reserved-width","value":"2.714rem","description":"38px, enough for \"⌘K\""},{"name":"--fui-sidebar-section-label-size","value":"var(--fui-font-size-xs)"},{"name":"--fui-control-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"--fui-control-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"--fui-control-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"--fui-control-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"--fui-target-size-min","value":"#{$fui-target-size-min}"}],"typography":[{"name":"--fui-markdown-text","value":"currentColor"},{"name":"--fui-textarea-min-rows","value":"1"},{"name":"--fui-textarea-max-rows","value":"9999"},{"name":"--fui-font-sans","value":"\"Onest Variable\", Onest, -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif"},{"name":"--fui-font-mono","value":"\"JetBrains Mono Variable\", \"JetBrains Mono\", ui-monospace, \"SF Mono\", Menlo, monospace"},{"name":"--fui-font-size-2xs","value":"#{$fui-font-size-2xs}"},{"name":"--fui-font-size-xs","value":"#{$fui-font-size-xs}"},{"name":"--fui-font-size-sm","value":"#{$fui-font-size-sm}"},{"name":"--fui-font-size-base","value":"#{$fui-font-size-base}"},{"name":"--fui-font-size-md","value":"#{$fui-font-size-md}"},{"name":"--fui-font-size-lg","value":"#{$fui-font-size-lg}"},{"name":"--fui-font-size-xl","value":"#{$fui-font-size-xl}"},{"name":"--fui-font-size-2xl","value":"#{$fui-font-size-2xl}"},{"name":"--fui-font-size-3xl","value":"#{$fui-font-size-3xl}"},{"name":"--fui-font-size-4xl","value":"#{$fui-font-size-4xl}"},{"name":"--fui-popup-item-font-size","value":"#{$fui-popup-item-font-size}"},{"name":"--fui-font-weight-normal","value":"#{$fui-font-weight-normal}"},{"name":"--fui-font-weight-medium","value":"#{$fui-font-weight-medium}"},{"name":"--fui-font-weight-semibold","value":"#{$fui-font-weight-semibold}"},{"name":"--fui-font-weight-bold","value":"#{$fui-font-weight-bold}"},{"name":"--fui-line-height-tight","value":"#{$fui-line-height-tight}"},{"name":"--fui-line-height-normal","value":"#{$fui-line-height-normal}"},{"name":"--fui-line-height-relaxed","value":"#{$fui-line-height-relaxed}"},{"name":"--fui-line-height-display","value":"#{$fui-line-height-display}"},{"name":"--fui-line-height-prose","value":"#{$fui-line-height-prose}"},{"name":"--fui-letter-spacing-tight","value":"#{$fui-letter-spacing-tight}"},{"name":"--fui-letter-spacing-normal","value":"#{$fui-letter-spacing-normal}"},{"name":"--fui-letter-spacing-display","value":"#{$fui-letter-spacing-display}"},{"name":"--fui-letter-spacing-wide","value":"#{$fui-letter-spacing-wide}"},{"name":"--fui-kbd-font-size","value":"var(--fui-font-size-2xs)"}],"size-variants":[{"name":"--_fui-textarea-block-inset","value":"calc(1 * 6px)})"}],"radius":[{"name":"--fui-checkbox-radius","value":"var(--fui-radius-l3)"},{"name":"--fui-radius-sm","value":"#{$fui-radius-sm}"},{"name":"--fui-radius-md","value":"#{$fui-radius-md}"},{"name":"--fui-radius-lg","value":"#{$fui-radius-lg}"},{"name":"--fui-radius-xl","value":"#{$fui-radius-xl}"},{"name":"--fui-radius-full","value":"#{$fui-radius-full}"},{"name":"--fui-radius-none","value":"0px"},{"name":"--fui-radius-l1","value":"var(--fui-radius-lg)"},{"name":"--fui-radius-l2","value":"var(--fui-radius-md)"},{"name":"--fui-radius-l3","value":"var(--fui-radius-sm)"},{"name":"--fui-kbd-radius","value":"var(--fui-radius-sm)"},{"name":"--fui-card-accent-radius","value":"#{$fui-card-accent-radius}"},{"name":"--fui-sidebar-item-radius","value":"var(--fui-radius-full)"},{"name":"--fui-badge-radius","value":"var(--fui-radius-lg)"},{"name":"--fui-card-radius","value":"var(--fui-radius-lg)"}],"z-index":[{"name":"--fui-stack-direction","value":"column"},{"name":"--fui-stack-direction-sm","value":"column"},{"name":"--fui-stack-direction-md","value":"column"},{"name":"--fui-stack-direction-lg","value":"column"},{"name":"--fui-stack-direction-xl","value":"column"}],"base":[{"name":"--fui-base-unit","value":"#{$fui-base-unit}"}],"transitions":[{"name":"--fui-transition-fast","value":"160ms cubic-bezier(0.25, 0.46, 0.45, 0.94)"},{"name":"--fui-opacity-disabled","value":"0.5"},{"name":"--fui-opacity-muted","value":"0.7"},{"name":"--fui-opacity-faint","value":"0.3"},{"name":"--fui-scale","value":"1"},{"name":"--fui-transition-normal","value":"200ms cubic-bezier(0.4, 0, 0.2, 1)"}],"motion-primitives":[{"name":"--fui-anim-offset-sm","value":"4px"},{"name":"--fui-anim-offset-md","value":"8px"},{"name":"--fui-duration-spin","value":"800ms"},{"name":"--fui-duration-pulse","value":"1500ms"},{"name":"--fui-duration-shimmer","value":"2000ms"}],"overlay-stacking-layers":[{"name":"--fui-overlay-layer-swipe","value":"49"},{"name":"--fui-overlay-layer-backdrop","value":"50"},{"name":"--fui-overlay-layer-modal","value":"51"},{"name":"--fui-overlay-layer-anchored","value":"52"},{"name":"--fui-overlay-layer-toast","value":"55"},{"name":"--fui-overlay-layer-tooltip","value":"60"}],"backdrop":[{"name":"--fui-backdrop","value":"light-dark(#{$fui-backdrop}, #{$fui-dark-backdrop})"}],"text":[{"name":"--fui-text-primary","value":"light-dark(#{$fui-text-primary}, #{$fui-dark-text-primary})"},{"name":"--fui-text-secondary","value":"light-dark(#{$fui-text-secondary}, #{$fui-dark-text-secondary})"},{"name":"--fui-text-tertiary","value":"light-dark(#{$fui-text-tertiary}, #{$fui-dark-text-tertiary})"},{"name":"--fui-text-inverse","value":"light-dark(#{$fui-text-inverse}, #{$fui-dark-text-inverse})"}],"component-sizing":[{"name":"--fui-button-primary-base","value":"var(--fui-bg-inverse)"},{"name":"--fui-button-primary-color","value":"var(--fui-text-inverse)"},{"name":"--fui-button-radius","value":"var(--fui-radius-xl)"},{"name":"--fui-button-primary-hover","value":"var(--fui-color-accent-hover)"},{"name":"--fui-button-primary-active","value":"var(--fui-color-accent-active)"},{"name":"--fui-button-primary-border","value":"var(--fui-button-primary-base)"},{"name":"--fui-button-primary-border-hover","value":"var(--fui-button-primary-hover)"},{"name":"--fui-button-primary-bg","value":"var(--fui-button-primary-base)"},{"name":"--fui-button-primary-bg-hover","value":"var(--fui-button-primary-hover)"},{"name":"--fui-button-primary-bg-active","value":"var(--fui-button-primary-active)"},{"name":"--fui-button-primary-shadow","value":"none"},{"name":"--fui-button-primary-shadow-active","value":"none"},{"name":"--fui-button-neutral-color","value":"var(--fui-text-primary)"},{"name":"--fui-button-outlined-shadow","value":"none"},{"name":"--fui-button-neutral-shadow","value":"none"},{"name":"--fui-button-neutral-shadow-active","value":"none"},{"name":"--fui-button-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"--fui-button-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"--fui-button-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"--fui-button-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"--fui-input-height-sm","value":"calc(1 * 28px)"},{"name":"--fui-input-height","value":"calc(1 * 32px)"},{"name":"--fui-input-height-lg","value":"calc(1 * 40px)"},{"name":"--fui-touch-sm","value":"#{$fui-touch-sm}"},{"name":"--fui-touch-md","value":"#{$fui-touch-md}"},{"name":"--fui-touch-lg","value":"#{$fui-touch-lg}"}],"layout":[{"name":"--fui-header-search-bg","value":"var(--fui-bg-hover)"},{"name":"--fui-appshell-header-height","value":"#{$fui-appshell-header-height}"},{"name":"--fui-header-z-index","value":"40"}],"focus":[{"name":"--fui-focus-ring-color","value":"light-dark(#{$fui-focus-ring-color}, #{$fui-dark-focus-ring-color})"},{"name":"--fui-focus-ring-offset","value":"2px"},{"name":"--fui-focus-ring-width","value":"2px"}],"scrollbar":[{"name":"--fui-scrollbar-width","value":"8px"},{"name":"--fui-scrollbar-track","value":"light-dark(#{$fui-scrollbar-track}, #{$fui-dark-scrollbar-track})"},{"name":"--fui-scrollbar-thumb","value":"light-dark(#{$fui-scrollbar-thumb}, #{$fui-dark-scrollbar-thumb})"},{"name":"--fui-scrollbar-thumb-hover","value":"#{$fui-dark-scrollbar-thumb-hover}"},{"name":"$fui-base-font-size","value":"computed.$computed-base-font-size"},{"name":"$fui-base-unit","value":"computed.$computed-base-unit"},{"name":"$fui-font-sans","value":"\"Onest Variable\", Onest, -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif"},{"name":"$fui-font-mono","value":"\"JetBrains Mono Variable\", \"JetBrains Mono\", ui-monospace, \"SF Mono\", Menlo, monospace"},{"name":"$fui-font-size-2xs","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"2xs\")"},{"name":"$fui-font-size-xs","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"xs\")"},{"name":"$fui-font-size-sm","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"sm\")"},{"name":"$fui-font-size-base","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"base\")"},{"name":"$fui-font-size-md","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"md\")"},{"name":"$fui-font-size-lg","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"lg\")"},{"name":"$fui-font-size-xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"xl\")"},{"name":"$fui-font-size-2xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"2xl\")"},{"name":"$fui-font-size-3xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"3xl\")"},{"name":"$fui-font-size-4xl","value":"map.get(measurements.$legacy, \"typography\", \"fontSize\", \"4xl\")"},{"name":"$fui-popup-item-font-size","value":"$fui-font-size-xs"},{"name":"$fui-font-weight-normal","value":"map.get( measurements.$legacy, \"typography\", \"fontWeight\", \"normal\" )"},{"name":"$fui-font-weight-medium","value":"map.get( measurements.$legacy, \"typography\", \"fontWeight\", \"medium\" )"},{"name":"$fui-font-weight-semibold","value":"map.get( measurements.$legacy, \"typography\", \"fontWeight\", \"semibold\" )"},{"name":"$fui-font-weight-bold","value":"map.get(measurements.$legacy, \"typography\", \"fontWeight\", \"bold\")"},{"name":"$fui-line-height-tight","value":"map.get(measurements.$legacy, \"typography\", \"lineHeight\", \"tight\")"},{"name":"$fui-line-height-normal","value":"map.get( measurements.$legacy, \"typography\", \"lineHeight\", \"normal\" )"},{"name":"$fui-line-height-relaxed","value":"map.get( measurements.$legacy, \"typography\", \"lineHeight\", \"relaxed\" )"},{"name":"$fui-line-height-display","value":"map.get( measurements.$legacy, \"typography\", \"lineHeight\", \"display\" )"},{"name":"$fui-line-height-prose","value":"map.get(measurements.$legacy, \"typography\", \"lineHeight\", \"prose\")"},{"name":"$fui-letter-spacing-tight","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"tight\" )"},{"name":"$fui-letter-spacing-normal","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"normal\" )"},{"name":"$fui-letter-spacing-display","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"display\" )"},{"name":"$fui-letter-spacing-wide","value":"map.get( measurements.$legacy, \"typography\", \"letterSpacing\", \"wide\" )"},{"name":"$fui-space-px","value":"computed.$computed-space-px"},{"name":"$fui-space-0-5","value":"computed.$computed-space-0-5"},{"name":"$fui-space-0-75","value":"computed.$computed-space-0-75"},{"name":"$fui-space-1","value":"computed.$computed-space-1"},{"name":"$fui-space-2","value":"computed.$computed-space-2"},{"name":"$fui-space-3","value":"computed.$computed-space-3"},{"name":"$fui-space-4","value":"computed.$computed-space-4"},{"name":"$fui-space-5","value":"computed.$computed-space-5"},{"name":"$fui-space-6","value":"computed.$computed-space-6"},{"name":"$fui-space-8","value":"computed.$computed-space-8"},{"name":"$fui-space-10","value":"computed.$computed-space-10"},{"name":"$fui-space-12","value":"computed.$computed-space-12"},{"name":"$fui-popup-padding","value":"$fui-space-1"},{"name":"$fui-popup-row-gap","value":"1px"},{"name":"$fui-popup-item-padding-block","value":"$fui-space-1"},{"name":"$fui-popup-item-padding-inline","value":"$fui-space-2"},{"name":"$fui-radius-sm","value":"computed.$computed-radius-sm"},{"name":"$fui-radius-md","value":"computed.$computed-radius-md"},{"name":"$fui-radius-lg","value":"computed.$computed-radius-lg"},{"name":"$fui-radius-xl","value":"computed.$computed-radius-xl"},{"name":"$fui-radius-full","value":"computed.$computed-radius-full"},{"name":"$fui-radius-none","value":"0px"},{"name":"$fui-radius-l1","value":"$fui-radius-lg"},{"name":"$fui-radius-l2","value":"$fui-radius-md"},{"name":"$fui-radius-l3","value":"$fui-radius-sm"},{"name":"$fui-stroke-hairline","value":"measurements.target-value(\"stroke\", \"hairline\")"},{"name":"$fui-stroke-default","value":"measurements.target-value(\"stroke\", \"default\")"},{"name":"$fui-stroke-strong","value":"measurements.target-value(\"stroke\", \"strong\")"},{"name":"$fui-opacity-disabled","value":"0.5"},{"name":"$fui-opacity-muted","value":"0.7"},{"name":"$fui-opacity-faint","value":"0.3"},{"name":"$fui-control-selected-border","value":"transparent"},{"name":"$fui-scale","value":"1"},{"name":"$fui-control-track-micro","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$fui-control-track-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"$fui-control-track-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$fui-control-track-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"$fui-transition-fast","value":"160ms cubic-bezier(0.25, 0.46, 0.45, 0.94)"},{"name":"$fui-transition-normal","value":"200ms cubic-bezier(0.4, 0, 0.2, 1)"},{"name":"$fui-color-accent","value":"computed.$computed-color-accent"},{"name":"$fui-color-on-accent","value":"computed.$computed-color-on-accent"},{"name":"$fui-color-accent-hover","value":"computed.$computed-color-accent-hover"},{"name":"$fui-color-accent-active","value":"computed.$computed-color-accent-active"},{"name":"$fui-color-danger","value":"computed.$computed-color-danger"},{"name":"$fui-color-danger-hover","value":"computed.$computed-color-danger-hover"},{"name":"$fui-color-success","value":"computed.$computed-color-success"},{"name":"$fui-color-warning","value":"computed.$computed-color-warning"},{"name":"$fui-color-info","value":"computed.$computed-color-info"},{"name":"$fui-color-danger-bg","value":"computed.$computed-color-danger-bg"},{"name":"$fui-color-success-bg","value":"computed.$computed-color-success-bg"},{"name":"$fui-color-warning-bg","value":"computed.$computed-color-warning-bg"},{"name":"$fui-color-info-bg","value":"computed.$computed-color-info-bg"},{"name":"$fui-color-danger-text","value":"computed.$computed-color-danger-text"},{"name":"$fui-color-success-text","value":"computed.$computed-color-success-text"},{"name":"$fui-color-warning-text","value":"computed.$computed-color-warning-text"},{"name":"$fui-color-info-text","value":"computed.$computed-color-info-text"},{"name":"$fui-color-danger-border","value":"color-mix(in srgb, $fui-color-danger-text 30%, transparent)"},{"name":"$fui-color-success-border","value":"color-mix(in srgb, $fui-color-success-text 28%, transparent)"},{"name":"$fui-color-warning-border","value":"color-mix(in srgb, $fui-color-warning-text 28%, transparent)"},{"name":"$fui-color-info-border","value":"color-mix(in srgb, $fui-color-info-text 30%, transparent)"},{"name":"$fui-bg-primary","value":"computed.$computed-bg-primary"},{"name":"$fui-bg-secondary","value":"computed.$computed-bg-secondary"},{"name":"$fui-bg-tertiary","value":"computed.$computed-bg-tertiary"},{"name":"$fui-bg-elevated","value":"computed.$computed-bg-elevated"},{"name":"$fui-bg-subtle","value":"computed.$computed-bg-subtle"},{"name":"$fui-bg-hover","value":"computed.$computed-bg-hover"},{"name":"$fui-bg-active","value":"computed.$computed-bg-active"},{"name":"$fui-body-bg","value":"computed.$computed-body-bg"},{"name":"$fui-main-bg","value":"computed.$computed-main-bg"},{"name":"$fui-text-primary","value":"computed.$computed-text-primary"},{"name":"$fui-text-secondary","value":"computed.$computed-text-secondary"},{"name":"$fui-text-tertiary","value":"computed.$computed-text-tertiary"},{"name":"$fui-text-inverse","value":"computed.$computed-text-inverse"},{"name":"$fui-bg-inverse","value":"$fui-text-primary"},{"name":"$fui-border","value":"computed.$computed-border"},{"name":"$fui-border-default","value":"computed.$computed-border-default"},{"name":"$fui-border-strong","value":"computed.$computed-border-strong"},{"name":"$fui-shadow-sm","value":"computed.$computed-shadow-sm"},{"name":"$fui-shadow-md","value":"computed.$computed-shadow-md"},{"name":"$fui-shadow-lg","value":"computed.$computed-shadow-lg"},{"name":"$fui-focus-ring-color","value":"computed.$computed-focus-ring-color"},{"name":"$fui-focus-ring-offset","value":"2px"},{"name":"$fui-focus-ring-width","value":"2px"},{"name":"$fui-scrollbar-width","value":"8px"},{"name":"$fui-scrollbar-track","value":"computed.$computed-scrollbar-track"},{"name":"$fui-scrollbar-thumb","value":"computed.$computed-scrollbar-thumb"},{"name":"$fui-scrollbar-thumb-hover","value":"computed.$computed-scrollbar-thumb-hover"},{"name":"$fui-dark-color-accent","value":"computed.$computed-dark-color-accent"},{"name":"$fui-dark-color-on-accent","value":"computed.$computed-dark-color-on-accent"},{"name":"$fui-dark-color-accent-hover","value":"computed.$computed-dark-color-accent-hover"},{"name":"$fui-dark-color-accent-active","value":"computed.$computed-dark-color-accent-active"},{"name":"$fui-brand-is-default","value":"computed.$brand-is-fragments-default"},{"name":"$_rt-dark-accent","value":"$fui-dark-color-accent"},{"name":"$_rt-dark-accent-hover","value":"$fui-dark-color-accent-hover"},{"name":"$_rt-dark-accent-active","value":"$fui-dark-color-accent-active"},{"name":"$fui-dark-bg-primary","value":"computed.$computed-dark-bg-primary"},{"name":"$fui-dark-bg-secondary","value":"computed.$computed-dark-bg-secondary"},{"name":"$fui-dark-bg-tertiary","value":"computed.$computed-dark-bg-tertiary"},{"name":"$fui-dark-bg-elevated","value":"computed.$computed-dark-bg-elevated"},{"name":"$fui-dark-bg-subtle","value":"computed.$computed-dark-bg-subtle"},{"name":"$fui-dark-bg-hover","value":"computed.$computed-dark-bg-hover"},{"name":"$fui-dark-bg-active","value":"computed.$computed-dark-bg-active"},{"name":"$fui-dark-body-bg","value":"computed.$computed-dark-body-bg"},{"name":"$fui-dark-main-bg","value":"computed.$computed-dark-main-bg"},{"name":"$fui-dark-text-primary","value":"computed.$computed-dark-text-primary"},{"name":"$fui-dark-text-secondary","value":"computed.$computed-dark-text-secondary"},{"name":"$fui-dark-text-tertiary","value":"computed.$computed-dark-text-tertiary"},{"name":"$fui-dark-text-inverse","value":"computed.$computed-dark-text-inverse"},{"name":"$fui-dark-bg-inverse","value":"computed.$computed-dark-text-primary"},{"name":"$fui-dark-border","value":"computed.$computed-dark-border"},{"name":"$fui-dark-border-default","value":"computed.$computed-dark-border-default"},{"name":"$fui-dark-border-strong","value":"computed.$computed-dark-border-strong"},{"name":"$fui-dark-shadow-sm","value":"computed.$computed-dark-shadow-sm"},{"name":"$fui-dark-shadow-md","value":"computed.$computed-dark-shadow-md"},{"name":"$fui-dark-shadow-lg","value":"computed.$computed-dark-shadow-lg"},{"name":"$fui-dark-color-danger-bg","value":"computed.$computed-dark-color-danger-bg"},{"name":"$fui-dark-color-success-bg","value":"computed.$computed-dark-color-success-bg"},{"name":"$fui-dark-color-warning-bg","value":"computed.$computed-dark-color-warning-bg"},{"name":"$fui-dark-color-info-bg","value":"computed.$computed-dark-color-info-bg"},{"name":"$fui-dark-color-danger-text","value":"computed.$computed-dark-color-danger-text"},{"name":"$fui-dark-color-success-text","value":"computed.$computed-dark-color-success-text"},{"name":"$fui-dark-color-warning-text","value":"computed.$computed-dark-color-warning-text"},{"name":"$fui-dark-color-info-text","value":"computed.$computed-dark-color-info-text"},{"name":"$fui-dark-focus-ring-color","value":"computed.$computed-dark-focus-ring-color"},{"name":"$fui-dark-scrollbar-track","value":"computed.$computed-dark-scrollbar-track"},{"name":"$fui-dark-scrollbar-thumb","value":"computed.$computed-dark-scrollbar-thumb"},{"name":"$fui-dark-scrollbar-thumb-hover","value":"computed.$computed-dark-scrollbar-thumb-hover"},{"name":"$fui-backdrop","value":"computed.$computed-backdrop"},{"name":"$fui-dark-backdrop","value":"computed.$computed-dark-backdrop"},{"name":"$fui-breakpoint-sm","value":"640px"},{"name":"$fui-breakpoint-md","value":"768px"},{"name":"$fui-breakpoint-lg","value":"1024px"},{"name":"$fui-breakpoint-xl","value":"1280px"},{"name":"$fui-control-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$fui-control-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"$fui-control-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$fui-control-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"$fui-button-height-xs","value":"measurements.target-value(\"controlTrack\", \"micro\")"},{"name":"$fui-button-height-sm","value":"measurements.target-value(\"controlTrack\", \"sm\")"},{"name":"$fui-button-height-md","value":"measurements.target-value(\"controlTrack\", \"md\")"},{"name":"$fui-button-height-lg","value":"measurements.target-value(\"controlTrack\", \"lg\")"},{"name":"$fui-button-outlined-shadow","value":"none"},{"name":"$fui-input-height-sm","value":"measurements.target-value(\"fieldTrack\", \"sm\")"},{"name":"$fui-input-height","value":"measurements.target-value(\"fieldTrack\", \"md\")"},{"name":"$fui-input-height-lg","value":"measurements.target-value(\"fieldTrack\", \"lg\")"},{"name":"$fui-touch-sm","value":"computed.$computed-touch-sm"},{"name":"$fui-touch-md","value":"computed.$computed-touch-md"},{"name":"$fui-touch-lg","value":"computed.$computed-touch-lg"},{"name":"$fui-target-size-min","value":"map.get(measurements.$legacy, \"touch\", \"minimum\")"},{"name":"$fui-target-size-comfortable","value":"$fui-touch-md"},{"name":"$fui-icon-xs","value":"measurements.target-value(\"icon\", \"xs\")"},{"name":"$fui-icon-sm","value":"measurements.target-value(\"icon\", \"sm\")"},{"name":"$fui-icon-md","value":"measurements.target-value(\"icon\", \"md\")"},{"name":"$fui-icon-lg","value":"measurements.target-value(\"icon\", \"lg\")"},{"name":"$fui-icon-xl","value":"measurements.target-value(\"icon\", \"xl\")"},{"name":"$fui-icon-2xl","value":"measurements.target-value(\"icon\", \"2xl\")"},{"name":"$fui-anim-offset-sm","value":"4px"},{"name":"$fui-anim-offset-md","value":"8px"},{"name":"$fui-duration-spin","value":"800ms"},{"name":"$fui-duration-pulse","value":"1500ms"},{"name":"$fui-duration-shimmer","value":"2000ms"},{"name":"$fui-overlay-layer-swipe","value":"49"},{"name":"$fui-overlay-layer-backdrop","value":"50"},{"name":"$fui-overlay-layer-modal","value":"51"},{"name":"$fui-overlay-layer-anchored","value":"52"},{"name":"$fui-overlay-layer-toast","value":"55"},{"name":"$fui-overlay-layer-tooltip","value":"60"},{"name":"$fui-sidebar-item-height","value":"computed.$computed-sidebar-item-height"},{"name":"$fui-appshell-header-height","value":"map.get( measurements.$legacy, \"navigation\", \"appShellHeaderHeight\" )"},{"name":"$fui-header-z-index","value":"40"},{"name":"$fui-code-bg","value":"light-dark(#{$fui-bg-tertiary}, #{$fui-dark-bg-tertiary})"},{"name":"$fui-card-accent-bg","value":"$fui-bg-tertiary"},{"name":"$fui-card-accent-border","value":"color-mix(in srgb, $fui-color-accent 30%, $fui-border)"},{"name":"$fui-card-accent-radius","value":"$fui-radius-xl"},{"name":"$fui-code-selection-bg","value":"color-mix( in srgb, var(--fui-color-accent, #f56138) 30%, transparent )"},{"name":"$fui-code-text","value":"$fui-text-primary"},{"name":"$fui-code-token-keyword","value":"#9a3412"},{"name":"$fui-code-token-string","value":"#166534"},{"name":"$fui-code-token-comment","value":"#5c5348"},{"name":"$fui-code-token-function","value":"#1e3a8a"},{"name":"$fui-code-token-number","value":"#92400e"},{"name":"$fui-code-token-punctuation","value":"#3d3429"},{"name":"$fui-code-token-variable","value":"#3d3429"},{"name":"$fui-dark-code-token-keyword","value":"#f56138"},{"name":"$fui-dark-code-token-string","value":"#7dcea0"},{"name":"$fui-dark-code-token-comment","value":"#a89b8c"},{"name":"$fui-dark-code-token-function","value":"#8cb4e8"},{"name":"$fui-dark-code-token-number","value":"#e8b86d"},{"name":"$fui-dark-code-token-punctuation","value":"#c9c2b8"},{"name":"$fui-dark-code-token-variable","value":"#f0ede9"},{"name":"$fui-link-ink","value":"#9a3412"},{"name":"$fui-dark-link-ink","value":"$fui-dark-color-accent"}],"sidebar":[{"name":"--fui-sidebar-item-height","value":"#{$fui-sidebar-item-height}"}],"semantic-borders":[{"name":"--fui-color-danger-border","value":"color-mix(in srgb, var(--fui-color-danger-text) 30%, transparent)"},{"name":"--fui-color-success-border","value":"color-mix(in srgb, var(--fui-color-success-text) 28%, transparent)"},{"name":"--fui-color-warning-border","value":"color-mix(in srgb, var(--fui-color-warning-text) 28%, transparent)"},{"name":"--fui-color-info-border","value":"color-mix(in srgb, var(--fui-color-info-text) 30%, transparent)"}]}},"graph":{"nodes":[{"name":"Accordion","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Item","Trigger","Content"]},{"name":"Alert","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Icon","Body","Title","Content","Actions","Action","Close"]},{"name":"AppShell","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Sidebar","Main","Aside"]},{"name":"Avatar","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Group"]},{"name":"Badge","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"BentoGrid","category":"layout","status":"stable"},{"name":"Box","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Breadcrumbs","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Item","Separator"]},{"name":"Button","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"ButtonGroup","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Card","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Title","Description","Body","Footer"]},{"name":"Chart","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root","Tooltip","TooltipContent","Legend","LegendContent","preload"]},{"name":"Checkbox","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Chip","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Group"]},{"name":"CodeBlock","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Tabbed"]},{"name":"Collapsible","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root","Trigger","Content"]},{"name":"ColorPicker","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root","preload"]},{"name":"Combobox","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Input","Trigger","Content","Item","ItemIndicator","Empty","Group","GroupLabel"]},{"name":"Command","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Input","List","Item","Group","Empty","Separator"]},{"name":"ComponentDefaults","category":"utilities","status":"stable"},{"name":"ConversationList","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["DateSeparator","TypingIndicator"]},{"name":"DataTable","category":"display","status":"stable","compositionPattern":"simple","subComponents":["Root","Columns","preload"]},{"name":"DatePicker","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Calendar","Preset","preload"]},{"name":"Dialog","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Close","Header","Title","Description","Body","Footer"]},{"name":"Drawer","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Close","SwipeArea","Header","Title","Description","Body","Footer"]},{"name":"Editor","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Toolbar","ToolbarGroup","ToolbarButton","Separator","StatusIndicator","Content","StatusBar","preload"]},{"name":"EmptyState","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Icon","Title","Description","Actions"]},{"name":"Field","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Label","Control","Description","Error","Validity","Required"]},{"name":"Fieldset","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Legend","Description"]},{"name":"Form","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root","Actions"]},{"name":"Grid","category":"layout","status":"stable"},{"name":"Header","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["SkipLink","Trigger","Brand","Nav","NavItem","MobileNav","MobileNavLink","MobileNavActions","NavMenu","NavMenuItem","Search","Spacer","Actions"]},{"name":"Icon","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"IconButton","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Image","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Input","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Link","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"List","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Item"]},{"name":"Listbox","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Item","Group","Empty"]},{"name":"Loading","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Inline","Screen"]},{"name":"Main","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Description","Content","Footer"]},{"name":"Markdown","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root","preload"]},{"name":"Menu","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Item","CheckboxItem","RadioGroup","RadioItem","Group","GroupLabel","Separator","Submenu","SubmenuTrigger"]},{"name":"Message","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["Content","Actions","Timestamp","Avatar"]},{"name":"NavigationMenu","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["List","Item","Trigger","Content","Link","Indicator","Viewport","MobileBrand","MobileContent","MobileSection"]},{"name":"Pagination","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Previous","Next","Items","Item","Ellipsis"]},{"name":"Popover","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Close","Title","Description","Body","Footer"]},{"name":"Progress","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Root","Circular"]},{"name":"Prompt","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["Textarea","Toolbar","Tabs","Tab","Actions","Info","ActionButton","ModeButton","Select","Attach","Attachments","Usage","Submit"]},{"name":"RadioGroup","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Item"]},{"name":"ScrollArea","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Select","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Trigger","Content","Item","Group","GroupLabel"]},{"name":"Separator","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Sidebar","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Header","Nav","Section","SectionAction","Item","SubItem","Submenu","Footer","Trigger","Overlay","CollapseToggle","Rail","MenuSkeleton"]},{"name":"Skeleton","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Text","Circle"]},{"name":"Slider","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Stack","category":"layout","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Switch","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Table","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root","Head","Body","Footer","Row","Cell","HeaderCell","Caption"]},{"name":"TableOfContents","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["Item","Group"]},{"name":"Tabs","category":"navigation","status":"stable","compositionPattern":"compound","subComponents":["List","Tab","Panel"]},{"name":"Text","category":"display","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Textarea","category":"inputs","status":"stable","compositionPattern":"compound","subComponents":["Root"]},{"name":"Theme","category":"utilities","status":"stable","compositionPattern":"compound","subComponents":["Root","Provider","Toggle","Button","useTheme"]},{"name":"ThinkingIndicator","category":"ai","status":"stable","compositionPattern":"compound","subComponents":["Steps","Step"]},{"name":"Toast","category":"feedback","status":"stable","compositionPattern":"compound","subComponents":["Provider"]},{"name":"ToggleGroup","category":"actions","status":"stable","compositionPattern":"compound","subComponents":["Item"]},{"name":"Tooltip","category":"overlays","status":"stable","compositionPattern":"compound","subComponents":["Root","Provider"]},{"name":"VisuallyHidden","category":"utilities","status":"stable","compositionPattern":"compound","subComponents":["Root"]}],"edges":[{"s":"AppShell","t":"Sidebar","ty":"imports","w":1,"p":"source:AppShell/index.tsx"},{"s":"AppShell","t":"Sidebar","ty":"hook-depends","w":0.75,"p":"source:AppShell/index.tsx"},{"s":"CodeBlock","t":"Button","ty":"imports","w":1,"p":"source:CodeBlock/index.tsx"},{"s":"CodeBlock","t":"IconButton","ty":"imports","w":1,"p":"source:CodeBlock/index.tsx"},{"s":"ColorPicker","t":"Input","ty":"imports","w":1,"p":"source:ColorPicker/index.tsx"},{"s":"ConversationList","t":"Loading","ty":"imports","w":1,"p":"source:ConversationList/index.tsx"},{"s":"DataTable","t":"Checkbox","ty":"imports","w":1,"p":"source:DataTable/index.tsx"},{"s":"Header","t":"ScrollArea","ty":"imports","w":1,"p":"source:Header/index.tsx"},{"s":"Header","t":"Sidebar","ty":"hook-depends","w":0.75,"p":"source:Header/index.tsx"},{"s":"Main","t":"Stack","ty":"imports","w":1,"p":"source:Main/index.tsx"},{"s":"Message","t":"Avatar","ty":"imports","w":1,"p":"source:Message/index.tsx"},{"s":"Message","t":"Markdown","ty":"imports","w":1,"p":"source:Message/index.tsx"},{"s":"NavigationMenu","t":"Collapsible","ty":"imports","w":1,"p":"source:NavigationMenu/index.tsx"},{"s":"NavigationMenu","t":"ScrollArea","ty":"imports","w":1,"p":"source:NavigationMenu/index.tsx"},{"s":"Prompt","t":"Loading","ty":"imports","w":1,"p":"source:Prompt/index.tsx"},{"s":"Prompt","t":"Select","ty":"imports","w":1,"p":"source:Prompt/index.tsx"},{"s":"Sidebar","t":"Badge","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"Tooltip","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"Skeleton","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"Collapsible","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"Sidebar","t":"ScrollArea","ty":"imports","w":1,"p":"source:Sidebar/index.tsx"},{"s":"TableOfContents","t":"Text","ty":"imports","w":1,"p":"source:TableOfContents/index.tsx"},{"s":"Theme","t":"ComponentDefaults","ty":"imports","w":1,"p":"source:Theme/index.tsx"},{"s":"ThinkingIndicator","t":"Loading","ty":"imports","w":1,"p":"source:ThinkingIndicator/index.tsx"},{"s":"Toast","t":"Button","ty":"imports","w":1,"p":"source:Toast/index.tsx"},{"s":"Toast","t":"IconButton","ty":"imports","w":1,"p":"source:Toast/index.tsx"},{"s":"AppShell","t":"Box","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Header","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Sidebar","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Icon","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Stack","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"AppShell","t":"Text","ty":"renders","w":0.5,"p":"variant:AppShell"},{"s":"Avatar","t":"Stack","ty":"renders","w":0.5,"p":"variant:Avatar"},{"s":"Badge","t":"Stack","ty":"renders","w":0.5,"p":"variant:Badge"},{"s":"BentoGrid","t":"Box","ty":"renders","w":0.5,"p":"variant:BentoGrid"},{"s":"Box","t":"Stack","ty":"renders","w":0.5,"p":"variant:Box"},{"s":"Button","t":"Stack","ty":"renders","w":0.5,"p":"variant:Button"},{"s":"ButtonGroup","t":"Button","ty":"renders","w":0.5,"p":"variant:ButtonGroup"},{"s":"ButtonGroup","t":"Stack","ty":"renders","w":0.5,"p":"variant:ButtonGroup"},{"s":"Card","t":"Text","ty":"renders","w":0.5,"p":"variant:Card"},{"s":"Chip","t":"Stack","ty":"renders","w":0.5,"p":"variant:Chip"},{"s":"CodeBlock","t":"Button","ty":"renders","w":0.5,"p":"variant:CodeBlock"},{"s":"CodeBlock","t":"Card","ty":"renders","w":0.5,"p":"variant:CodeBlock"},{"s":"Command","t":"Dialog","ty":"renders","w":0.5,"p":"variant:Command"},{"s":"Command","t":"Button","ty":"renders","w":0.5,"p":"variant:Command"},{"s":"ComponentDefaults","t":"Button","ty":"renders","w":0.5,"p":"variant:ComponentDefaults"},{"s":"ConversationList","t":"Message","ty":"renders","w":0.5,"p":"variant:ConversationList"},{"s":"ConversationList","t":"EmptyState","ty":"renders","w":0.5,"p":"variant:ConversationList"},{"s":"DataTable","t":"Stack","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"DataTable","t":"Avatar","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"DataTable","t":"Badge","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"DataTable","t":"Input","ty":"renders","w":0.5,"p":"variant:DataTable"},{"s":"Dialog","t":"Button","ty":"renders","w":0.5,"p":"variant:Dialog"},{"s":"Drawer","t":"Button","ty":"renders","w":0.5,"p":"variant:Drawer"},{"s":"Drawer","t":"Stack","ty":"renders","w":0.5,"p":"variant:Drawer"},{"s":"Drawer","t":"Input","ty":"renders","w":0.5,"p":"variant:Drawer"},{"s":"Editor","t":"Button","ty":"renders","w":0.5,"p":"variant:Editor"},{"s":"EmptyState","t":"Button","ty":"renders","w":0.5,"p":"variant:EmptyState"},{"s":"Field","t":"Input","ty":"renders","w":0.5,"p":"variant:Field"},{"s":"Field","t":"Grid","ty":"renders","w":0.5,"p":"variant:Field"},{"s":"Fieldset","t":"Grid","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Field","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Input","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Textarea","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Select","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Fieldset","t":"Checkbox","ty":"renders","w":0.5,"p":"variant:Fieldset"},{"s":"Form","t":"Grid","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Field","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Input","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Checkbox","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Button","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Fieldset","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Select","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Textarea","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"Switch","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Form","t":"RadioGroup","ty":"renders","w":0.5,"p":"variant:Form"},{"s":"Grid","t":"Box","ty":"renders","w":0.5,"p":"variant:Grid"},{"s":"Grid","t":"Field","ty":"renders","w":0.5,"p":"variant:Grid"},{"s":"Grid","t":"Input","ty":"renders","w":0.5,"p":"variant:Grid"},{"s":"Header","t":"Box","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"Button","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"Input","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"NavigationMenu","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"Header","t":"Stack","ty":"renders","w":0.5,"p":"variant:Header"},{"s":"IconButton","t":"Stack","ty":"renders","w":0.5,"p":"variant:IconButton"},{"s":"Link","t":"Stack","ty":"renders","w":0.5,"p":"variant:Link"},{"s":"Loading","t":"Stack","ty":"renders","w":0.5,"p":"variant:Loading"},{"s":"Main","t":"Box","ty":"renders","w":0.5,"p":"variant:Main"},{"s":"Menu","t":"Button","ty":"renders","w":0.5,"p":"variant:Menu"},{"s":"Message","t":"Button","ty":"renders","w":0.5,"p":"variant:Message"},{"s":"Popover","t":"Button","ty":"renders","w":0.5,"p":"variant:Popover"},{"s":"Popover","t":"Input","ty":"renders","w":0.5,"p":"variant:Popover"},{"s":"Progress","t":"Stack","ty":"renders","w":0.5,"p":"variant:Progress"},{"s":"ScrollArea","t":"Box","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"ScrollArea","t":"Stack","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"ScrollArea","t":"Text","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"ScrollArea","t":"Chip","ty":"renders","w":0.5,"p":"variant:ScrollArea"},{"s":"Separator","t":"Box","ty":"renders","w":0.5,"p":"variant:Separator"},{"s":"Separator","t":"Text","ty":"renders","w":0.5,"p":"variant:Separator"},{"s":"Separator","t":"Stack","ty":"renders","w":0.5,"p":"variant:Separator"},{"s":"Sidebar","t":"Stack","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Sidebar","t":"Text","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Sidebar","t":"Button","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Sidebar","t":"Link","ty":"renders","w":0.5,"p":"variant:Sidebar"},{"s":"Stack","t":"Box","ty":"renders","w":0.5,"p":"variant:Stack"},{"s":"Stack","t":"Button","ty":"renders","w":0.5,"p":"variant:Stack"},{"s":"Stack","t":"Text","ty":"renders","w":0.5,"p":"variant:Stack"},{"s":"Toast","t":"Stack","ty":"renders","w":0.5,"p":"variant:Toast"},{"s":"ToggleGroup","t":"Stack","ty":"renders","w":0.5,"p":"variant:ToggleGroup"},{"s":"Tooltip","t":"Button","ty":"renders","w":0.5,"p":"variant:Tooltip"},{"s":"Tooltip","t":"Stack","ty":"renders","w":0.5,"p":"variant:Tooltip"},{"s":"Card","t":"Stack","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Card","t":"Text","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Card","t":"Avatar","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Stack","t":"Text","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Stack","t":"Avatar","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"Text","t":"Avatar","ty":"composes","w":0.5,"p":"block:Activity Feed"},{"s":"AppShell","t":"Header","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Sidebar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"AppShell","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Sidebar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Header","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Stack","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Sidebar","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Grid","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Stack","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Card","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Text","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Grid","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Card","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Card","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Card","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Text","t":"Badge","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Text","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Text","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Badge","t":"Input","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Badge","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Badge","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Input","t":"ThemeToggle","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Input","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"ThemeToggle","t":"Avatar","ty":"composes","w":0.5,"p":"block:Dashboard Layout"},{"s":"Card","t":"Button","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Card","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Stack","t":"Button","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Stack","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Input","t":"Button","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Input","t":"Text","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Input","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Button","t":"Text","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Button","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Text","t":"Link","ty":"composes","w":0.5,"p":"block:Login Form"},{"s":"Card","t":"Icon","ty":"composes","w":0.5,"p":"block:Stats Card"},{"s":"Stack","t":"Icon","ty":"composes","w":0.5,"p":"block:Stats Card"},{"s":"Text","t":"Icon","ty":"composes","w":0.5,"p":"block:Stats Card"},{"s":"Badge","t":"Icon","ty":"composes","w":0.5,"p":"block:Stats Card"},{"s":"Accordion","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Use Tabs for horizontal switching between related views"},{"s":"Accordion","t":"Dialog","ty":"alternative-to","w":1,"p":"relation","no":"Use Dialog for focused content that interrupts the flow"},{"s":"Alert","t":"Badge","ty":"alternative-to","w":1,"p":"relation","no":"Use Badge for compact, inline status labels"},{"s":"Alert","t":"Toast","ty":"alternative-to","w":1,"p":"relation","no":"Use Toast for transient notifications that auto-dismiss"},{"s":"Alert","t":"Dialog","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Dialog for blocking confirmations"},{"s":"Theme","t":"AppShell","ty":"parent-of","w":1,"p":"relation","no":"AppShell should be wrapped in ThemeProvider"},{"s":"AppShell","t":"Header","ty":"parent-of","w":1,"p":"relation","no":"Header is placed inside AppShell.Header"},{"s":"AppShell","t":"Sidebar","ty":"parent-of","w":1,"p":"relation","no":"Sidebar content goes inside AppShell.Sidebar"},{"s":"Avatar","t":"Image","ty":"alternative-to","w":1,"p":"relation","no":"Use Image for content pictures that are not a person or entity"},{"s":"Avatar","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with Badge to show presence or role beside a name"},{"s":"Badge","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for prominent, longer messages with actions"},{"s":"Badge","t":"Chip","ty":"sibling-of","w":0.75,"p":"relation","no":"Chip is interactive (clickable/filterable); Badge is display-only"},{"s":"BentoGrid","t":"Grid","ty":"alternative-to","w":1,"p":"relation","no":"Use Grid for uniform layouts; BentoGrid for asymmetric spans with built-in surfaces"},{"s":"BentoGrid","t":"Card","ty":"sibling-of","w":0.75,"p":"relation","no":"BentoGrid.Item has built-in surface styling similar to Card"},{"s":"Box","t":"Stack","ty":"alternative-to","w":1,"p":"relation","no":"Use Stack for directional layouts with gap"},{"s":"Box","t":"Grid","ty":"alternative-to","w":1,"p":"relation","no":"Use Grid for column-based layouts"},{"s":"Box","t":"Card","ty":"alternative-to","w":1,"p":"relation","no":"Use Card for content containers with structure"},{"s":"Breadcrumbs","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Use Tabs for flat, non-hierarchical navigation"},{"s":"Button","t":"Link","ty":"alternative-to","w":1,"p":"relation","no":"Use Link for navigation without action context"},{"s":"ButtonGroup","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Use ButtonGroup for related action sets"},{"s":"ButtonGroup","t":"Stack","ty":"alternative-to","w":1,"p":"relation","no":"Use Stack for more general layout needs"},{"s":"Grid","t":"Card","ty":"parent-of","w":1,"p":"relation","no":"Use Grid + Card for responsive card layouts"},{"s":"Card","t":"List","ty":"alternative-to","w":1,"p":"relation","no":"Use List for linear, text-first layouts"},{"s":"Card","t":"Chart","ty":"parent-of","w":1,"p":"relation","no":"Charts are typically placed inside Cards"},{"s":"Chart","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress for single-value completion"},{"s":"Chart","t":"Table","ty":"sibling-of","w":0.75,"p":"relation","no":"Combine with Table for full data views"},{"s":"Checkbox","t":"Switch","ty":"alternative-to","w":1,"p":"relation","no":"Use Switch for immediate-effect settings"},{"s":"Checkbox","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Checkbox handles boolean; Input handles text"},{"s":"Chip","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Badge is display-only; Chip is interactive"},{"s":"Chip","t":"ToggleGroup","ty":"alternative-to","w":1,"p":"relation","no":"Use ToggleGroup for mutually exclusive options"},{"s":"Chip","t":"Button","ty":"alternative-to","w":1,"p":"relation","no":"Use Button for primary actions, Chip for selection/filtering"},{"s":"Card","t":"CodeBlock","ty":"parent-of","w":1,"p":"relation","no":"Can be wrapped in Card for additional context"},{"s":"CodeBlock","t":"Tabs","ty":"parent-of","w":1,"p":"relation","no":"Use in Tabs for showing code in multiple languages"},{"s":"Collapsible","t":"Accordion","ty":"alternative-to","w":1,"p":"relation","no":"Use Accordion for multiple exclusive collapsible sections"},{"s":"Collapsible","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for dropdown navigation with actions"},{"s":"ColorPicker","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"ColorPicker is a specialized input for colors"},{"s":"ColorPicker","t":"RadioGroup","ty":"alternative-to","w":1,"p":"relation","no":"Use RadioGroup for predefined color choices"},{"s":"Field","t":"ColorPicker","ty":"parent-of","w":1,"p":"relation","no":"ColorPicker uses Field internally for structure"},{"s":"Combobox","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select when search/filtering is not needed"},{"s":"Combobox","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Input for free-form text entry"},{"s":"Combobox","t":"Listbox","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Listbox for inline option lists"},{"s":"Command","t":"Dialog","ty":"sibling-of","w":0.75,"p":"relation","no":"Compose inside Dialog for modal command palette"},{"s":"Command","t":"Listbox","ty":"sibling-of","w":0.75,"p":"relation","no":"Command uses Listbox-like keyboard navigation internally"},{"s":"Command","t":"Combobox","ty":"alternative-to","w":1,"p":"relation","no":"Use Combobox for form field selection with search"},{"s":"Theme","t":"ComponentDefaults","ty":"parent-of","w":1,"p":"relation","no":"ThemeProvider accepts componentDefaults and mounts this provider"},{"s":"ComponentDefaults","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Controls resolve their size through useResolvedControlSize"},{"s":"ConversationList","t":"Message","ty":"parent-of","w":1,"p":"relation","no":"ConversationList contains Message components"},{"s":"ConversationList","t":"ThinkingIndicator","ty":"parent-of","w":1,"p":"relation","no":"Show ThinkingIndicator at bottom while awaiting response"},{"s":"ConversationList","t":"Prompt","ty":"sibling-of","w":0.75,"p":"relation","no":"Typically paired with Prompt for input"},{"s":"DataTable","t":"Table","ty":"alternative-to","w":1,"p":"relation","no":"Use Table for simple semantic HTML tables"},{"s":"DataTable","t":"EmptyState","ty":"sibling-of","w":0.75,"p":"relation","no":"Use EmptyState for empty table states"},{"s":"DataTable","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Badge for status columns"},{"s":"DataTable","t":"Menu","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Menu for filter dropdowns"},{"s":"DataTable","t":"Checkbox","ty":"sibling-of","w":0.75,"p":"relation","no":"Built-in checkbox selection via showCheckbox"},{"s":"DatePicker","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for choosing from a list of options"},{"s":"DatePicker","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Input for free-form text date entry"},{"s":"DatePicker","t":"Popover","ty":"composes","w":0.5,"p":"relation","no":"DatePicker uses Popover for the calendar dropdown"},{"s":"Dialog","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for non-modal contextual content"},{"s":"Dialog","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action lists"},{"s":"Dialog","t":"Alert","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Alert for inline notifications"},{"s":"Drawer","t":"Dialog","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Dialog for centered modal overlays"},{"s":"Drawer","t":"Sidebar","ty":"alternative-to","w":1,"p":"relation","no":"Use Sidebar for permanent side navigation"},{"s":"Drawer","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for small contextual content"},{"s":"Editor","t":"Prompt","ty":"sibling-of","w":0.75,"p":"relation","no":"Prompt is for AI/chat input; Editor is for long-form content editing"},{"s":"Editor","t":"Textarea","ty":"alternative-to","w":1,"p":"relation","no":"Use Textarea for simple multi-line input without formatting toolbar"},{"s":"Editor","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for single-line text input"},{"s":"EmptyState","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for error states with retry"},{"s":"EmptyState","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress/Spinner for loading states"},{"s":"Field","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for simple fields with built-in label/error"},{"s":"Form","t":"Field","ty":"parent-of","w":1,"p":"relation","no":"Wrap in Form for server-side error distribution"},{"s":"Field","t":"Fieldset","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Fieldset to group related fields"},{"s":"Fieldset","t":"Field","ty":"sibling-of","w":0.75,"p":"relation","no":"Contains Field components"},{"s":"Form","t":"Fieldset","ty":"parent-of","w":1,"p":"relation","no":"Used within a Form"},{"s":"Fieldset","t":"Card","ty":"alternative-to","w":1,"p":"relation","no":"Use Card for non-form visual grouping"},{"s":"Form","t":"Field","ty":"sibling-of","w":0.75,"p":"relation","no":"Contains Field components for error distribution"},{"s":"Form","t":"Fieldset","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Fieldset to group fields within a Form"},{"s":"Form","t":"Button","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Button type=\"submit\" for form submission"},{"s":"Grid","t":"Separator","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Separator between grid sections"},{"s":"Header","t":"Sidebar","ty":"sibling-of","w":0.75,"p":"relation","no":"Header.Trigger toggles Sidebar on mobile"},{"s":"Header","t":"Theme","ty":"parent-of","w":1,"p":"relation","no":"ThemeToggle is commonly placed in Header.Actions"},{"s":"Header","t":"NavigationMenu","ty":"parent-of","w":1,"p":"relation","no":"Use NavigationMenu inside Header for rich dropdown nav with auto mobile drawer"},{"s":"Icon","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Use inside icon-only buttons with VisuallyHidden label"},{"s":"Icon","t":"VisuallyHidden","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with VisuallyHidden for accessible icon-only elements"},{"s":"Icon","t":"Badge","ty":"parent-of","w":1,"p":"relation","no":"Can be used as badge icon prop"},{"s":"IconButton","t":"Button","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Button when the action should have a visible text label or broader layout variants"},{"s":"Image","t":"Card","ty":"parent-of","w":1,"p":"relation","no":"Common pattern to use Image at top of product cards"},{"s":"Image","t":"Avatar","ty":"alternative-to","w":1,"p":"relation","no":"Use Avatar for user profile pictures"},{"s":"Input","t":"Textarea","ty":"alternative-to","w":1,"p":"relation","no":"Use Textarea for multi-line text input"},{"s":"Input","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select when choosing from predefined options"},{"s":"Field","t":"Input","ty":"parent-of","w":1,"p":"relation","no":"Use Field for advanced form composition and custom controls"},{"s":"Link","t":"Button","ty":"alternative-to","w":1,"p":"relation","no":"Use Button for primary actions, Link for navigation"},{"s":"Text","t":"Link","ty":"parent-of","w":1,"p":"relation","no":"Links often appear within Text components"},{"s":"List","t":"Icon","ty":"parent-of","w":1,"p":"relation","no":"Use Icon as List.Item icon prop"},{"s":"List","t":"Stack","ty":"alternative-to","w":1,"p":"relation","no":"Use Stack for non-semantic vertical lists"},{"s":"Listbox","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with Input for search/autocomplete patterns"},{"s":"Listbox","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu when you need a trigger button"},{"s":"Listbox","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for form field selection"},{"s":"Listbox","t":"List","ty":"alternative-to","w":1,"p":"relation","no":"Use List for static, non-interactive lists"},{"s":"Markdown","t":"Text","ty":"alternative-to","w":1,"p":"relation","no":"Use Text for plain, non-markdown text"},{"s":"Message","t":"Markdown","ty":"parent-of","w":1,"p":"relation","no":"Message wraps Markdown when markdown prop is true"},{"s":"Menu","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for form field selection"},{"s":"Menu","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for rich non-action content"},{"s":"Message","t":"Avatar","ty":"parent-of","w":1,"p":"relation","no":"Use Avatar component for custom avatar content"},{"s":"Message","t":"ThinkingIndicator","ty":"sibling-of","w":0.75,"p":"relation","no":"Show ThinkingIndicator while awaiting assistant response"},{"s":"NavigationMenu","t":"Header","ty":"sibling-of","w":0.75,"p":"relation","no":"Place NavigationMenu inside Header for site navigation"},{"s":"NavigationMenu","t":"Sidebar","ty":"alternative-to","w":1,"p":"relation","no":"Use Sidebar for persistent side navigation, NavigationMenu for header dropdowns"},{"s":"NavigationMenu","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action menus (role=menu), NavigationMenu for site navigation (disclosure pattern)"},{"s":"NavigationMenu","t":"Breadcrumbs","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Breadcrumbs for hierarchical page trail, NavigationMenu for site-level navigation"},{"s":"Pagination","t":"Table","ty":"sibling-of","w":0.75,"p":"relation","no":"Commonly paired for table pagination"},{"s":"Pagination","t":"Listbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Listbox for small sets of options"},{"s":"Popover","t":"Tooltip","ty":"alternative-to","w":1,"p":"relation","no":"Use Tooltip for brief, non-interactive hints"},{"s":"Popover","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action lists"},{"s":"Popover","t":"Dialog","ty":"alternative-to","w":1,"p":"relation","no":"Use Dialog for blocking interactions"},{"s":"Progress","t":"Badge","ty":"alternative-to","w":1,"p":"relation","no":"Use Badge for status without percentage"},{"s":"Progress","t":"Alert","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Alert for completion messages"},{"s":"Prompt","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for simple single-line text input"},{"s":"Prompt","t":"Textarea","ty":"alternative-to","w":1,"p":"relation","no":"Use Textarea for multi-line without toolbar"},{"s":"RadioGroup","t":"Checkbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Checkbox for multiple selections"},{"s":"RadioGroup","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for many options or limited space"},{"s":"RadioGroup","t":"Switch","ty":"alternative-to","w":1,"p":"relation","no":"Use Switch for binary on/off choices"},{"s":"Select","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action-based dropdowns"},{"s":"Select","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Input for free-form text entry"},{"s":"Select","t":"Checkbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Checkbox group for multiple selections"},{"s":"Separator","t":"Card","ty":"sibling-of","w":0.75,"p":"relation","no":"Cards provide stronger visual grouping"},{"s":"Sidebar","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Use Tabs for in-page section navigation"},{"s":"Sidebar","t":"Menu","ty":"composes","w":0.5,"p":"relation","no":"Use Menu for contextual actions within sidebar"},{"s":"Skeleton","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress for determinate loading"},{"s":"Slider","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for precise numeric entry"},{"s":"Slider","t":"Progress","ty":"sibling-of","w":0.75,"p":"relation","no":"Similar visual, but Progress is read-only"},{"s":"Stack","t":"Grid","ty":"alternative-to","w":1,"p":"relation","no":"Use Grid for complex 2D layouts"},{"s":"Stack","t":"ButtonGroup","ty":"sibling-of","w":0.75,"p":"relation","no":"ButtonGroup is specialized for buttons"},{"s":"Stack","t":"Box","ty":"sibling-of","w":0.75,"p":"relation","no":"Box for single-element styling"},{"s":"Switch","t":"Input","ty":"sibling-of","w":0.75,"p":"relation","no":"Input handles text/number entry; Switch handles boolean state"},{"s":"Switch","t":"Checkbox","ty":"alternative-to","w":1,"p":"relation","no":"Use Checkbox when change requires form submission"},{"s":"Table","t":"DataTable","ty":"alternative-to","w":1,"p":"relation","no":"Use DataTable for sorting, selection, and TanStack features"},{"s":"TableOfContents","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Tabs for switching views, TOC for scrolling to sections"},{"s":"Tabs","t":"Select","ty":"alternative-to","w":1,"p":"relation","no":"Use Select for many options in compact space"},{"s":"Tabs","t":"Menu","ty":"alternative-to","w":1,"p":"relation","no":"Use Menu for action-based navigation"},{"s":"Text","t":"Link","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Link for clickable text"},{"s":"Text","t":"CodeBlock","ty":"alternative-to","w":1,"p":"relation","no":"Use CodeBlock for code display"},{"s":"Text","t":"Badge","ty":"sibling-of","w":0.75,"p":"relation","no":"Use Badge for labels/tags"},{"s":"Textarea","t":"Input","ty":"alternative-to","w":1,"p":"relation","no":"Use Input for single-line text"},{"s":"Theme","t":"AppShell","ty":"sibling-of","w":0.75,"p":"relation","no":"ThemeProvider typically wraps AppShell"},{"s":"ThinkingIndicator","t":"Message","ty":"sibling-of","w":0.75,"p":"relation","no":"Show ThinkingIndicator while waiting for assistant message"},{"s":"ThinkingIndicator","t":"Progress","ty":"alternative-to","w":1,"p":"relation","no":"Use Progress for determinate progress"},{"s":"Toast","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for persistent inline messages"},{"s":"Toast","t":"Dialog","ty":"alternative-to","w":1,"p":"relation","no":"Use Dialog for messages requiring user action"},{"s":"ToggleGroup","t":"RadioGroup","ty":"alternative-to","w":1,"p":"relation","no":"RadioGroup for form-style single selection"},{"s":"ToggleGroup","t":"Tabs","ty":"alternative-to","w":1,"p":"relation","no":"Tabs for content panel switching"},{"s":"ToggleGroup","t":"Switch","ty":"sibling-of","w":0.75,"p":"relation","no":"Switch for single on/off control"},{"s":"Tooltip","t":"Popover","ty":"alternative-to","w":1,"p":"relation","no":"Use Popover for interactive or longer content"},{"s":"Tooltip","t":"Alert","ty":"alternative-to","w":1,"p":"relation","no":"Use Alert for critical information that must be visible"},{"s":"VisuallyHidden","t":"Button","ty":"parent-of","w":1,"p":"relation","no":"Use inside icon-only buttons for accessible labels"},{"s":"VisuallyHidden","t":"Icon","ty":"sibling-of","w":0.75,"p":"relation","no":"Pair with icons to provide text alternatives"}],"health":{"orphans":[],"hubs":[{"name":"Stack","degree":44},{"name":"Input","degree":37},{"name":"Button","degree":33},{"name":"Sidebar","degree":29},{"name":"Text","degree":26},{"name":"Card","degree":25},{"name":"Badge","degree":23},{"name":"Header","degree":23},{"name":"AppShell","degree":22},{"name":"Grid","degree":21}],"compositionCoverage":19,"connectedComponents":[["Accordion","Alert","AppShell","Avatar","Badge","BentoGrid","Box","Breadcrumbs","Button","ButtonGroup","Card","Chart","Checkbox","Chip","CodeBlock","Collapsible","ColorPicker","Combobox","Command","ComponentDefaults","ConversationList","DataTable","DatePicker","Dialog","Drawer","Editor","EmptyState","Field","Fieldset","Form","Grid","Header","Icon","IconButton","Image","Input","Link","List","Listbox","Loading","Main","Markdown","Menu","Message","NavigationMenu","Pagination","Popover","Progress","Prompt","RadioGroup","ScrollArea","Select","Separator","Sidebar","Skeleton","Slider","Stack","Switch","Table","TableOfContents","Tabs","Text","Textarea","Theme","ThemeToggle","ThinkingIndicator","Toast","ToggleGroup","Tooltip","VisuallyHidden"]],"averageDegree":9.71,"nodeCount":69,"edgeCount":335}},"performanceSummary":{"preset":"standard","budget":15360,"total":69,"overBudget":3,"tiers":{"lightweight":58,"moderate":8,"heavy":3}}}
|