@platned/ui 0.6.1 → 0.7.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 +7 -7
- package/dist/index.cjs +4928 -2815
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1431 -193
- package/dist/index.d.ts +1431 -193
- package/dist/index.js +4908 -2885
- package/dist/index.js.map +1 -1
- package/dist/sidebar.cjs +542 -876
- package/dist/sidebar.cjs.map +1 -1
- package/dist/sidebar.d.cts +56 -0
- package/dist/sidebar.d.ts +56 -0
- package/dist/sidebar.js +539 -894
- package/dist/sidebar.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -3
- package/tailwind-preset.cjs +79 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx","../src/components/forms/button.tsx","../src/lib/slot.tsx","../src/components/feedback/spinner.tsx","../src/components/forms/control-size.tsx","../src/components/forms/icon-button.tsx","../src/components/forms/button-group.tsx","../src/components/avatar/avatar.tsx","../src/components/avatar/avatar-group.tsx","../src/components/avatar/avatar-block.tsx","../src/components/forms/field.tsx","../src/lib/cn.ts","../src/components/forms/input.tsx","../src/components/forms/textarea.tsx","../src/components/forms/select.tsx","../src/lib/use-controllable-state.ts","../src/lib/use-roving-focus.ts","../src/components/overlays/floating.tsx","../src/components/overlays/menu-styles.ts","../src/lib/scrollbar.ts","../src/components/overlays/overlay.ts","../src/components/overlays/overlay-stack.ts","../src/components/overlays/portal.tsx","../src/components/forms/date-picker.tsx","../src/components/forms/stepper.tsx","../src/components/forms/multiselect-card.tsx","../src/components/forms/switch.tsx","../src/components/forms/toggle.tsx","../src/components/forms/input-otp.tsx","../src/components/forms/file-drop-zone.tsx","../src/components/forms/form-card.tsx","../src/components/status/badge.tsx","../src/components/status/role-badge.tsx","../src/components/forms/combobox.tsx","../src/components/forms/role-combo-box.tsx","../src/components/forms/country-select.tsx","../src/components/forms/time-zone-select.tsx","../src/components/forms/command.tsx","../src/components/status/status-badge.tsx","../src/components/status/status-dot.tsx","../src/components/status/status-chip.tsx","../src/components/status/count-badge.tsx","../src/components/status/tag-pill.tsx","../src/components/status/trail-chip.tsx","../src/components/status/user-status-pill.tsx","../src/components/status/check-indicator.tsx","../src/components/status/entity-icon-badge.tsx","../src/components/forms/checkbox.tsx","../src/components/forms/check-control.tsx","../src/components/forms/radio-group.tsx","../src/components/forms/segmented-control.tsx","../src/components/forms/slider.tsx","../src/components/forms/label.tsx","../src/components/forms/calendar.tsx","../src/components/forms/input-group.tsx","../src/components/overlays/modal.tsx","../src/components/overlays/tooltip.tsx","../src/components/overlays/popover.tsx","../src/components/overlays/hover-card.tsx","../src/components/overlays/context-menu.tsx","../src/components/overlays/menu-core.tsx","../src/components/overlays/menubar.tsx","../src/components/overlays/drawer.tsx","../src/components/cards/scroll-area.tsx","../src/components/overlays/confirm-dialog.tsx","../src/components/overlays/note-confirm-modal.tsx","../src/components/overlays/dropdown-menu.tsx","../src/components/cards/card.tsx","../src/components/cards/accordion.tsx","../src/components/cards/collapsible.tsx","../src/components/cards/aspect-ratio.tsx","../src/components/cards/carousel.tsx","../src/components/cards/resizable.tsx","../src/components/chrome/page-heading.tsx","../src/components/chrome/page-toolbar.tsx","../src/components/chrome/filter-bar.tsx","../src/components/chrome/tabs.tsx","../src/components/chrome/nav-item.tsx","../src/components/chrome/eyebrow-label.tsx","../src/components/chrome/separator.tsx","../src/components/chrome/kbd.tsx","../src/components/chrome/breadcrumb.tsx","../src/components/chrome/pagination.tsx","../src/components/chrome/navigation-menu.tsx","../src/components/chrome/typography.tsx","../src/components/widgets/widget-header.tsx","../src/components/widgets/widget-title.tsx","../src/components/widgets/widget-footer.tsx","../src/components/stats/stat-tile.tsx","../src/components/stats/stat-number.tsx","../src/components/stats/score-value.tsx","../src/components/stats/tile-grid.tsx","../src/components/charts/chart-tone.ts","../src/components/charts/bar-chart.tsx","../src/components/charts/donut-chart.tsx","../src/components/charts/radial-gauge.tsx","../src/components/charts/sparkline.tsx","../src/components/charts/mini-bar-chart.tsx","../src/components/charts/chart-legend.tsx","../src/components/charts/legend-dot.tsx","../src/components/charts/trend-label.tsx","../src/components/lists/list-row.tsx","../src/components/lists/file-row.tsx","../src/components/lists/scored-row.tsx","../src/components/lists/numbered-list.tsx","../src/components/feedback/progress-bar.tsx","../src/components/lists/icon-text-row.tsx","../src/components/lists/checklist-row.tsx","../src/components/lists/steps-list.tsx","../src/components/lists/detail-item.tsx","../src/components/lists/checked-group-list.tsx","../src/components/lists/tree-view.tsx","../src/components/lists/table.tsx","../src/components/lists/data-table.tsx","../src/components/feedback/inline-alert.tsx","../src/components/feedback/empty-state.tsx","../src/components/feedback/skeleton.tsx","../src/components/feedback/banner.tsx","../src/components/feedback/toast.tsx","../src/components/forms/password-input.tsx","../src/components/ai/ai-chat-bar.tsx","../src/components/ai/ai-suggestion-chip.tsx","../src/components/ai/quick-actions-bar.tsx","../src/components/decorative/aurora-backdrop.tsx"],"sourcesContent":["export { Button } from './components/forms/button';\nexport type { ButtonProps, ButtonVariant, ButtonSize } from './components/forms/button';\n\nexport { IconButton } from './components/forms/icon-button';\nexport type { IconButtonProps, IconButtonVariant } from './components/forms/icon-button';\n\nexport { ButtonGroup } from './components/forms/button-group';\nexport type { ButtonGroupProps, ButtonGroupItem, ButtonGroupVariant, ButtonGroupAlign } from './components/forms/button-group';\n\nexport { Avatar } from './components/avatar/avatar';\nexport type { AvatarProps, AvatarInitialProps, AvatarImageProps, AvatarSize, AvatarShape } from './components/avatar/avatar';\n\nexport { AvatarGroup } from './components/avatar/avatar-group';\nexport type { AvatarGroupProps, AvatarGroupSpacing } from './components/avatar/avatar-group';\n\nexport { AvatarBlock } from './components/avatar/avatar-block';\nexport type { AvatarBlockProps } from './components/avatar/avatar-block';\n\n\n// ── Field ──────────────────────────────────────────────────────────────────────\n// The label / description / error / control wiring. Every text field composes it, and\n// it is exported so controls the library does not wrap can share the same association.\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldGroup,\n FieldSet,\n FieldLegend,\n FieldSeparator,\n useFieldContext,\n useFieldControl,\n} from './components/forms/field';\nexport type {\n FieldProps,\n FieldLabelProps,\n FieldTextProps,\n FieldGroupProps,\n FieldSetProps,\n FieldLegendProps,\n FieldSeparatorProps,\n FieldOrientation,\n FieldContextValue,\n} from './components/forms/field';\n\nexport { Input, InputControl } from './components/forms/input';\nexport type { InputProps, InputControlProps, InputSize } from './components/forms/input';\n\n// Supplies a default `size` to the form controls beneath it. `FilterBar` is the built-in\n// provider; export it so an app can set a density for a form section of its own.\nexport { ControlSizeProvider, useControlSize } from './components/forms/control-size';\nexport type { ControlSizeProviderProps } from './components/forms/control-size';\n\nexport { Textarea, TextareaControl } from './components/forms/textarea';\nexport type { TextareaProps, TextareaControlProps } from './components/forms/textarea';\n\nexport { Select, SelectControl } from './components/forms/select';\nexport type {\n SelectProps,\n SelectControlProps,\n SelectOption,\n SelectOptionGroup,\n} from './components/forms/select';\n\nexport { DatePicker } from './components/forms/date-picker';\nexport type { DatePickerProps } from './components/forms/date-picker';\n\nexport { Stepper } from './components/forms/stepper';\nexport type { StepperProps, StepperSize, StepItem, StepStatus } from './components/forms/stepper';\n\nexport { MultiSelectCard } from './components/forms/multiselect-card';\nexport type {\n MultiSelectCardProps,\n MultiSelectCardSize,\n} from './components/forms/multiselect-card';\n\n/**\n * On/off setting. Was named `Toggle` through 0.3.0 — see the CHANGELOG rename table. The\n * name `Toggle` now belongs to the pressed-state button, as it does in shadcn/ui.\n */\nexport { Switch } from './components/forms/switch';\nexport type { SwitchProps, SwitchSize } from './components/forms/switch';\n\n/** Pressed-state button, and a group of them. New in 0.4.0. */\nexport { Toggle, ToggleGroup, ToggleGroupItem } from './components/forms/toggle';\nexport type {\n ToggleProps,\n ToggleSize,\n ToggleVariant,\n ToggleGroupProps,\n ToggleGroupItemProps,\n ToggleGroupType,\n} from './components/forms/toggle';\n\nexport { InputOTP } from './components/forms/input-otp';\nexport type { InputOTPProps, InputOTPMode } from './components/forms/input-otp';\n\nexport { FileDropZone } from './components/forms/file-drop-zone';\nexport type { FileDropZoneProps } from './components/forms/file-drop-zone';\n\nexport { FormCard, FormCardHeader, FormCardFooter } from './components/forms/form-card';\nexport type { FormCardHeaderProps, FormCardFooterProps } from './components/forms/form-card';\n\nexport { Badge } from './components/status/badge';\nexport type { BadgeProps, BadgeColor, BadgeSize, BadgeVariant } from './components/status/badge';\n\nexport { RoleBadge } from './components/status/role-badge';\nexport type { RoleBadgeProps, RoleBadgeTone } from './components/status/role-badge';\n\nexport { RoleComboBox, ROLE_COMBO_OPTIONS } from './components/forms/role-combo-box';\nexport type { RoleComboBoxProps, RoleOption } from './components/forms/role-combo-box';\n\n/** Single-select autocomplete. ARIA 1.2 combobox pattern. */\nexport { Combobox } from './components/forms/combobox';\nexport type { ComboboxProps, ComboboxOption } from './components/forms/combobox';\n\n/** Searchable country picker over Combobox. Value is an ISO 3166-1 alpha-2 code. */\nexport { CountrySelect, COUNTRY_CODES, countryOptions } from './components/forms/country-select';\nexport type { CountrySelectProps } from './components/forms/country-select';\n\n/** Searchable IANA time-zone picker over Combobox, labelled with the current UTC offset. */\nexport { TimeZoneSelect, timeZoneOptions, timeZoneOffset, currentZoneName } from './components/forms/time-zone-select';\nexport type { TimeZoneSelectProps } from './components/forms/time-zone-select';\n\n/** ⌘K command palette body. Compose with `Modal` for the usual overlay. */\nexport { Command } from './components/forms/command';\nexport type { CommandProps, CommandItem } from './components/forms/command';\n\n// ── Status & tags ──────────────────────────────────────────────────────────────\n\nexport { StatusBadge } from './components/status/status-badge';\nexport type { StatusBadgeProps, StatusTone, StatusBadgeSize } from './components/status/status-badge';\n\nexport { StatusDot } from './components/status/status-dot';\nexport type { StatusDotProps, StatusDotTone } from './components/status/status-dot';\n\nexport { StatusChip } from './components/status/status-chip';\nexport type { StatusChipProps } from './components/status/status-chip';\n\nexport { CountBadge } from './components/status/count-badge';\nexport type { CountBadgeProps } from './components/status/count-badge';\n\nexport { TagPill } from './components/status/tag-pill';\nexport type { TagPillProps, TagPillTone } from './components/status/tag-pill';\n\nexport { TrailChip } from './components/status/trail-chip';\nexport type { TrailChipProps } from './components/status/trail-chip';\n\nexport { UserStatusPill } from './components/status/user-status-pill';\nexport type { UserStatusPillProps, UserAccountStatus } from './components/status/user-status-pill';\n\nexport { CheckIndicator } from './components/status/check-indicator';\nexport type { CheckIndicatorProps, CheckIndicatorStatus } from './components/status/check-indicator';\n\nexport { EntityIconBadge } from './components/status/entity-icon-badge';\nexport type { EntityIconBadgeProps, EntityIconBadgeSize, EntityIconBadgeTone } from './components/status/entity-icon-badge';\n\n// ── Selection ──────────────────────────────────────────────────────────────────\n\nexport { Checkbox } from './components/forms/checkbox';\nexport type { CheckboxProps, CheckboxSize } from './components/forms/checkbox';\n\nexport { RadioGroup, Radio } from './components/forms/radio-group';\nexport type {\n RadioGroupProps,\n RadioProps,\n RadioGroupOrientation,\n} from './components/forms/radio-group';\n\nexport { SegmentedControl } from './components/forms/segmented-control';\nexport type { SegmentedControlProps, SegmentedControlOption } from './components/forms/segmented-control';\n\nexport { Slider } from './components/forms/slider';\nexport type { SliderProps } from './components/forms/slider';\n\nexport { Label } from './components/forms/label';\nexport type { LabelProps } from './components/forms/label';\n\nexport { Calendar } from './components/forms/calendar';\nexport type { CalendarProps, CalendarMode, DateRange } from './components/forms/calendar';\n\nexport {\n InputGroup,\n InputGroupInput,\n InputGroupAddon,\n InputGroupText,\n SearchInput,\n} from './components/forms/input-group';\nexport type {\n InputGroupProps,\n InputGroupInputProps,\n InputGroupAddonProps,\n InputGroupTextProps,\n InputGroupAlign,\n SearchInputProps,\n} from './components/forms/input-group';\n\n// ── Overlays ───────────────────────────────────────────────────────────────────\n\nexport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalBody,\n ModalFooter,\n} from './components/overlays/modal';\nexport type {\n ModalProps,\n ModalSize,\n ModalTone,\n ModalFooterAlign,\n ModalHeaderProps,\n ModalTitleProps,\n ModalDescriptionProps,\n ModalBodyProps,\n ModalFooterProps,\n} from './components/overlays/modal';\n\nexport { Tooltip } from './components/overlays/tooltip';\nexport type { TooltipProps } from './components/overlays/tooltip';\n\n/** Anchored panel for **interactive** content — unlike `Tooltip`, which cannot be entered. */\nexport { Popover, PopoverTrigger, PopoverContent } from './components/overlays/popover';\nexport type {\n PopoverProps,\n PopoverTriggerProps,\n PopoverContentProps,\n} from './components/overlays/popover';\n\n/** Hover preview that can be entered. Supplementary by contract — hover has no touch equivalent. */\nexport { HoverCard } from './components/overlays/hover-card';\nexport type { HoverCardProps } from './components/overlays/hover-card';\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuGroup,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuShortcut,\n} from './components/overlays/context-menu';\nexport type {\n ContextMenuProps,\n ContextMenuTriggerProps,\n ContextMenuContentProps,\n} from './components/overlays/context-menu';\n\nexport {\n Menubar,\n MenubarMenu,\n MenubarTrigger,\n MenubarContent,\n MenubarItem,\n MenubarCheckboxItem,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarGroup,\n MenubarLabel,\n MenubarSeparator,\n MenubarShortcut,\n} from './components/overlays/menubar';\nexport type {\n MenubarProps,\n MenubarMenuProps,\n MenubarTriggerProps,\n MenubarContentProps,\n} from './components/overlays/menubar';\n\nexport { Drawer } from './components/overlays/drawer';\nexport type { DrawerProps } from './components/overlays/drawer';\n\nexport { ConfirmDialog } from './components/overlays/confirm-dialog';\nexport type { ConfirmDialogProps } from './components/overlays/confirm-dialog';\n\nexport { NoteConfirmModal } from './components/overlays/note-confirm-modal';\nexport type { NoteConfirmModalProps } from './components/overlays/note-confirm-modal';\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n} from './components/overlays/dropdown-menu';\nexport type {\n DropdownMenuProps,\n DropdownMenuTriggerProps,\n DropdownMenuContentProps,\n DropdownMenuItemProps,\n DropdownMenuItemTone,\n DropdownMenuCheckboxItemProps,\n DropdownMenuRadioGroupProps,\n DropdownMenuRadioItemProps,\n DropdownMenuGroupProps,\n DropdownMenuLabelProps,\n DropdownMenuSeparatorProps,\n DropdownMenuShortcutProps,\n} from './components/overlays/dropdown-menu';\n\nexport { Portal } from './components/overlays/portal';\nexport type { PortalProps } from './components/overlays/portal';\n\n// ── Utilities ──────────────────────────────────────────────────────────────────\n\n/** Esc-to-close, Tab focus trap and focus restore — for building your own overlays. */\nexport { OVERLAY_SCRIM, useOverlayDismiss } from './components/overlays/overlay';\n\n/** `clsx` + `tailwind-merge` — for compositions where your className must win. */\nexport { cn } from './lib/cn';\n\n// ── Cards & containers ─────────────────────────────────────────────────────────\n\nexport {\n Card,\n CardHeader,\n CardTitle,\n CardDescription,\n CardAction,\n CardBody,\n CardFooter,\n} from './components/cards/card';\nexport type {\n CardProps,\n CardSize,\n CardRadius,\n CardTone,\n CardFooterAlign,\n CardHeaderProps,\n CardTitleProps,\n CardDescriptionProps,\n CardActionProps,\n CardBodyProps,\n CardFooterProps,\n} from './components/cards/card';\n\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from './components/cards/accordion';\nexport type {\n AccordionProps,\n AccordionItemProps,\n AccordionTriggerProps,\n AccordionContentProps,\n AccordionType,\n} from './components/cards/accordion';\n\nexport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n} from './components/cards/collapsible';\nexport type {\n CollapsibleProps,\n CollapsibleTriggerProps,\n CollapsibleContentProps,\n} from './components/cards/collapsible';\n\nexport { AspectRatio } from './components/cards/aspect-ratio';\nexport type { AspectRatioProps } from './components/cards/aspect-ratio';\n\nexport { ScrollArea } from './components/cards/scroll-area';\nexport type { ScrollAreaProps, ScrollAreaAxis } from './components/cards/scroll-area';\n\n// The scrollbar styling on its own, for a component that must own its own overflow — a\n// table wrapper, a tab strip, a floating panel. Use `ScrollArea` for a region of content.\nexport { SCROLLBAR_CLASSES } from './lib/scrollbar';\n\nexport {\n Carousel,\n CarouselViewport,\n CarouselSlide,\n CarouselControls,\n} from './components/cards/carousel';\nexport type {\n CarouselProps,\n CarouselViewportProps,\n CarouselSlideProps,\n CarouselControlsProps,\n} from './components/cards/carousel';\n\nexport { Resizable, ResizablePanel, ResizableHandle } from './components/cards/resizable';\nexport type {\n ResizableProps,\n ResizablePanelProps,\n ResizableHandleProps,\n ResizableDirection,\n} from './components/cards/resizable';\n\n// ── Page chrome ────────────────────────────────────────────────────────────────\n\nexport { PageHeading } from './components/chrome/page-heading';\nexport type { PageHeadingProps, PageHeadingSize } from './components/chrome/page-heading';\n\nexport { PageToolbar } from './components/chrome/page-toolbar';\nexport type { PageToolbarProps, PageToolbarSize } from './components/chrome/page-toolbar';\n\nexport { FilterBar } from './components/chrome/filter-bar';\nexport type { FilterBarProps, FilterBarSize } from './components/chrome/filter-bar';\n\nexport { Tabs, TabsPanel, tabId, tabPanelId } from './components/chrome/tabs';\nexport type {\n TabsProps,\n TabsPanelProps,\n TabItem,\n TabsVariant,\n TabsSize,\n TabsOrientation,\n TabsActivation,\n} from './components/chrome/tabs';\n\nexport { NavItem } from './components/chrome/nav-item';\nexport type {\n NavItemProps,\n NavItemSize,\n NavItemVariant,\n} from './components/chrome/nav-item';\n\nexport { EyebrowLabel } from './components/chrome/eyebrow-label';\nexport type { EyebrowLabelProps, EyebrowLabelVariant } from './components/chrome/eyebrow-label';\n\nexport { Separator } from './components/chrome/separator';\nexport type { SeparatorProps, SeparatorOrientation } from './components/chrome/separator';\n\nexport { Kbd } from './components/chrome/kbd';\nexport type { KbdProps, KbdSize } from './components/chrome/kbd';\n\nexport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbEllipsis,\n} from './components/chrome/breadcrumb';\nexport type {\n BreadcrumbProps,\n BreadcrumbItemProps,\n BreadcrumbEllipsisProps,\n} from './components/chrome/breadcrumb';\n\nexport { Pagination, paginationRange } from './components/chrome/pagination';\nexport type { PaginationProps, PaginationType } from './components/chrome/pagination';\n\nexport { NavigationMenu, NavigationMenuItem } from './components/chrome/navigation-menu';\nexport type {\n NavigationMenuProps,\n NavigationMenuItemProps,\n NavigationMenuOrientation,\n NavigationMenuVariant,\n} from './components/chrome/navigation-menu';\n\n// ── Typography ─────────────────────────────────────────────────────────────────\n// The type ramp as components, mirroring Figma's `Text*` primitives. Every one takes\n// `asChild`, because the right element depends on the surrounding document outline.\n\nexport {\n Text,\n TextSmall,\n TextTiny,\n TextStrong,\n TextEmphasis,\n TextCode,\n TextLink,\n TextList,\n TextListItem,\n TitleHero,\n TitlePage,\n Subtitle,\n Heading,\n Subheading,\n} from './components/chrome/typography';\nexport type {\n TextProps,\n TextLinkProps,\n TextListProps,\n TextListItemProps,\n TextListVariant,\n TextListDensity,\n} from './components/chrome/typography';\n\n// ── Widgets ────────────────────────────────────────────────────────────────────\n\nexport { WidgetHeader } from './components/widgets/widget-header';\nexport type { WidgetHeaderProps, WidgetHeaderEyebrowVariant } from './components/widgets/widget-header';\n\nexport { WidgetTitle } from './components/widgets/widget-title';\nexport type { WidgetTitleProps, WidgetTitleSize } from './components/widgets/widget-title';\n\nexport { WidgetFooter } from './components/widgets/widget-footer';\nexport type { WidgetFooterProps } from './components/widgets/widget-footer';\n\n// ── Stats ──────────────────────────────────────────────────────────────────────\n\nexport { StatTile } from './components/stats/stat-tile';\nexport type { StatTileProps } from './components/stats/stat-tile';\n\nexport { StatNumber } from './components/stats/stat-number';\nexport type { StatNumberProps, StatNumberSize, StatNumberWeight } from './components/stats/stat-number';\n\nexport { ScoreValue, getScoreTone, DEFAULT_SCORE_THRESHOLDS } from './components/stats/score-value';\nexport type {\n ScoreValueProps,\n ScoreValueSize,\n ScoreValueWeight,\n ScoreValueTone,\n ScoreTone,\n ScoreRampTone,\n ScoreDirection,\n ScoreThresholds,\n} from './components/stats/score-value';\n\nexport { TileGrid } from './components/stats/tile-grid';\nexport type { TileGridProps, TileGridColumns, TileGridBreakpoint } from './components/stats/tile-grid';\n\n// ── Data visualisation ─────────────────────────────────────────────────────────\n\nexport { CHART_TONE, CHART_SEQUENCE, CHART_TRACK, resolveChartColor } from './components/charts/chart-tone';\nexport type { ChartTone } from './components/charts/chart-tone';\n\nexport { BarChart } from './components/charts/bar-chart';\nexport type {\n BarChartProps,\n BarChartSeries,\n BarChartOrientation,\n BarChartSize,\n} from './components/charts/bar-chart';\n\nexport { DonutChart } from './components/charts/donut-chart';\nexport type { DonutChartProps, DonutSegment, DonutChartSize } from './components/charts/donut-chart';\n\nexport { RadialGauge } from './components/charts/radial-gauge';\nexport type { RadialGaugeProps, RadialGaugeSize } from './components/charts/radial-gauge';\n\nexport { Sparkline } from './components/charts/sparkline';\nexport type { SparklineProps, SparklineVariant, SparklineSize } from './components/charts/sparkline';\n\nexport { MiniBarChart } from './components/charts/mini-bar-chart';\nexport type {\n MiniBarChartProps,\n MiniBarChartSize,\n MiniBarChartOrientation,\n} from './components/charts/mini-bar-chart';\n\nexport { ChartLegend } from './components/charts/chart-legend';\nexport type {\n ChartLegendProps,\n ChartLegendItem,\n ChartLegendOrientation,\n} from './components/charts/chart-legend';\n\nexport { LegendDot } from './components/charts/legend-dot';\nexport type { LegendDotProps, LegendDotSize, LegendDotShape } from './components/charts/legend-dot';\n\nexport { TrendLabel } from './components/charts/trend-label';\nexport type {\n TrendLabelProps,\n TrendLabelWeight,\n TrendLabelSize,\n TrendDirection,\n} from './components/charts/trend-label';\n\n// ── Lists & rows ───────────────────────────────────────────────────────────────\n\nexport { ListRow } from './components/lists/list-row';\nexport type { ListRowProps, ListRowDensity, ListRowDivider } from './components/lists/list-row';\n\nexport { FileRow } from './components/lists/file-row';\nexport type { FileRowProps } from './components/lists/file-row';\n\nexport { ScoredRow } from './components/lists/scored-row';\nexport type { ScoredRowProps, ScoredRowAlign, ScoredRowGap } from './components/lists/scored-row';\n\nexport { NumberedList } from './components/lists/numbered-list';\nexport type {\n NumberedListProps,\n NumberedListItem,\n NumberedListGap,\n} from './components/lists/numbered-list';\n\nexport { IconTextRow } from './components/lists/icon-text-row';\nexport type { IconTextRowProps } from './components/lists/icon-text-row';\n\nexport { ChecklistRow } from './components/lists/checklist-row';\nexport type { ChecklistRowProps, ChecklistRowState } from './components/lists/checklist-row';\n\nexport { StepsList } from './components/lists/steps-list';\nexport type { StepsListProps } from './components/lists/steps-list';\n\nexport { DetailItem, DetailGrid } from './components/lists/detail-item';\nexport type {\n DetailItemProps,\n DetailItemLayout,\n DetailItemSpan,\n DetailGridProps,\n DetailGridColumns,\n} from './components/lists/detail-item';\n\nexport { CheckedGroupList } from './components/lists/checked-group-list';\nexport type {\n CheckedGroupListProps,\n CheckedGroupListColumns,\n CheckedGroup,\n} from './components/lists/checked-group-list';\n\n/** Expandable tree — ARIA tree pattern, one tab stop, rows as a render slot. */\nexport { TreeView } from './components/lists/tree-view';\nexport type { TreeViewProps, TreeItemState, TreeViewSize } from './components/lists/tree-view';\n\n// ── Table ──────────────────────────────────────────────────────────────────────\n// The composable primitive, for the tables `DataTable`'s column config cannot express —\n// grouped headers, footers, colspans. `DataTable` remains the right default.\n\nexport {\n Table,\n TableCaption,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n} from './components/lists/table';\nexport type {\n TableProps,\n TableCaptionProps,\n TableRowProps,\n TableHeadProps,\n TableCellProps,\n TableDensity,\n TableSortDirection,\n} from './components/lists/table';\n\n// ── Data table ─────────────────────────────────────────────────────────────────\n// Lives in components/lists/ but is documented on its own page.\n\nexport {\n DataTable,\n TableCellLeadText,\n TableCellText,\n TableCellBadge,\n TableCellProgress,\n} from './components/lists/data-table';\nexport type {\n DataTableProps,\n DataTableDensity,\n DataTableAlign,\n ColumnDef,\n TableCellSize,\n TableCellLeadTextProps,\n TableCellTextProps,\n TableCellBadgeProps,\n TableCellProgressProps,\n} from './components/lists/data-table';\n\n// ── Feedback ───────────────────────────────────────────────────────────────────\n\nexport { InlineAlert } from './components/feedback/inline-alert';\nexport type { InlineAlertProps, InlineAlertTone } from './components/feedback/inline-alert';\n\nexport { EmptyState } from './components/feedback/empty-state';\nexport type { EmptyStateProps, EmptyStateVariant, EmptyStateSize } from './components/feedback/empty-state';\n\nexport { ProgressBar } from './components/feedback/progress-bar';\nexport type { ProgressBarProps, ProgressBarTone, ProgressBarSize } from './components/feedback/progress-bar';\n\nexport { Spinner } from './components/feedback/spinner';\nexport type { SpinnerProps, SpinnerSize } from './components/feedback/spinner';\n\nexport { Skeleton } from './components/feedback/skeleton';\nexport type { SkeletonProps, SkeletonShape } from './components/feedback/skeleton';\n\n/** Persistent, in-flow notice with a title and an action — Figma's `Notification`. */\nexport { Banner } from './components/feedback/banner';\nexport type { BannerProps, BannerVariant } from './components/feedback/banner';\n\n/** Transient notifications. Mount `Toaster` once at the app root, then call `useToast()`. */\nexport { Toaster, useToast } from './components/feedback/toast';\nexport type {\n ToasterProps,\n ToasterPosition,\n ToastOptions,\n ToastRecord,\n ToastTone,\n} from './components/feedback/toast';\n\n// ── Forms ──────────────────────────────────────────────────────────────────────\n\nexport { PasswordInput } from './components/forms/password-input';\nexport type { PasswordInputProps } from './components/forms/password-input';\n\n// ── AI surfaces & decorative ───────────────────────────────────────────────────\n\nexport { AIChatBar } from './components/ai/ai-chat-bar';\nexport type { AIChatBarProps } from './components/ai/ai-chat-bar';\n\nexport { AISuggestionChip } from './components/ai/ai-suggestion-chip';\nexport type { AISuggestionChipProps } from './components/ai/ai-suggestion-chip';\n\nexport { QuickActionsBar } from './components/ai/quick-actions-bar';\nexport type { QuickActionsBarProps, QuickAction } from './components/ai/quick-actions-bar';\n\nexport { AuroraBackdrop } from './components/decorative/aurora-backdrop';\n\n// Icons are not re-exported. Import them straight from `react-icons/lu` — the nine filled\n// 20×20 `Solid*` marks that used to live here were used by no component in this library,\n// only by its own documentation, and they were the one place the library shipped a second\n// icon set. Charts remain the sole exception to `lu`, because their SVG is geometry.\n","import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\nimport { Spinner } from '../feedback/spinner';\nimport { useControlSize } from './control-size';\n\nexport type ButtonVariant = 'primary' | 'neutral' | 'subtle' | 'danger' | 'danger-subtle';\nexport type ButtonSize = 'lg' | 'md' | 'sm';\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n /**\n * Render the single child element instead of a `<button>` — e.g. a router `Link`, so a\n * navigation action can look like a button without nesting an anchor inside one.\n */\n asChild?: boolean;\n /**\n * Swaps the leading icon for a spinner and disables the button. `aria-busy` is set so\n * assistive tech reports the pending state rather than only the disabled one.\n */\n loading?: boolean;\n /** Announced while `loading`. Defaults to the button's own content. */\n loadingLabel?: string;\n}\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary: clsx(\n 'bg-brand border border-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n neutral: clsx(\n 'bg-default border border-default text-default',\n 'hover:bg-default-hover hover:text-brand',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n subtle: clsx(\n // border-transparent holds space so hover border doesn't shift layout\n 'bg-transparent border border-transparent text-neutral',\n 'hover:border-default hover:text-brand',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n danger: clsx(\n 'bg-danger border border-danger-secondary text-danger-on-danger',\n // border shifts from danger-secondary → danger-default on hover (Figma spec)\n 'hover:bg-danger-hover hover:border-danger',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n 'danger-subtle': clsx(\n // border-transparent base avoids layout shift when hover border appears\n 'bg-transparent border border-transparent text-danger',\n 'hover:bg-danger-tertiary-hover hover:border-danger',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n};\n\n// Horizontal padding is on the label span, not a nested div — through 0.3.0 the children\n// were wrapped in `<div className=\"px-1\">` *inside* the `<button>`, which is a block\n// element inside a phrasing-content context and knocked the flex baseline about.\nconst sizeStyles: Record<ButtonSize, string> = {\n lg: 'h-12 px-3 gap-1 rounded-2xl text-body font-semibold [&_svg]:size-5',\n md: 'h-9 px-2 gap-0.5 rounded-lg text-body-sm font-semibold [&_svg]:size-5',\n sm: 'h-6 px-1.5 pt-0.5 gap-0 rounded-full text-body-tiny font-semibold [&_svg]:size-4',\n};\n\nconst SPINNER_SIZE: Record<ButtonSize, 'sm' | 'md'> = {\n lg: 'md',\n md: 'sm',\n sm: 'sm',\n};\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = 'primary',\n size: sizeProp,\n leadingIcon,\n trailingIcon,\n asChild = false,\n loading = false,\n loadingLabel,\n disabled,\n type,\n children,\n className,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n\n const decorate = (content: ReactNode) => (\n <>\n {loading ? <Spinner size={SPINNER_SIZE[size]} label={loadingLabel} /> : leadingIcon}\n <span className=\"px-1\">{content}</span>\n {trailingIcon}\n </>\n );\n\n const rootProps = {\n className: clsx(\n 'inline-flex items-center justify-center whitespace-nowrap transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed',\n variantStyles[variant],\n sizeStyles[size],\n className,\n ),\n 'aria-busy': loading || undefined,\n ...props,\n };\n\n if (asChild) {\n // `aria-disabled`, not `disabled`: the child may be an `<a>`, which has no disabled\n // attribute, and removing the href would change what the element *is*.\n return (\n <Slot\n ref={ref}\n aria-disabled={disabled || loading || undefined}\n wrapChildren={decorate}\n {...rootProps}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n // Through 0.3.0 no default `type` was set, so `<Button onClick={…}>` inside a\n // `<form>` submitted it. Every other button in the library set `type=\"button\"`\n // explicitly; this one did not.\n type={type ?? 'button'}\n disabled={disabled || loading}\n {...rootProps}\n >\n {decorate(children)}\n </button>\n );\n});\n","import {\n cloneElement,\n forwardRef,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport clsx from 'clsx';\n\n/**\n * `Slot` renders its own props onto its single child element instead of emitting a\n * wrapper of its own. It is what makes `asChild` work.\n *\n * Why the library needs it: before 0.4.0 there was no way to render a `Button` as a\n * router `<Link>`, or to use any component as a tooltip/popover anchor, because every\n * component hardcoded its host element. The usual workaround — a `component`/`as` prop —\n * multiplies generics across the whole surface and still cannot forward a ref through\n * two levels. Delegating to the child instead keeps the type surface flat.\n *\n * <Button asChild><Link to=\"/x\">Go</Link></Button>\n *\n * Merge rules, in order of who wins:\n * - `className` — concatenated, slot first, so the child's classes come last\n * - `style` — shallow-merged, child wins on conflicting keys\n * - `on*` — both run, slot's handler first; the child's runs even if the slot's\n * called `preventDefault`, matching normal DOM listener behaviour\n * - everything else — child wins, so a child's explicit `type` or `role` is never\n * clobbered by a default the slot happens to carry\n */\nexport interface SlotProps extends HTMLAttributes<HTMLElement> {\n /** The single element to merge into. */\n children?: ReactNode;\n /**\n * Rebuilds the child's children, so a component that decorates its content can keep\n * doing so through `asChild`.\n *\n * `Button` renders `leadingIcon`, a padded label span and `trailingIcon` around whatever\n * it is given. Without this, `<Button asChild><Link>Go</Link></Button>` would either drop\n * the icons (cloning the Link untouched) or drop \"Go\" (replacing the Link's children\n * outright). It receives the child's own children — \"Go\" — and returns the decorated\n * tree to place inside the child.\n */\n wrapChildren?: (childChildren: ReactNode) => ReactNode;\n}\n\nexport const Slot = forwardRef<HTMLElement, SlotProps>(function Slot(\n { children, wrapChildren, ...slotProps },\n forwardedRef,\n) {\n // A bare string, an array, or nothing at all — there is no element to merge into.\n // Rendering the children plain would silently drop every prop the slot carries\n // (including the ref and the ARIA wiring a trigger depends on), so this renders\n // nothing rather than something subtly broken.\n if (!isValidElement(children)) return null;\n\n const child = children as ReactElement<{ children?: ReactNode }>;\n\n const merged = {\n ...mergeProps(slotProps, child.props as Record<string, unknown>),\n ref: composeRefs(forwardedRef, getElementRef(child)),\n } as Record<string, unknown>;\n\n return wrapChildren\n ? cloneElement(child, merged, wrapChildren(child.props.children))\n : cloneElement(child, merged);\n});\n\nfunction mergeProps(\n slotProps: Record<string, unknown>,\n childProps: Record<string, unknown>,\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...slotProps };\n\n for (const key in childProps) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n if (/^on[A-Z]/.test(key)) {\n // Both handlers run. The slot's fires first so a component can set up state\n // before the consumer's own handler observes it.\n if (typeof slotValue === 'function' && typeof childValue === 'function') {\n merged[key] = (...args: unknown[]) => {\n (slotValue as (...a: unknown[]) => void)(...args);\n (childValue as (...a: unknown[]) => void)(...args);\n };\n } else {\n merged[key] = childValue ?? slotValue;\n }\n } else if (key === 'className') {\n merged[key] = clsx(slotValue as string, childValue as string);\n } else if (key === 'style') {\n merged[key] = { ...(slotValue as CSSProperties), ...(childValue as CSSProperties) };\n } else {\n merged[key] = childValue;\n }\n }\n\n return merged;\n}\n\n/**\n * React 19 exposes a `ref` on `props`; React 18 keeps it on the element. The peer range\n * is `>=18`, so both have to be read.\n */\nfunction getElementRef(element: ReactElement): Ref<unknown> | undefined {\n const asRecord = element as unknown as {\n ref?: Ref<unknown>;\n props?: { ref?: Ref<unknown> };\n };\n return asRecord.props?.ref ?? asRecord.ref;\n}\n\n/** Fan one node out to several refs, callback or object. */\nexport function composeRefs<T>(...refs: (Ref<T> | undefined)[]) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === 'function') {\n ref(node);\n } else {\n (ref as { current: T | null }).current = node;\n }\n }\n };\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\n\nexport type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {\n size?: SpinnerSize;\n /**\n * Accessible name. When omitted the spinner is marked decorative — correct when it sits\n * inside a control that already announces the pending state (`Button loading` sets\n * `aria-busy`), and wrong when the spinner is the only thing on screen.\n */\n label?: string;\n}\n\nconst SIZE: Record<SpinnerSize, string> = {\n xs: 'size-3 border',\n sm: 'size-4 border-[1.5px]',\n md: 'size-5 border-2',\n lg: 'size-8 border-2',\n};\n\n/**\n * Indeterminate loading indicator. `ProgressBar` is the determinate counterpart.\n *\n * The spin is a border-based ring rather than an SVG so it inherits `currentColor` and\n * needs no fill/stroke plumbing — it works on any button variant unchanged. The animation\n * is suppressed under `prefers-reduced-motion` by the preset's base rule, which leaves a\n * static ring; that is why the transparent segment is a full quarter and still legible\n * when frozen.\n */\nexport const Spinner = forwardRef<HTMLSpanElement, SpinnerProps>(function Spinner(\n { size = 'sm', label, className, ...rest },\n ref,\n) {\n return (\n <span\n ref={ref}\n role={label ? 'status' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={clsx(\n 'inline-block shrink-0 animate-spin rounded-full',\n 'border-current border-t-transparent',\n SIZE[size],\n className,\n )}\n {...rest}\n />\n );\n});\n","import { createContext, useContext, type ReactNode } from 'react';\nimport type { InputSize } from './input';\n\n/**\n * A default `size` for the form controls inside a container.\n *\n * `FilterBar size=\"sm\"` used to set only the gap between its children, so its own \"Sizes\"\n * example put a 24px Input beside a 36px Select and nothing in the API said the caller had\n * to size each control by hand. A container that has a size prop should mean it.\n *\n * Deliberately narrow: the context carries an `InputSize` and nothing else. It is not a\n * general \"component config\" channel — that is where implicit inheritance stops being\n * predictable. And an explicit `size` prop always wins, so the escape hatch is one prop on\n * the one control that needs to differ.\n *\n * `cloneElement` would have been the alternative and cannot work here: it never reaches a\n * control wrapped for layout (`<div className=\"w-56\"><Input /></div>`) or one nested inside\n * a consumer's own composite, and it would inject `size` into whatever element happens to\n * be the child — including a `<span>`, which React then warns about. Context is also how\n * the library already solves this shape, in `FieldContext`, `RadioGroupContext` and\n * `ToggleGroupContext`.\n */\nconst ControlSizeContext = createContext<InputSize | null>(null);\n\nexport interface ControlSizeProviderProps {\n size: InputSize;\n children: ReactNode;\n}\n\nexport function ControlSizeProvider({ size, children }: ControlSizeProviderProps) {\n return <ControlSizeContext.Provider value={size}>{children}</ControlSizeContext.Provider>;\n}\n\n/**\n * Resolve a control's size: an explicit prop, else the enclosing container's default,\n * else `md`.\n *\n * Call it unconditionally at the top of the component — it is a hook.\n */\nexport function useControlSize(explicit?: InputSize): InputSize {\n const inherited = useContext(ControlSizeContext);\n return explicit ?? inherited ?? 'md';\n}\n","import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\nimport { type ButtonSize } from './button';\nimport { useControlSize } from './control-size';\n\nexport type IconButtonVariant = 'primary' | 'neutral' | 'subtle';\n\nexport interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: IconButtonVariant;\n size?: ButtonSize;\n /** Required for accessibility — no visible text label */\n 'aria-label': string;\n /** Render the single child element instead of a `<button>` — e.g. a router `Link`. */\n asChild?: boolean;\n children?: ReactNode;\n}\n\nconst variantStyles: Record<IconButtonVariant, string> = {\n primary: clsx(\n 'bg-brand border border-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n // Neutral uses secondary background (light gray) for visual weight without a text label\n neutral: clsx(\n 'bg-default-secondary border border-default text-default',\n // icon turns brand blue on hover (Figma spec)\n 'hover:bg-default-secondary-hover hover:text-brand',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n subtle: clsx(\n 'bg-transparent text-neutral',\n // hover uses background-default-default-hover (#f5f5f5), icon turns brand blue (Figma spec)\n 'hover:bg-default-hover hover:text-brand',\n // disabled needs explicit border since there is no base border\n 'disabled:bg-disabled disabled:border disabled:border-disabled disabled:text-disabled-on-disabled',\n ),\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n lg: 'size-12 rounded-2xl [&_svg]:size-5',\n md: 'size-9 rounded-lg [&_svg]:size-5',\n sm: 'size-6 rounded-full [&_svg]:size-4',\n};\n\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { variant = 'primary', size: sizeProp, asChild = false, type, children, className, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const rootProps = {\n className: clsx(\n 'inline-flex shrink-0 items-center justify-center transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed',\n variantStyles[variant],\n sizeStyles[size],\n className,\n ),\n ...props,\n };\n\n // No `wrapChildren` here: an icon button has no label span or icon slots to rebuild, so\n // the child's own content is already the whole thing.\n if (asChild) {\n return (\n <Slot ref={ref} {...rootProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n // Without an explicit type, a button inside a <form> defaults to `submit` and an\n // icon button meant to reveal a password or open a menu submits the form instead.\n type={type ?? 'button'}\n {...rootProps}\n >\n {children}\n </button>\n );\n});\n","import { type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { type ButtonSize } from './button';\n\nexport type ButtonGroupVariant = 'primary' | 'neutral' | 'filter';\nexport type ButtonGroupAlign = 'justify' | 'start' | 'end' | 'center' | 'stack';\n\nexport interface ButtonGroupItem {\n value: string;\n label: ReactNode;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n disabled?: boolean;\n}\n\nexport interface ButtonGroupProps {\n items: ButtonGroupItem[];\n value: string;\n onChange: (value: string) => void;\n variant?: ButtonGroupVariant;\n size?: ButtonSize;\n align?: ButtonGroupAlign;\n /** Forwarded to the container as aria-label */\n 'aria-label'?: string;\n className?: string;\n}\n\nconst containerStyles: Record<ButtonGroupVariant, string> = {\n primary: 'bg-neutral-tertiary p-1 rounded-2xl',\n neutral: 'bg-neutral-tertiary p-1 rounded-2xl',\n filter: 'bg-default border border-default p-1 rounded-xl',\n};\n\nconst selectedStyles: Record<ButtonGroupVariant, string> = {\n primary: clsx(\n 'bg-brand border border-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n ),\n neutral: clsx(\n 'bg-default border border-default text-default',\n 'hover:bg-default-hover',\n ),\n filter: clsx(\n 'bg-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n ),\n};\n\nconst unselectedStyles: Record<ButtonGroupVariant, string> = {\n primary: clsx('bg-transparent text-neutral', 'hover:bg-neutral-tertiary-hover'),\n neutral: clsx('bg-transparent text-neutral', 'hover:bg-neutral-tertiary-hover'),\n filter: clsx('text-default-secondary', 'hover:text-default'),\n};\n\nconst itemSizeStyles: Record<ButtonSize, string> = {\n lg: 'h-12 px-3 gap-1 rounded-2xl text-body font-semibold [&_svg]:size-5',\n md: 'h-9 px-2 gap-0.5 rounded-lg text-body-sm font-semibold [&_svg]:size-5',\n sm: 'h-6 px-1.5 pt-0.5 gap-0 rounded-full text-body-tiny font-semibold [&_svg]:size-4',\n};\n\nconst containerAlignStyles: Record<ButtonGroupAlign, string> = {\n justify: 'flex flex-row items-center',\n start: 'flex flex-row items-center justify-start',\n end: 'flex flex-row items-center justify-end',\n center: 'flex flex-row items-center justify-center',\n stack: 'flex flex-col items-center',\n};\n\nexport function ButtonGroup({\n items,\n value,\n onChange,\n variant = 'primary',\n size = 'md',\n align = 'start',\n className,\n 'aria-label': ariaLabel,\n}: ButtonGroupProps) {\n const isJustify = align === 'justify';\n const isStack = align === 'stack';\n\n return (\n <div\n role=\"group\"\n aria-label={ariaLabel}\n className={clsx(\n containerStyles[variant],\n containerAlignStyles[align],\n className,\n )}\n >\n {items.map((item) => {\n const isSelected = item.value === value;\n return (\n <div\n key={item.value}\n className={clsx(isJustify && 'flex-1 min-w-0', isStack && 'w-full')}\n >\n <button\n type=\"button\"\n aria-pressed={isSelected}\n disabled={item.disabled}\n onClick={() => onChange(item.value)}\n className={clsx(\n 'inline-flex items-center justify-center whitespace-nowrap transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1',\n 'disabled:cursor-not-allowed disabled:text-disabled',\n (isJustify || isStack) && 'w-full',\n itemSizeStyles[size],\n isSelected ? selectedStyles[variant] : unselectedStyles[variant],\n )}\n >\n {item.leadingIcon}\n <div className='px-1'>{item.label}</div>\n {item.trailingIcon}\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n","import clsx from 'clsx';\n\nexport type AvatarSize = 'sm' | 'md' | 'lg';\nexport type AvatarShape = 'circle' | 'square';\n\nexport interface AvatarInitialProps {\n type?: 'initial';\n /** Single character — Figma spec: one letter only to avoid overflow */\n initial: string;\n size?: AvatarSize;\n shape?: AvatarShape;\n className?: string;\n}\n\nexport interface AvatarImageProps {\n type: 'image';\n src: string;\n alt?: string;\n size?: AvatarSize;\n shape?: AvatarShape;\n className?: string;\n}\n\nexport type AvatarProps = AvatarInitialProps | AvatarImageProps;\n\n// Figma sizes: lg=40px, md=32px, sm=24px\nconst sizeStyles: Record<AvatarSize, string> = {\n lg: 'size-10',\n md: 'size-8',\n sm: 'size-6',\n};\n\n// Figma text sizes for initials: body-medium at lg, scales down proportionally\nconst initialTextStyles: Record<AvatarSize, string> = {\n lg: 'text-body font-semibold',\n md: 'text-body-xs font-semibold',\n sm: 'text-body-tiny font-semibold',\n};\n\n// Figma shape radii: circle=full, square: lg/md=8px (rounded-lg), sm=4px (rounded)\nfunction getShapeClass(shape: AvatarShape, size: AvatarSize): string {\n if (shape === 'circle') return 'rounded-full';\n return size === 'sm' ? 'rounded' : 'rounded-lg';\n}\n\nexport function Avatar(props: AvatarProps) {\n const { size = 'lg', shape = 'circle', className } = props;\n\n const base = clsx(\n 'shrink-0 overflow-hidden',\n sizeStyles[size],\n getShapeClass(shape, size),\n className,\n );\n\n if (props.type === 'image') {\n return (\n <div className={base}>\n <img\n src={props.src}\n alt={props.alt ?? ''}\n className=\"size-full object-cover\"\n />\n </div>\n );\n }\n\n return (\n <div\n className={clsx(base, 'flex items-center justify-center')}\n style={{\n background:\n 'linear-gradient(135deg, var(--color-graphic-blue) 30%, var(--color-graphic-red) 100%)',\n }}\n >\n <span\n className={clsx(\n 'select-none leading-none text-brand-on-brand',\n initialTextStyles[size],\n )}\n >\n {props.initial.charAt(0).toUpperCase()}\n </span>\n </div>\n );\n}\n","import { type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport type AvatarGroupSpacing = 'spaced' | 'overlap';\n\nexport interface AvatarGroupProps {\n children: ReactNode;\n /** Number shown in the overflow badge — omit to hide the badge */\n overflow?: number;\n spacing?: AvatarGroupSpacing;\n className?: string;\n}\n\nexport function AvatarGroup({\n children,\n overflow,\n spacing = 'spaced',\n className,\n}: AvatarGroupProps) {\n return (\n <div\n className={clsx(\n 'flex items-center',\n spacing === 'spaced' ? 'gap-1' : '-space-x-2 isolate',\n className,\n )}\n >\n {children}\n {overflow !== undefined && (\n <div\n className={clsx(\n 'flex items-center justify-center',\n 'min-w-6 h-6 px-1 rounded-lg',\n 'bg-default-secondary text-default-secondary text-body-sm',\n spacing === 'overlap' && 'drop-shadow-sm',\n )}\n >\n +{overflow}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface AvatarBlockProps {\n children: ReactNode;\n title: string;\n description?: string;\n className?: string;\n}\n\nexport function AvatarBlock({ children, title, description, className }: AvatarBlockProps) {\n return (\n <div className={clsx('flex items-start gap-3', className)}>\n <div className=\"shrink-0\">{children}</div>\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"text-body font-semibold text-default-secondary\">\n {title}\n </span>\n {description && (\n <span className=\"text-body text-default-tertiary\">\n {description}\n </span>\n )}\n </div>\n </div>\n );\n}\n","import {\n createContext,\n useContext,\n useId,\n type HTMLAttributes,\n type LabelHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '../../lib/cn';\nimport type { InputSize } from './input';\n\n/**\n * The label / description / error / control wiring, in one place.\n *\n * This exists because of the single largest defect the 0.3.0 audit found. `Input`,\n * `Textarea`, `Select` and `DatePicker` all accepted `label`, `description`, `error` and\n * `hint`, rendered them, and then connected **none** of them:\n *\n * - `<label htmlFor={id}>` used the caller's `id` with no fallback. Omit `id` — the\n * common case — and `htmlFor` was `undefined`, so the label pointed at nothing.\n * Clicking it did nothing and assistive tech announced an unlabelled field.\n * - `description`, `error` and `hint` were bare `<p>` elements with no `id`, and no\n * control ever referenced them. A consumer could not fix this from outside either:\n * passing `aria-describedby` had nothing to point at.\n * - `error` drove the border colour and nothing else. No `aria-invalid`, no `role`, no\n * live region — so an async validation failure was completely silent.\n *\n * For scale: `aria-describedby`, `aria-invalid` and `aria-required` appeared nowhere in\n * `src/`, and `useId` was used exactly once in the whole library — in `Sparkline`, for an\n * SVG gradient.\n *\n * `Field` generates the ids and hands them down through context, so a control only has to\n * spread `useFieldControl()` onto its input element. It is also usable directly for\n * controls the library does not wrap, which is why the parts are exported.\n */\n\nexport interface FieldContextValue {\n controlId: string;\n /**\n * Id of the `FieldLabel`, for controls whose accessible name cannot come from a\n * `<label for>` association. A `<button>` is named by its own contents, so the Select\n * trigger has to point `aria-labelledby` at the label explicitly or it announces only\n * the chosen value.\n */\n labelId: string;\n descriptionId: string;\n errorId: string;\n hintId: string;\n hasDescription: boolean;\n hasError: boolean;\n hasHint: boolean;\n invalid: boolean;\n required: boolean;\n disabled: boolean;\n size: InputSize;\n}\n\nconst FieldContext = createContext<FieldContextValue | null>(null);\n\nexport function useFieldContext(): FieldContextValue | null {\n return useContext(FieldContext);\n}\n\n/**\n * Props for the control itself. Spread onto the `<input>`/`<select>`/`<textarea>`.\n *\n * `aria-describedby` deliberately lists description *and* message: a field can carry\n * both persistent guidance and a transient error, and a screen reader should read both\n * rather than have the error replace the instruction that explains the format.\n */\nexport function useFieldControl(): {\n id: string | undefined;\n 'aria-describedby': string | undefined;\n 'aria-invalid': true | undefined;\n 'aria-required': true | undefined;\n disabled: boolean | undefined;\n} {\n const field = useFieldContext();\n if (!field) {\n return {\n id: undefined,\n 'aria-describedby': undefined,\n 'aria-invalid': undefined,\n 'aria-required': undefined,\n disabled: undefined,\n };\n }\n\n const describedBy = [\n field.hasDescription && field.descriptionId,\n field.hasError && field.errorId,\n field.hasHint && !field.hasError && field.hintId,\n ]\n .filter(Boolean)\n .join(' ');\n\n return {\n id: field.controlId,\n 'aria-describedby': describedBy || undefined,\n 'aria-invalid': field.invalid || undefined,\n 'aria-required': field.required || undefined,\n disabled: field.disabled || undefined,\n };\n}\n\n// ── Field ──────────────────────────────────────────────────────────────────────\n\nexport type FieldOrientation = 'vertical' | 'horizontal';\n\nexport interface FieldProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Supply to control the id yourself; otherwise one is generated. */\n id?: string;\n size?: InputSize;\n invalid?: boolean;\n required?: boolean;\n disabled?: boolean;\n /** `horizontal` puts the label beside the control — for switches and checkboxes. */\n orientation?: FieldOrientation;\n /** Set when a `FieldDescription` is rendered. Inferred by the wrapped controls. */\n hasDescription?: boolean;\n hasError?: boolean;\n hasHint?: boolean;\n}\n\nconst GAP: Record<InputSize, string> = {\n lg: 'gap-2',\n md: 'gap-1',\n sm: 'gap-0.5',\n};\n\nexport function Field({\n children,\n id,\n size = 'md',\n invalid = false,\n required = false,\n disabled = false,\n orientation = 'vertical',\n hasDescription = false,\n hasError = false,\n hasHint = false,\n className,\n ...rest\n}: FieldProps) {\n const generated = useId();\n const controlId = id ?? generated;\n\n return (\n <FieldContext.Provider\n value={{\n controlId,\n labelId: `${controlId}-label`,\n descriptionId: `${controlId}-description`,\n errorId: `${controlId}-error`,\n hintId: `${controlId}-hint`,\n hasDescription,\n hasError,\n hasHint,\n invalid: invalid || hasError,\n required,\n disabled,\n size,\n }}\n >\n <div\n // role=\"group\" so the label of a fieldset-like cluster is inherited by every\n // control inside it, matching shadcn's Field.\n role={orientation === 'horizontal' ? 'group' : undefined}\n data-slot=\"field\"\n data-invalid={invalid || hasError || undefined}\n data-disabled={disabled || undefined}\n className={cn(\n orientation === 'horizontal'\n ? 'flex flex-row items-center justify-between gap-3'\n : cn('flex flex-col', GAP[size]),\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </FieldContext.Provider>\n );\n}\n\n// ── FieldLabel ─────────────────────────────────────────────────────────────────\n\nconst LABEL_TEXT: Record<InputSize, string> = {\n lg: 'text-body',\n md: 'text-body-sm',\n sm: 'text-body-tiny',\n};\n\nexport interface FieldLabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n children: ReactNode;\n}\n\nexport function FieldLabel({ children, className, htmlFor, ...rest }: FieldLabelProps) {\n const field = useFieldContext();\n\n return (\n <label\n id={field?.labelId}\n htmlFor={htmlFor ?? field?.controlId}\n data-slot=\"field-label\"\n className={cn(\n LABEL_TEXT[field?.size ?? 'md'],\n field?.disabled ? 'text-disabled' : 'text-default',\n // The required marker is CSS generated content, not a child element. An\n // `<span aria-hidden>*</span>` would be correct for accessible-name computation\n // (which skips aria-hidden) but it still lands in `textContent`, so every\n // `getByLabelText('Name')` — ours and every consumer's — would have to become\n // `/Name/`. Generated content is in neither, and the real signal is\n // `aria-required` on the control regardless.\n field?.required && \"after:ml-0.5 after:text-danger after:content-['*']\",\n className,\n )}\n {...rest}\n >\n {children}\n </label>\n );\n}\n\n// ── FieldDescription / FieldError / FieldHint ──────────────────────────────────\n\nexport interface FieldTextProps extends HTMLAttributes<HTMLParagraphElement> {\n children: ReactNode;\n}\n\n/** Persistent guidance, shown above the control and announced with it. */\nexport function FieldDescription({ children, className, ...rest }: FieldTextProps) {\n const field = useFieldContext();\n return (\n <p\n id={field?.descriptionId}\n data-slot=\"field-description\"\n className={cn(\n LABEL_TEXT[field?.size ?? 'md'],\n field?.disabled ? 'text-disabled' : 'text-default-secondary',\n className,\n )}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\n/**\n * Validation message. `role=\"alert\"` because an error that appears after submit —\n * asynchronously, without focus moving — is otherwise never announced at all.\n */\nexport function FieldError({ children, className, ...rest }: FieldTextProps) {\n const field = useFieldContext();\n return (\n <p\n id={field?.errorId}\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(LABEL_TEXT[field?.size ?? 'md'], 'text-danger', className)}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\n/** Neutral helper text. Suppressed while an error is showing, so the two never stack. */\nexport function FieldHint({ children, className, ...rest }: FieldTextProps) {\n const field = useFieldContext();\n return (\n <p\n id={field?.hintId}\n data-slot=\"field-hint\"\n className={cn(LABEL_TEXT[field?.size ?? 'md'], 'text-default-secondary', className)}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\n// ── Grouping ───────────────────────────────────────────────────────────────────\n\nexport interface FieldGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** Stacks several `Field`s with consistent rhythm. */\nexport function FieldGroup({ children, className, ...rest }: FieldGroupProps) {\n return (\n <div data-slot=\"field-group\" className={cn('flex flex-col gap-4', className)} {...rest}>\n {children}\n </div>\n );\n}\n\nexport interface FieldSetProps extends HTMLAttributes<HTMLFieldSetElement> {\n children: ReactNode;\n}\n\n/**\n * A real `<fieldset>`. Required for radio groups and checkbox groups: the group needs a\n * name of its own, and only `<legend>` gives it one that is announced before each option.\n */\nexport function FieldSet({ children, className, ...rest }: FieldSetProps) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn('flex flex-col gap-3 border-0 p-0', className)}\n {...rest}\n >\n {children}\n </fieldset>\n );\n}\n\nexport interface FieldLegendProps extends HTMLAttributes<HTMLLegendElement> {\n children: ReactNode;\n /** `label` matches a field label's weight; `legend` is the larger section heading. */\n variant?: 'legend' | 'label';\n}\n\nexport function FieldLegend({\n children,\n variant = 'legend',\n className,\n ...rest\n}: FieldLegendProps) {\n return (\n <legend\n data-slot=\"field-legend\"\n className={cn(\n 'p-0',\n variant === 'legend'\n ? 'text-body font-semibold text-default'\n : 'text-body-sm text-default',\n className,\n )}\n {...rest}\n >\n {children}\n </legend>\n );\n}\n\nexport interface FieldSeparatorProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function FieldSeparator({ className, ...rest }: FieldSeparatorProps) {\n return (\n <div\n role=\"separator\"\n data-slot=\"field-separator\"\n className={cn('h-px w-full bg-divider', className)}\n {...rest}\n />\n );\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * Every `fontSize` key in `tailwind-preset.cjs`, in the same order.\n *\n * `tailwind-merge` decides whether a `text-*` class is a **font size** or a **text colour**\n * by pattern: it recognises t-shirt sizes (`text-sm`, `text-2xl`) and bare lengths, and files\n * everything else under colour. Every size in this design system is a word — `text-body-sm`,\n * `text-heading`, `text-scale-07` — so without this list twMerge calls them colours, and then\n * drops them when a real colour follows in the same string:\n *\n * cn('text-body-micro text-neutral-tertiary') // → 'text-neutral-tertiary'\n *\n * The size vanishes and the element inherits its parent's. That is not hypothetical: it is\n * why the sidebar's group headings rendered at the 16px body default for two releases while\n * the source said `text-body-tiny`, and why chasing the number in the source never moved it.\n *\n * Keep in sync with the preset — `cn.test.ts` fails if they drift.\n */\nconst FONT_SIZES = [\n 'body-micro',\n 'body-tiny',\n 'body-xs',\n 'body-sm',\n 'body',\n 'body-lg',\n 'heading-sm',\n 'heading',\n 'heading-lg',\n 'subheading-sm',\n 'subheading',\n 'subheading-lg',\n 'subtitle-sm',\n 'subtitle',\n 'subtitle-lg',\n 'title-sm',\n 'title',\n 'title-lg',\n 'title-hero',\n 'scale-01',\n 'scale-02',\n 'scale-03',\n 'scale-04',\n 'scale-05',\n 'scale-06',\n 'scale-07',\n 'scale-08',\n 'scale-09',\n 'scale-10',\n 'scale-12',\n] as const;\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: [...FONT_SIZES] }],\n },\n },\n});\n\n/**\n * `clsx` + `tailwind-merge`, taught this system's type scale.\n *\n * Use this instead of bare `clsx` in any component whose `className` prop is meant to\n * *override* a base utility — the composable `Card*` and `Modal*` parts, and anything\n * else built to be reshaped by its caller.\n *\n * Why it is necessary: `clsx` only concatenates. When two conflicting Tailwind\n * utilities both end up in the attribute, the winner is decided by *stylesheet order*,\n * not attribute order. Tailwind emits `flex-row` before `flex-col` and `gap-3` before\n * `gap-4`, so under plain `clsx`:\n *\n * <CardBody className=\"flex-row gap-3\" /> // base is 'flex flex-col gap-4 p-4'\n *\n * silently stays a column with a 4-unit gap. `twMerge` drops the losing class instead,\n * so the caller's intent wins.\n *\n * Everywhere else in the library `className` is purely additive, and plain `clsx`\n * remains correct — and cheaper. Do not sweep it out of those files.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { forwardRef, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldControl,\n} from './field';\n\nexport type InputSize = 'lg' | 'md' | 'sm';\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n label?: string;\n description?: string;\n /** Red border + message shown below the input. Also sets `aria-invalid`. */\n error?: string;\n /** Neutral helper text shown below the input (hidden when error is set) */\n hint?: string;\n size?: InputSize;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n /** Interactive trailing slot (e.g. a show/hide password button) — unlike\n * `trailingIcon` it receives pointer events. */\n trailingAction?: ReactNode;\n}\n\n// Figma sizes: lg=48px md=36px sm=24px\nconst inputBase: Record<InputSize, string> = {\n lg: 'h-12 px-5 py-3.5 text-body',\n md: 'h-9 px-4 py-2.5 text-body-sm',\n sm: 'h-6 px-3 py-[5px] text-body-tiny',\n};\n\n// Extra left padding to clear the leading icon\n// lg adds 8px for the explicit flex gap Figma uses on large; md/sm have no gap\nconst leadingPad: Record<InputSize, string> = {\n lg: 'pl-12',\n md: 'pl-8',\n sm: 'pl-6',\n};\n\n// Extra right padding to clear the trailing icon\nconst trailingPad: Record<InputSize, string> = {\n lg: 'pr-12',\n md: 'pr-8',\n sm: 'pr-6',\n};\n\n// Icon wrapper: absolutely positioned inside the input container\nconst iconWrap: Record<InputSize, { left: string; right: string; size: string }> = {\n lg: { left: 'left-4', right: 'right-4', size: 'size-5' },\n md: { left: 'left-3', right: 'right-3', size: 'size-4' },\n sm: { left: 'left-2', right: 'right-2', size: 'size-3' },\n};\n\n/**\n * Focus styling note: `focus-visible:` rather than `focus:`, and `ring-2 ring-brand` to\n * match the button family. Through 0.3.0 this used `focus:ring-1 ring-brand-secondary`,\n * which showed a ring on plain mouse clicks and was a third distinct focus treatment in a\n * library that already had two.\n */\nexport const inputControlClasses = (size: InputSize, invalid: boolean, disabled?: boolean) =>\n clsx(\n 'w-full rounded-lg border outline-none transition-colors',\n 'bg-default text-default',\n 'placeholder:text-default-tertiary',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n inputBase[size],\n disabled\n ? 'cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled'\n : invalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n // read-only is not disabled: the value still matters and is still selectable, but it\n // must not look editable. Nothing in the library styled this before 0.4.0.\n 'read-only:bg-default-secondary read-only:cursor-default',\n );\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n label,\n description,\n error,\n hint,\n size: sizeProp,\n leadingIcon,\n trailingIcon,\n trailingAction,\n className,\n disabled,\n required,\n id,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n const iw = iconWrap[size];\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n\n <div className=\"relative flex items-center\">\n {leadingIcon && (\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n iw.left,\n iw.size,\n 'flex items-center justify-center text-icon-default-secondary',\n )}\n >\n {leadingIcon}\n </span>\n )}\n <InputControl\n ref={ref}\n size={size}\n invalid={hasError}\n disabled={disabled}\n required={required}\n className={clsx(\n leadingIcon && leadingPad[size],\n (trailingIcon || trailingAction) && trailingPad[size],\n )}\n {...props}\n />\n {trailingIcon && !trailingAction && (\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n iw.right,\n iw.size,\n 'flex items-center justify-center text-icon-default-secondary',\n )}\n >\n {trailingIcon}\n </span>\n )}\n {trailingAction && (\n <span\n className={clsx(\n 'absolute',\n iw.right,\n 'flex items-center justify-center text-icon-default-secondary',\n )}\n >\n {trailingAction}\n </span>\n )}\n </div>\n\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n\n/**\n * The bare `<input>` with the field wiring applied and no label/message chrome — for\n * `InputGroup` and any composition that supplies its own `Field`.\n */\nexport interface InputControlProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: InputSize;\n invalid?: boolean;\n}\n\nexport const InputControl = forwardRef<HTMLInputElement, InputControlProps>(\n function InputControl({ size: sizeProp, invalid = false, className, ...props }, ref) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n return (\n <input\n ref={ref}\n // A container's default control size is reported so a test — and a caller reading\n // the DOM — can see which size actually won, rather than inferring it from classes.\n data-size={size}\n // Field wiring first so an explicit prop from the caller still wins.\n {...field}\n className={clsx(inputControlClasses(size, isInvalid, isDisabled), className)}\n {...props}\n />\n );\n },\n);\n","import { forwardRef, type TextareaHTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { type InputSize } from './input';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldControl,\n} from './field';\n\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n label?: string;\n description?: string;\n /** Red border + message shown below the control. Also sets `aria-invalid`. */\n error?: string;\n hint?: string;\n size?: InputSize;\n}\n\n// Figma: large textarea inner height ~80px, medium ~68px, small ~52px\nconst textareaBase: Record<InputSize, string> = {\n lg: 'min-h-20 px-4 py-3.5 text-body',\n md: 'min-h-[68px] px-3 py-2.5 text-body-sm',\n sm: 'min-h-[52px] px-2 py-[5px] text-body-tiny',\n};\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n { label, description, error, hint, size: sizeProp, className, disabled, required, id, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n <TextareaControl\n ref={ref}\n size={size}\n invalid={hasError}\n disabled={disabled}\n required={required}\n {...props}\n />\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n\nexport interface TextareaControlProps\n extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n size?: InputSize;\n invalid?: boolean;\n}\n\n/** The bare `<textarea>` with field wiring, for compositions that supply their own `Field`. */\nexport const TextareaControl = forwardRef<HTMLTextAreaElement, TextareaControlProps>(\n function TextareaControl({ size: sizeProp, invalid = false, className, ...props }, ref) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n return (\n <textarea\n ref={ref}\n data-size={size}\n {...field}\n className={clsx(\n 'w-full resize-y rounded-lg border outline-none transition-colors',\n 'bg-default text-default',\n 'placeholder:text-default-tertiary',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n textareaBase[size],\n isDisabled\n ? 'cursor-not-allowed resize-none border-disabled bg-disabled text-disabled placeholder:text-disabled'\n : isInvalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n 'read-only:cursor-default read-only:resize-none read-only:bg-default-secondary',\n className,\n )}\n {...props}\n />\n );\n },\n);\n","import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuCheck, LuChevronDown } from 'react-icons/lu';\n\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useFloatingPanel } from '../overlays/floating';\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n OVERLAY_PANEL,\n OVERLAY_PANEL_SCROLL,\n overlayItemTone,\n} from '../overlays/menu-styles';\nimport { useOverlayDismiss } from '../overlays/overlay';\nimport { Portal } from '../overlays/portal';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldContext,\n useFieldControl,\n} from './field';\nimport { type InputSize } from './input';\n\nexport interface SelectOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectOptionGroup {\n label: string;\n options: SelectOption[];\n}\n\n/** Trigger geometry. `pr` = chevron right-offset + chevron width, the exact clearance. */\nconst selectBase: Record<InputSize, string> = {\n lg: 'h-12 pl-4 pr-9 text-body', // right-4 (16) + size-5 (20) = 36px\n md: 'h-9 pl-3 pr-7 text-body-sm', // right-3 (12) + size-4 (16) = 28px\n sm: 'h-6 pl-2 pr-5 text-body-tiny', // right-2 (8) + size-3 (12) = 20px\n};\n\nconst chevronPos: Record<InputSize, { right: string; size: string }> = {\n lg: { right: 'right-4', size: 'size-5' },\n md: { right: 'right-3', size: 'size-4' },\n sm: { right: 'right-2', size: 'size-3' },\n};\n\nfunction isGroup(entry: SelectOption | SelectOptionGroup): entry is SelectOptionGroup {\n return 'options' in entry;\n}\n\n/** Options in render order, so a roving index is just a position. */\nfunction flatten(entries: (SelectOption | SelectOptionGroup)[]): SelectOption[] {\n return entries.flatMap((entry) => (isGroup(entry) ? entry.options : [entry]));\n}\n\n// ── SelectControl ──────────────────────────────────────────────────────────────\n\nexport interface SelectControlProps\n extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'value' | 'defaultValue' | 'onChange' | 'children' | 'type'\n > {\n /** Flat options, or groups which render as a labelled `role=\"group\"`. */\n options: (SelectOption | SelectOptionGroup)[];\n value?: string | null;\n defaultValue?: string | null;\n onValueChange?: (value: string) => void;\n /**\n * Submits with a surrounding form, through a hidden input. Note that hidden inputs are\n * exempt from constraint validation, so `required` no longer blocks submit — see the\n * note on `Select`.\n */\n name?: string;\n size?: InputSize;\n invalid?: boolean;\n placeholder?: string;\n}\n\n/**\n * The bare trigger and its listbox, with field wiring and no label/message chrome — for\n * `Select` and any composition that supplies its own `Field`.\n */\nexport const SelectControl = forwardRef<HTMLButtonElement, SelectControlProps>(\n function SelectControl(\n {\n options,\n value: valueProp,\n defaultValue = null,\n onValueChange,\n name,\n size: sizeProp,\n invalid = false,\n placeholder = 'Select…',\n className,\n onKeyDown,\n ...props\n },\n ref,\n ) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const fieldContext = useFieldContext();\n\n const [value, setValue] = useControllableState<string | null>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: string | null) => void) | undefined,\n });\n\n const [open, setOpen] = useState(false);\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const valueId = `${baseId}-value`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const panelRef = useRef<HTMLDivElement | null>(null);\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n\n // Which end to land on when the panel opens. The trigger handles the key before the\n // panel exists, so the intent has to survive one render.\n const pendingEdge = useRef<'start' | 'end'>('start');\n\n const flat = flatten(options);\n const selected = flat.find((option) => option.value === value) ?? null;\n\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n /**\n * A roving tabindex, not `aria-activedescendant`.\n *\n * `Combobox` uses activedescendant because focus must stay in its text input — moving\n * it into the list would stop the user typing. A Select has no input, so real DOM\n * focus is available, and it brings three things with it: `useRovingFocus` already\n * implements arrows, Home/End, disabled-skipping, wrap **and typeahead** (which the\n * native `<select>` had and losing would be a regression); the browser scrolls the\n * focused option into view for free; and the options are genuinely focusable, so none\n * of the jsx-a11y suppressions the Combobox listbox needs apply here.\n */\n const roving = useRovingFocus({ orientation: 'vertical', loop: true, typeahead: true });\n\n const { refs, floatingStyles } = useFloatingPanel({\n open,\n onOpenChange: setOpen,\n side: 'bottom',\n align: 'start',\n sideOffset: 4,\n matchAnchorWidth: true,\n });\n\n useEffect(() => {\n refs.setReference(triggerRef.current);\n }, [refs, open]);\n\n useOverlayDismiss({\n onDismiss: () => setOpen(false),\n panelRef,\n active: open,\n // Not modal: the page behind stays readable and interactive. Only Escape,\n // outside-press and focus restore — the same four falses as DropdownMenu.\n trapFocus: false,\n lockScroll: false,\n inertBackground: false,\n // The listbox owns its initial focus below; a \"first tabbable element\" scan would\n // fight the roving tabindex, which exposes exactly one option at a time.\n autoFocus: false,\n });\n\n // Keyed on the panel node rather than on `open`: Portal gates its children behind a\n // mounted flag, so on the render where the panel opens the options do not exist yet.\n const wasOpen = useRef(false);\n useEffect(() => {\n if (open && panelNode && !wasOpen.current) {\n const index = selected ? flat.indexOf(selected) : -1;\n // Open onto the current selection when there is one — the native select did, and\n // it is the difference between \"resume\" and \"start over\" on a long list.\n if (index >= 0 && pendingEdge.current === 'start') roving.focusIndex(index);\n else roving.moveToEdge(pendingEdge.current);\n pendingEdge.current = 'start';\n wasOpen.current = true;\n }\n if (!open) wasOpen.current = false;\n // `flat`/`selected` are recomputed every render; including them would re-run this on\n // every keystroke and fight the roving focus it just set.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, panelNode, roving]);\n\n const commit = (option: SelectOption) => {\n if (option.disabled) return;\n setValue(option.value);\n setOpen(false);\n };\n\n const triggerKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || open) return;\n // Arrows open onto the near or far end, per the APG. Enter and Space arrive as a\n // click on a native button, so `onClick` already covers them.\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n pendingEdge.current = event.key === 'ArrowUp' ? 'end' : 'start';\n setOpen(true);\n }\n };\n\n let cursor = 0;\n\n const renderOption = (option: SelectOption, index: number) => {\n const isSelected = option.value === value;\n const itemProps = roving.itemProps(index, {\n disabled: option.disabled,\n label: option.label,\n });\n\n return (\n <div\n key={option.value}\n // `role=\"option\"` on a div rather than a <button>: the roving tabindex owns\n // focusability, and a native button would re-enter the tab sequence.\n role=\"option\"\n id={optionId(index)}\n aria-selected={isSelected}\n aria-disabled={option.disabled || undefined}\n {...itemProps}\n // Restated after the spread so jsx-a11y can see it — it cannot follow a\n // tabIndex that arrives through an object spread.\n tabIndex={itemProps.tabIndex}\n onClick={() => commit(option)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n commit(option);\n }\n }}\n className={clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE[size],\n 'items-center',\n overlayItemTone('default', !!option.disabled),\n )}\n >\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {isSelected && (\n <LuCheck className=\"size-3.5 shrink-0\" strokeWidth={3} aria-hidden />\n )}\n </div>\n );\n };\n\n const cp = chevronPos[size];\n\n return (\n <>\n <div className=\"relative flex items-center\">\n <button\n ref={composeRefs<HTMLButtonElement>(triggerRef, ref)}\n type=\"button\"\n /**\n * `role=\"combobox\"`, matching Radix Select. It is the role that permits\n * `aria-expanded`, `aria-controls`, `aria-required` and `aria-invalid` — all\n * of which `Field` supplies and none of which a plain `role=\"button\"` accepts.\n * `aria-activedescendant` is optional on a combobox and deliberately absent:\n * real focus moves into the listbox instead.\n */\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n // A <button> is named by its contents, so a `<label for>` association does not\n // name it the way it named the old <select>. Point at the label explicitly and\n // let the value follow it: \"Role Analyst\". The second id targets the value span\n // rather than the button itself — a self-reference is legal per spec but several\n // name-computation implementations decline to resolve it.\n aria-labelledby={fieldContext ? `${fieldContext.labelId} ${valueId}` : undefined}\n data-size={size}\n {...field}\n disabled={isDisabled}\n onClick={() => setOpen(!open)}\n onKeyDown={triggerKeyDown}\n className={clsx(\n 'w-full appearance-none rounded-lg border text-left outline-none transition-colors',\n 'bg-default text-default',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n selectBase[size],\n isDisabled\n ? 'cursor-not-allowed border-disabled bg-disabled text-disabled'\n : isInvalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n className,\n )}\n {...props}\n >\n <span\n id={valueId}\n className={clsx('block truncate', !selected && 'text-default-tertiary')}\n >\n {selected?.label ?? placeholder}\n </span>\n </button>\n\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n cp.right,\n cp.size,\n 'flex items-center justify-center',\n isDisabled ? 'text-icon-disabled' : 'text-icon-default-secondary',\n )}\n >\n <LuChevronDown className=\"size-full\" />\n </span>\n\n {/* Form participation. Not an `sr-only <select>`: that would duplicate every\n option into the accessibility tree, and a real <select> reaching focus would\n reopen the OS picker this component exists to replace. */}\n {name && <input type=\"hidden\" name={name} value={value ?? ''} />}\n </div>\n\n {open && (\n <Portal>\n <div\n ref={composeRefs<HTMLDivElement>(panelRef, setPanelNode, refs.setFloating)}\n id={listboxId}\n role=\"listbox\"\n // Focusable but out of the tab sequence: the fallback target for an empty\n // list, and it keeps key events on the panel.\n tabIndex={-1}\n aria-orientation=\"vertical\"\n aria-labelledby={fieldContext?.labelId}\n aria-required={field['aria-required']}\n aria-invalid={field['aria-invalid']}\n style={{ ...floatingStyles, width: 'var(--panel-anchor-width)' }}\n className={clsx('z-popover', OVERLAY_PANEL, OVERLAY_PANEL_SCROLL)}\n {...roving.containerProps}\n onKeyDown={(event) => {\n roving.containerProps.onKeyDown(event);\n // Tab leaves the control rather than walking the list, so close first and\n // let the browser move on from the trigger. No commit: arrowing to an\n // option is browsing, and only Enter, Space or a click chooses it.\n if (event.key === 'Tab') setOpen(false);\n }}\n >\n {options.map((entry, entryIndex) => {\n if (!isGroup(entry)) return renderOption(entry, cursor++);\n\n const headingId = `${baseId}-group-${entryIndex}`;\n return (\n <div key={`group-${entryIndex}`} role=\"group\" aria-labelledby={headingId}>\n <div id={headingId} className={OVERLAY_HEADING}>\n {entry.label}\n </div>\n {entry.options.map((option) => renderOption(option, cursor++))}\n </div>\n );\n })}\n </div>\n </Portal>\n )}\n </>\n );\n },\n);\n\n// ── Select ─────────────────────────────────────────────────────────────────────\n\nexport interface SelectProps extends SelectControlProps {\n label?: string;\n description?: string;\n /** Red border + message shown below the control. Also sets `aria-invalid`. */\n error?: string;\n hint?: string;\n required?: boolean;\n}\n\n/**\n * Single-select dropdown: a trigger and a portalled listbox.\n *\n * Through 0.4.0 this wrapped a native `<select>`, which was the right call for its keyboard\n * contract and the wrong one for everything visual: the option popup is drawn by the OS and\n * cannot be styled at all, so a Select never matched the `DropdownMenu` and `Combobox`\n * panels sitting beside it on the same filter row. It is now the same panel as those, and\n * the keyboard contract it used to inherit is implemented rather than borrowed — arrows,\n * Home/End, typeahead, Escape, and Tab that leaves without committing.\n *\n * Two consequences of dropping the native element, neither papered over:\n *\n * - **No OS picker on mobile.** The wheel/sheet a native select opens is gone.\n * - **`required` no longer blocks submit.** The value posts through a hidden input, and\n * hidden inputs are exempt from constraint validation. `required` remains semantic and\n * visual — `aria-required` on the control and the `*` on its label — which is already\n * true of `Combobox`, `RadioGroup` and `MultiSelectCard`. In react-hook-form, register\n * it with `Controller` rather than `register`.\n *\n * For a list long enough to need filtering, use `Combobox`.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n label,\n description,\n error,\n hint,\n size: sizeProp,\n className,\n disabled,\n required,\n id,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n\n <SelectControl ref={ref} size={size} invalid={hasError} disabled={disabled} {...props} />\n\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n","import { useCallback, useRef, useState } from 'react';\n\nexport interface UseControllableStateOptions<T> {\n /** The controlled value. Passing anything other than `undefined` takes control. */\n value?: T;\n /** Initial value when uncontrolled. */\n defaultValue: T;\n /** Fired on every change, controlled or not. */\n onChange?: (value: T) => void;\n}\n\n/**\n * One state value that works controlled or uncontrolled, the way every Radix and\n * shadcn/ui control does.\n *\n * Before 0.4.0 nothing in this library supported an uncontrolled mode — `Checkbox`,\n * `Toggle`, `Tabs`, `SegmentedControl`, `ButtonGroup` and `MultiSelectCard` all *required*\n * a value plus a change handler, so the simplest possible use site still needed a\n * `useState` in the consumer. `DropdownMenu` had the opposite problem: its open state was\n * entirely internal, so a caller could neither open it programmatically nor observe it.\n *\n * Control is decided per render by whether `value` is `undefined`. A component that\n * starts controlled and later passes `undefined` will fall back to its internal value —\n * the same caveat React itself has with inputs, and for the same reason.\n */\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T, (next: T | ((prev: T) => T)) => void] {\n const [internal, setInternal] = useState<T>(defaultValue);\n\n const isControlled = value !== undefined;\n const current = isControlled ? value : internal;\n\n // Kept in a ref so `setValue` stays referentially stable across renders. Without this\n // every consumer that puts it in a dependency array re-subscribes on each render.\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const currentRef = useRef(current);\n currentRef.current = current;\n\n const isControlledRef = useRef(isControlled);\n isControlledRef.current = isControlled;\n\n const setValue = useCallback((next: T | ((prev: T) => T)) => {\n const resolved =\n typeof next === 'function' ? (next as (prev: T) => T)(currentRef.current) : next;\n\n if (resolved === currentRef.current) return;\n\n // A controlled component must not move its own value — the parent owns it and will\n // pass the new one back down. Only the notification goes out.\n if (!isControlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [current, setValue];\n}\n","import { useCallback, useEffect, useRef, useState, type KeyboardEvent } from 'react';\n\nexport type RovingOrientation = 'horizontal' | 'vertical' | 'both';\n\nexport interface UseRovingFocusOptions {\n /** Which arrow keys move focus. `both` accepts all four. Default `horizontal`. */\n orientation?: RovingOrientation;\n /** Wrap past the ends. Default `true`. */\n loop?: boolean;\n /** Jump to an item by typing the start of its label. Default `false`. */\n typeahead?: boolean;\n /** Item to start on. Default `0`. */\n defaultIndex?: number;\n /** Fired when the composite is exited with Escape — menus use it to close. */\n onEscape?: () => void;\n}\n\nexport interface RovingItemOptions {\n disabled?: boolean;\n /** Typeahead match target. Only read when `typeahead` is on. */\n label?: string;\n}\n\nexport interface RovingItemProps {\n ref: (node: HTMLElement | null) => void;\n tabIndex: 0 | -1;\n onFocus: () => void;\n 'data-roving-index': number;\n}\n\n/**\n * Arrow-key navigation with a roving tabindex, for any composite widget that owns a\n * single-stop tab sequence: `menu`, `tablist`, `listbox`, `radiogroup`, `toolbar`.\n *\n * Before 0.4.0 this library had **no arrow-key handling anywhere** — `ArrowDown`,\n * `Home` and `End` appeared in no file. `Tabs`, `DropdownMenu`, `ButtonGroup`,\n * `SegmentedControl` and `RoleComboBox` all announced a composite role to assistive tech\n * while behaving like a plain row of buttons: every item natively tabbable, arrows inert.\n * That is worse than shipping no role at all, because a screen reader tells the user\n * \"tab 3 of 5\" and then the keys it implies do nothing.\n *\n * Keyboard handling lives on the container and is delegated, rather than being attached\n * per item — one listener, and the item list can change length without re-binding.\n *\n * const roving = useRovingFocus({ orientation: 'vertical', loop: true, typeahead: true });\n *\n * <div role=\"menu\" {...roving.containerProps}>\n * {items.map((item, i) => (\n * <button\n * key={item.id}\n * role=\"menuitem\"\n * {...roving.itemProps(i, { disabled: item.disabled, label: item.label })}\n * />\n * ))}\n * </div>\n */\nexport function useRovingFocus({\n orientation = 'horizontal',\n loop = true,\n typeahead = false,\n defaultIndex = 0,\n onEscape,\n}: UseRovingFocusOptions = {}) {\n const [activeIndex, setActiveIndex] = useState(defaultIndex);\n\n const items = useRef<(HTMLElement | null)[]>([]);\n const meta = useRef<RovingItemOptions[]>([]);\n\n const search = useRef('');\n const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n },\n [],\n );\n\n const focusIndex = useCallback((index: number) => {\n const node = items.current[index];\n if (!node) return;\n setActiveIndex(index);\n node.focus();\n }, []);\n\n /** Walk from `start` in `step` until a registered, enabled item turns up. */\n const move = useCallback(\n (start: number, step: number) => {\n const total = items.current.length;\n if (total === 0) return;\n\n for (let i = 1; i <= total; i++) {\n let next = start + step * i;\n if (loop) {\n next = ((next % total) + total) % total;\n } else if (next < 0 || next >= total) {\n return;\n }\n if (items.current[next] && !meta.current[next]?.disabled) {\n focusIndex(next);\n return;\n }\n }\n },\n [loop, focusIndex],\n );\n\n const moveToEdge = useCallback(\n (from: 'start' | 'end') => {\n const total = items.current.length;\n if (total === 0) return;\n // Start just outside the range so `move` lands on the first enabled item inward.\n move(from === 'start' ? -1 : total, from === 'start' ? 1 : -1);\n },\n [move],\n );\n\n const runTypeahead = useCallback(\n (char: string) => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n search.current += char.toLowerCase();\n searchTimer.current = setTimeout(() => {\n search.current = '';\n }, 500);\n\n const total = items.current.length;\n const query = search.current;\n\n // Search forward from the item after the active one so repeated presses of the\n // same letter cycle through the matches instead of sticking on the first.\n for (let i = 1; i <= total; i++) {\n const index = (activeIndex + i) % total;\n if (meta.current[index]?.disabled) continue;\n const label = meta.current[index]?.label?.toLowerCase();\n if (label?.startsWith(query)) {\n focusIndex(index);\n return;\n }\n }\n },\n [activeIndex, focusIndex],\n );\n\n const onKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n const { key } = event;\n const vertical = orientation === 'vertical' || orientation === 'both';\n const horizontal = orientation === 'horizontal' || orientation === 'both';\n\n const next =\n (vertical && key === 'ArrowDown') || (horizontal && key === 'ArrowRight');\n const prev = (vertical && key === 'ArrowUp') || (horizontal && key === 'ArrowLeft');\n\n if (next || prev) {\n event.preventDefault();\n move(activeIndex, next ? 1 : -1);\n return;\n }\n\n if (key === 'Home') {\n event.preventDefault();\n moveToEdge('start');\n return;\n }\n\n if (key === 'End') {\n event.preventDefault();\n moveToEdge('end');\n return;\n }\n\n if (key === 'Escape' && onEscape) {\n onEscape();\n return;\n }\n\n // Single printable character, no modifier — a typeahead jump, not a shortcut.\n if (\n typeahead &&\n key.length === 1 &&\n key !== ' ' &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n runTypeahead(key);\n }\n },\n [orientation, activeIndex, move, moveToEdge, onEscape, typeahead, runTypeahead],\n );\n\n const itemProps = useCallback(\n (index: number, options: RovingItemOptions = {}): RovingItemProps => {\n meta.current[index] = options;\n return {\n ref: (node: HTMLElement | null) => {\n items.current[index] = node;\n },\n // The roving part: exactly one item is in the tab sequence, so Tab enters the\n // composite once and Tab again leaves it.\n tabIndex: index === activeIndex ? 0 : -1,\n onFocus: () => setActiveIndex(index),\n 'data-roving-index': index,\n };\n },\n [activeIndex],\n );\n\n return {\n activeIndex,\n setActiveIndex,\n focusIndex,\n moveToEdge,\n itemProps,\n containerProps: { onKeyDown },\n };\n}\n","import { useRef } from 'react';\nimport {\n arrow,\n autoUpdate,\n flip,\n offset,\n shift,\n size,\n useFloating,\n type Middleware,\n type Placement,\n} from '@floating-ui/react';\n\nexport type FloatingSide = 'top' | 'right' | 'bottom' | 'left';\nexport type FloatingAlign = 'start' | 'center' | 'end';\n\nexport interface UseFloatingPanelOptions {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Preferred edge of the trigger to sit on. Flips when there is no room. Default `bottom`. */\n side?: FloatingSide;\n /** Alignment along that edge. Default `center`. */\n align?: FloatingAlign;\n /** Gap between trigger and panel, in px. Default `6`. */\n sideOffset?: number;\n /** Nudge along the alignment axis, in px. Default `0`. */\n alignOffset?: number;\n /** Minimum gap to keep from the viewport edge, in px. Default `8`. */\n collisionPadding?: number;\n /** Render an arrow and position it. Default `false`. */\n withArrow?: boolean;\n /**\n * Constrain the panel to the space available and expose the trigger's width as\n * `--panel-anchor-width`, so a listbox can match its input. Default `false`.\n */\n matchAnchorWidth?: boolean;\n}\n\n/**\n * The one floating-panel configuration, shared by every popover-shaped component —\n * `DropdownMenu`, `Tooltip`, `Popover`, `HoverCard`, `ContextMenu`, `Combobox`, `Select`.\n *\n * Everything here is behaviour the hand-rolled version had none of. Panels were plain\n * `absolute top-full` with a static `left-0`/`right-0`, so there was no flipping when a\n * panel ran off the bottom of the viewport, no shifting when it ran off the side, no\n * repositioning on scroll or resize (nothing listened for either), and no way to ask for\n * anything other than \"below, aligned left or right\".\n *\n * `side`/`align` is the shadcn/Radix vocabulary rather than Floating UI's single\n * `placement` string, because it keeps the two axes independent at the call site and\n * `align=\"center\"` does not have to be spelled as an empty suffix.\n */\nexport function useFloatingPanel({\n open,\n onOpenChange,\n side = 'bottom',\n align = 'center',\n sideOffset = 6,\n alignOffset = 0,\n collisionPadding = 8,\n withArrow = false,\n matchAnchorWidth = false,\n}: UseFloatingPanelOptions) {\n const arrowRef = useRef<HTMLElement | null>(null);\n\n const placement: Placement = (align === 'center' ? side : `${side}-${align}`) as Placement;\n\n const floating = useFloating({\n open,\n onOpenChange,\n placement,\n // Only track while the panel is actually on screen. `autoUpdate` attaches scroll and\n // resize listeners plus a ResizeObserver, so leaving it running on a closed panel\n // would cost every consumer a listener per menu on the page.\n whileElementsMounted: autoUpdate,\n middleware: [\n offset({ mainAxis: sideOffset, crossAxis: alignOffset }),\n // `flip` before `shift`: try the opposite edge first, and only slide along the\n // current one if neither edge fits. The reverse order produces panels that cling to\n // the viewport edge when they had room to simply flip.\n flip({ padding: collisionPadding }),\n shift({ padding: collisionPadding }),\n matchAnchorWidth &&\n size({\n padding: collisionPadding,\n apply({ rects, elements, availableHeight }) {\n elements.floating.style.setProperty(\n '--panel-anchor-width',\n `${rects.reference.width}px`,\n );\n elements.floating.style.setProperty(\n '--panel-available-height',\n `${availableHeight}px`,\n );\n },\n }),\n withArrow && arrow({ element: arrowRef, padding: 4 }),\n ].filter(Boolean) as Middleware[],\n });\n\n return { ...floating, arrowRef };\n}\n","import clsx from 'clsx';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport type { InputSize } from '../forms/input';\n\n/**\n * The one option-list look, shared by every component that pops a panel of choices:\n * `DropdownMenu`, `ContextMenu`, `Menubar`, `Combobox`, `Command` and `Select`.\n *\n * Before this existed the four implementations had drifted: menus used `py-1` panels with\n * full-bleed square `px-3` items, while `Combobox` and `Command` used `p-1` panels with\n * inset `rounded-md px-2.5` ones. Menus moved, not the other two — a rounded highlight\n * needs the panel's own inset padding or its corners collide with the panel border on the\n * first and last item, and the inset form was already 2 of the 3 sites and the 2 newest.\n *\n * Strings, not components, and deliberately in its own module: `forms/` consumes these,\n * and importing `menu-core` from there would pull the whole menu component tree into the\n * bundle graph — tsup runs with no code splitting.\n */\n\n// ── Panel ──────────────────────────────────────────────────────────────────────\n\nexport const OVERLAY_PANEL = 'rounded-lg border border-default bg-default p-1 shadow-300';\n\n/** Menus need a floor width; anchored lists take their width from the trigger. */\nexport const OVERLAY_PANEL_MENU = clsx(OVERLAY_PANEL, 'min-w-[168px]');\n\n/**\n * Scroll cap for an anchored list. Prefers the collision-aware height `useFloatingPanel`\n * writes to `--panel-available-height` when `matchAnchorWidth` is set, falling back to\n * 16rem so the class is safe on a panel that never measured.\n */\nexport const OVERLAY_PANEL_SCROLL = clsx(\n 'max-h-[min(16rem,var(--panel-available-height,16rem))] overflow-y-auto',\n // A floating panel is already its own scroll container and keeps focus on the input or a\n // roving option, so it needs the scrollbar styling but not `ScrollArea`'s tab stop.\n SCROLLBAR_CLASSES,\n);\n\n// ── Item ───────────────────────────────────────────────────────────────────────\n\n/**\n * Carries no padding and no text size — those live in `OVERLAY_ITEM_SIZE`.\n *\n * `clsx` only concatenates, so a base carrying `px-3` beside a size carrying `px-2.5`\n * would resolve by stylesheet order rather than attribute order. Keeping each utility in\n * exactly one of the two strings makes the composition order-independent.\n */\nexport const OVERLAY_ITEM_BASE =\n 'flex w-full cursor-pointer select-none items-start gap-2 rounded-md text-left outline-none transition-colors';\n\nexport const OVERLAY_ITEM_SIZE: Record<InputSize, string> = {\n lg: 'px-3 py-2.5 text-body',\n md: 'px-2.5 py-2 text-body-sm',\n sm: 'px-2 py-1.5 text-body-tiny',\n};\n\nexport type OverlayItemTone = 'default' | 'danger';\n\n/** Hover and keyboard focus share one background — there is no separate active token. */\nexport function overlayItemTone(tone: OverlayItemTone, disabled: boolean) {\n if (disabled) return 'cursor-not-allowed text-disabled';\n return tone === 'danger'\n ? 'text-danger hover:bg-danger-tertiary focus:bg-danger-tertiary'\n : 'text-default hover:bg-default-secondary focus:bg-default-secondary';\n}\n\n/** Highlight driven by state rather than `:hover` — for lists using aria-activedescendant. */\nexport const OVERLAY_ITEM_ACTIVE = 'bg-default-secondary';\n\n// ── Group heading and separator ────────────────────────────────────────────────\n\nexport const OVERLAY_HEADING =\n 'px-2.5 py-1.5 text-body-tiny font-semibold uppercase tracking-wide text-default-tertiary';\n\n/** `-mx-1` cancels the panel's `p-1` so the rule still spans edge to edge. */\nexport const OVERLAY_SEPARATOR = '-mx-1 my-1 h-px bg-divider';\n","import clsx from 'clsx';\n\n/**\n * Styled native scrollbars, for the components that must own their own overflow and so\n * cannot delegate to `ScrollArea`.\n *\n * Two kinds qualify. A table wrapper, a tab strip or a stepper, where inserting another\n * element would break the layout or the `<table>` element relationship; and a floating panel\n * that is already its own scroll container. Both hold focusable children, so a keyboard user\n * can already reach and scroll them — which is the one thing `ScrollArea` adds beyond these\n * classes, and the one thing they do not need.\n *\n * Prefer `ScrollArea` for a scrolling *region* of content. Reach for this only when a wrapper\n * element is not an option, and say why at the call site.\n *\n * A plain string module rather than an export from `scroll-area.tsx`: `menu-styles.ts` needs\n * it, and importing a component module from a style module would pull the component into the\n * bundle graph for the sake of a class list.\n */\nexport const SCROLLBAR_CLASSES = clsx(\n // Firefox and the standard property.\n '[scrollbar-color:var(--color-background-default-tertiary)_transparent] [scrollbar-width:thin]',\n // WebKit/Blink.\n '[&::-webkit-scrollbar]:size-2',\n '[&::-webkit-scrollbar-track]:bg-transparent',\n '[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-default-tertiary',\n '[&::-webkit-scrollbar-thumb:hover]:bg-neutral-secondary',\n '[&::-webkit-scrollbar-corner]:bg-transparent',\n);\n","import { useEffect, useRef, type RefObject } from 'react';\nimport { tabbable } from 'tabbable';\nimport { useOverlayLayer } from './overlay-stack';\n\n/** The one scrim for every overlay primitive.\n *\n * Modal and Drawer both reference this constant, so there is a single place to change\n * the dimming behind a dialog. Backed by `--color-background-utilities-overlay`. */\nexport const OVERLAY_SCRIM = 'bg-overlay';\n\nexport interface UseOverlayDismissOptions {\n /** Called when the overlay should close. */\n onDismiss: () => void;\n /** The panel element — not the scrim. */\n panelRef: RefObject<HTMLElement | null>;\n /** Set `false` to suspend every behaviour without unmounting. Default `true`. */\n active?: boolean;\n /** Default `true`. */\n closeOnEscape?: boolean;\n /** Default `true`. */\n closeOnOutsidePress?: boolean;\n /** Keep Tab inside the panel. Default `true`. Turn off for non-modal surfaces. */\n trapFocus?: boolean;\n /** Default `true`. */\n lockScroll?: boolean;\n /** Mark sibling content `inert`. Default `true`. */\n inertBackground?: boolean;\n /**\n * Move focus into the panel on mount. Default `true`.\n *\n * Set `false` when the overlay manages its own entry point — a menu with a roving\n * tabindex exposes exactly one focusable item at a time, so a generic\n * \"focus the first tabbable element\" scan would fight it.\n */\n autoFocus?: boolean;\n /** Focus this instead of the first tabbable element. */\n initialFocus?: RefObject<HTMLElement | null>;\n /**\n * Restore focus here instead of wherever it was when the overlay opened.\n *\n * Passing the ref at all takes over the restore: a `current` of `null` means \"leave\n * focus alone\", not \"fall back to the previously focused element\". `Menubar` depends on\n * that — while it is switching from one menu to a sibling, focus already belongs to the\n * sibling and pulling it back to the closing menu's trigger reopens the menu.\n */\n returnFocus?: RefObject<HTMLElement | null>;\n /** Call `preventDefault()` to veto the close — e.g. a form with unsaved input. */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** Call `preventDefault()` to veto the close. */\n onInteractOutside?: (event: PointerEvent) => void;\n}\n\n/** Esc-to-close, a Tab focus trap, scroll lock, an inert background, and focus restore\n * for a mounted overlay. Pass the ref of the panel element (not the scrim).\n *\n * Rewritten in 0.4.0. The previous version handled Esc, Tab and focus restore, and had\n * the following defects — each is now covered by a test:\n *\n * - **One Escape closed every open overlay.** Each overlay put its own listener on\n * `document` and called `stopPropagation`, which stops propagation to other *nodes*,\n * not to sibling listeners on the same node. Dismissal is now gated on `isTopmost`\n * from the shared layer stack.\n * - **A text-selection drag dismissed the dialog.** Outside-press used `click`, whose\n * target for a drag is the nearest common ancestor — the scrim. Now `pointerdown`.\n * - **Forward Tab could walk out of the panel.** The trap only compared against the\n * last tabbable element; once focus was outside by any other route, Tab roamed the\n * background freely. A `focusin` guard now pulls focus back.\n * - **Fixed-position elements were excluded from the trap.** The visibility filter was\n * `offsetParent !== null`, which is `null` for `position: fixed`. Element collection\n * is delegated to `tabbable`, which also honours real tab order (a positive\n * `tabindex` reorders the sequence, so DOM order was the wrong answer), `inert`,\n * `[aria-disabled]`, `contenteditable`, `<summary>`, media with controls, and\n * descendants of a disabled `<fieldset>`.\n * - **Initial focus was a silent no-op for a content-only dialog.** It fell back to\n * focusing the panel, which does nothing without `tabIndex=\"-1\"`. The hook now sets\n * that itself, and retries once content arrives asynchronously.\n * - **Focus restore could land on a detached node**, resetting focus to `<body>`.\n * Now checked with `isConnected`.\n * - No opt-out existed for either dismissal route. Both are now vetoable.\n */\nexport function useOverlayDismiss({\n onDismiss,\n panelRef,\n active = true,\n closeOnEscape = true,\n closeOnOutsidePress = true,\n trapFocus = true,\n lockScroll = true,\n inertBackground = true,\n autoFocus = true,\n initialFocus,\n returnFocus,\n onEscapeKeyDown,\n onInteractOutside,\n}: UseOverlayDismissOptions): void {\n const { isTopmost } = useOverlayLayer(active, {\n lockScroll,\n inertBackground,\n panelRef,\n });\n\n // Read through refs so the listener effects do not re-subscribe on every render of a\n // consumer that passes inline callbacks — which is all of them.\n const handlers = useRef({ onDismiss, onEscapeKeyDown, onInteractOutside });\n handlers.current = { onDismiss, onEscapeKeyDown, onInteractOutside };\n\n const isTopmostRef = useRef(isTopmost);\n isTopmostRef.current = isTopmost;\n\n // ── Escape ───────────────────────────────────────────────────────────────────\n useEffect(() => {\n if (!active || !closeOnEscape) return;\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Escape') return;\n if (!isTopmostRef.current) return;\n\n handlers.current.onEscapeKeyDown?.(event);\n if (event.defaultPrevented) return;\n\n handlers.current.onDismiss();\n }\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [active, closeOnEscape]);\n\n // ── Outside press ────────────────────────────────────────────────────────────\n useEffect(() => {\n if (!active || !closeOnOutsidePress) return;\n\n function onPointerDown(event: PointerEvent) {\n if (!isTopmostRef.current) return;\n const panel = panelRef.current;\n if (!panel || panel.contains(event.target as Node)) return;\n\n handlers.current.onInteractOutside?.(event);\n if (event.defaultPrevented) return;\n\n handlers.current.onDismiss();\n }\n\n document.addEventListener('pointerdown', onPointerDown);\n return () => document.removeEventListener('pointerdown', onPointerDown);\n }, [active, closeOnOutsidePress, panelRef]);\n\n // ── Focus trap ───────────────────────────────────────────────────────────────\n useEffect(() => {\n if (!active || !trapFocus) return;\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Tab' || !isTopmostRef.current) return;\n const panel = panelRef.current;\n if (!panel) return;\n\n const items = tabbable(panel);\n if (items.length === 0) {\n // Nothing to cycle between, but Tab must still not escape the dialog.\n event.preventDefault();\n panel.focus({ preventScroll: true });\n return;\n }\n\n const first = items[0];\n const last = items[items.length - 1];\n const activeElement = document.activeElement;\n const inside = panel.contains(activeElement);\n\n if (event.shiftKey && (activeElement === first || !inside)) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && (activeElement === last || !inside)) {\n event.preventDefault();\n first.focus();\n }\n }\n\n // The keydown boundary check above only catches the moment focus is *about* to leave.\n // Focus can also arrive outside by a route Tab never sees — a click on the scrim, a\n // programmatic `.focus()`, or a round trip through the browser chrome. This pulls it\n // back whenever that happens.\n function onFocusIn(event: FocusEvent) {\n if (!isTopmostRef.current) return;\n const panel = panelRef.current;\n if (!panel) return;\n if (panel.contains(event.target as Node)) return;\n\n const items = tabbable(panel);\n (items[0] ?? panel).focus({ preventScroll: true });\n }\n\n document.addEventListener('keydown', onKeyDown);\n document.addEventListener('focusin', onFocusIn);\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n document.removeEventListener('focusin', onFocusIn);\n };\n }, [active, trapFocus, panelRef]);\n\n // ── Initial focus and restore ────────────────────────────────────────────────\n useEffect(() => {\n if (!active) return;\n\n const previouslyFocused = document.activeElement as HTMLElement | null;\n const panel = panelRef.current;\n let observer: MutationObserver | null = null;\n\n if (panel && autoFocus) {\n // A content-only dialog has nothing tabbable, and `focus()` on an element without\n // a tabindex silently does nothing. Making the panel itself focusable is what turns\n // the fallback below into a real focus move.\n if (!panel.hasAttribute('tabindex')) panel.setAttribute('tabindex', '-1');\n\n const focusTarget = () => {\n const explicit = initialFocus?.current;\n if (explicit) {\n explicit.focus({ preventScroll: true });\n return true;\n }\n const items = tabbable(panel);\n if (items.length > 0) {\n items[0].focus({ preventScroll: true });\n return true;\n }\n return false;\n };\n\n if (!focusTarget()) {\n panel.focus({ preventScroll: true });\n\n // Panel content can arrive after mount — a fetch, a Suspense boundary. Watch for\n // the first tabbable element and move focus onto it once, then stop.\n observer = new MutationObserver(() => {\n if (focusTarget()) {\n observer?.disconnect();\n observer = null;\n }\n });\n observer.observe(panel, { childList: true, subtree: true });\n }\n }\n\n return () => {\n observer?.disconnect();\n // Reading `returnFocus.current` at cleanup time is the intent, not an oversight:\n // the element to return focus to may not exist when the overlay mounts, and the\n // caller may repoint it while the overlay is open.\n //\n // A caller that passes the ref owns the decision outright, `null` included — `??`\n // here instead of the ternary made `{ current: null }` mean \"restore to whatever\n // was focused before\", the exact opposite of what the one caller passing it wanted.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const target = returnFocus ? returnFocus.current : previouslyFocused;\n // A detached node's `focus()` is a silent no-op that leaves focus on <body>, which\n // strands keyboard users at the top of the page. Better to leave focus where the\n // browser put it than to pretend.\n if (target?.isConnected) target.focus({ preventScroll: true });\n };\n }, [active, panelRef, initialFocus, returnFocus, autoFocus]);\n}\n","import { useEffect, useRef, useState, type RefObject } from 'react';\n\n/**\n * A process-wide stack of the overlays currently mounted, plus the two document-level\n * side effects that belong to \"there is a dialog open\": scroll lock and an inert\n * background.\n *\n * Why a stack rather than per-overlay listeners. Before 0.4.0 every overlay attached its\n * own `keydown` handler to `document`. `useOverlayDismiss` called `e.stopPropagation()`\n * on Escape, which stops propagation *to other nodes* — it does not stop the other\n * listeners already registered on the same node. All of them were on `document`. So a\n * `DropdownMenu` open inside a `Modal` closed both on one Escape, and two stacked modals\n * closed together. Ordering has to be decided centrally, by asking \"am I topmost?\",\n * which is what this module answers.\n */\n\ntype Layer = { id: symbol };\n\nconst layers: Layer[] = [];\nconst listeners = new Set<() => void>();\n\nfunction notify() {\n for (const listener of listeners) listener();\n}\n\nfunction topmost(): symbol | undefined {\n return layers[layers.length - 1]?.id;\n}\n\n// ── Scroll lock ────────────────────────────────────────────────────────────────\n\nlet scrollLocks = 0;\nlet restoreBody: (() => void) | null = null;\n\nfunction lockScroll() {\n scrollLocks += 1;\n if (scrollLocks > 1 || typeof document === 'undefined') return;\n\n const { body, documentElement } = document;\n const previousOverflow = body.style.overflow;\n const previousPaddingRight = body.style.paddingRight;\n\n // Removing the scrollbar reflows the page a few pixels narrower, which reads as the\n // whole layout twitching sideways as the dialog appears. Pad by exactly the width the\n // scrollbar occupied to hold everything still.\n const scrollbarWidth = window.innerWidth - documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n const current = parseFloat(window.getComputedStyle(body).paddingRight) || 0;\n body.style.paddingRight = `${current + scrollbarWidth}px`;\n }\n body.style.overflow = 'hidden';\n\n restoreBody = () => {\n body.style.overflow = previousOverflow;\n body.style.paddingRight = previousPaddingRight;\n };\n}\n\nfunction unlockScroll() {\n scrollLocks = Math.max(0, scrollLocks - 1);\n if (scrollLocks === 0 && restoreBody) {\n restoreBody();\n restoreBody = null;\n }\n}\n\n// ── Inert background ───────────────────────────────────────────────────────────\n\nconst inerted = new Set<HTMLElement>();\n\n/**\n * Marks every top-level sibling of the overlay's own subtree `inert`, which removes it\n * from the accessibility tree *and* from the tab sequence in one attribute.\n *\n * `aria-modal=\"true\"` alone — all this library had before — is honoured by modern screen\n * readers for virtual-cursor browsing but does nothing about focus, and older AT ignores\n * it entirely. `inert` is the actual guarantee.\n */\nfunction applyInert(node: HTMLElement | null) {\n if (typeof document === 'undefined' || !node) return;\n\n // Walk up to whichever direct child of <body> contains this overlay, so the overlay's\n // own portal container is the one subtree left interactive.\n let root: HTMLElement = node;\n while (root.parentElement && root.parentElement !== document.body) {\n root = root.parentElement;\n }\n\n for (const child of Array.from(document.body.children)) {\n if (child === root || !(child instanceof HTMLElement)) continue;\n if (child.hasAttribute('inert')) continue;\n child.setAttribute('inert', '');\n inerted.add(child);\n }\n}\n\nfunction releaseInert() {\n for (const el of inerted) el.removeAttribute('inert');\n inerted.clear();\n}\n\n// ── Hook ───────────────────────────────────────────────────────────────────────\n\nexport interface UseOverlayLayerOptions {\n /** Prevent the page behind from scrolling. Default `true`. */\n lockScroll?: boolean;\n /**\n * Mark sibling content `inert`. Default `true`. Turn it off for non-modal surfaces —\n * a tooltip or a popover must leave the rest of the page usable.\n */\n inertBackground?: boolean;\n /**\n * Ref to the panel element, used to work out which subtree to leave interactive.\n *\n * Deliberately the ref object rather than the node: a node read during render is\n * always `null` on the first pass, and nothing re-renders the consumer once the ref\n * is attached, so the inert pass would never run. Effects read `.current` after the\n * DOM is committed, where it is populated.\n */\n panelRef?: RefObject<HTMLElement | null>;\n}\n\n/**\n * Registers a mounted overlay with the stack.\n *\n * Returns `isTopmost`, which every dismissal handler must gate on so only the frontmost\n * layer reacts to Escape or an outside pointer press.\n */\nexport function useOverlayLayer(\n active: boolean,\n {\n lockScroll: shouldLockScroll = true,\n inertBackground = true,\n panelRef,\n }: UseOverlayLayerOptions = {},\n): { isTopmost: boolean } {\n const id = useRef<symbol>();\n if (!id.current) id.current = Symbol('overlay-layer');\n\n const [isTopmost, setIsTopmost] = useState(false);\n\n useEffect(() => {\n if (!active) return;\n const self = id.current!;\n\n layers.push({ id: self });\n\n const sync = () => setIsTopmost(topmost() === self);\n listeners.add(sync);\n sync();\n notify();\n\n if (shouldLockScroll) lockScroll();\n\n return () => {\n const index = layers.findIndex((layer) => layer.id === self);\n if (index !== -1) layers.splice(index, 1);\n listeners.delete(sync);\n notify();\n if (shouldLockScroll) unlockScroll();\n };\n }, [active, shouldLockScroll]);\n\n useEffect(() => {\n if (!active || !inertBackground) return;\n // Only the bottom-most modal layer needs to set this: it already hides everything\n // outside the overlay tree, and every overlay above it portals into the same root.\n if (inerted.size === 0) applyInert(panelRef?.current ?? null);\n return () => {\n if (layers.length <= 1) releaseInert();\n };\n }, [active, inertBackground, panelRef]);\n\n return { isTopmost };\n}\n","import { useEffect, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport interface PortalProps {\n children: ReactNode;\n /**\n * Where to mount. Defaults to `document.body`.\n *\n * Pass a container when the app renders inside a shadow root or a scoped theme\n * wrapper — the portal must stay inside whatever element the design tokens are\n * declared on, or every `var(--color-*)` resolves to nothing.\n */\n container?: HTMLElement | null;\n}\n\n/**\n * Renders `children` outside the parent DOM hierarchy.\n *\n * Until 0.4.0 this library never called `createPortal` — `Modal`, `Drawer`,\n * `DropdownMenu`, `RoleComboBox` and the sidebar menu all rendered inline. Two concrete\n * failures came out of that:\n *\n * - `DropdownMenu` was positioned `absolute` inside a `relative` wrapper, so it was\n * clipped by `Card`'s `overflow-hidden` and by `DataTable`'s `overflow-x-auto` — the\n * two places its own doc comment said it was for.\n * - `position: fixed` resolves against the nearest ancestor with `transform`, `filter`,\n * `backdrop-filter`, `perspective`, `will-change` or `contain`, so a `Modal` opened\n * from inside any transformed ancestor was positioned against that ancestor rather\n * than the viewport, and `z-50` was scoped to a stacking context it did not control.\n *\n * Mounting is deferred to an effect so the server render and the first client render\n * agree — reaching for `document` during render breaks SSR and hydration.\n */\nexport function Portal({ children, container }: PortalProps) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (!mounted) return null;\n\n const target = container ?? (typeof document === 'undefined' ? null : document.body);\n if (!target) return null;\n\n return createPortal(children, target);\n}\n","import { forwardRef, type InputHTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { LuCalendar } from 'react-icons/lu';\nimport { type InputSize } from './input';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldControl,\n} from './field';\n\nexport interface DatePickerProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n label?: string;\n description?: string;\n /** Red border + message shown below the control. Also sets `aria-invalid`. */\n error?: string;\n hint?: string;\n size?: InputSize;\n}\n\nconst inputBase: Record<InputSize, string> = {\n lg: 'h-12 px-5 py-3.5 pr-12 text-body',\n md: 'h-9 px-4 py-2.5 pr-8 text-body-sm',\n sm: 'h-6 px-3 py-[5px] pr-6 text-body-tiny',\n};\n\nconst iconWrap: Record<InputSize, { right: string; size: string }> = {\n lg: { right: 'right-4', size: 'size-5' },\n md: { right: 'right-3', size: 'size-4' },\n sm: { right: 'right-2', size: 'size-3' },\n};\n\n/**\n * A native `<input type=\"date\">`.\n *\n * The `::-webkit-calendar-picker-indicator` styling below is Chromium-only — on Firefox\n * and Safari the native affordance differs, so the drawn `LuCalendar` sits alongside\n * whatever the platform renders rather than replacing it. That is a known limitation of\n * this component, not a bug to paper over: for a real month grid, range selection, locale\n * control or min/max navigation, use `Calendar` and `DateField` instead.\n */\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(function DatePicker(\n { label, description, error, hint, size: sizeProp, className, disabled, required, id, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n const iw = iconWrap[size];\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n <div className=\"relative flex items-center\">\n <DateInput\n ref={ref}\n size={size}\n invalid={hasError}\n disabled={disabled}\n required={required}\n {...props}\n />\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n iw.right,\n iw.size,\n 'flex items-center justify-center',\n disabled ? 'text-icon-disabled' : 'text-icon-default-secondary',\n )}\n >\n <LuCalendar className=\"size-full\" />\n </span>\n </div>\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n\ninterface DateInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n size?: InputSize;\n invalid?: boolean;\n}\n\nconst DateInput = forwardRef<HTMLInputElement, DateInputProps>(function DateInput(\n { size: sizeProp, invalid = false, className, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n return (\n <input\n ref={ref}\n type=\"date\"\n {...field}\n className={clsx(\n 'w-full rounded-lg border outline-none transition-colors',\n 'bg-default text-default',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n '[&::-webkit-calendar-picker-indicator]:opacity-0',\n '[&::-webkit-calendar-picker-indicator]:absolute',\n '[&::-webkit-calendar-picker-indicator]:right-0',\n '[&::-webkit-calendar-picker-indicator]:h-full',\n '[&::-webkit-calendar-picker-indicator]:w-10',\n '[&::-webkit-calendar-picker-indicator]:cursor-pointer',\n inputBase[size],\n isDisabled\n ? 'cursor-not-allowed border-disabled bg-disabled text-disabled'\n : isInvalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n className,\n )}\n {...props}\n />\n );\n});\n","import clsx from 'clsx';\nimport { LuCheck, LuChevronRight } from 'react-icons/lu';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\nexport type StepStatus = 'complete' | 'active' | 'upcoming';\n\nexport interface StepItem {\n label: string;\n status: StepStatus;\n}\n\nexport type StepperSize = 'sm' | 'md';\n\nexport interface StepperProps {\n steps: StepItem[];\n /** Matches Figma's `Size` axis on the `Stepper` component set. */\n size?: StepperSize;\n /** Names the list. Defaults to `Progress`. Override for a non-English UI. */\n label?: string;\n className?: string;\n}\n\n/**\n * Status words announced after each step's label.\n *\n * Step status was conveyed by colour plus an `aria-hidden` glyph only, so \"complete\" and\n * \"upcoming\" were indistinguishable to a screen reader — `aria-current=\"step\"` marked the\n * active one and nothing said which of the rest were done.\n */\nconst STATUS_TEXT: Record<StepStatus, string> = {\n complete: 'completed',\n active: 'current step',\n upcoming: 'not started',\n};\n\nconst SIZE: Record<StepperSize, { indicator: string; glyph: number; label: string }> = {\n sm: { indicator: 'size-4', glyph: 9, label: 'text-body-tiny' },\n md: { indicator: 'size-5', glyph: 11, label: 'text-body-xs' },\n};\n\nfunction StepIndicator({ status, size }: { status: StepStatus; size: StepperSize }) {\n const s = SIZE[size];\n\n if (status === 'complete') {\n return (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full bg-brand text-brand-on-brand',\n s.indicator,\n )}\n >\n <LuCheck size={s.glyph} />\n </span>\n );\n }\n\n if (status === 'active') {\n return (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full border-2 border-brand-emphasis',\n s.indicator,\n )}\n >\n <span className=\"size-2.5 rounded-full bg-brand\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden\n className={clsx('shrink-0 rounded-full border-2 border-disabled', s.indicator)}\n />\n );\n}\n\nfunction ChevronSeparator() {\n return <LuChevronRight className=\"mx-1 size-4 shrink-0 text-default-tertiary\" aria-hidden />;\n}\n\nconst labelClass: Record<StepStatus, string> = {\n complete: 'text-brand font-semibold',\n active: 'text-brand font-semibold',\n upcoming: 'text-disabled font-regular',\n};\n\nexport function Stepper({ steps, size = 'md', label = 'Progress', className }: StepperProps) {\n const s = SIZE[size];\n\n return (\n // An <ol> cannot be wrapped without breaking the list relationship with its <li>s.\n <ol\n className={clsx('flex items-center overflow-x-auto', SCROLLBAR_CLASSES, className)}\n aria-label={label}\n >\n {steps.map((step, i) => (\n <li\n // Keyed by label rather than index, so reordering or inserting a step does not\n // reuse the wrong element's state.\n key={step.label}\n className=\"flex items-center\"\n aria-current={step.status === 'active' ? 'step' : undefined}\n >\n <span className=\"flex items-center gap-1.5\">\n <StepIndicator status={step.status} size={size} />\n <span className={clsx('whitespace-nowrap', s.label, labelClass[step.status])}>\n {step.label}\n </span>\n <span className=\"sr-only\">, {STATUS_TEXT[step.status]}</span>\n </span>\n {i < steps.length - 1 && <ChevronSeparator />}\n </li>\n ))}\n </ol>\n );\n}\n","import clsx from 'clsx';\nimport { type ReactNode } from 'react';\nimport { LuCheck } from 'react-icons/lu';\n\n/** Matches Figma's `Size` axis on `Multiselect Card` (`Default | Small`). */\nexport type MultiSelectCardSize = 'default' | 'sm';\n\nexport interface MultiSelectCardProps {\n icon: ReactNode;\n title: string;\n description?: string;\n selected: boolean;\n onToggle: () => void;\n /**\n * Figma has had this axis since 0.2.0; the 0.3.0 CHANGELOG recorded it as \"left alone\n * pending a design decision\". `Default` and `Small` differ only in padding, icon box and\n * type step, so there was nothing to decide.\n */\n size?: MultiSelectCardSize;\n disabled?: boolean;\n className?: string;\n}\n\nconst SIZE: Record<\n MultiSelectCardSize,\n { pad: string; iconBox: string; icon: string; mark: string; gap: string; title: string }\n> = {\n default: {\n pad: 'p-4',\n iconBox: 'size-10 rounded-xl',\n icon: 'size-5',\n mark: 'size-5',\n gap: 'mt-3',\n title: 'text-body-sm',\n },\n sm: {\n pad: 'p-3',\n iconBox: 'size-8 rounded-lg',\n icon: 'size-4',\n mark: 'size-4',\n gap: 'mt-2',\n title: 'text-body-xs',\n },\n};\n\nexport function MultiSelectCard({\n icon,\n title,\n description,\n selected,\n onToggle,\n size = 'default',\n disabled = false,\n className,\n}: MultiSelectCardProps) {\n const s = SIZE[size];\n\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={selected}\n disabled={disabled}\n onClick={onToggle}\n className={clsx(\n 'relative w-full rounded-2xl border-2 text-left transition-all',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:opacity-60',\n s.pad,\n selected\n ? 'border-brand bg-brand-tertiary'\n : 'border-default bg-default hover:border-default-secondary',\n className,\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center',\n s.iconBox,\n selected ? 'bg-brand' : 'bg-brand-tertiary',\n )}\n >\n <span className={clsx(s.icon, selected ? 'text-icon-brand-on-brand' : 'text-icon-brand')}>\n {icon}\n </span>\n </span>\n\n {selected ? (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full bg-brand text-icon-brand-on-brand',\n s.mark,\n )}\n >\n <LuCheck className=\"size-3\" strokeWidth={2.5} />\n </span>\n ) : (\n <span\n aria-hidden\n className={clsx('shrink-0 rounded-full border-2 border-default', s.mark)}\n />\n )}\n </div>\n\n <div className={s.gap}>\n <p className={clsx('font-semibold', s.title, selected ? 'text-brand' : 'text-default')}>\n {title}\n </p>\n {description && (\n <p className=\"mt-0.5 text-body-tiny text-default-secondary\">{description}</p>\n )}\n </div>\n </button>\n );\n}\n","import { forwardRef, useId, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type SwitchSize = 'sm' | 'md';\n\nexport interface SwitchProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value' | 'type'> {\n /** Controlled. Omit and pass `defaultChecked` for uncontrolled. */\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Visible text beside the switch. Doubles as the accessible name. */\n label?: ReactNode;\n /** Second line under the label. Matches Figma's `Supporting text` axis. */\n description?: ReactNode;\n /** Track size. `sm` is 36×20, `md` is 44×24. */\n size?: SwitchSize;\n}\n\n/**\n * Track / knob geometry, straight from the Figma `_Toggle base` component (see the naming\n * note below). The knob sits on a 2px inset, so travel = track width − knob − (2 × inset).\n */\nconst SIZE: Record<SwitchSize, { track: string; knob: string; translate: string }> = {\n sm: { track: 'h-5 w-9', knob: 'size-4', translate: 'translate-x-4' },\n md: { track: 'h-6 w-11', knob: 'size-5', translate: 'translate-x-5' },\n};\n\n/**\n * An on/off switch — a setting that takes effect immediately, with no save step.\n *\n * **Renamed from `Toggle` in 0.4.0.** It was always a switch: `role=\"switch\"`,\n * `aria-checked`, and the track/knob geometry taken from Figma. The name was blocking,\n * because \"Toggle\" means something else in shadcn/ui and in most design systems — a\n * pressed-state *button*, like a bold button in a text toolbar. That component now exists\n * here under the name everyone expects, and the two are not interchangeable:\n *\n * - `Switch` — `role=\"switch\"`, \"on\"/\"off\", applies immediately. A setting.\n * - `Toggle` — `aria-pressed`, \"pressed\"/\"not pressed\". A button whose effect persists.\n *\n * Figma calls its set `Toggle` with a `Pressed` axis, but its geometry and `_Toggle base`\n * match this component exactly, so Figma's `Toggle` **is** this switch. Figma has no\n * pressed-button equivalent yet; that is a gap on the design side, recorded in the\n * CHANGELOG rather than papered over here.\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(function Switch(\n {\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n label,\n description,\n size = 'md',\n disabled = false,\n id,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...rest\n },\n ref,\n) {\n const [checked, setChecked] = useControllableState({\n value: checkedProp,\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n });\n\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n const s = SIZE[size];\n\n const control = (\n <button\n ref={ref}\n type=\"button\"\n role=\"switch\"\n id={controlId}\n aria-checked={checked}\n // With no visible label the switch would otherwise ship with no accessible name.\n aria-label={label ? undefined : ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={description ? descriptionId : undefined}\n disabled={disabled}\n onClick={() => setChecked(!checked)}\n className={clsx(\n 'group flex items-center gap-2',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n disabled && 'cursor-not-allowed opacity-50',\n !description && className,\n )}\n {...rest}\n >\n <span\n aria-hidden\n className={clsx(\n 'relative inline-flex shrink-0 rounded-full transition-colors',\n s.track,\n // The unchecked track is borderless per the spec. A border here would also shift\n // the knob's rendered inset by 1px between states, since the knob is positioned\n // against the padding box.\n disabled\n ? 'bg-disabled'\n : checked\n ? 'bg-brand group-hover:bg-brand-hover'\n : 'bg-default-secondary group-hover:bg-default-secondary-hover',\n )}\n >\n <span\n className={clsx(\n 'absolute left-0.5 top-0.5 rounded-full bg-default shadow-100 transition-transform',\n s.knob,\n checked ? s.translate : 'translate-x-0',\n )}\n />\n </span>\n {label && <span className=\"text-body-xs text-default\">{label}</span>}\n </button>\n );\n\n if (!description) return control;\n\n return (\n <div className={clsx('flex flex-col', className)}>\n {control}\n {/* Outside the button, so it is not folded into the accessible name — the same\n reasoning as `Checkbox` and `Radio`. Indented past the track. */}\n <span\n id={descriptionId}\n className={clsx(\n 'mt-0.5 text-body-tiny',\n size === 'md' ? 'pl-[52px]' : 'pl-[44px]',\n disabled ? 'text-disabled' : 'text-default-secondary',\n )}\n >\n {description}\n </span>\n </div>\n );\n});\n","import {\n createContext,\n forwardRef,\n useContext,\n useMemo,\n useRef,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\n\nexport type ToggleSize = 'sm' | 'md' | 'lg';\nexport type ToggleVariant = 'ghost' | 'outline';\n\nconst SIZE: Record<ToggleSize, string> = {\n sm: 'h-8 min-w-8 px-2 text-body-tiny [&_svg]:size-3.5',\n md: 'h-9 min-w-9 px-2.5 text-body-xs [&_svg]:size-4',\n lg: 'h-11 min-w-11 px-3 text-body-sm [&_svg]:size-5',\n};\n\nconst VARIANT: Record<ToggleVariant, string> = {\n ghost: 'border border-transparent bg-transparent',\n outline: 'border border-default bg-default',\n};\n\nexport interface ToggleProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'type'> {\n /** Controlled pressed state. Omit and pass `defaultPressed` for uncontrolled. */\n pressed?: boolean;\n defaultPressed?: boolean;\n onPressedChange?: (pressed: boolean) => void;\n size?: ToggleSize;\n variant?: ToggleVariant;\n children?: ReactNode;\n}\n\n/**\n * A button with a sticky pressed state — bold in a text toolbar, a map layer on/off, a\n * filter that stays applied.\n *\n * **New in 0.4.0, and not what `Toggle` used to be.** Through 0.3.0 this name belonged to\n * the on/off switch, which is now `Switch`. The two look similar and mean different things:\n *\n * - `Toggle` — `aria-pressed`. A *button*. \"Bold is pressed.\"\n * - `Switch` — `role=\"switch\"` + `aria-checked`. A *setting*. \"Notifications are on.\"\n *\n * `aria-pressed` rather than `aria-checked` is the whole distinction as far as assistive\n * tech is concerned, and it is why this is not just `Switch` with different styling.\n *\n * An icon-only toggle needs `aria-label`, exactly as `IconButton` does — there is no visible\n * text to name it.\n */\nexport const Toggle = forwardRef<HTMLButtonElement, ToggleProps>(function Toggle(\n {\n pressed: pressedProp,\n defaultPressed = false,\n onPressedChange,\n size = 'md',\n variant = 'ghost',\n disabled,\n children,\n className,\n ...rest\n },\n ref,\n) {\n const group = useContext(ToggleGroupContext);\n\n // Inside a ToggleGroup the group owns the state; standalone it owns its own.\n const [standalonePressed, setStandalonePressed] = useControllableState({\n value: pressedProp,\n defaultValue: defaultPressed,\n onChange: onPressedChange,\n });\n\n const pressed = group ? group.isPressed(rest.value as string) : standalonePressed;\n const isDisabled = disabled ?? group?.disabled;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-pressed={pressed}\n disabled={isDisabled}\n onClick={(event) => {\n rest.onClick?.(event);\n if (group) group.toggle(rest.value as string);\n else setStandalonePressed(!pressed);\n }}\n className={clsx(\n 'inline-flex shrink-0 items-center justify-center gap-1.5 rounded-lg font-medium transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n SIZE[size],\n VARIANT[variant],\n pressed\n ? 'border-brand-tertiary bg-brand-tertiary text-brand'\n : 'text-default-secondary hover:bg-default-secondary hover:text-default',\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n );\n});\n\n// ── ToggleGroup ────────────────────────────────────────────────────────────────\n\nexport type ToggleGroupType = 'single' | 'multiple';\n\ninterface ToggleGroupContextValue {\n isPressed: (value: string) => boolean;\n toggle: (value: string) => void;\n disabled?: boolean;\n /** Items claim a roving index in render order, which is their visual order. */\n claimIndex: () => number;\n roving: ReturnType<typeof useRovingFocus>;\n}\n\nconst ToggleGroupContext = createContext<ToggleGroupContextValue | null>(null);\n\nexport interface ToggleGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n children: ReactNode;\n /** `single` behaves like a radio group; `multiple` like a set of checkboxes. */\n type?: ToggleGroupType;\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n /** Names the group. Required by the APG for a toolbar-style group. */\n label: string;\n disabled?: boolean;\n orientation?: 'horizontal' | 'vertical';\n}\n\n/**\n * A set of related toggles sharing one selection.\n *\n * `role=\"group\"` with `aria-pressed` on each child, and a roving tabindex so the set is one\n * tab stop with arrow keys inside — the same contract `SegmentedControl` was missing before\n * 0.4.0.\n *\n * How this differs from the neighbours, since three components in this library now look\n * similar: `SegmentedControl` is a `radiogroup` for choosing *one* of a small set of views,\n * and always has exactly one selection. `ToggleGroup type=\"multiple\"` allows none or many.\n * `ToggleGroup type=\"single\"` allows none or one — the deselectable case a radio group\n * cannot express.\n */\nexport function ToggleGroup({\n children,\n type = 'single',\n value: valueProp,\n defaultValue,\n onValueChange,\n label,\n disabled,\n orientation = 'horizontal',\n className,\n ...rest\n}: ToggleGroupProps) {\n const [value, setValue] = useControllableState<string | string[]>({\n value: valueProp,\n defaultValue: defaultValue ?? (type === 'multiple' ? [] : ''),\n onChange: onValueChange,\n });\n\n const roving = useRovingFocus({\n orientation: orientation === 'vertical' ? 'vertical' : 'horizontal',\n loop: true,\n });\n\n const cursor = useRef(0);\n\n const context = useMemo<ToggleGroupContextValue>(\n () => ({\n isPressed: (itemValue) =>\n Array.isArray(value) ? value.includes(itemValue) : value === itemValue,\n toggle: (itemValue) => {\n if (type === 'multiple') {\n const list = Array.isArray(value) ? value : [];\n setValue(\n list.includes(itemValue) ? list.filter((v) => v !== itemValue) : [...list, itemValue],\n );\n return;\n }\n // Single mode deselects on re-press — the behaviour a radiogroup cannot offer.\n setValue(value === itemValue ? '' : itemValue);\n },\n disabled,\n claimIndex: () => cursor.current++,\n roving,\n }),\n [value, setValue, type, disabled, roving],\n );\n\n // Reset before the children's render bodies run, so indices restart from zero each pass.\n cursor.current = 0;\n\n return (\n <ToggleGroupContext.Provider value={context}>\n <div\n role=\"group\"\n aria-label={label}\n // No `aria-orientation`: `role=\"group\"` does not support it. The orientation only\n // affects which arrow keys move focus, which the roving hook already knows —\n // announcing it here would be an invalid attribute for the role.\n data-slot=\"toggle-group\"\n className={clsx(\n 'inline-flex gap-0.5',\n orientation === 'vertical' ? 'flex-col' : 'flex-row items-center',\n className,\n )}\n {...roving.containerProps}\n {...rest}\n >\n {children}\n </div>\n </ToggleGroupContext.Provider>\n );\n}\n\nexport interface ToggleGroupItemProps extends Omit<ToggleProps, 'pressed' | 'defaultPressed'> {\n value: string;\n}\n\n/** A `Toggle` wired to its `ToggleGroup`, with the roving tabindex applied. */\nexport const ToggleGroupItem = forwardRef<HTMLButtonElement, ToggleGroupItemProps>(\n function ToggleGroupItem({ value, children, ...rest }, ref) {\n const group = useContext(ToggleGroupContext);\n if (!group) throw new Error('<ToggleGroupItem> must be used inside <ToggleGroup>');\n\n const index = group.claimIndex();\n const { ref: rovingRef, ...itemProps } = group.roving.itemProps(index, {\n disabled: rest.disabled ?? group.disabled,\n label: typeof children === 'string' ? children : undefined,\n });\n\n return (\n <Toggle\n ref={composeRefs<HTMLButtonElement>(ref, rovingRef)}\n value={value}\n {...itemProps}\n // Restated after the spread so it is statically visible, and so a group of five\n // toggles is one tab stop rather than five.\n tabIndex={itemProps.tabIndex}\n {...rest}\n >\n {children}\n </Toggle>\n );\n },\n);\n","import {\n forwardRef,\n useId,\n useRef,\n useState,\n type ClipboardEvent as ReactClipboardEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n} from 'react';\nimport clsx from 'clsx';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type InputOTPMode = 'numeric' | 'alphanumeric';\n\nexport interface InputOTPProps {\n /** Number of characters. Default `6`. */\n length?: number;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Fired once the last slot is filled. */\n onComplete?: (value: string) => void;\n mode?: InputOTPMode;\n /** Draws a gap after this many slots — `3` for a `123 456` code. */\n groupAfter?: number;\n /** Accessible name. Default `Verification code`. */\n label?: string;\n disabled?: boolean;\n invalid?: boolean;\n autoFocus?: boolean;\n className?: string;\n}\n\n/**\n * A one-time-code field — the boxed digits from a 2FA or email-verification flow.\n *\n * **One real input, N drawn boxes.** The obvious implementation is N separate `<input>`s,\n * and it is the wrong one: it makes the code N tab stops, breaks paste (the browser puts all\n * six characters in the first box), fights password managers and SMS autofill, and announces\n * \"edit text, blank\" six times. Instead there is a single input holding the whole value —\n * with `autocomplete=\"one-time-code\"`, so iOS and Android offer the code from the incoming\n * message — rendered transparently over the boxes, which are decorative.\n *\n * That means paste, autofill, undo, selection and screen readers all get the real value, and\n * the caret position simply drives which box is highlighted.\n */\nexport const InputOTP = forwardRef<HTMLInputElement, InputOTPProps>(function InputOTP(\n {\n length = 6,\n value: valueProp,\n defaultValue = '',\n onValueChange,\n onComplete,\n mode = 'numeric',\n groupAfter,\n label = 'Verification code',\n disabled = false,\n invalid = false,\n autoFocus = false,\n className,\n },\n ref,\n) {\n const [value, setValue] = useControllableState({\n value: valueProp,\n defaultValue,\n onChange: onValueChange,\n });\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const describedById = useId();\n\n const pattern = mode === 'numeric' ? /[^0-9]/g : /[^a-zA-Z0-9]/g;\n\n const commit = (next: string) => {\n const cleaned = next.replace(pattern, '').slice(0, length);\n setValue(cleaned);\n if (cleaned.length === length) onComplete?.(cleaned);\n };\n\n const chars = value.split('');\n // The caret sits on the first empty slot, or the last one when full.\n const activeIndex = Math.min(value.length, length - 1);\n\n return (\n <div className={clsx('inline-flex flex-col gap-1.5', className)}>\n {/* Clicking any box focuses the single real input. Not a control itself and not\n focusable — the input stretched across it is the control, and it is already keyboard\n reachable, so no key handler belongs here. */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n className=\"relative inline-flex items-center gap-2\"\n onClick={() => inputRef.current?.focus()}\n >\n <input\n ref={composeRefs<HTMLInputElement>(inputRef, ref)}\n type=\"text\"\n inputMode={mode === 'numeric' ? 'numeric' : 'text'}\n // The one attribute that makes SMS and email autofill work on mobile.\n autoComplete=\"one-time-code\"\n autoCorrect=\"off\"\n spellCheck={false}\n maxLength={length}\n value={value}\n disabled={disabled}\n // Off by default; opt-in for the case this exists for — a verification screen whose\n // only purpose is entering the code that just arrived.\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedById}\n onChange={(event) => commit(event.target.value)}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n onKeyDown={(event: ReactKeyboardEvent<HTMLInputElement>) => {\n // Arrow keys would move the caret into the middle of the value, which has no\n // meaning here — the code is filled left to right.\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') event.preventDefault();\n }}\n onPaste={(event: ReactClipboardEvent<HTMLInputElement>) => {\n // Handled explicitly so a pasted \"123-456\" or \"123 456\" still works.\n event.preventDefault();\n commit(event.clipboardData.getData('text'));\n }}\n // Transparent and stretched across the boxes: the real input stays where the\n // browser expects it (so autofill anchors correctly) while the boxes below are\n // what the user sees.\n className=\"absolute inset-0 z-raised w-full cursor-default bg-transparent text-transparent caret-transparent outline-none\"\n />\n\n {Array.from({ length }, (_, index) => (\n <span\n key={index}\n // Decorative: the input above holds the value and the accessible name.\n aria-hidden\n className={clsx(\n 'flex h-12 w-10 items-center justify-center rounded-lg border text-body font-semibold tabular-nums transition-colors',\n groupAfter && index === groupAfter && 'ml-3',\n disabled\n ? 'border-disabled bg-disabled text-disabled'\n : invalid\n ? 'border-danger-secondary bg-default text-default'\n : 'border-default bg-default text-default',\n focused &&\n !disabled &&\n index === activeIndex &&\n 'border-brand ring-2 ring-brand ring-offset-1 ring-offset-default',\n )}\n >\n {chars[index] ?? ''}\n </span>\n ))}\n </div>\n <span id={describedById} className=\"sr-only\">\n {`Enter the ${length}-character code. ${value.length} of ${length} entered.`}\n </span>\n </div>\n );\n});\n","import { useRef, useState } from 'react';\nimport clsx from 'clsx';\nimport { LuUpload } from 'react-icons/lu';\n\nexport interface FileDropZoneProps {\n className?: string;\n /** Caption shown under \"Upload file\". Defaults to the generic document hint. */\n description?: string;\n accept?: string;\n /** Files above this size are rejected before any upload starts. */\n maxSizeBytes?: number;\n onFileSelected?: (file: File) => void;\n disabled?: boolean;\n}\n\nconst DEFAULT_ACCEPT = '.pdf,.jpg,.jpeg,.png';\nconst DEFAULT_MAX_SIZE_BYTES = 10 * 1024 * 1024;\n\nfunction formatSize(bytes: number): string {\n const mb = bytes / (1024 * 1024);\n return `${Number.isInteger(mb) ? mb : mb.toFixed(1)} MB`;\n}\n\nfunction matchesAccept(file: File, accept: string): boolean {\n const extensions = accept\n .split(',')\n .map((part) => part.trim().toLowerCase())\n .filter((part) => part.startsWith('.'));\n if (extensions.length === 0) {\n return true;\n }\n return extensions.some((extension) => file.name.toLowerCase().endsWith(extension));\n}\n\nexport function FileDropZone({\n className,\n description = 'Drag & drop or browse · PDF, JPG, PNG · up to 10 MB',\n accept = DEFAULT_ACCEPT,\n maxSizeBytes = DEFAULT_MAX_SIZE_BYTES,\n onFileSelected,\n disabled = false,\n}: FileDropZoneProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n function handleFiles(files: FileList | null) {\n const file = files?.[0];\n if (!file) {\n return;\n }\n if (!matchesAccept(file, accept)) {\n setError(`Unsupported file type. Allowed: ${accept}.`);\n return;\n }\n if (file.size > maxSizeBytes) {\n setError(`That file is ${formatSize(file.size)}. The limit is ${formatSize(maxSizeBytes)}.`);\n return;\n }\n setError(null);\n onFileSelected?.(file);\n }\n\n return (\n <>\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n className=\"sr-only\"\n tabIndex={-1}\n disabled={disabled}\n onChange={(e) => {\n handleFiles(e.target.files);\n e.target.value = '';\n }}\n />\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n onClick={() => { if (!disabled) inputRef.current?.click(); }}\n onKeyDown={(e) => {\n if (!disabled && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n inputRef.current?.click();\n }\n }}\n onDragOver={(e) => { e.preventDefault(); if (!disabled) setIsDragging(true); }}\n onDragEnter={(e) => { e.preventDefault(); if (!disabled) setIsDragging(true); }}\n onDragLeave={() => setIsDragging(false)}\n onDrop={(e) => {\n e.preventDefault();\n setIsDragging(false);\n if (!disabled) handleFiles(e.dataTransfer.files);\n }}\n className={clsx(\n 'flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed py-4 px-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1',\n disabled\n ? 'cursor-not-allowed border-disabled bg-disabled'\n : clsx(\n 'cursor-pointer',\n isDragging\n ? 'border-brand bg-brand-tertiary'\n : 'border-default bg-default-secondary hover:border-brand hover:bg-brand-tertiary',\n ),\n className,\n )}\n >\n <span\n aria-hidden\n className={disabled ? 'text-disabled' : isDragging ? 'text-brand' : 'text-default-secondary'}\n >\n <LuUpload className=\"size-5\" />\n </span>\n <span className={clsx('text-body-sm font-medium', disabled ? 'text-disabled' : 'text-default')}>Upload file</span>\n <span className=\"text-body-xs text-default-secondary text-center\">\n {description}\n </span>\n </div>\n {error && (\n <span role=\"alert\" className=\"text-body-xs text-danger\">\n {error}\n </span>\n )}\n </>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { LuArrowLeft, LuArrowRight } from 'react-icons/lu';\nimport { Button } from './button';\n\n// ── FormCard ───────────────────────────────────────────────────────────────────\n\nexport function FormCard({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={clsx(\n 'overflow-hidden rounded-xl border border-default bg-default',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// ── FormCardHeader ─────────────────────────────────────────────────────────────\n\nexport interface FormCardHeaderProps {\n title: string;\n subtitle?: string;\n}\n\nexport function FormCardHeader({ title, subtitle }: FormCardHeaderProps) {\n return (\n <div className=\"border-b border-default px-7 py-6\">\n <h2 className=\"text-heading-sm font-semibold text-default leading-snug\">{title}</h2>\n {subtitle && (\n <p className=\"mt-1 text-body-xs text-default-secondary\">{subtitle}</p>\n )}\n </div>\n );\n}\n\n// ── FormCardFooter ─────────────────────────────────────────────────────────────\n\nexport interface FormCardFooterProps {\n onSaveDraft?: () => void;\n onBack?: () => void;\n onContinue?: () => void;\n continueLabel?: string;\n backDisabled?: boolean;\n continueDisabled?: boolean;\n}\n\nexport function FormCardFooter({\n onSaveDraft,\n onBack,\n onContinue,\n continueLabel = 'Continue',\n backDisabled = false,\n continueDisabled = false,\n}: FormCardFooterProps) {\n return (\n <div className=\"flex items-center justify-between border-t border-default px-7 py-5\">\n {/* No handler means the host has nothing to save to — disable rather than no-op */}\n <Button variant=\"neutral\" size=\"md\" onClick={onSaveDraft} disabled={!onSaveDraft}>\n Save as draft\n </Button>\n <div className=\"flex items-center gap-2\">\n {!backDisabled && (\n <Button\n variant=\"neutral\"\n size=\"md\"\n leadingIcon={<LuArrowLeft aria-hidden size={16} />}\n onClick={onBack}\n >\n Back\n </Button>\n )}\n <Button\n variant=\"primary\"\n size=\"md\"\n trailingIcon={<LuArrowRight aria-hidden size={16} />}\n onClick={onContinue}\n disabled={continueDisabled}\n >\n {continueLabel}\n </Button>\n </div>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { LuX } from 'react-icons/lu';\n\nexport type BadgeColor = 'gray' | 'red' | 'yellow' | 'lime' | 'green' | 'teal' | 'blue' | 'pink' | 'slate';\nexport type BadgeSize = 'sm' | 'lg';\nexport type BadgeVariant = 'default' | 'subtle';\n\nexport interface BadgeProps {\n label: string;\n color?: BadgeColor;\n size?: BadgeSize;\n variant?: BadgeVariant;\n indicator?: boolean;\n onClose?: () => void;\n className?: string;\n}\n\nconst defaultClasses: Record<BadgeColor, string> = {\n gray: 'bg-badge-gray text-badge-gray',\n red: 'bg-badge-red text-badge-red',\n yellow: 'bg-badge-yellow text-badge-yellow',\n lime: 'bg-badge-lime text-badge-lime',\n green: 'bg-badge-green text-badge-green',\n teal: 'bg-badge-teal text-badge-teal',\n blue: 'bg-badge-blue text-badge-blue',\n pink: 'bg-badge-pink text-badge-pink',\n slate: 'bg-badge-slate text-badge-slate',\n};\n\nconst subtleClasses: Record<BadgeColor, string> = {\n gray: 'border border-badge-gray text-default-secondary',\n red: 'border border-badge-red text-default-secondary',\n yellow: 'border border-badge-yellow text-default-secondary',\n lime: 'border border-badge-lime text-default-secondary',\n green: 'border border-badge-green text-default-secondary',\n teal: 'border border-badge-teal text-default-secondary',\n blue: 'border border-badge-blue text-default-secondary',\n pink: 'border border-badge-pink text-default-secondary',\n slate: 'border border-badge-slate text-default-secondary',\n};\n\nexport function Badge({\n label,\n color = 'gray',\n size = 'sm',\n variant = 'default',\n indicator = false,\n onClose,\n className,\n}: BadgeProps) {\n const isDefault = variant === 'default';\n\n return (\n <span\n className={clsx(\n 'inline-flex items-center rounded-full px-2 py-0.5',\n size === 'sm' ? 'gap-1' : 'gap-1.5',\n isDefault ? defaultClasses[color] : subtleClasses[color],\n className,\n )}\n >\n {indicator && (\n <span\n className={clsx(\n 'shrink-0 rounded-full bg-current',\n size === 'sm' ? 'h-1.5 w-1.5' : 'h-2 w-2',\n )}\n />\n )}\n <span\n className={clsx(\n 'whitespace-nowrap',\n size === 'sm'\n ? clsx('text-body-tiny', isDefault && 'font-semibold')\n : 'text-body-xs',\n )}\n >\n {label}\n </span>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className={clsx(\n 'inline-flex shrink-0 items-center justify-center rounded-full opacity-60 transition-opacity hover:opacity-100',\n size === 'sm' ? 'h-3 w-3' : 'h-4 w-4',\n )}\n // Was a hardcoded \"Remove\", so a row of five dismissible badges produced five\n // identically named buttons with nothing to tell them apart.\n aria-label={`Remove ${label}`}\n >\n <LuX className=\"h-full w-full\" strokeWidth={2.5} aria-hidden />\n </button>\n )}\n </span>\n );\n}\n","import clsx from 'clsx';\n\n/**\n * The nine-hue categorical palette from `badge.css`, which is what roles want: a role is a\n * *category*, not a severity, so it must not borrow the semantic tones — a `danger`-coloured\n * role badge would imply the role itself is a problem.\n */\nexport type RoleBadgeTone =\n | 'slate'\n | 'blue'\n | 'green'\n | 'yellow'\n | 'red'\n | 'pink'\n | 'teal'\n | 'lime'\n | 'gray';\n\nexport interface RoleBadgeProps {\n role: string;\n size?: 'sm' | 'md';\n /**\n * Override the name-map lookup. Use this for roles the map does not know, in preference to\n * `color` — it stays on the token layer and re-themes with the rest of the badge palette.\n */\n tone?: RoleBadgeTone;\n /**\n * @deprecated Bypasses the design tokens — pass `tone` instead. Raw 6-digit hex; text uses\n * the hex and the background a 12% tint of it. Kept for role colours that genuinely come\n * from API data rather than from the design system.\n */\n color?: string | null;\n}\n\n/**\n * Role → palette hue.\n *\n * Through 0.4.0 this was ten hardcoded hex pairs, thirteen of whose twenty values sat off\n * the palette entirely. `Compliance Lead` was the worst: `#5b3da8`, a violet with no ramp in\n * `Color Primitives` at all — a gap `status.css` had already documented for `accent`.\n *\n * Hues were chosen by comparing the original hex against the resolved palette, not by eye.\n * Several land almost exactly:\n *\n * Auditor / Viewer #f5f5f5 / #757575 → gray #f5f5f5 / #757575 (exact)\n * admin family #e9eff7 / #0c2d58 → slate #f1f1f5 / #0c2d58 (text exact)\n * Entity Manager #fbe6cf / #9a6206 → yellow #feedcf / #996100\n * Intelligence Analyst #fde2e7 / #a3284a → red #fce9eb / #bb223a\n * Reviewer #dbeafe / #1d4ed8 → blue\n * Requester #e6f4ea / #1f7a3d → green\n *\n * `Compliance Lead` is the one reassignment rather than a match. Violet has no equivalent at\n * all, and of its two neighbours blue was already Reviewer's — so it takes pink, the nearest\n * remaining hue. `teal` and `lime` are deliberately left free for roles added later.\n */\nconst ROLE_TONES: Record<string, RoleBadgeTone> = {\n 'Super Admin': 'slate',\n 'Admin': 'slate',\n 'User': 'slate',\n 'Compliance Lead': 'pink',\n 'Reviewer': 'blue',\n 'Requester': 'green',\n 'Entity Manager': 'yellow',\n 'Intelligence Analyst': 'red',\n 'Auditor': 'gray',\n 'Viewer': 'gray',\n};\n\nconst FALLBACK_TONE: RoleBadgeTone = 'gray';\n\n/**\n * `bg-badge-*` resolves to `--badge-*-bg` and `text-badge-*` to `--badge-*-text`, so each\n * pair is the label/on-label duo the palette was designed around.\n */\nconst TONE_STYLES: Record<RoleBadgeTone, string> = {\n slate: 'bg-badge-slate text-badge-slate',\n blue: 'bg-badge-blue text-badge-blue',\n green: 'bg-badge-green text-badge-green',\n yellow: 'bg-badge-yellow text-badge-yellow',\n red: 'bg-badge-red text-badge-red',\n pink: 'bg-badge-pink text-badge-pink',\n teal: 'bg-badge-teal text-badge-teal',\n lime: 'bg-badge-lime text-badge-lime',\n gray: 'bg-badge-gray text-badge-gray',\n};\n\nconst HEX6 = /^#[0-9a-fA-F]{6}$/;\n\nexport function RoleBadge({ role, size = 'sm', tone, color }: RoleBadgeProps) {\n // The raw-hex path stays for data-driven colour, but it no longer wins by default: a\n // caller has to opt into leaving the token layer.\n const rawColor = color && HEX6.test(color) ? color : undefined;\n const resolved = tone ?? ROLE_TONES[role] ?? FALLBACK_TONE;\n\n return (\n <span\n className={clsx(\n 'inline-flex items-center rounded-full font-medium whitespace-nowrap',\n size === 'sm' ? 'px-2 py-0.5 text-body-tiny' : 'px-3 py-1 text-body-xs',\n !rawColor && TONE_STYLES[resolved],\n )}\n style={rawColor ? { backgroundColor: `${rawColor}1F`, color: rawColor } : undefined}\n >\n {role}\n </span>\n );\n}\n","import {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuCheck, LuChevronDown } from 'react-icons/lu';\n\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useFloatingPanel } from '../overlays/floating';\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_ACTIVE,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n OVERLAY_PANEL,\n OVERLAY_PANEL_SCROLL,\n} from '../overlays/menu-styles';\nimport { Portal } from '../overlays/portal';\nimport { useFieldControl } from './field';\nimport { useControlSize } from './control-size';\nimport type { InputSize } from './input';\n\nexport interface ComboboxOption<T = string> {\n value: T;\n label: string;\n description?: string;\n disabled?: boolean;\n /** Optional group heading. Options sharing a group are rendered together. */\n group?: string;\n}\n\nexport interface ComboboxProps<T extends string = string> {\n options: ComboboxOption<T>[];\n value?: T | null;\n defaultValue?: T | null;\n onValueChange?: (value: T | null) => void;\n /** Accessible name. Required unless the combobox is inside a `Field` with a label. */\n label?: string;\n placeholder?: string;\n size?: InputSize;\n disabled?: boolean;\n invalid?: boolean;\n /** Allow clearing back to `null` by selecting the chosen option again. Default `true`. */\n clearable?: boolean;\n /** Override the filter. Default is a case-insensitive substring match on `label`. */\n filter?: (option: ComboboxOption<T>, query: string) => boolean;\n /** Shown when nothing matches. */\n emptyMessage?: ReactNode;\n /** Custom option rendering. Receives the option and whether it is selected. */\n renderOption?: (option: ComboboxOption<T>, selected: boolean) => ReactNode;\n className?: string;\n}\n\nconst HEIGHT: Record<InputSize, string> = {\n lg: 'h-12 px-4 text-body',\n md: 'h-9 px-3 text-body-sm',\n sm: 'h-6 px-2 text-body-tiny',\n};\n\n/**\n * Single-select combobox with a text filter — an autocomplete.\n *\n * Implements the ARIA 1.2 combobox pattern, which is specific about a few things that are\n * easy to get wrong and were all wrong in the `RoleComboBox` this replaces:\n *\n * - **`role=\"combobox\"` belongs on the text input**, not on a wrapping `<div>`. The div\n * version means the state attributes sit on an element the user never focuses.\n * - **`aria-activedescendant`, not focus, tracks the highlighted option.** Focus stays in\n * the input the whole time — moving DOM focus into the list breaks typing. This is the\n * one place a roving tabindex is the *wrong* answer, which is why this does not use\n * `useRovingFocus`.\n * - **`aria-controls` points at the listbox**, which therefore needs a stable id.\n * - The listbox is portaled, so it is not clipped by a `Card` or a scrolling container.\n *\n * For a command palette — filter over *actions* rather than a value — use `Command`.\n */\nexport function Combobox<T extends string = string>({\n options,\n value: valueProp,\n defaultValue = null,\n onValueChange,\n label,\n placeholder = 'Select…',\n size: sizeProp,\n disabled = false,\n invalid = false,\n clearable = true,\n filter,\n emptyMessage = 'No matches',\n renderOption,\n className,\n}: ComboboxProps<T>) {\n const size = useControlSize(sizeProp);\n const [value, setValue] = useControllableState<T | null>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: T | null) => void) | undefined,\n });\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const field = useFieldControl();\n\n const matches = useMemo(() => {\n const predicate =\n filter ?? ((option: ComboboxOption<T>, q: string) =>\n option.label.toLowerCase().includes(q.toLowerCase()));\n return query ? options.filter((option) => predicate(option, query)) : options;\n }, [options, query, filter]);\n\n const selected = options.find((option) => option.value === value) ?? null;\n\n // What the input displays: the query while filtering, the selection otherwise.\n const displayValue = open ? query : (selected?.label ?? '');\n\n const close = useCallback((restoreFocus = true) => {\n setOpen(false);\n setQuery('');\n if (restoreFocus) inputRef.current?.focus();\n }, []);\n\n const commit = (option: ComboboxOption<T>) => {\n if (option.disabled) return;\n setValue(clearable && option.value === value ? null : option.value);\n close();\n };\n\n const move = (delta: number) => {\n if (matches.length === 0) return;\n setActiveIndex((current) => {\n let next = current;\n for (let i = 0; i < matches.length; i++) {\n next = (next + delta + matches.length) % matches.length;\n if (!matches[next]?.disabled) break;\n }\n return next;\n });\n };\n\n const { refs, floatingStyles } = useFloatingPanel({\n open,\n onOpenChange: setOpen,\n side: 'bottom',\n align: 'start',\n sideOffset: 4,\n matchAnchorWidth: true,\n });\n\n useEffect(() => {\n refs.setReference(rootRef.current);\n }, [refs, open]);\n\n // Reset the highlight whenever the result set changes, so it never points past the end.\n useEffect(() => {\n setActiveIndex(0);\n }, [query, options]);\n\n // Keep the highlighted option in view. `aria-activedescendant` moves the virtual cursor but\n // does not scroll, which DOM focus would have done for free.\n useEffect(() => {\n if (!open) return;\n const node = listRef.current?.querySelector(`#${CSS.escape(optionId(activeIndex))}`);\n // Feature-detected: `scrollIntoView` is absent in jsdom and in some embedded webviews,\n // and an unguarded call there throws during render of an otherwise working combobox.\n if (node instanceof Element && typeof node.scrollIntoView === 'function') {\n node.scrollIntoView({ block: 'nearest' });\n }\n });\n\n useEffect(() => {\n if (!open) return;\n function onPointerDown(event: PointerEvent) {\n const withinRoot = rootRef.current?.contains(event.target as Node);\n const withinList = listRef.current?.contains(event.target as Node);\n if (!withinRoot && !withinList) close(false);\n }\n document.addEventListener('pointerdown', onPointerDown);\n return () => document.removeEventListener('pointerdown', onPointerDown);\n }, [open, close]);\n\n let renderedGroup: string | undefined;\n\n return (\n <div ref={rootRef} className={clsx('relative w-full', className)}>\n <div\n className={clsx(\n 'flex w-full items-center gap-2 rounded-lg border transition-colors',\n HEIGHT[size],\n 'focus-within:ring-2 focus-within:ring-offset-1 focus-within:ring-offset-default',\n disabled\n ? 'cursor-not-allowed border-disabled bg-disabled'\n : invalid || field['aria-invalid']\n ? 'border-danger-secondary focus-within:border-danger focus-within:ring-danger'\n : 'border-default bg-default focus-within:border-brand focus-within:ring-brand',\n )}\n >\n <input\n ref={inputRef}\n // ARIA 1.2: the role goes on the input the user actually focuses.\n role=\"combobox\"\n type=\"text\"\n autoComplete=\"off\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={open && matches.length > 0 ? optionId(activeIndex) : undefined}\n aria-label={label}\n {...field}\n disabled={disabled}\n value={displayValue}\n placeholder={selected ? selected.label : placeholder}\n onChange={(event) => {\n setQuery(event.target.value);\n if (!open) setOpen(true);\n }}\n onFocus={() => !disabled && setOpen(true)}\n onKeyDown={(event) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (!open) setOpen(true);\n else move(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (!open) setOpen(true);\n else move(-1);\n break;\n case 'Home':\n if (open) {\n event.preventDefault();\n setActiveIndex(0);\n }\n break;\n case 'End':\n if (open) {\n event.preventDefault();\n setActiveIndex(matches.length - 1);\n }\n break;\n case 'Enter':\n if (open && matches[activeIndex]) {\n event.preventDefault();\n commit(matches[activeIndex]);\n }\n break;\n case 'Escape':\n event.preventDefault();\n close();\n break;\n case 'Tab':\n // Tab commits nothing and closes — the value only changes on Enter or click,\n // so tabbing away cannot silently pick whatever happened to be highlighted.\n if (open) close(false);\n break;\n default:\n break;\n }\n }}\n className={clsx(\n 'min-w-0 flex-1 bg-transparent text-default outline-none',\n 'placeholder:text-default-tertiary',\n 'disabled:cursor-not-allowed disabled:text-disabled',\n )}\n />\n <LuChevronDown\n aria-hidden\n className={clsx(\n 'shrink-0 transition-transform',\n size === 'sm' ? 'size-3' : 'size-4',\n disabled ? 'text-icon-disabled' : 'text-icon-default-secondary',\n open && 'rotate-180',\n )}\n />\n </div>\n\n {open && (\n <Portal>\n <div\n ref={(node) => {\n listRef.current = node;\n refs.setFloating(node);\n }}\n id={listboxId}\n role=\"listbox\"\n aria-label={label}\n style={{ ...floatingStyles, width: 'var(--panel-anchor-width)' }}\n className={clsx('z-popover', OVERLAY_PANEL, OVERLAY_PANEL_SCROLL)}\n >\n {matches.length === 0 && (\n <p className=\"px-2.5 py-2 text-body-xs text-default-secondary\">{emptyMessage}</p>\n )}\n {matches.map((option, index) => {\n const isSelected = option.value === value;\n const isActive = index === activeIndex;\n const groupHeading = option.group !== renderedGroup ? option.group : undefined;\n renderedGroup = option.group;\n\n return (\n <div key={String(option.value)}>\n {groupHeading && (\n <div\n role=\"presentation\"\n className={OVERLAY_HEADING}\n >\n {groupHeading}\n </div>\n )}\n {/* Options are deliberately not focusable and carry no key handler. In the\n ARIA 1.2 combobox pattern focus never leaves the input — moving it into\n the list would stop the user typing — and `aria-activedescendant`\n carries the highlight instead, with the input owning every key.\n jsx-a11y cannot model that, so it sees an unreachable option; it is\n reachable, just not by DOM focus. */}\n {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus, jsx-a11y/click-events-have-key-events */}\n <div\n id={optionId(index)}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={option.disabled || undefined}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => commit(option)}\n onPointerEnter={() => !option.disabled && setActiveIndex(index)}\n className={clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE.md,\n 'items-center',\n option.disabled\n ? 'cursor-not-allowed text-disabled'\n : isActive\n ? clsx(OVERLAY_ITEM_ACTIVE, 'text-default')\n : 'text-default',\n )}\n >\n {renderOption ? (\n renderOption(option, isSelected)\n ) : (\n <>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{option.label}</span>\n {option.description && (\n <span className=\"block truncate text-body-tiny text-default-secondary\">\n {option.description}\n </span>\n )}\n </span>\n {isSelected && (\n <LuCheck aria-hidden className=\"size-3.5 shrink-0 text-brand\" strokeWidth={3} />\n )}\n </>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </Portal>\n )}\n </div>\n );\n}\n","import { RoleBadge } from '../status/role-badge';\nimport { Combobox, type ComboboxOption } from './combobox';\nimport type { InputSize } from './input';\n\nexport interface RoleOption {\n role: string;\n description: string;\n}\n\nexport const ROLE_COMBO_OPTIONS: RoleOption[] = [\n { role: 'Reviewer', description: 'Reviews onboarding requests' },\n { role: 'Admin', description: 'Full org control' },\n { role: 'Compliance Lead', description: 'Owns compliance' },\n { role: 'Requester', description: 'Creates onboarding requests' },\n { role: 'Viewer', description: 'Read-only access' },\n { role: 'User', description: 'Default user access' },\n];\n\nexport interface RoleComboBoxProps {\n value: string;\n onChange: (role: string) => void;\n options?: RoleOption[];\n /** Accessible name. Defaults to `Role`. */\n label?: string;\n size?: InputSize;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Role picker.\n *\n * Rebuilt in 0.4.0 as a thin wrapper over `Combobox`, which is all it should ever have been.\n * The version it replaces was the least correct component in the library and is worth\n * recording, because every one of these was a category of bug rather than a detail:\n *\n * - `role=\"combobox\"` sat on a `<div>` while the real `<input>` had no role and none of the\n * state attributes. Under ARIA 1.2 the role belongs on the input.\n * - The `role=\"listbox\"` had no `id`, so `aria-controls` could not point at it, and there\n * was no `aria-activedescendant` at all.\n * - No arrow keys, no Home/End, no wrap. The **selected** option had no `tabIndex`, so it\n * was mouse-only, while every *other* option was individually tabbable.\n * - Escape worked on the trigger but not on the search input or the options, and closing\n * never returned focus to the trigger.\n * - The tick was a literal `✓` text node, announced as \"check mark\" mid-option.\n * - It bypassed the token system entirely — `border-blue-500`, `bg-white`, `bg-blue-50`,\n * `text-blue-600`, `text-sm` — and built its className with a template literal. Both are\n * explicitly against the rules in CLAUDE.md, and the raw colours meant it would not theme.\n *\n * It stays a preset rather than becoming `Combobox` usage at every call site only because it\n * renders a `RoleBadge` per option, which `renderOption` exists for.\n */\nexport function RoleComboBox({\n value,\n onChange,\n options = ROLE_COMBO_OPTIONS,\n label = 'Role',\n size = 'md',\n disabled = false,\n className,\n}: RoleComboBoxProps) {\n const comboboxOptions: ComboboxOption[] = options.map((option) => ({\n value: option.role,\n label: option.role,\n description: option.description,\n }));\n\n return (\n <Combobox\n options={comboboxOptions}\n value={value}\n onValueChange={(next) => next && onChange(next)}\n label={label}\n size={size}\n disabled={disabled}\n // A role is always set — there is no \"no role\" state — so re-selecting must not clear.\n clearable={false}\n emptyMessage=\"No roles match\"\n className={className}\n renderOption={(option) => (\n <>\n <RoleBadge role={option.value} size=\"sm\" />\n <span className=\"min-w-0 flex-1 truncate text-body-xs text-default-secondary\">\n {option.description}\n </span>\n </>\n )}\n />\n );\n}\n","import { useMemo } from 'react';\n\nimport { Combobox, type ComboboxOption, type ComboboxProps } from './combobox';\n\n/**\n * ISO 3166-1 alpha-2 codes for every officially assigned country and territory.\n *\n * `Intl` can name a region but cannot list them — there is no `supportedValuesOf('region')` —\n * so the codes are the one thing this component has to carry itself. Labels still come from\n * `Intl.DisplayNames`, which means they follow the locale instead of being frozen in English.\n */\nconst ISO_3166_ALPHA_2 =\n 'AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR ' +\n 'BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ ' +\n 'EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW ' +\n 'GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY ' +\n 'KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV ' +\n 'MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY ' +\n 'QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG ' +\n 'TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW';\n\nexport const COUNTRY_CODES: readonly string[] = ISO_3166_ALPHA_2.split(' ');\n\nexport interface CountrySelectProps\n extends Omit<ComboboxProps<string>, 'options' | 'filter' | 'renderOption'> {\n /** Restrict the list to these ISO 3166-1 alpha-2 codes. Default: every code. */\n countries?: readonly string[];\n /** Locale for the country names. Default: the browser's. */\n locale?: string;\n}\n\n/** Country names for `codes` in `locale`, sorted by name. Falls back to the code itself. */\nexport function countryOptions(\n codes: readonly string[] = COUNTRY_CODES,\n locale?: string,\n): ComboboxOption<string>[] {\n let names: Intl.DisplayNames | null = null;\n try {\n names = new Intl.DisplayNames(locale ? [locale] : undefined, { type: 'region' });\n } catch {\n // An unknown locale throws. Codes are still a usable list.\n }\n return codes\n .map((code) => ({ value: code, label: names?.of(code) ?? code, description: code }))\n .sort((a, b) => a.label.localeCompare(b.label, locale));\n}\n\n/**\n * Searchable country picker. The value is an ISO 3166-1 alpha-2 code (`\"LK\"`), never the\n * display name, so it survives a locale change and can be stored as-is.\n *\n * A thin layer over `Combobox` — same keyboard contract, same panel — that adds the list and\n * lets the query match the code as well as the name, so typing `GB` finds United Kingdom.\n * A value outside `countries` is still listed, so a saved country never renders as an empty\n * field.\n */\nexport function CountrySelect({\n countries,\n locale,\n placeholder = 'Select a country…',\n emptyMessage = 'No countries match',\n ...props\n}: CountrySelectProps) {\n const keep = [props.value, props.defaultValue].filter((v): v is string => !!v);\n const keepKey = keep.join('|');\n const options = useMemo(() => {\n const list = countryOptions(countries, locale);\n const missing = keep.filter((v) => !list.some((o) => o.value === v));\n return [...countryOptions(missing, locale), ...list];\n // `keep` is rebuilt every render; `keepKey` is its stable identity.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [countries, locale, keepKey]);\n\n return (\n <Combobox\n {...props}\n options={options}\n placeholder={placeholder}\n emptyMessage={emptyMessage}\n filter={(option, query) => {\n const q = query.trim().toLowerCase();\n return option.label.toLowerCase().includes(q) || option.value.toLowerCase() === q;\n }}\n />\n );\n}\n","import { useMemo } from 'react';\n\nimport { Combobox, type ComboboxOption, type ComboboxProps } from './combobox';\n\nexport interface TimeZoneSelectProps\n extends Omit<ComboboxProps<string>, 'options' | 'filter' | 'renderOption'> {\n /** Restrict the list to these IANA zone names. Default: every zone the runtime supports. */\n timeZones?: readonly string[];\n /**\n * The instant offsets are computed for. Default: now. Offsets move with daylight saving,\n * so a fixed date is mainly useful for tests and screenshots.\n */\n at?: Date;\n}\n\n/**\n * Renamed zones, old name → current IANA name. Chromium's ICU still lists the old names\n * (`Asia/Calcutta`, not `Asia/Kolkata`), so without this a search for Kolkata finds nothing\n * and a stored `Asia/Kolkata` matches no option.\n */\nconst RENAMED: Record<string, string> = {\n 'America/Godthab': 'America/Nuuk',\n 'Asia/Calcutta': 'Asia/Kolkata',\n 'Asia/Katmandu': 'Asia/Kathmandu',\n 'Asia/Rangoon': 'Asia/Yangon',\n 'Asia/Saigon': 'Asia/Ho_Chi_Minh',\n 'Atlantic/Faeroe': 'Atlantic/Faroe',\n 'Europe/Kiev': 'Europe/Kyiv',\n 'Pacific/Enderbury': 'Pacific/Kanton',\n 'Pacific/Ponape': 'Pacific/Pohnpei',\n 'Pacific/Truk': 'Pacific/Chuuk',\n};\n\n/** The current IANA name for a zone: `Asia/Kolkata` for `Asia/Calcutta`. */\nexport const currentZoneName = (zone: string): string => RENAMED[zone] ?? zone;\n\n/** `Intl.supportedValuesOf` is ES2022 and missing from older runtimes — read it defensively. */\nfunction supportedTimeZones(): string[] {\n const intl = Intl as typeof Intl & { supportedValuesOf?: (key: 'timeZone') => string[] };\n try {\n const zones = intl.supportedValuesOf?.('timeZone');\n if (zones && zones.length > 0) return zones;\n } catch {\n // Fall through.\n }\n return ['UTC'];\n}\n\n/** `\"+05:30\"` for Asia/Colombo. Minutes east of UTC are returned alongside for sorting. */\nexport function timeZoneOffset(timeZone: string, at: Date = new Date()): { label: string; minutes: number } {\n try {\n const part = new Intl.DateTimeFormat('en-US', { timeZone, timeZoneName: 'longOffset' })\n .formatToParts(at)\n .find((p) => p.type === 'timeZoneName')?.value;\n // \"GMT+05:30\", \"GMT-03:00\", or bare \"GMT\" for UTC itself.\n const match = part?.match(/GMT([+-])(\\d{2}):(\\d{2})/);\n if (!match) return { label: '+00:00', minutes: 0 };\n const [, sign, hh, mm] = match;\n const minutes = (Number(hh) * 60 + Number(mm)) * (sign === '-' ? -1 : 1);\n return { label: `${sign}${hh}:${mm}`, minutes };\n } catch {\n return { label: '+00:00', minutes: 0 };\n }\n}\n\n/**\n * One option per zone, labelled `(UTC+05:30) Asia/Colombo`, west to east then by name.\n * Renamed zones are listed under their current name, once.\n */\nexport function timeZoneOptions(\n zones: readonly string[] = supportedTimeZones(),\n at: Date = new Date(),\n): ComboboxOption<string>[] {\n return Array.from(new Set(zones.map(currentZoneName)))\n .map((zone) => ({ zone, minutes: timeZoneOffset(zone, at).minutes }))\n .sort((a, b) => a.minutes - b.minutes || a.zone.localeCompare(b.zone))\n .map(({ zone }) => zoneOption(zone, at));\n}\n\nconst zoneOption = (zone: string, at: Date): ComboboxOption<string> => ({\n value: zone,\n label: `(UTC${timeZoneOffset(zone, at).label}) ${zone.replace(/_/g, ' ')}`,\n});\n\n/**\n * Searchable IANA time-zone picker. The value is the zone name (`\"Asia/Colombo\"`), never an\n * offset: an offset changes with daylight saving and cannot be turned back into a zone.\n *\n * Labels show the current UTC offset, and the query matches the zone name with or without\n * underscores and the offset itself, so `colombo`, `new york` and `+05:30` all find a zone.\n * A value missing from the list — stored under another name, or outside `timeZones` — is\n * still listed, so a saved zone never renders as an empty field.\n */\nexport function TimeZoneSelect({\n timeZones,\n at,\n placeholder = 'Select a time zone…',\n emptyMessage = 'No time zones match',\n ...props\n}: TimeZoneSelectProps) {\n // `at` is a Date, so depend on its timestamp rather than its identity.\n const atTime = at?.getTime();\n const keep = [props.value, props.defaultValue].filter((v): v is string => !!v);\n const keepKey = keep.join('|');\n const options = useMemo(() => {\n const when = atTime === undefined ? new Date() : new Date(atTime);\n const list = timeZoneOptions(timeZones, when);\n const missing = keep.filter((v) => !list.some((o) => o.value === v));\n return [...missing.map((v) => zoneOption(v, when)), ...list];\n // `keep` is rebuilt every render; `keepKey` is its stable identity.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeZones, atTime, keepKey]);\n\n return (\n <Combobox\n {...props}\n options={options}\n placeholder={placeholder}\n emptyMessage={emptyMessage}\n filter={(option, query) => {\n const q = query.trim().toLowerCase();\n return option.label.toLowerCase().includes(q) || option.value.toLowerCase().includes(q);\n }}\n />\n );\n}\n","import { useEffect, useId, useMemo, useRef, useState, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { LuSearch } from 'react-icons/lu';\n\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_ACTIVE,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n} from '../overlays/menu-styles';\n\nexport interface CommandItem {\n id: string;\n label: string;\n description?: string;\n /** Group heading. Items sharing a group render together, in the order given. */\n group?: string;\n icon?: ReactNode;\n /** Trailing hint — pass `<Kbd>` elements. */\n shortcut?: ReactNode;\n /** Extra words to match on that are not in the label — synonyms, the old name of a page. */\n keywords?: string[];\n disabled?: boolean;\n onSelect: () => void;\n}\n\nexport interface CommandProps {\n items: CommandItem[];\n /** Accessible name. Default `Command palette`. */\n label?: string;\n placeholder?: string;\n emptyMessage?: ReactNode;\n /** Called after any item is chosen — usually closes the containing dialog. */\n onAfterSelect?: () => void;\n autoFocus?: boolean;\n className?: string;\n}\n\n/**\n * A ⌘K command palette — filter over *actions* and run one.\n *\n * The same ARIA combobox pattern as `Combobox`, and for the same reasons: `role=\"combobox\"`\n * on the input, focus never leaving it, and `aria-activedescendant` carrying the highlight.\n * What differs is the intent, and it changes two behaviours:\n *\n * - Items are **commands, not values**. There is no selected state to display, no way to\n * clear, and choosing one runs a callback rather than setting anything.\n * - Matching includes `keywords`, so \"logout\" can find \"Sign out\" — a palette is useless if\n * you have to already know the wording.\n *\n * This is the palette body only. Put it in a `Modal` for the usual ⌘K overlay; keeping the\n * two separate means the palette can also be embedded in a page or a `Popover`, and the\n * dialog semantics stay with the component that owns them.\n *\n * A live region reports the result count, because otherwise a screen reader user typing into\n * the filter gets no feedback that the list changed underneath them.\n */\nexport function Command({\n items,\n label = 'Command palette',\n placeholder = 'Type a command or search…',\n emptyMessage = 'No results',\n onAfterSelect,\n autoFocus = true,\n className,\n}: CommandProps) {\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const listRef = useRef<HTMLDivElement>(null);\n\n const matches = useMemo(() => {\n if (!query) return items;\n const q = query.toLowerCase();\n return items.filter((item) => {\n if (item.label.toLowerCase().includes(q)) return true;\n if (item.group?.toLowerCase().includes(q)) return true;\n return item.keywords?.some((keyword) => keyword.toLowerCase().includes(q)) ?? false;\n });\n }, [items, query]);\n\n useEffect(() => {\n setActiveIndex(0);\n }, [query]);\n\n useEffect(() => {\n const node = listRef.current?.querySelector(`#${CSS.escape(optionId(activeIndex))}`);\n // Feature-detected — see the same note in `Combobox`. Absent in jsdom and some webviews.\n if (node instanceof Element && typeof node.scrollIntoView === 'function') {\n node.scrollIntoView({ block: 'nearest' });\n }\n });\n\n const run = (item: CommandItem) => {\n if (item.disabled) return;\n item.onSelect();\n onAfterSelect?.();\n };\n\n const move = (delta: number) => {\n if (matches.length === 0) return;\n setActiveIndex((current) => {\n let next = current;\n for (let i = 0; i < matches.length; i++) {\n next = (next + delta + matches.length) % matches.length;\n if (!matches[next]?.disabled) break;\n }\n return next;\n });\n };\n\n let renderedGroup: string | undefined;\n\n return (\n <div className={clsx('flex w-full flex-col', className)}>\n <div className=\"flex items-center gap-2 border-b border-default px-3.5 py-3\">\n <LuSearch aria-hidden className=\"size-4 shrink-0 text-icon-default-secondary\" />\n <input\n role=\"combobox\"\n type=\"text\"\n autoComplete=\"off\"\n // A palette's list is always visible while it is open, so `aria-expanded` is\n // permanently true rather than tracking a collapsed state that never happens.\n aria-expanded\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={matches.length > 0 ? optionId(activeIndex) : undefined}\n aria-label={label}\n // Autofocus is correct here specifically: a command palette is opened by an\n // explicit gesture (⌘K) whose entire purpose is to start typing, so *not* focusing\n // the input would strand the user. The rule guards against autofocus on ordinary\n // page load, which this is not. Caller can still opt out.\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n value={query}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n move(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n move(-1);\n break;\n case 'Home':\n event.preventDefault();\n setActiveIndex(0);\n break;\n case 'End':\n event.preventDefault();\n setActiveIndex(matches.length - 1);\n break;\n case 'Enter':\n if (matches[activeIndex]) {\n event.preventDefault();\n run(matches[activeIndex]);\n }\n break;\n default:\n break;\n }\n }}\n className=\"min-w-0 flex-1 bg-transparent text-body-sm text-default outline-none placeholder:text-default-tertiary\"\n />\n </div>\n\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label={label}\n // Focus stays in the filter input and `aria-activedescendant` carries the\n // highlight, so this must not become a tab stop of its own.\n className={clsx('max-h-80 overflow-y-auto p-1.5', SCROLLBAR_CLASSES)}\n >\n {matches.length === 0 && (\n <p className=\"px-2.5 py-6 text-center text-body-sm text-default-secondary\">\n {emptyMessage}\n </p>\n )}\n {matches.map((item, index) => {\n const isActive = index === activeIndex;\n const groupHeading = item.group !== renderedGroup ? item.group : undefined;\n renderedGroup = item.group;\n\n return (\n <div key={item.id}>\n {groupHeading && (\n <div\n role=\"presentation\"\n className={OVERLAY_HEADING}\n >\n {groupHeading}\n </div>\n )}\n {/* Not focusable by design — see the note in `Combobox`. Focus stays in the\n filter input and `aria-activedescendant` carries the highlight. */}\n {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus, jsx-a11y/click-events-have-key-events */}\n <div\n id={optionId(index)}\n role=\"option\"\n aria-selected={isActive}\n aria-disabled={item.disabled || undefined}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => run(item)}\n onPointerEnter={() => !item.disabled && setActiveIndex(index)}\n className={clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE.md,\n 'items-center',\n item.disabled\n ? 'cursor-not-allowed text-disabled'\n : isActive\n ? clsx(OVERLAY_ITEM_ACTIVE, 'text-default')\n : 'text-default',\n )}\n >\n {item.icon && (\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n {item.icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{item.label}</span>\n {item.description && (\n <span className=\"block truncate text-body-tiny text-default-secondary\">\n {item.description}\n </span>\n )}\n </span>\n {item.shortcut && (\n <span className=\"ml-auto flex shrink-0 items-center gap-1\">{item.shortcut}</span>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Typing filters the list silently otherwise — a sighted user sees it shrink, a\n screen reader user gets nothing. */}\n <span aria-live=\"polite\" className=\"sr-only\">\n {`${matches.length} ${matches.length === 1 ? 'result' : 'results'}`}\n </span>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\n/**\n * The six status tones from the Figma design system.\n * Values live in `src/app/styles/tokens/status.css`; see that file for why they do\n * not derive from the SDS semantic colour families.\n */\nexport type StatusTone =\n | 'neutral'\n | 'info'\n | 'warning'\n | 'caution'\n | 'accent'\n | 'positive'\n | 'danger';\n\nexport type StatusBadgeSize = 'sm' | 'md';\n\nconst TONE_STYLES: Record<StatusTone, string> = {\n neutral: 'bg-status-neutral text-status-neutral',\n info: 'bg-status-info text-status-info',\n warning: 'bg-status-warning text-status-warning',\n caution: 'bg-status-caution text-status-caution',\n accent: 'bg-status-accent text-status-accent',\n positive: 'bg-status-positive text-status-positive',\n danger: 'bg-status-danger text-status-danger',\n};\n\nconst DOT_STYLES: Record<StatusTone, string> = {\n neutral: 'bg-status-dot-neutral',\n info: 'bg-status-dot-info',\n warning: 'bg-status-dot-warning',\n caution: 'bg-status-dot-caution',\n accent: 'bg-status-dot-accent',\n positive: 'bg-status-dot-positive',\n danger: 'bg-status-dot-danger',\n};\n\nconst SIZE_STYLES: Record<StatusBadgeSize, string> = {\n sm: 'px-2 py-0.5 text-body-tiny',\n md: 'px-3 py-1 text-body-xs',\n};\n\nexport interface StatusBadgeProps {\n label: string;\n tone?: StatusTone;\n size?: StatusBadgeSize;\n /** Leading dot. On by default — the Figma status pills all carry one. */\n dot?: boolean;\n /**\n * Leading glyph, replacing the dot — e.g. `<LuCheck className=\"size-3\" />`.\n * Use for states a colour alone under-states, like verified or rejected.\n */\n icon?: ReactNode;\n className?: string;\n}\n\n/**\n * The status pill.\n *\n * Replaces thirteen inline re-implementations of the same markup plus five\n * competing hardcoded hex palettes. Generalises `TableCellStatusPill`, which had\n * this exact markup but required callers to pass raw hex strings.\n *\n * Note this is NOT `StatusChip` — that one renders a label *and a count* and is a\n * different component.\n */\nexport function StatusBadge({\n label,\n tone = 'neutral',\n size = 'md',\n dot = true,\n icon,\n className,\n}: StatusBadgeProps) {\n return (\n <span\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded-full font-medium leading-tight whitespace-nowrap',\n SIZE_STYLES[size],\n TONE_STYLES[tone],\n className,\n )}\n >\n {icon ? (\n <span className=\"shrink-0\">{icon}</span>\n ) : (\n dot && <span className={clsx('size-1.5 shrink-0 rounded-full', DOT_STYLES[tone])} />\n )}\n {label}\n </span>\n );\n}\n","import clsx from 'clsx';\n\nexport type StatusDotTone = 'brand' | 'positive' | 'warning' | 'danger' | 'neutral' | 'default';\n\nexport interface StatusDotProps {\n tone?: StatusDotTone;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex color, overrides `tone` via inline style. Use when the exact source color doesn't match a design token. */\n color?: string;\n className?: string;\n}\n\nconst dotTones: Record<StatusDotTone, string> = {\n brand: 'bg-brand',\n positive:'bg-positive',\n warning: 'bg-warning',\n danger: 'bg-danger',\n neutral: 'bg-neutral',\n default: 'bg-default-tertiary',\n};\n\nexport function StatusDot({ tone = 'default', color, className }: StatusDotProps) {\n return (\n <span\n className={clsx('inline-block size-1.5 shrink-0 rounded-full', !color && dotTones[tone], className)}\n style={color ? { backgroundColor: color } : undefined}\n />\n );\n}\n","import clsx from 'clsx';\nimport { StatusDot } from './status-dot';\nimport type { StatusDotTone } from './status-dot';\n\nexport interface StatusChipProps {\n label: string;\n count: number | string;\n tone?: StatusDotTone;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex dot color, overrides `tone` via inline style. Use when the exact source color doesn't match a design token. */\n dotColor?: string;\n bg?: string;\n className?: string;\n}\n\nexport function StatusChip({ label, count, tone = 'default', dotColor, bg, className }: StatusChipProps) {\n return (\n <span\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded-full px-3 py-1',\n !bg && 'bg-default-secondary',\n className,\n )}\n style={bg ? { backgroundColor: bg } : undefined}\n >\n <StatusDot tone={tone} color={dotColor} />\n <span className=\"text-body-xs font-medium text-default\">{count}</span>\n <span className=\"text-body-xs text-default-secondary\">{label}</span>\n </span>\n );\n}\n","import clsx from 'clsx';\nimport { StatusDot } from './status-dot';\nimport type { StatusDotTone } from './status-dot';\n\nexport interface CountBadgeProps {\n count: number | string;\n label?: string;\n tone?: StatusDotTone;\n className?: string;\n}\n\nexport function CountBadge({ count, label, tone = 'positive', className }: CountBadgeProps) {\n return (\n <span\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded-full border border-default px-3 py-1 text-body-xs font-medium text-default',\n className,\n )}\n >\n <StatusDot tone={tone} />\n {count}\n {label && <span className=\"text-default-secondary\">{label}</span>}\n </span>\n );\n}\n","import clsx from 'clsx';\n\nexport type TagPillTone = 'default' | 'brand' | 'positive' | 'warning' | 'danger';\n\nexport interface TagPillProps {\n label: string;\n tone?: TagPillTone;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex bg/text pair, overrides `tone` via inline style. Use when the exact source colors don't match design tokens. */\n bg?: string;\n color?: string;\n className?: string;\n}\n\nconst toneStyles: Record<TagPillTone, string> = {\n default: 'bg-default-secondary text-default-secondary',\n brand: 'bg-brand-tertiary text-brand',\n positive:'bg-positive-tertiary text-positive',\n warning: 'bg-warning-tertiary text-warning',\n danger: 'bg-danger-tertiary text-danger',\n};\n\nexport function TagPill({ label, tone = 'default', bg, color, className }: TagPillProps) {\n return (\n <span\n className={clsx(\n 'inline-flex items-center rounded-full px-2 py-0.5 text-body-xs font-medium',\n !bg && !color && toneStyles[tone],\n className,\n )}\n style={{\n ...(bg ? { backgroundColor: bg } : undefined),\n ...(color ? { color } : undefined),\n }}\n >\n {label}\n </span>\n );\n}\n","import clsx from 'clsx';\n\nimport type { StatusTone } from './status-badge';\n\nconst DOT: Record<StatusTone, string> = {\n neutral: 'bg-status-dot-neutral',\n info: 'bg-status-dot-info',\n warning: 'bg-status-dot-warning',\n caution: 'bg-status-dot-caution',\n accent: 'bg-status-dot-accent',\n positive: 'bg-status-dot-positive',\n danger: 'bg-status-dot-danger',\n};\n\nexport interface TrailChipProps {\n label: string;\n value: string;\n tone?: StatusTone;\n /**\n * Data-driven dot colour, overriding `tone`. The investigations trail mirrors the\n * severity accent of whichever tree node is selected, and those accents come from\n * the row data rather than the status palette — this is the escape hatch Phase 10\n * classifies as \"genuinely data-driven colour\", not a token bypass.\n */\n dotColor?: string;\n className?: string;\n}\n\n/**\n * Dot + small uppercase label + value, used for the drill-down breadcrumb trail on\n * the investigations page.\n *\n * Promoted from `pages/investigations`, where the dot colour was passed as a raw hex.\n */\nexport function TrailChip({ label, value, tone = 'info', dotColor, className }: TrailChipProps) {\n return (\n <div\n className={clsx(\n 'flex items-center gap-2 rounded-full border border-default bg-default px-3 py-1.5',\n className,\n )}\n >\n <span\n className={clsx('size-1.5 shrink-0 rounded-full', !dotColor && DOT[tone])}\n style={dotColor ? { backgroundColor: dotColor } : undefined}\n />\n <span className=\"text-body-tiny font-semibold uppercase tracking-wide text-default-secondary\">\n {label}\n </span>\n <span className=\"text-body-xs font-medium text-default\">{value}</span>\n </div>\n );\n}\n","import { StatusBadge, type StatusTone } from './status-badge';\n\nexport type UserAccountStatus = 'active' | 'pending' | 'deactivated';\n\nconst STATUS_META: Record<UserAccountStatus, { label: string; tone: StatusTone }> = {\n active: { label: 'Active', tone: 'positive' },\n // `caution` (pale yellow), not `warning` (orange) — Pending is one step below a\n // warning on the severity ramp, and reads as waiting rather than at risk.\n pending: { label: 'Pending', tone: 'caution' },\n deactivated: { label: 'Deactivated', tone: 'danger' },\n};\n\nexport interface UserStatusPillProps {\n status: UserAccountStatus;\n}\n\n/** Account-status pill. A thin wrapper over `StatusBadge`. */\nexport function UserStatusPill({ status }: UserStatusPillProps) {\n const { label, tone } = STATUS_META[status];\n return <StatusBadge label={label} tone={tone} />;\n}\n","import clsx from 'clsx';\nimport { LuCheck, LuCircleAlert, LuLoaderCircle, LuMinus, LuX } from 'react-icons/lu';\n\n/**\n * States of a compliance check.\n *\n * Union of the two previously-divergent local unions:\n * - `features/entity-detail` had passed | in_progress | pending | action_required\n * - `features/reviewer-detail` had passed | in-progress | failed | pending | waived\n *\n * Note `in_progress` (underscore) is canonical — entity-detail's spelling, which is\n * the one backed by the API. reviewer-detail used `in-progress` (hyphen) in mock data.\n */\nexport type CheckIndicatorStatus =\n | 'passed'\n | 'in_progress'\n | 'action_required'\n | 'failed'\n | 'pending'\n | 'waived';\n\n/**\n * `action_required` and `failed` share the Figma colours and differ only in glyph\n * (`!` vs `✕`); `waived` shares `pending`'s colours and adds a dash.\n */\nconst STATUS_STYLES: Record<CheckIndicatorStatus, string> = {\n passed: 'bg-status-check-passed border-status-check-passed text-status-check-passed',\n in_progress: 'bg-status-check-progress border-status-check-progress text-status-check-progress',\n action_required: 'bg-status-check-failed border-status-check-failed text-status-check-failed',\n failed: 'bg-status-check-failed border-status-check-failed text-status-check-failed',\n pending: 'bg-status-check-pending border-status-check-pending text-status-check-pending',\n waived: 'bg-status-check-pending border-status-check-pending text-status-check-pending',\n};\n\n/**\n * Glyphs — every one now comes from `react-icons/lu`, so the set is stroke-consistent.\n *\n * The two that used to be typographic: `◐` became `LuLoaderCircle` (lucide has no\n * half-filled circle, but a partial ring reads as in-progress and is a real icon), and\n * `!` became `LuCircleAlert`. Both are a small visual change from 0.2.0.\n */\nfunction StatusGlyph({ status }: { status: CheckIndicatorStatus }) {\n switch (status) {\n case 'passed':\n return <LuCheck className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'failed':\n return <LuX className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'waived':\n return <LuMinus className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'in_progress':\n return <LuLoaderCircle className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'action_required':\n return <LuCircleAlert className=\"size-3.5\" strokeWidth={2.5} aria-hidden />;\n case 'pending':\n return null;\n }\n}\n\nexport interface CheckIndicatorProps {\n status: CheckIndicatorStatus;\n /** Accessible label. Without one the indicator is decorative, which is correct when an adjacent text label already names the state. */\n label?: string;\n className?: string;\n}\n\n/**\n * The 22px outlined circle used for compliance-check state in entity and reviewer\n * detail. Ring and glyph share one colour; see the check tokens in\n * `src/app/styles/tokens/status.css`.\n */\nexport function CheckIndicator({ status, label, className }: CheckIndicatorProps) {\n return (\n <div\n className={clsx(\n 'flex size-[22px] shrink-0 items-center justify-center rounded-full border-[1.5px]',\n STATUS_STYLES[status],\n className,\n )}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n >\n <StatusGlyph status={status} />\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type EntityIconBadgeSize = 'sm' | 'md';\nexport type EntityIconBadgeTone = 'default' | 'brand' | 'positive' | 'warning' | 'danger' | 'neutral';\nexport type EntityIconBadgeShape = 'square' | 'circle';\n\nexport interface EntityIconBadgeProps {\n size?: EntityIconBadgeSize;\n tone?: EntityIconBadgeTone;\n /**\n * `square` is the rounded-rect used on entity rows. `circle` is the tinted glyph\n * circle used in modal headers. A prop rather than a `className` override, so it\n * does not depend on Tailwind's stylesheet emit order.\n */\n shape?: EntityIconBadgeShape;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex background, overrides `tone` via inline style. Use when the exact source color doesn't match a design token. */\n bg?: string;\n iconColor?: string;\n children: ReactNode;\n className?: string;\n}\n\nconst sizeStyles: Record<EntityIconBadgeSize, string> = {\n sm: 'size-8',\n md: 'size-10',\n};\n\nconst shapeStyles: Record<EntityIconBadgeShape, Record<EntityIconBadgeSize, string>> = {\n square: { sm: 'rounded-lg', md: 'rounded-xl' },\n circle: { sm: 'rounded-full', md: 'rounded-full' },\n};\n\nconst toneStyles: Record<EntityIconBadgeTone, string> = {\n default: 'bg-default-secondary text-icon-default',\n brand: 'bg-brand-tertiary text-icon-brand',\n positive:'bg-positive-tertiary text-icon-positive',\n warning: 'bg-warning-tertiary text-icon-warning',\n danger: 'bg-danger-tertiary text-icon-danger',\n neutral: 'bg-neutral-tertiary text-icon-neutral',\n};\n\nexport function EntityIconBadge({ size = 'sm', tone = 'default', shape = 'square', bg, iconColor, children, className }: EntityIconBadgeProps) {\n return (\n <span\n className={clsx(\n 'inline-flex shrink-0 items-center justify-center',\n sizeStyles[size],\n shapeStyles[shape][size],\n !bg && !iconColor && toneStyles[tone],\n className,\n )}\n style={{\n ...(bg ? { backgroundColor: bg } : undefined),\n ...(iconColor ? { color: iconColor } : undefined),\n }}\n >\n {children}\n </span>\n );\n}\n","import { forwardRef, useEffect, useId, useRef, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { CheckControl, type CheckControlSize } from './check-control';\n\nexport type CheckboxSize = CheckControlSize;\n\nexport interface CheckboxProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'checked'> {\n /** Controlled. Omit and pass `defaultChecked` for uncontrolled. */\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n label?: ReactNode;\n /** Second line under the label. Matches Figma's `Supporting text` axis. */\n description?: ReactNode;\n /** Matches Figma's `Size` axis. Default `md`, which is 0.3.0's fixed 18px. */\n size?: CheckboxSize;\n indeterminate?: boolean;\n invalid?: boolean;\n className?: string;\n}\n\nconst LABEL_TEXT: Record<CheckboxSize, string> = {\n sm: 'text-body-tiny',\n md: 'text-body-xs',\n};\n\n/**\n * Checkbox built on a real `<input type=\"checkbox\">`.\n *\n * Widened in 0.4.0 to match Figma's `Checkbox` set, which has `Size: sm | md`,\n * `Text` and `Supporting text` axes — none of which existed in code, where the control was\n * a fixed 18px with an optional single-line label and no `id`, `name`, `value`, `required`\n * or ref. It also had no uncontrolled mode: `checked` and `onChange` were both required, so\n * the simplest possible use site needed a `useState` in the consumer.\n *\n * `onChange` became `onCheckedChange` and takes a boolean, matching the rest of 0.4.0.\n * The native `onChange` event shape is still reachable — the ref is forwarded to the real\n * input, so `react-hook-form`'s `register()` works.\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n {\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n label,\n description,\n size = 'md',\n indeterminate = false,\n invalid = false,\n disabled = false,\n id,\n className,\n ...props\n },\n ref,\n) {\n const [checked, setChecked] = useControllableState({\n value: checkedProp,\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n });\n\n const inputRef = useRef<HTMLInputElement>(null);\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n\n // `indeterminate` is a DOM property with no React attribute, so it has to be applied\n // imperatively.\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n return (\n <div className={clsx('flex flex-col', className)}>\n <label\n htmlFor={controlId}\n className={clsx(\n 'group inline-flex items-start gap-2.5',\n disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer',\n )}\n >\n <input\n ref={composeRefs<HTMLInputElement>(inputRef, ref)}\n id={controlId}\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={description ? descriptionId : undefined}\n onChange={(event) => setChecked(event.target.checked)}\n className=\"peer sr-only\"\n {...props}\n />\n <CheckControl\n type=\"checkbox\"\n checked={checked}\n indeterminate={indeterminate}\n disabled={disabled}\n invalid={invalid}\n size={size}\n />\n {label && <span className={clsx(LABEL_TEXT[size], 'text-default')}>{label}</span>}\n </label>\n {/* Outside the <label>, deliberately. Anything inside a label becomes part of the\n control's *accessible name*, so a nested description turns the name into\n \"Marketing We will not spam you\" — and `aria-describedby` then points at text that\n was already read as the name. Indented to line up under the label text. */}\n {description && (\n <span\n id={descriptionId}\n className={clsx(\n 'mt-0.5 pl-[26px]',\n LABEL_TEXT[size],\n disabled ? 'text-disabled' : 'text-default-secondary',\n )}\n >\n {description}\n </span>\n )}\n </div>\n );\n});\n","import clsx from 'clsx';\nimport { LuCheck, LuMinus } from 'react-icons/lu';\n\nexport type CheckControlSize = 'sm' | 'md';\n\n/**\n * The box/circle glyph shared by `Checkbox` and `RadioGroup`.\n *\n * Figma models both in a single `Checkbox` component set with a `Type: Checkbox | Radio`\n * axis and a `Size: sm | md` axis, because the geometry, border weight, states and\n * spacing are identical — only the corner radius and the checked mark differ. Splitting\n * them in code while Figma keeps them together is how the two drift, so this holds the\n * shared half.\n *\n * Always `aria-hidden`: the real `<input>` carries the state, and this is its picture.\n */\nexport const CHECK_SIZE: Record<CheckControlSize, { box: string; glyph: string; dot: string }> = {\n sm: { box: 'size-4', glyph: 'size-2.5', dot: 'size-1.5' },\n md: { box: 'size-[18px]', glyph: 'size-3', dot: 'size-2' },\n};\n\nexport interface CheckControlProps {\n type: 'checkbox' | 'radio';\n checked: boolean;\n indeterminate?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n size?: CheckControlSize;\n}\n\nexport function CheckControl({\n type,\n checked,\n indeterminate = false,\n disabled = false,\n invalid = false,\n size = 'md',\n}: CheckControlProps) {\n const s = CHECK_SIZE[size];\n const on = checked || indeterminate;\n\n return (\n <span\n aria-hidden\n className={clsx(\n 'mt-px flex shrink-0 items-center justify-center border-[1.5px] transition-colors',\n s.box,\n type === 'radio' ? 'rounded-full' : 'rounded-[4px]',\n // Ring is drawn from the peer input's focus state, so the visual box tracks real\n // focus rather than hover.\n 'peer-focus-visible:ring-2 peer-focus-visible:ring-brand peer-focus-visible:ring-offset-1 peer-focus-visible:ring-offset-default',\n disabled\n ? on\n ? 'border-disabled bg-disabled text-disabled-on-disabled'\n : 'border-disabled bg-disabled'\n : on\n ? 'border-brand-emphasis bg-brand text-brand-on-brand'\n : invalid\n ? 'border-danger bg-default'\n : 'border-default-secondary bg-default',\n )}\n >\n {type === 'checkbox' ? (\n indeterminate ? (\n <LuMinus className={s.glyph} strokeWidth={3} />\n ) : checked ? (\n <LuCheck className={s.glyph} strokeWidth={3} />\n ) : null\n ) : checked ? (\n <span className={clsx('rounded-full bg-current', s.dot)} />\n ) : null}\n </span>\n );\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { CheckControl, type CheckControlSize } from './check-control';\n\nexport type RadioGroupOrientation = 'vertical' | 'horizontal';\n\ninterface RadioGroupContextValue {\n name: string;\n value: string | undefined;\n setValue: (value: string) => void;\n size: CheckControlSize;\n disabled: boolean;\n invalid: boolean;\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextValue | null>(null);\n\nexport interface RadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n children: ReactNode;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Shared `name` for the underlying inputs. Generated when omitted. */\n name?: string;\n /** Names the group. Prefer wrapping in `FieldSet` + `FieldLegend` for a visible label. */\n label?: string;\n size?: CheckControlSize;\n orientation?: RadioGroupOrientation;\n disabled?: boolean;\n invalid?: boolean;\n required?: boolean;\n}\n\n/**\n * Radio group. Matches the `Type=Radio` half of Figma's `Checkbox` set, and shares its\n * geometry through `CheckControl`.\n *\n * Built on real `<input type=\"radio\">` elements sharing a `name`, which is what buys the\n * whole keyboard contract for free: arrow keys move *and* select, only the checked radio is\n * in the tab sequence, and the group is announced as \"2 of 4\". A `div`-based\n * `role=\"radiogroup\"` has to reimplement all of that, and the version of this pattern the\n * library already had — `SegmentedControl` before 0.4.0 — shipped with none of it.\n *\n * `role=\"radiogroup\"` is still set explicitly rather than relying on a `<fieldset>`, so the\n * group works with or without a visible legend.\n */\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(function RadioGroup(\n {\n children,\n value: valueProp,\n defaultValue,\n onValueChange,\n name,\n label,\n size = 'md',\n orientation = 'vertical',\n disabled = false,\n invalid = false,\n required = false,\n className,\n ...rest\n },\n ref,\n) {\n const generatedName = useId();\n const [value, setValue] = useControllableState<string | undefined>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: string | undefined) => void) | undefined,\n });\n\n return (\n <RadioGroupContext.Provider\n value={{\n name: name ?? generatedName,\n value,\n setValue: (next) => setValue(next),\n size,\n disabled,\n invalid,\n }}\n >\n <div\n ref={ref}\n role=\"radiogroup\"\n aria-label={label}\n aria-required={required || undefined}\n aria-invalid={invalid || undefined}\n aria-orientation={orientation}\n data-slot=\"radio-group\"\n className={clsx(\n 'flex',\n orientation === 'vertical' ? 'flex-col gap-2.5' : 'flex-row flex-wrap gap-4',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </RadioGroupContext.Provider>\n );\n});\n\nexport interface RadioProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'checked'> {\n value: string;\n label?: ReactNode;\n /** Second line under the label. Matches Figma's `Supporting text` axis. */\n description?: ReactNode;\n className?: string;\n}\n\nconst LABEL_TEXT: Record<CheckControlSize, string> = {\n sm: 'text-body-tiny',\n md: 'text-body-xs',\n};\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n { value, label, description, disabled, id, className, ...props },\n ref,\n) {\n const group = useContext(RadioGroupContext);\n if (!group) throw new Error('<Radio> must be used inside <RadioGroup>');\n\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n const isDisabled = disabled ?? group.disabled;\n const checked = group.value === value;\n\n return (\n <div className={clsx('flex flex-col', className)}>\n <label\n htmlFor={controlId}\n className={clsx(\n 'group inline-flex items-start gap-2.5',\n isDisabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer',\n )}\n >\n <input\n ref={ref}\n id={controlId}\n type=\"radio\"\n name={group.name}\n value={value}\n checked={checked}\n disabled={isDisabled}\n aria-describedby={description ? descriptionId : undefined}\n onChange={() => group.setValue(value)}\n className=\"peer sr-only\"\n {...props}\n />\n <CheckControl\n type=\"radio\"\n checked={checked}\n disabled={isDisabled}\n invalid={group.invalid}\n size={group.size}\n />\n {label && <span className={clsx(LABEL_TEXT[group.size], 'text-default')}>{label}</span>}\n </label>\n {/* Outside the <label> — see the note in `Checkbox`. Text nested in a label becomes\n part of the accessible *name*, so the description would be read twice: once as\n the name and again as the description. */}\n {description && (\n <span\n id={descriptionId}\n className={clsx(\n 'mt-0.5 pl-[26px]',\n LABEL_TEXT[group.size],\n isDisabled ? 'text-disabled' : 'text-default-secondary',\n )}\n >\n {description}\n </span>\n )}\n </div>\n );\n});\n","import clsx from 'clsx';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport interface SegmentedControlOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps {\n options: SegmentedControlOption[];\n /** Controlled selection. Omit and pass `defaultValue` for uncontrolled. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Names the group. Required by the APG when the control has no visible label. */\n label?: string;\n className?: string;\n}\n\n/**\n * Single-select segmented toggle.\n *\n * Through 0.3.0 this had **no ARIA whatsoever** — the selected segment was distinguished\n * only by `bg-default shadow-panel`, so a screen reader user could not tell which of the\n * segments was active. It is single-select, so `radiogroup`/`radio` is the correct pattern\n * rather than a row of `aria-pressed` buttons: it announces \"2 of 3\" and lets the arrow\n * keys move between options, which a toggle-button group does not.\n *\n * `onChange` was also optional, so `<SegmentedControl options value />` rendered a control\n * that looked interactive and silently did nothing.\n */\nexport function SegmentedControl({\n options,\n value: valueProp,\n defaultValue,\n onValueChange,\n label,\n className,\n}: SegmentedControlProps) {\n const [value, setValue] = useControllableState({\n value: valueProp,\n defaultValue: defaultValue ?? options[0]?.value,\n onChange: onValueChange,\n });\n\n const selectedIndex = Math.max(\n 0,\n options.findIndex((option) => option.value === value),\n );\n\n const roving = useRovingFocus({\n orientation: 'horizontal',\n loop: true,\n defaultIndex: selectedIndex,\n });\n\n return (\n <div\n role=\"radiogroup\"\n aria-label={label}\n className={clsx(\n 'inline-flex items-center rounded-xl border border-default bg-default-secondary p-0.5',\n className,\n )}\n {...roving.containerProps}\n >\n {options.map((option, index) => {\n const selected = option.value === value;\n const itemProps = roving.itemProps(index, {\n disabled: option.disabled,\n label: option.label,\n });\n\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n disabled={option.disabled}\n {...itemProps}\n // The tab stop follows selection, not focus, so Tab lands on the active\n // segment rather than wherever the arrows were last used.\n tabIndex={selected ? 0 : -1}\n onFocus={() => {\n itemProps.onFocus();\n if (!option.disabled) setValue(option.value);\n }}\n onClick={() => !option.disabled && setValue(option.value)}\n className={clsx(\n 'rounded-lg px-3.5 py-1.5 text-body-xs font-medium transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default-secondary',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n selected\n ? 'bg-default text-default shadow-panel'\n : 'text-default-secondary hover:text-default',\n )}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { forwardRef, useId, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport interface SliderProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'onChange' | 'value'> {\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n /** Matches Figma's `Label` / `Has Label`. */\n label?: ReactNode;\n /** Matches Figma's `Description` / `Has Description`. */\n description?: ReactNode;\n /** Show the current value at the right of the label row. */\n showValue?: boolean;\n /** Formats the displayed and announced value — percentages, currency, durations. */\n formatValue?: (value: number) => string;\n className?: string;\n}\n\n/**\n * Range slider. Matches Figma's `Slider Field` (`State: Default | Disabled`, with label and\n * description slots).\n *\n * A native `<input type=\"range\">`, deliberately. It arrives with the entire APG slider\n * contract already implemented — arrow keys, Page Up/Down, Home/End, the correct\n * `aria-valuenow`/`valuemin`/`valuemax`, touch and pointer dragging, and RTL handling — and\n * a `div`-based slider has to rebuild all of it. The track and thumb are styled through the\n * vendor pseudo-elements instead, which is the one place raw `[&::-webkit-…]` selectors are\n * the right tool.\n *\n * `formatValue` feeds `aria-valuetext`, because \"70\" announced on a price slider is\n * meaningless where \"£70\" is not.\n */\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(\n {\n value,\n defaultValue,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n label,\n description,\n showValue = false,\n formatValue,\n disabled = false,\n id,\n className,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n\n const current = value ?? defaultValue ?? min;\n const display = formatValue ? formatValue(current) : String(current);\n\n return (\n <div className={clsx('flex w-full flex-col gap-1.5', className)}>\n {(label || showValue) && (\n <div className=\"flex items-baseline justify-between gap-2\">\n {label && (\n <label\n htmlFor={controlId}\n className={clsx('text-body-sm', disabled ? 'text-disabled' : 'text-default')}\n >\n {label}\n </label>\n )}\n {showValue && (\n <span className=\"text-body-sm font-medium tabular-nums text-default\">{display}</span>\n )}\n </div>\n )}\n {description && (\n <p\n id={descriptionId}\n className={clsx('text-body-xs', disabled ? 'text-disabled' : 'text-default-secondary')}\n >\n {description}\n </p>\n )}\n <input\n ref={ref}\n id={controlId}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={value}\n defaultValue={value === undefined ? defaultValue : undefined}\n disabled={disabled}\n aria-describedby={description ? descriptionId : undefined}\n // Only when a formatter is supplied — an aria-valuetext that merely repeats\n // aria-valuenow is noise.\n aria-valuetext={formatValue ? display : undefined}\n onChange={(event) => onValueChange?.(Number(event.target.value))}\n className={clsx(\n 'h-5 w-full cursor-pointer appearance-none bg-transparent',\n 'focus-visible:outline-none',\n disabled && 'cursor-not-allowed opacity-50',\n // Track\n '[&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-default-tertiary',\n '[&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-default-tertiary',\n '[&::-moz-range-progress]:h-1.5 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-brand',\n // Thumb. The negative margin centres it on the track, since the input box is\n // taller than the track to keep a comfortable pointer target.\n '[&::-webkit-slider-thumb]:-mt-[7px] [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-brand [&::-webkit-slider-thumb]:bg-default [&::-webkit-slider-thumb]:shadow-100',\n '[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-brand [&::-moz-range-thumb]:bg-default',\n // Focus ring on the thumb, not the whole 100%-wide input — a ring around the\n // full track reads as the row being focused rather than the handle.\n 'focus-visible:[&::-webkit-slider-thumb]:ring-2 focus-visible:[&::-webkit-slider-thumb]:ring-brand focus-visible:[&::-webkit-slider-thumb]:ring-offset-1',\n 'focus-visible:[&::-moz-range-thumb]:ring-2 focus-visible:[&::-moz-range-thumb]:ring-brand',\n )}\n {...props}\n />\n </div>\n );\n});\n","import { forwardRef, type LabelHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { useFieldContext } from './field';\nimport type { InputSize } from './input';\n\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n children: ReactNode;\n size?: InputSize;\n}\n\nconst SIZE: Record<InputSize, string> = {\n lg: 'text-body',\n md: 'text-body-sm',\n sm: 'text-body-tiny',\n};\n\n/**\n * A standalone `<label>`.\n *\n * `FieldLabel` is the one to reach for inside a `Field` — it picks up the generated id,\n * the size and the disabled state from context automatically. This is for the cases that\n * are not a field: naming a `SegmentedControl`, a group of buttons, or any control the\n * library does not wrap. It still reads `Field` context when it happens to be inside one,\n * so it degrades to `FieldLabel` behaviour rather than silently losing the association.\n */\nexport const Label = forwardRef<HTMLLabelElement, LabelProps>(function Label(\n { children, size, className, htmlFor, ...rest },\n ref,\n) {\n const field = useFieldContext();\n const resolvedSize = size ?? field?.size ?? 'md';\n\n return (\n <label\n ref={ref}\n htmlFor={htmlFor ?? field?.controlId}\n data-slot=\"label\"\n className={clsx(\n 'select-none',\n SIZE[resolvedSize],\n field?.disabled ? 'text-disabled' : 'text-default',\n className,\n )}\n {...rest}\n >\n {children}\n </label>\n );\n});\n","import {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuChevronLeft, LuChevronRight } from 'react-icons/lu';\nimport { IconButton } from './icon-button';\n\nexport type CalendarMode = 'single' | 'range';\n\nexport interface DateRange {\n from: Date | null;\n to: Date | null;\n}\n\nexport interface CalendarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n mode?: CalendarMode;\n /** Selected date in `single` mode. */\n value?: Date | null;\n /** Selected range in `range` mode. */\n range?: DateRange;\n onSelect?: (value: Date) => void;\n onRangeChange?: (range: DateRange) => void;\n /** Month shown on mount. Defaults to the selection's month, else today. */\n defaultMonth?: Date;\n min?: Date;\n max?: Date;\n /** Return `true` to disable a day. Combined with `min`/`max`. */\n isDateDisabled?: (date: Date) => boolean;\n /** 0 = Sunday, 1 = Monday. Default `1`. */\n weekStartsOn?: 0 | 1;\n /** BCP 47 tag for month, weekday and announced day names. Default: the browser's. */\n locale?: string;\n /** Names the grid. Default `Calendar`. */\n label?: string;\n}\n\n// ── Date helpers ───────────────────────────────────────────────────────────────\n// Deliberately no date library. Everything below is calendar-grid arithmetic on local\n// dates, which is a few dozen lines; pulling in date-fns for it would be the largest\n// dependency in the package.\n\nconst startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());\nconst sameDay = (a: Date | null | undefined, b: Date | null | undefined) =>\n !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\nconst addDays = (d: Date, n: number) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);\nconst addMonths = (d: Date, n: number) => new Date(d.getFullYear(), d.getMonth() + n, 1);\nconst isBefore = (a: Date, b: Date) => startOfDay(a).getTime() < startOfDay(b).getTime();\nconst isAfter = (a: Date, b: Date) => startOfDay(a).getTime() > startOfDay(b).getTime();\nconst inRange = (d: Date, from: Date, to: Date) =>\n startOfDay(d).getTime() > startOfDay(from).getTime() &&\n startOfDay(d).getTime() < startOfDay(to).getTime();\n\n/** Six weeks of cells so the grid never changes height as the month changes. */\nfunction monthGrid(month: Date, weekStartsOn: 0 | 1): Date[] {\n const first = new Date(month.getFullYear(), month.getMonth(), 1);\n const offset = (first.getDay() - weekStartsOn + 7) % 7;\n const start = addDays(first, -offset);\n return Array.from({ length: 42 }, (_, i) => addDays(start, i));\n}\n\n/**\n * Month grid. Matches Figma's `Calendar`, `Calendar Button`\n * (`State: Default | Hover | Active | Disabled | Range | Range Disabled | Hidden`),\n * `Calendar Select Group` and `Calendar Month/Year Field`.\n *\n * The code had no calendar at all — `DatePicker` was a bare `<input type=\"date\">` with\n * Chromium-only indicator styling, so there was nothing to build a range picker on, no\n * locale control and no min/max navigation.\n *\n * The keyboard model is the APG date-grid pattern, and it is the whole reason this is not\n * just a table of buttons:\n *\n * - **One tab stop.** Tab enters the grid once and leaves it; arrows move within. A grid of\n * 42 individually tabbable buttons takes 42 presses to get past.\n * - **Arrows cross month boundaries.** Pressing Left on the 1st moves to the previous\n * month's last day and pages the view, rather than dead-ending.\n * - **PageUp/PageDown** move by month, **Home/End** to the start/end of the week.\n * - Each day's accessible name is the full date, not the number — \"14\" tells a screen\n * reader user nothing.\n */\nexport function Calendar({\n mode = 'single',\n value,\n range,\n onSelect,\n onRangeChange,\n defaultMonth,\n min,\n max,\n isDateDisabled,\n weekStartsOn = 1,\n locale,\n label = 'Calendar',\n className,\n ...rest\n}: CalendarProps) {\n const today = useMemo(() => startOfDay(new Date()), []);\n const gridId = useId();\n\n const [month, setMonth] = useState<Date>(\n () => defaultMonth ?? value ?? range?.from ?? today,\n );\n // The focused cell, which is what the roving tabindex follows. Distinct from the\n // selection: you can arrow around without selecting.\n const [focusedDate, setFocusedDate] = useState<Date>(\n () => value ?? range?.from ?? today,\n );\n const cellRefs = useRef(new Map<string, HTMLButtonElement>());\n\n const monthFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }),\n [locale],\n );\n const dayNameFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, { weekday: 'short' }),\n [locale],\n );\n const fullDateFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }),\n [locale],\n );\n\n const disabled = useCallback(\n (date: Date) => {\n if (min && isBefore(date, min)) return true;\n if (max && isAfter(date, max)) return true;\n return isDateDisabled?.(date) ?? false;\n },\n [min, max, isDateDisabled],\n );\n\n const key = (d: Date) => `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;\n\n // Set by keyboard moves only. Focus must not be stolen on mount, or when a click has\n // already put focus on the cell the user pressed.\n const pendingFocus = useRef(false);\n\n const focusDate = useCallback((date: Date) => {\n pendingFocus.current = true;\n setFocusedDate(date);\n // A move across the month boundary pages the view; the target cell does not exist\n // until after that commit, which is why focus is applied in the effect below rather\n // than here.\n setMonth((current) =>\n current.getFullYear() === date.getFullYear() && current.getMonth() === date.getMonth()\n ? current\n : new Date(date.getFullYear(), date.getMonth(), 1),\n );\n }, []);\n\n useEffect(() => {\n if (!pendingFocus.current) return;\n const node = cellRefs.current.get(key(focusedDate));\n if (node) {\n node.focus();\n pendingFocus.current = false;\n }\n // If the node is still absent the month is mid-change; the next commit re-runs this.\n }, [focusedDate, month]);\n\n const select = (date: Date) => {\n if (disabled(date)) return;\n setFocusedDate(date);\n\n if (mode === 'single') {\n onSelect?.(date);\n return;\n }\n\n const current = range ?? { from: null, to: null };\n // Anchor a new range when there is none, when one is already complete, or when the\n // click lands before the anchor — the last case is what makes dragging backwards work\n // instead of producing an inverted range.\n if (!current.from || current.to || isBefore(date, current.from)) {\n onRangeChange?.({ from: date, to: null });\n } else {\n onRangeChange?.({ from: current.from, to: date });\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const moves: Record<string, () => Date> = {\n ArrowLeft: () => addDays(focusedDate, -1),\n ArrowRight: () => addDays(focusedDate, 1),\n ArrowUp: () => addDays(focusedDate, -7),\n ArrowDown: () => addDays(focusedDate, 7),\n Home: () => addDays(focusedDate, -((focusedDate.getDay() - weekStartsOn + 7) % 7)),\n End: () => addDays(focusedDate, 6 - ((focusedDate.getDay() - weekStartsOn + 7) % 7)),\n PageUp: () => addDays(focusedDate, 0) && new Date(focusedDate.getFullYear(), focusedDate.getMonth() - 1, focusedDate.getDate()),\n PageDown: () => new Date(focusedDate.getFullYear(), focusedDate.getMonth() + 1, focusedDate.getDate()),\n };\n\n const move = moves[event.key];\n if (move) {\n event.preventDefault();\n focusDate(move());\n }\n };\n\n const days = monthGrid(month, weekStartsOn);\n const weekdayNames = days.slice(0, 7).map((d) => dayNameFormatter.format(d));\n\n return (\n <div\n data-slot=\"calendar\"\n className={clsx('w-fit rounded-xl border border-default bg-default p-3', className)}\n {...rest}\n >\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Previous month\"\n disabled={!!min && isBefore(addMonths(month, -1), new Date(min.getFullYear(), min.getMonth(), 1))}\n onClick={() => setMonth(addMonths(month, -1))}\n >\n <LuChevronLeft aria-hidden size={16} />\n </IconButton>\n {/* aria-live so paging the month is announced — otherwise a screen reader user\n arrowing past the end of a month has no idea the view moved. */}\n <span aria-live=\"polite\" className=\"text-body-sm font-semibold text-default\">\n {monthFormatter.format(month)}\n </span>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Next month\"\n disabled={!!max && isAfter(addMonths(month, 1), new Date(max.getFullYear(), max.getMonth(), 1))}\n onClick={() => setMonth(addMonths(month, 1))}\n >\n <LuChevronRight aria-hidden size={16} />\n </IconButton>\n </div>\n\n {/* role=\"grid\" with an explicit row/cell structure, so a screen reader announces\n \"column 3, row 2\" and the day headers are tied to the columns. */}\n <div\n role=\"grid\"\n aria-label={label}\n id={gridId}\n // Programmatically focusable but out of the tab sequence: the roving day buttons\n // own the tab stop, and key handling is delegated here so it keeps working while\n // focus moves between cells.\n tabIndex={-1}\n onKeyDown={onKeyDown}\n >\n <div role=\"row\" className=\"mb-1 grid grid-cols-7\">\n {weekdayNames.map((name) => (\n <div\n key={name}\n role=\"columnheader\"\n // The short form is shown; the long form is not needed because each cell\n // announces its own full date.\n className=\"flex h-8 items-center justify-center text-body-tiny font-medium text-default-tertiary\"\n >\n {name}\n </div>\n ))}\n </div>\n\n {Array.from({ length: 6 }, (_, week) => (\n <div key={week} role=\"row\" className=\"grid grid-cols-7\">\n {days.slice(week * 7, week * 7 + 7).map((date) => {\n const outside = date.getMonth() !== month.getMonth();\n const isDisabled = disabled(date);\n const selected =\n mode === 'single'\n ? sameDay(date, value)\n : sameDay(date, range?.from) || sameDay(date, range?.to);\n const between =\n mode === 'range' && range?.from && range?.to\n ? inRange(date, range.from, range.to)\n : false;\n const isFocused = sameDay(date, focusedDate);\n\n return (\n <div role=\"gridcell\" key={key(date)} aria-selected={selected || undefined}>\n <button\n ref={(node) => {\n if (node) cellRefs.current.set(key(date), node);\n else cellRefs.current.delete(key(date));\n }}\n type=\"button\"\n // The roving tab stop: exactly one cell is reachable by Tab.\n tabIndex={isFocused ? 0 : -1}\n disabled={isDisabled}\n aria-label={fullDateFormatter.format(date)}\n aria-current={sameDay(date, today) ? 'date' : undefined}\n onClick={() => select(date)}\n onFocus={() => setFocusedDate(date)}\n className={clsx(\n 'flex size-9 items-center justify-center rounded-lg text-body-sm tabular-nums transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:text-disabled disabled:hover:bg-transparent',\n selected\n ? 'bg-brand font-semibold text-brand-on-brand'\n : between\n ? 'rounded-none bg-brand-tertiary text-default'\n : outside\n ? 'text-default-tertiary hover:bg-default-secondary'\n : 'text-default hover:bg-default-secondary',\n // Today is marked by a ring rather than a fill, so it stays legible\n // when it is also the selected day.\n sameDay(date, today) && !selected && 'ring-1 ring-inset ring-brand-tertiary',\n )}\n >\n {date.getDate()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { forwardRef, type HTMLAttributes, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { LuSearch, LuX } from 'react-icons/lu';\nimport { useFieldControl } from './field';\nimport type { InputSize } from './input';\nimport { useControlSize } from './control-size';\n\nexport type InputGroupAlign = 'inline-start' | 'inline-end' | 'block-start' | 'block-end';\n\nconst HEIGHT: Record<InputSize, string> = {\n lg: 'h-12 text-body',\n md: 'h-9 text-body-sm',\n sm: 'h-6 text-body-tiny',\n};\n\nconst PAD: Record<InputSize, string> = {\n lg: 'px-4 gap-2',\n md: 'px-3 gap-1.5',\n sm: 'px-2 gap-1',\n};\n\nexport interface InputGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: InputSize;\n invalid?: boolean;\n disabled?: boolean;\n}\n\n/**\n * A bordered shell that holds an input alongside addons — a prefix, a unit suffix, a\n * search glyph, a clear button, a copy button.\n *\n * This generalises what `PasswordInput` did as a one-off. `Input` has `leadingIcon`,\n * `trailingIcon` and `trailingAction` props, which works for a single decoration but forces\n * absolute positioning and per-size padding maps to keep the text clear of it. Here the\n * addons are real flex siblings, so the input's text box simply ends where the addon\n * begins and nothing has to be measured.\n *\n * The border and focus ring live on the group, not the input — so focusing the input rings\n * the whole control, which is what a user perceives as \"the field\".\n */\nexport const InputGroup = forwardRef<HTMLDivElement, InputGroupProps>(function InputGroup(\n { children, size: sizeProp, invalid = false, disabled = false, className, ...rest },\n ref,\n) {\n const size = useControlSize(sizeProp);\n\n return (\n <div\n ref={ref}\n data-slot=\"input-group\"\n data-size={size}\n className={clsx(\n 'flex w-full items-center rounded-lg border transition-colors',\n 'bg-default text-default',\n HEIGHT[size],\n PAD[size],\n // `focus-within`, because the focused element is the nested input while the ring\n // belongs to the shell.\n 'focus-within:ring-2 focus-within:ring-offset-1 focus-within:ring-offset-default',\n disabled\n ? 'cursor-not-allowed border-disabled bg-disabled text-disabled'\n : invalid\n ? 'border-danger-secondary focus-within:border-danger focus-within:ring-danger'\n : 'border-default focus-within:border-brand focus-within:ring-brand',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n});\n\nexport interface InputGroupInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {}\n\n/**\n * The input inside an `InputGroup`. Carries no border, background or ring of its own —\n * the group owns all three.\n */\nexport const InputGroupInput = forwardRef<HTMLInputElement, InputGroupInputProps>(\n function InputGroupInput({ className, ...props }, ref) {\n const field = useFieldControl();\n return (\n <input\n ref={ref}\n {...field}\n className={clsx(\n 'min-w-0 flex-1 bg-transparent outline-none',\n 'placeholder:text-default-tertiary',\n 'disabled:cursor-not-allowed disabled:text-disabled disabled:placeholder:text-disabled',\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nexport interface InputGroupAddonProps extends HTMLAttributes<HTMLSpanElement> {\n children: ReactNode;\n align?: InputGroupAlign;\n /**\n * `true` when the addon is decoration — an icon, a unit. Decorative addons are\n * `aria-hidden` and ignore pointer events, so they never steal a click meant for the\n * text box. Default `true`; set `false` for an addon containing a control.\n */\n decorative?: boolean;\n}\n\nexport const InputGroupAddon = forwardRef<HTMLSpanElement, InputGroupAddonProps>(\n function InputGroupAddon(\n { children, align = 'inline-start', decorative = true, className, ...rest },\n ref,\n ) {\n return (\n <span\n ref={ref}\n aria-hidden={decorative || undefined}\n data-slot=\"input-group-addon\"\n data-align={align}\n className={clsx(\n 'flex shrink-0 items-center text-icon-default-secondary',\n decorative && 'pointer-events-none',\n align === 'inline-end' && 'order-last',\n className,\n )}\n {...rest}\n >\n {children}\n </span>\n );\n },\n);\n\nexport interface InputGroupTextProps extends HTMLAttributes<HTMLSpanElement> {\n children: ReactNode;\n}\n\n/** Static text inside the shell — a currency symbol, a domain suffix, a unit. */\nexport const InputGroupText = forwardRef<HTMLSpanElement, InputGroupTextProps>(\n function InputGroupText({ children, className, ...rest }, ref) {\n return (\n <span\n ref={ref}\n className={clsx('shrink-0 whitespace-nowrap text-default-secondary', className)}\n {...rest}\n >\n {children}\n </span>\n );\n },\n);\n\n// ── SearchInput ────────────────────────────────────────────────────────────────\n\nexport interface SearchInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n size?: InputSize;\n /** Renders a clear button once there is a value. */\n onClear?: () => void;\n /** Accessible name. Default `Search`. */\n label?: string;\n className?: string;\n}\n\n/**\n * Search field. Matches Figma's `Search` set — `Size: Large | Medium | Small`,\n * `State: Default | Disabled`, `Value Type: Filled | Placeholder`.\n *\n * `type=\"search\"` rather than `type=\"text\"`: it gets the platform's search affordances and\n * is announced as a search field. The clear button is a real button so it is keyboard\n * reachable, unlike the UA-provided cancel widget which is pointer-only in most browsers\n * and is therefore suppressed.\n */\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n { size: sizeProp, onClear, label = 'Search', disabled, value, className, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasValue = value !== undefined && value !== '';\n\n return (\n <InputGroup size={size} disabled={disabled} className={className}>\n <InputGroupAddon>\n <LuSearch className={size === 'sm' ? 'size-3' : 'size-4'} />\n </InputGroupAddon>\n <InputGroupInput\n ref={ref}\n type=\"search\"\n aria-label={label}\n disabled={disabled}\n value={value}\n // The UA cancel button cannot be focused or styled consistently, so it is hidden\n // in favour of the real button below.\n className=\"[&::-webkit-search-cancel-button]:appearance-none\"\n {...props}\n />\n {onClear && hasValue && (\n <InputGroupAddon align=\"inline-end\" decorative={false}>\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={onClear}\n disabled={disabled}\n className=\"flex items-center justify-center rounded transition-colors hover:text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n <LuX aria-hidden className={size === 'sm' ? 'size-3' : 'size-4'} />\n </button>\n </InputGroupAddon>\n )}\n </InputGroup>\n );\n});\n","import {\n createContext,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { LuCircleCheckBig, LuInfo, LuOctagonAlert, LuTriangleAlert, LuX } from 'react-icons/lu';\nimport { cn } from '../../lib/cn';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { EntityIconBadge, type EntityIconBadgeTone } from '../status/entity-icon-badge';\nimport { IconButton } from '../forms/icon-button';\nimport { OVERLAY_SCRIM, useOverlayDismiss } from './overlay';\nimport { Portal } from './portal';\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'xl';\n/**\n * Note `positive`, not `success` — every other tone union in the library\n * (`InlineAlertTone`, `TagPillTone`, `EntityIconBadgeTone`) and the token layer say\n * `positive`, and one vocabulary beats a familiar synonym.\n */\nexport type ModalTone = 'default' | 'info' | 'positive' | 'warning' | 'danger';\nexport type ModalFooterAlign = 'start' | 'between' | 'end';\n\n/**\n * The `sm:` prefix is mandatory, not cosmetic. In 0.2.0 `max-w-[540px]` was applied\n * unprefixed, so between 540px and the `sm` breakpoint (640px) the \"bottom sheet\" was\n * a 540px card floating in the middle of the viewport.\n */\nconst SIZE: Record<ModalSize, string> = {\n sm: 'sm:max-w-[420px]',\n md: 'sm:max-w-[540px]',\n lg: 'sm:max-w-[640px]',\n xl: 'sm:max-w-[800px]',\n};\n\n/**\n * `info` / `positive` / `warning` reuse `InlineAlert`'s glyphs, so one semantic has one\n * mark across the system. `danger` deliberately differs from `warning`: a dialog that\n * is about to destroy something should not be glyph-identical to one merely cautioning.\n */\nconst TONE_ICON: Record<Exclude<ModalTone, 'default'>, ReactNode> = {\n info: <LuInfo aria-hidden className=\"size-5\" />,\n positive: <LuCircleCheckBig aria-hidden className=\"size-5\" />,\n warning: <LuTriangleAlert aria-hidden className=\"size-5\" />,\n danger: <LuOctagonAlert aria-hidden className=\"size-5\" />,\n};\n\n/** Reuses EntityIconBadge's tone map — one token map for tinted icon circles. */\nconst TONE_BADGE: Record<Exclude<ModalTone, 'default'>, EntityIconBadgeTone> = {\n info: 'brand',\n positive: 'positive',\n warning: 'warning',\n danger: 'danger',\n};\n\nconst FOOTER_ALIGN: Record<ModalFooterAlign, string> = {\n start: 'justify-start',\n between: 'justify-between',\n end: 'justify-end',\n};\n\n// ── Naming context ─────────────────────────────────────────────────────────────\n\n/**\n * Lets `ModalTitle` and `ModalDescription` name the dialog by reference rather than by\n * having the caller repeat the string.\n *\n * 0.3.0 set `aria-label={label}` on the panel *and* rendered a visible `<h2>`, so the\n * accessible name was a duplicate of the heading that nothing kept in sync — and a rich\n * title (an element, a count, an icon) could not be the name at all. The parts register\n * themselves here on mount, and the panel points `aria-labelledby` /\n * `aria-describedby` at whichever are actually present.\n */\ninterface ModalNamingContext {\n titleId: string;\n descriptionId: string;\n registerTitle: (present: boolean) => void;\n registerDescription: (present: boolean) => void;\n}\n\nconst ModalNaming = createContext<ModalNamingContext | null>(null);\n\n// ── Modal ──────────────────────────────────────────────────────────────────────\n\nexport interface ModalProps {\n open: boolean;\n /** Fired with `false` on Escape, an outside press, or the close button. */\n onOpenChange: (open: boolean) => void;\n /**\n * Accessible name. Only needed when the dialog renders no `ModalTitle` — with one, the\n * name comes from the heading itself via `aria-labelledby`, so it cannot drift.\n */\n label?: string;\n children: ReactNode;\n size?: ModalSize;\n /**\n * `alertdialog` for a dialog that interrupts to confirm or warn — it makes assistive\n * tech announce the body immediately rather than waiting to be browsed. `ConfirmDialog`\n * passes it; plain content dialogs should stay `dialog`.\n */\n role?: 'dialog' | 'alertdialog';\n /** Renders the top-right close button. */\n showClose?: boolean;\n /** Applied to the panel. With `cn`, `className=\"sm:max-w-[560px]\"` beats `size`. */\n className?: string;\n /** Call `preventDefault()` to keep the dialog open — e.g. unsaved input. */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** Call `preventDefault()` to keep the dialog open. */\n onInteractOutside?: (event: PointerEvent) => void;\n /** Focus this on open instead of the first tabbable element. */\n initialFocus?: React.RefObject<HTMLElement | null>;\n}\n\n/**\n * A centred dialog above `sm`, a bottom sheet below it.\n *\n * Composed from `ModalHeader` / `ModalBody` / `ModalFooter`, mirroring the `Card`\n * parts — so a modal can take any layout a card can, including headerless. Tone lives\n * on `ModalHeader` (the part that draws the glyph); `ConfirmDialog` and\n * `NoteConfirmModal` accept `tone` at their top level and forward it.\n */\nexport function Modal(props: ModalProps) {\n if (!props.open) return null;\n return (\n <Portal>\n <ModalShell {...props} />\n </Portal>\n );\n}\n\n/**\n * Split out so the Esc / focus-trap hooks only mount while the dialog is open —\n * calling them in `Modal` itself would break the `if (!open) return null` exit.\n */\nfunction ModalShell({\n onOpenChange,\n label,\n children,\n size = 'md',\n role = 'dialog',\n showClose = true,\n className,\n onEscapeKeyDown,\n onInteractOutside,\n initialFocus,\n}: Omit<ModalProps, 'open'>) {\n const panelRef = useRef<HTMLDivElement>(null);\n const baseId = useId();\n const [hasTitle, setHasTitle] = useState(false);\n const [hasDescription, setHasDescription] = useState(false);\n\n const titleId = `${baseId}-title`;\n const descriptionId = `${baseId}-description`;\n\n useOverlayDismiss({\n onDismiss: () => onOpenChange(false),\n panelRef,\n initialFocus,\n onEscapeKeyDown,\n onInteractOutside,\n });\n\n return (\n <div\n className={cn(\n 'fixed inset-0 z-overlay flex items-end justify-center sm:items-center',\n OVERLAY_SCRIM,\n )}\n >\n <div\n ref={panelRef}\n role={role}\n aria-modal=\"true\"\n aria-labelledby={hasTitle ? titleId : undefined}\n aria-label={hasTitle ? undefined : label}\n aria-describedby={hasDescription ? descriptionId : undefined}\n className={cn(\n 'relative max-h-[92dvh] w-full overflow-y-auto bg-default shadow-400',\n // Not a `ScrollArea`: the panel is the dialog, so the scroll container has to stay\n // the element carrying `role`, `aria-modal` and the trap boundary. It is already\n // keyboard-scrollable because the trap focuses it on open.\n SCROLLBAR_CLASSES,\n 'rounded-t-2xl pb-[env(safe-area-inset-bottom)] sm:mx-4 sm:rounded-2xl sm:pb-0',\n SIZE[size],\n className,\n )}\n >\n {showClose && (\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Close dialog\"\n onClick={() => onOpenChange(false)}\n // Floating rather than inside the header, so a headerless modal is still\n // dismissible. right-6/top-5 reproduces 0.2.0's position exactly.\n className=\"absolute right-6 top-5 z-raised\"\n >\n <LuX size={16} aria-hidden />\n </IconButton>\n )}\n <ModalNaming.Provider\n value={{\n titleId,\n descriptionId,\n registerTitle: setHasTitle,\n registerDescription: setHasDescription,\n }}\n >\n {children}\n </ModalNaming.Provider>\n </div>\n </div>\n );\n}\n\n// ── ModalHeader ────────────────────────────────────────────────────────────────\n\nexport interface ModalHeaderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Adds a tinted glyph circle. `default` renders none. */\n tone?: ModalTone;\n divider?: boolean;\n}\n\nexport function ModalHeader({\n children,\n tone = 'default',\n divider = true,\n className,\n ...rest\n}: ModalHeaderProps) {\n return (\n <div\n className={cn(\n // pr-14 reserves the floating close button's column (24px gutter + 24px\n // button + gap), which the old flex-between header used to hold open.\n 'flex items-start gap-3 px-6 py-5 pr-14',\n divider && 'border-b border-default',\n className,\n )}\n {...rest}\n >\n {tone !== 'default' && (\n <EntityIconBadge size=\"md\" shape=\"circle\" tone={TONE_BADGE[tone]}>\n {TONE_ICON[tone]}\n </EntityIconBadge>\n )}\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\n// ── ModalTitle / ModalDescription / ModalBody / ModalFooter ────────────────────\n\nexport interface ModalTitleProps extends HTMLAttributes<HTMLHeadingElement> {\n children: ReactNode;\n}\n\nexport function ModalTitle({ children, className, id, ...rest }: ModalTitleProps) {\n const naming = useContext(ModalNaming);\n\n useEffect(() => {\n naming?.registerTitle(true);\n return () => naming?.registerTitle(false);\n }, [naming]);\n\n return (\n <h2\n id={id ?? naming?.titleId}\n className={cn('text-heading-sm font-semibold text-default', className)}\n {...rest}\n >\n {children}\n </h2>\n );\n}\n\nexport interface ModalDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {\n children: ReactNode;\n}\n\nexport function ModalDescription({ children, className, id, ...rest }: ModalDescriptionProps) {\n const naming = useContext(ModalNaming);\n\n useEffect(() => {\n naming?.registerDescription(true);\n return () => naming?.registerDescription(false);\n }, [naming]);\n\n return (\n <p\n id={id ?? naming?.descriptionId}\n className={cn('mt-0.5 text-body-xs text-default-secondary', className)}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\nexport interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** Must not carry its own `overflow` — the panel is the scroll container. */\nexport function ModalBody({ children, className, ...rest }: ModalBodyProps) {\n return (\n <div className={cn('px-6 py-5', className)} {...rest}>\n {children}\n </div>\n );\n}\n\nexport interface ModalFooterProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n align?: ModalFooterAlign;\n divider?: boolean;\n}\n\nexport function ModalFooter({\n children,\n align = 'end',\n divider = true,\n className,\n ...rest\n}: ModalFooterProps) {\n return (\n <div\n className={cn(\n 'flex items-center gap-2 px-6 py-4',\n FOOTER_ALIGN[align],\n divider && 'border-t border-default',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","import {\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useFloatingPanel, type FloatingAlign, type FloatingSide } from './floating';\nimport { Portal } from './portal';\n\nexport interface TooltipProps {\n /**\n * The trigger. Must be a single focusable element — a tooltip that can only be reached\n * with a pointer is invisible to keyboard and touch users, so this deliberately does not\n * wrap its child in a span to make it hoverable.\n */\n children: ReactElement;\n /** Bold first line. Matches Figma's `Title` property. */\n title?: ReactNode;\n /** Supporting line. Matches Figma's `Body` / `Has Body`. */\n body?: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n /** Delay before opening, in ms. Default `150`. */\n openDelay?: number;\n /** Delay before closing, in ms. Default `0`. */\n closeDelay?: number;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * `describedby` — the trigger keeps its own name and the tooltip adds detail. This is\n * almost always what you want. `labelledby` makes the tooltip *be* the trigger's name,\n * for an icon-only button with no other text. Default `describedby`.\n *\n * Deliberately not called `as`: everywhere else in this library `as` chooses the rendered\n * element, and reusing it for something else here would be a trap (it also makes\n * `jsx-a11y`'s polymorphic-component checking treat the value as a tag name).\n */\n association?: 'describedby' | 'labelledby';\n className?: string;\n}\n\n/**\n * Tooltip. Matches Figma's `Tooltip` set — `Placement: Top | Left | Right | Bottom`, with\n * a title and an optional body.\n *\n * Things this gets right that a naive tooltip does not:\n *\n * - **Keyboard and touch reachable.** Opens on `focus` as well as hover, and closes on\n * Escape. A hover-only tooltip is inaccessible to half the people using it.\n * - **Referenced, not floating text.** The panel is wired to the trigger with\n * `aria-describedby` (or `aria-labelledby`), so it is announced *with* the control\n * rather than being an orphan region a screen reader may never reach.\n * - **`role=\"tooltip\"` and no interactive content.** A tooltip cannot be hovered into or\n * focused, so anything interactive inside it is unreachable — use `Popover` for that.\n * - Not modal: no focus trap, no scroll lock, no inert background.\n */\nexport function Tooltip({\n children,\n title,\n body,\n side = 'top',\n align = 'center',\n openDelay = 150,\n closeDelay = 0,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n association = 'describedby',\n className,\n}: TooltipProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const tooltipId = useId();\n const [triggerNode, setTriggerNode] = useState<HTMLElement | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearTimer = useCallback(() => {\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n }, []);\n\n const schedule = useCallback(\n (next: boolean, delay: number) => {\n clearTimer();\n if (delay === 0) {\n setOpen(next);\n return;\n }\n timer.current = setTimeout(() => setOpen(next), delay);\n },\n [clearTimer, setOpen],\n );\n\n useEffect(() => clearTimer, [clearTimer]);\n\n const { refs, floatingStyles } = useFloatingPanel({\n open,\n onOpenChange: setOpen,\n side,\n align,\n sideOffset: 6,\n });\n\n useEffect(() => {\n refs.setReference(triggerNode);\n }, [refs, triggerNode]);\n\n // Escape must dismiss a tooltip even though it never holds focus, so this listens at the\n // document rather than on the trigger.\n useEffect(() => {\n if (!open) return;\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') setOpen(false);\n }\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [open, setOpen]);\n\n if (!isValidElement(children)) return null;\n\n const child = children as ReactElement<Record<string, unknown>>;\n const childProps = child.props;\n const describedBy = association === 'describedby' ? tooltipId : undefined;\n const labelledBy = association === 'labelledby' ? tooltipId : undefined;\n\n const trigger = cloneElement(child, {\n ref: composeRefs<HTMLElement>(\n (node) => setTriggerNode(node),\n (child as unknown as { ref?: React.Ref<HTMLElement> }).ref,\n ),\n 'aria-describedby':\n [childProps['aria-describedby'], open ? describedBy : undefined].filter(Boolean).join(' ') ||\n undefined,\n 'aria-labelledby':\n [childProps['aria-labelledby'], labelledBy].filter(Boolean).join(' ') || undefined,\n onPointerEnter: (event: React.PointerEvent) => {\n (childProps.onPointerEnter as ((e: React.PointerEvent) => void) | undefined)?.(event);\n schedule(true, openDelay);\n },\n onPointerLeave: (event: React.PointerEvent) => {\n (childProps.onPointerLeave as ((e: React.PointerEvent) => void) | undefined)?.(event);\n schedule(false, closeDelay);\n },\n // Focus, not just hover — this is the difference between a tooltip a keyboard user can\n // read and one they cannot.\n onFocus: (event: React.FocusEvent) => {\n (childProps.onFocus as ((e: React.FocusEvent) => void) | undefined)?.(event);\n schedule(true, 0);\n },\n onBlur: (event: React.FocusEvent) => {\n (childProps.onBlur as ((e: React.FocusEvent) => void) | undefined)?.(event);\n schedule(false, 0);\n },\n } as Record<string, unknown>);\n\n return (\n <>\n {trigger}\n {/* Always rendered under `association=\"labelledby\"` so the id it points at exists\n even while closed — an `aria-labelledby` that resolves to nothing leaves the\n trigger unnamed, which is worse than having no tooltip at all. */}\n {(open || association === 'labelledby') && (\n <Portal>\n <div\n ref={refs.setFloating}\n id={tooltipId}\n role=\"tooltip\"\n style={floatingStyles}\n className={clsx(\n 'z-tooltip max-w-[260px] rounded-lg bg-neutral px-3 py-2 shadow-300',\n 'text-body-xs text-neutral-on-neutral',\n !open && 'sr-only',\n className,\n )}\n >\n {title && <p className=\"font-semibold\">{title}</p>}\n {body && <p className={clsx(title && 'mt-0.5 opacity-80')}>{body}</p>}\n </div>\n </Portal>\n )}\n </>\n );\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\nimport clsx from 'clsx';\n\nimport { Slot, composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useFloatingPanel, type FloatingAlign, type FloatingSide } from './floating';\nimport { useOverlayDismiss } from './overlay';\nimport { Portal } from './portal';\n\ninterface PopoverContextValue {\n open: boolean;\n setOpen: (open: boolean) => void;\n contentId: string;\n triggerId: string;\n triggerNode: HTMLElement | null;\n setTriggerNode: (node: HTMLElement | null) => void;\n modal: boolean;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nfunction usePopover(part: string): PopoverContextValue {\n const value = useContext(PopoverContext);\n if (!value) throw new Error(`<${part}> must be used inside <Popover>`);\n return value;\n}\n\nexport interface PopoverProps {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Trap focus, lock scroll and mark the rest of the page inert. Default `false`.\n *\n * A popover is normally non-modal: the page behind stays usable, and Tab moves out of the\n * panel and on through the document. Set `modal` when the panel is a small form whose\n * background must not be touched until it is dismissed.\n */\n modal?: boolean;\n}\n\n/**\n * A floating panel anchored to a trigger, for **interactive** content.\n *\n * The distinction from `Tooltip` is not visual and it matters: a tooltip cannot be hovered\n * into or focused, so anything interactive inside one is unreachable. If the panel holds a\n * link, a button or a field, it has to be a popover — which means a real trigger with\n * `aria-expanded`/`aria-controls`, focus moving into the panel on open, and focus returning\n * to the trigger on close. All of that is here; none of it is in `Tooltip`, by design.\n */\nexport function Popover({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n modal = false,\n}: PopoverProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const baseId = useId();\n const [triggerNode, setTriggerNode] = useState<HTMLElement | null>(null);\n\n const context = useMemo<PopoverContextValue>(\n () => ({\n open,\n setOpen,\n contentId: `${baseId}-content`,\n triggerId: `${baseId}-trigger`,\n triggerNode,\n setTriggerNode,\n modal,\n }),\n [open, setOpen, baseId, triggerNode, modal],\n );\n\n return <PopoverContext.Provider value={context}>{children}</PopoverContext.Provider>;\n}\n\nexport interface PopoverTriggerProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n asChild?: boolean;\n}\n\nexport function PopoverTrigger({\n children,\n asChild = false,\n className,\n ...rest\n}: PopoverTriggerProps) {\n const popover = usePopover('PopoverTrigger');\n\n const triggerProps = {\n id: popover.triggerId,\n // `dialog`, not `menu` — the panel holds arbitrary content, not a list of commands.\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': popover.open,\n 'aria-controls': popover.open ? popover.contentId : undefined,\n onClick: () => popover.setOpen(!popover.open),\n className,\n ...rest,\n };\n\n if (asChild) {\n return (\n <Slot ref={composeRefs(popover.setTriggerNode)} {...triggerProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={composeRefs(popover.setTriggerNode) as Ref<HTMLButtonElement>}\n type=\"button\"\n {...triggerProps}\n >\n {children}\n </button>\n );\n}\n\nexport interface PopoverContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n sideOffset?: number;\n /** Accessible name for the panel. Falls back to being labelled by the trigger. */\n label?: string;\n}\n\nexport function PopoverContent({\n children,\n side = 'bottom',\n align = 'center',\n sideOffset = 8,\n label,\n className,\n ...rest\n}: PopoverContentProps) {\n const popover = usePopover('PopoverContent');\n const panelRef = useRef<HTMLDivElement | null>(null);\n\n const { refs, floatingStyles } = useFloatingPanel({\n open: popover.open,\n onOpenChange: popover.setOpen,\n side,\n align,\n sideOffset,\n });\n\n useEffect(() => {\n refs.setReference(popover.triggerNode);\n }, [refs, popover.triggerNode]);\n\n useOverlayDismiss({\n onDismiss: () => popover.setOpen(false),\n panelRef,\n active: popover.open,\n // Focus is trapped only in modal mode. In the default non-modal mode Tab should carry\n // on into the rest of the page, which is what users expect of a popover.\n trapFocus: popover.modal,\n lockScroll: popover.modal,\n inertBackground: popover.modal,\n });\n\n if (!popover.open) return null;\n\n return (\n <Portal>\n <div\n ref={composeRefs<HTMLDivElement>(panelRef, refs.setFloating)}\n id={popover.contentId}\n role=\"dialog\"\n aria-modal={popover.modal || undefined}\n aria-label={label}\n aria-labelledby={label ? undefined : popover.triggerId}\n style={floatingStyles}\n className={clsx(\n 'z-popover max-w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-default bg-default p-4 shadow-400',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </Portal>\n );\n}\n","import {\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent as ReactFocusEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport clsx from 'clsx';\n\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useFloatingPanel, type FloatingAlign, type FloatingSide } from './floating';\nimport { Portal } from './portal';\n\nexport interface HoverCardProps {\n /** The trigger. Must be a single focusable element — normally a link. */\n children: ReactElement;\n /** Panel content. May contain links and text; see the note on interactivity below. */\n content: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n /** Delay before opening, in ms. Default `400`. */\n openDelay?: number;\n /** Delay before closing, in ms. Default `200`. */\n closeDelay?: number;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n className?: string;\n}\n\n/**\n * A preview panel that appears on hover — a user card on an @mention, a page preview on a\n * link.\n *\n * Sits between `Tooltip` and `Popover`, and the difference is about intent rather than\n * looks:\n *\n * - `Tooltip` is a short label. It cannot be entered, so it must hold no controls.\n * - `HoverCard` is supplementary content that *can* be entered — the panel stays open while\n * the pointer is inside it, so a link in the preview is reachable. It is opened by hover\n * and focus, never by click.\n * - `Popover` is opened deliberately by click and is the only one of the three appropriate\n * for content the user must act on.\n *\n * **It is supplementary by contract.** Hover has no touch equivalent, so anything only\n * reachable here is unreachable on a phone. The panel is `aria-labelledby` the trigger and\n * exposed as a group; the trigger keeps its own name and destination.\n *\n * The close delay is what makes the panel usable: without it, moving the pointer from the\n * trigger to the panel crosses a gap and dismisses the thing you were reaching for.\n */\nexport function HoverCard({\n children,\n content,\n side = 'bottom',\n align = 'center',\n openDelay = 400,\n closeDelay = 200,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n className,\n}: HoverCardProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const baseId = useId();\n const contentId = `${baseId}-content`;\n const triggerId = `${baseId}-trigger`;\n const [triggerNode, setTriggerNode] = useState<HTMLElement | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const schedule = useCallback(\n (next: boolean, delay: number) => {\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(next), delay);\n },\n [setOpen],\n );\n\n useEffect(\n () => () => {\n if (timer.current) clearTimeout(timer.current);\n },\n [],\n );\n\n const { refs, floatingStyles } = useFloatingPanel({\n open,\n onOpenChange: setOpen,\n side,\n align,\n sideOffset: 8,\n });\n\n useEffect(() => {\n refs.setReference(triggerNode);\n }, [refs, triggerNode]);\n\n useEffect(() => {\n if (!open) return;\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') setOpen(false);\n }\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [open, setOpen]);\n\n if (!isValidElement(children)) return null;\n\n const child = children as ReactElement<Record<string, unknown>>;\n const childProps = child.props;\n\n const trigger = cloneElement(child, {\n id: triggerId,\n ref: composeRefs<HTMLElement>(\n (node) => setTriggerNode(node),\n (child as unknown as { ref?: Ref<HTMLElement> }).ref,\n ),\n // Not `aria-haspopup`: nothing here is triggered by activation, and claiming a popup on\n // a plain link makes a screen reader promise an interaction that does not exist.\n 'aria-describedby': open ? contentId : undefined,\n onPointerEnter: (event: ReactPointerEvent) => {\n (childProps.onPointerEnter as ((e: ReactPointerEvent) => void) | undefined)?.(event);\n schedule(true, openDelay);\n },\n onPointerLeave: (event: ReactPointerEvent) => {\n (childProps.onPointerLeave as ((e: ReactPointerEvent) => void) | undefined)?.(event);\n schedule(false, closeDelay);\n },\n onFocus: (event: ReactFocusEvent) => {\n (childProps.onFocus as ((e: ReactFocusEvent) => void) | undefined)?.(event);\n schedule(true, 0);\n },\n onBlur: (event: ReactFocusEvent) => {\n (childProps.onBlur as ((e: ReactFocusEvent) => void) | undefined)?.(event);\n schedule(false, closeDelay);\n },\n } as Record<string, unknown>);\n\n return (\n <>\n {trigger}\n {open && (\n <Portal>\n <div\n ref={refs.setFloating}\n id={contentId}\n // `group`, not `dialog` — it was not opened deliberately and it traps nothing,\n // so announcing a dialog would be a lie.\n role=\"group\"\n aria-labelledby={triggerId}\n style={floatingStyles}\n // Hovering the panel keeps it open; leaving it closes after the same delay.\n // Without this the panel vanishes as soon as the pointer leaves the trigger.\n onPointerEnter={() => schedule(true, 0)}\n onPointerLeave={() => schedule(false, closeDelay)}\n className={clsx(\n 'z-popover max-w-[min(20rem,calc(100vw-2rem))] rounded-xl border border-default bg-default p-4 shadow-400',\n className,\n )}\n >\n {content}\n </div>\n </Portal>\n )}\n </>\n );\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\n\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { MENU_PANEL_CLASSES, MenuContext, useMenu, useMenuState } from './menu-core';\nimport { useOverlayDismiss } from './overlay';\nimport { Portal } from './portal';\n\ninterface ContextMenuPositionValue {\n point: { x: number; y: number } | null;\n setPoint: (point: { x: number; y: number } | null) => void;\n}\n\nconst PositionContext = createContext<ContextMenuPositionValue | null>(null);\n\nfunction usePosition(): ContextMenuPositionValue {\n const value = useContext(PositionContext);\n if (!value) throw new Error('ContextMenu parts must be used inside <ContextMenu>');\n return value;\n}\n\nexport interface ContextMenuProps {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * Right-click menu.\n *\n * Shares every item and the whole keyboard contract with `DropdownMenu` via `menu-core`;\n * the only difference is how it opens — at the pointer, with no trigger element to anchor\n * to, so it is positioned from coordinates rather than by Floating UI's reference/floating\n * pair.\n *\n * **A context menu must never be the only way to reach an action.** `contextmenu` fires on\n * right-click and on the Windows Menu / Shift+F10 keys, but not on touch, and plenty of\n * users never right-click at all. `ContextMenuTrigger` therefore also opens on Shift+F10 and\n * the ContextMenu key, and anything in here should have a visible equivalent elsewhere —\n * usually a `DropdownMenu` on the same row.\n */\nexport function ContextMenu({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n}: ContextMenuProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const menu = useMenuState({ open, setOpen });\n const [point, setPoint] = useState<{ x: number; y: number } | null>(null);\n const position = useMemo(() => ({ point, setPoint }), [point]);\n\n return (\n <MenuContext.Provider value={menu}>\n <PositionContext.Provider value={position}>{children}</PositionContext.Provider>\n </MenuContext.Provider>\n );\n}\n\nexport interface ContextMenuTriggerProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n disabled?: boolean;\n}\n\nexport function ContextMenuTrigger({\n children,\n disabled = false,\n className,\n ...rest\n}: ContextMenuTriggerProps) {\n const menu = useMenu('ContextMenuTrigger');\n const position = usePosition();\n\n const openAt = (x: number, y: number) => {\n if (disabled) return;\n position.setPoint({ x, y });\n menu.pendingEdge.current = 'start';\n menu.setOpen(true);\n };\n\n return (\n // A transparent wrapper around arbitrary content, not a control. It must not be\n // focusable or take a role: the actions it exposes have a visible equivalent elsewhere\n // (see the note on `ContextMenu`), and a tab stop here would put an unexplained one in\n // the middle of a table row.\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n data-slot=\"context-menu-trigger\"\n className={className}\n onContextMenu={(event: ReactMouseEvent) => {\n event.preventDefault();\n openAt(event.clientX, event.clientY);\n }}\n onKeyDown={(event) => {\n // Shift+F10 and the dedicated ContextMenu key are the keyboard equivalents of a\n // right-click, and the only way this is reachable without a pointer. The wrapper is\n // not focusable itself — deliberately, so it adds no tab stop — so the key arrives by\n // bubbling from whatever focusable element inside it has focus. That means the\n // trigger's content must contain something focusable for the keyboard path to exist;\n // in practice it always does, since the same content carries the visible actions.\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n event.preventDefault();\n const rect = event.currentTarget.getBoundingClientRect();\n openAt(rect.left + rect.width / 2, rect.top + rect.height / 2);\n }\n }}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport interface ContextMenuContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Minimum gap from the viewport edge, in px. Default `8`. */\n collisionPadding?: number;\n}\n\nexport function ContextMenuContent({\n children,\n collisionPadding = 8,\n className,\n ...rest\n}: ContextMenuContentProps) {\n const menu = useMenu('ContextMenuContent');\n const position = usePosition();\n const panelRef = useRef<HTMLDivElement | null>(null);\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n\n menu.resetIndices();\n\n useOverlayDismiss({\n onDismiss: () => menu.setOpen(false),\n panelRef,\n active: menu.open,\n trapFocus: false,\n lockScroll: false,\n inertBackground: false,\n autoFocus: false,\n });\n\n const wasOpen = useRef(false);\n useEffect(() => {\n if (menu.open && panelNode && !wasOpen.current) {\n menu.roving.moveToEdge(menu.pendingEdge.current);\n wasOpen.current = true;\n }\n if (!menu.open) wasOpen.current = false;\n }, [menu.open, panelNode, menu.roving, menu.pendingEdge]);\n\n // Flip about the pointer when the menu would overflow, which is what every native context\n // menu does. Measured after mount, so the first paint may be one frame off-edge in the\n // rare case the menu is taller than the viewport.\n const [offset, setOffset] = useState({ dx: 0, dy: 0 });\n useEffect(() => {\n if (!panelNode || !position.point) return;\n const rect = panelNode.getBoundingClientRect();\n const overflowX = position.point.x + rect.width + collisionPadding - window.innerWidth;\n const overflowY = position.point.y + rect.height + collisionPadding - window.innerHeight;\n setOffset({\n dx: overflowX > 0 ? -Math.min(rect.width, overflowX) : 0,\n dy: overflowY > 0 ? -Math.min(rect.height, overflowY) : 0,\n });\n }, [panelNode, position.point, collisionPadding]);\n\n if (!menu.open || !position.point) return null;\n\n return (\n <Portal>\n <div\n ref={composeRefs<HTMLDivElement>(panelRef, (node) => setPanelNode(node))}\n id={menu.menuId}\n role=\"menu\"\n tabIndex={-1}\n aria-orientation=\"vertical\"\n style={{\n position: 'fixed',\n left: position.point.x + offset.dx,\n top: position.point.y + offset.dy,\n }}\n className={clsx('z-popover', MENU_PANEL_CLASSES, className)}\n {...menu.roving.containerProps}\n onKeyDown={(event) => {\n menu.roving.containerProps.onKeyDown(event);\n if (event.key === 'Tab') menu.setOpen(false);\n }}\n {...rest}\n >\n {children}\n </div>\n </Portal>\n );\n}\n\nexport {\n MenuItem as ContextMenuItem,\n MenuCheckboxItem as ContextMenuCheckboxItem,\n MenuRadioGroup as ContextMenuRadioGroup,\n MenuRadioItem as ContextMenuRadioItem,\n MenuGroup as ContextMenuGroup,\n MenuLabel as ContextMenuLabel,\n MenuSeparator as ContextMenuSeparator,\n MenuShortcut as ContextMenuShortcut,\n} from './menu-core';\n","import {\n createContext,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuCheck } from 'react-icons/lu';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n OVERLAY_PANEL_MENU,\n OVERLAY_SEPARATOR,\n overlayItemTone,\n type OverlayItemTone,\n} from './menu-styles';\n\n/**\n * The shared machinery behind `DropdownMenu`, `ContextMenu` and `Menubar`.\n *\n * All three are the same WAI-ARIA menu: identical items, identical keyboard contract,\n * identical ARIA. Only how they *open* differs — a trigger button, a right-click at pointer\n * coordinates, or a horizontal bar of triggers. Extracted in 0.4.0 so there is one\n * implementation of the contract rather than three; the version this library shipped\n * through 0.3.0 implemented it zero times, and copying that mistake three ways would have\n * been worse than copying it once.\n *\n * Roots build their context with `useMenuState()` and provide it; items read it and need to\n * know nothing about which kind of menu they are in.\n */\n\nexport interface MenuContextValue {\n open: boolean;\n setOpen: (open: boolean) => void;\n menuId: string;\n triggerId: string;\n /** Items claim a roving index in render order, which is their visual order. */\n claimIndex: () => number;\n /** Called by the panel before its children render, so indices restart from zero. */\n resetIndices: () => void;\n /**\n * Which end of the list to land on when the menu opens. ArrowUp on a trigger means \"last\n * item\", per the APG. A ref handoff rather than the trigger focusing directly: the panel\n * does not exist yet when the trigger handles the key, and `Portal` adds a further commit\n * before the items mount.\n */\n pendingEdge: { current: 'start' | 'end' };\n roving: ReturnType<typeof useRovingFocus>;\n}\n\nexport const MenuContext = createContext<MenuContextValue | null>(null);\n\nexport function useMenu(part: string): MenuContextValue {\n const context = useContext(MenuContext);\n if (!context) {\n throw new Error(`<${part}> must be used inside a menu root (DropdownMenu, ContextMenu, Menubar)`);\n }\n return context;\n}\n\nexport interface UseMenuStateOptions {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\n/** Builds the context value a menu root provides. */\nexport function useMenuState({ open, setOpen }: UseMenuStateOptions): MenuContextValue {\n const baseId = useId();\n const cursor = useRef(0);\n const pendingEdge = useRef<'start' | 'end'>('start');\n\n const roving = useRovingFocus({\n orientation: 'vertical',\n loop: true,\n typeahead: true,\n onEscape: () => setOpen(false),\n });\n\n const claimIndex = useCallback(() => cursor.current++, []);\n const resetIndices = useCallback(() => {\n cursor.current = 0;\n }, []);\n\n return useMemo(\n () => ({\n open,\n setOpen,\n menuId: `${baseId}-menu`,\n triggerId: `${baseId}-trigger`,\n claimIndex,\n resetIndices,\n pendingEdge,\n roving,\n }),\n [open, setOpen, baseId, claimIndex, resetIndices, roving],\n );\n}\n\n/**\n * Panel chrome, shared so the three menus cannot drift apart visually.\n *\n * Now an alias of the library-wide `OVERLAY_PANEL_MENU` — the same chrome backs the\n * Combobox, Command and Select lists. See `menu-styles.ts` for why menus adopted the\n * inset `p-1` panel rather than the other three adopting `py-1`.\n */\nexport const MENU_PANEL_CLASSES = OVERLAY_PANEL_MENU;\n\nconst ITEM_BASE = clsx(OVERLAY_ITEM_BASE, OVERLAY_ITEM_SIZE.md);\n\nexport type MenuItemTone = OverlayItemTone;\n\nconst itemToneClasses = overlayItemTone;\n\n// ── Item ───────────────────────────────────────────────────────────────────────\n\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n children: ReactNode;\n onSelect?: () => void;\n tone?: MenuItemTone;\n disabled?: boolean;\n /** Leading glyph. Marked decorative automatically. Matches Figma's `Icon` / `Has Icon`. */\n icon?: ReactNode;\n /** Second line. Matches Figma's `Description` / `Has Description`. */\n description?: ReactNode;\n /** Trailing shortcut hint. Matches Figma's `Shortcut` / `Has Shortcut`. */\n shortcut?: ReactNode;\n /** Typeahead match text, when `children` is not a plain string. */\n textValue?: string;\n}\n\nexport function MenuItem({\n children,\n onSelect,\n tone = 'default',\n disabled = false,\n icon,\n description,\n shortcut,\n textValue,\n className,\n ...rest\n}: MenuItemProps) {\n const menu = useMenu('MenuItem');\n const index = menu.claimIndex();\n const descriptionId = `${menu.menuId}-desc-${index}`;\n\n const label = textValue ?? (typeof children === 'string' ? children : undefined);\n const itemProps = menu.roving.itemProps(index, { disabled, label });\n\n const activate = () => {\n if (disabled) return;\n menu.setOpen(false);\n onSelect?.();\n };\n\n return (\n <div\n // `role=\"menuitem\"` on a div rather than a <button>: the roving tabindex owns\n // focusability, and a native button would re-enter the tab sequence.\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n aria-describedby={description ? descriptionId : undefined}\n {...itemProps}\n // Restated after the spread so jsx-a11y can see it — it cannot follow a tabIndex\n // that arrives through an object spread.\n tabIndex={itemProps.tabIndex}\n className={clsx(ITEM_BASE, itemToneClasses(tone, disabled), className)}\n onClick={(event) => {\n event.stopPropagation();\n activate();\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n activate();\n }\n }}\n {...rest}\n >\n {icon && (\n <span aria-hidden className=\"mt-0.5 flex size-4 shrink-0 items-center justify-center\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{children}</span>\n {description && (\n <span id={descriptionId} className=\"mt-0.5 block text-body-tiny text-default-secondary\">\n {description}\n </span>\n )}\n </span>\n {shortcut && (\n <span className=\"ml-auto shrink-0 pl-4 text-body-tiny text-default-tertiary\">\n {shortcut}\n </span>\n )}\n </div>\n );\n}\n\n// ── CheckboxItem ───────────────────────────────────────────────────────────────\n\nexport interface MenuCheckboxItemProps extends Omit<MenuItemProps, 'onSelect' | 'icon'> {\n checked: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nexport function MenuCheckboxItem({\n children,\n checked,\n onCheckedChange,\n disabled = false,\n tone = 'default',\n shortcut,\n textValue,\n className,\n ...rest\n}: MenuCheckboxItemProps) {\n const menu = useMenu('MenuCheckboxItem');\n const index = menu.claimIndex();\n const label = textValue ?? (typeof children === 'string' ? children : undefined);\n const itemProps = menu.roving.itemProps(index, { disabled, label });\n\n const toggle = () => {\n if (disabled) return;\n onCheckedChange?.(!checked);\n // Deliberately stays open — a checkbox item is for multi-select, and closing after each\n // toggle would make selecting three things take three round trips.\n };\n\n return (\n <div\n role=\"menuitemcheckbox\"\n aria-checked={checked}\n aria-disabled={disabled || undefined}\n {...itemProps}\n tabIndex={itemProps.tabIndex}\n className={clsx(ITEM_BASE, 'items-center', itemToneClasses(tone, disabled), className)}\n onClick={(event) => {\n event.stopPropagation();\n toggle();\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n toggle();\n }\n }}\n {...rest}\n >\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n {checked && <LuCheck className=\"size-3.5\" strokeWidth={3} />}\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n {shortcut && (\n <span className=\"ml-auto shrink-0 pl-4 text-body-tiny text-default-tertiary\">\n {shortcut}\n </span>\n )}\n </div>\n );\n}\n\n// ── RadioGroup / RadioItem ─────────────────────────────────────────────────────\n\ninterface MenuRadioContextValue {\n value: string | undefined;\n onValueChange?: (value: string) => void;\n}\n\nconst MenuRadioContext = createContext<MenuRadioContextValue | null>(null);\n\nexport interface MenuRadioGroupProps {\n children: ReactNode;\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nexport function MenuRadioGroup({ children, value, onValueChange }: MenuRadioGroupProps) {\n const context = useMemo(() => ({ value, onValueChange }), [value, onValueChange]);\n return (\n <MenuRadioContext.Provider value={context}>\n <div role=\"group\">{children}</div>\n </MenuRadioContext.Provider>\n );\n}\n\nexport interface MenuRadioItemProps extends Omit<MenuItemProps, 'onSelect' | 'icon'> {\n value: string;\n}\n\nexport function MenuRadioItem({\n children,\n value,\n disabled = false,\n tone = 'default',\n textValue,\n className,\n ...rest\n}: MenuRadioItemProps) {\n const menu = useMenu('MenuRadioItem');\n const group = useContext(MenuRadioContext);\n const index = menu.claimIndex();\n const label = textValue ?? (typeof children === 'string' ? children : undefined);\n const itemProps = menu.roving.itemProps(index, { disabled, label });\n\n const checked = group?.value === value;\n\n const select = () => {\n if (disabled) return;\n group?.onValueChange?.(value);\n menu.setOpen(false);\n };\n\n return (\n <div\n role=\"menuitemradio\"\n aria-checked={checked}\n aria-disabled={disabled || undefined}\n {...itemProps}\n tabIndex={itemProps.tabIndex}\n className={clsx(ITEM_BASE, 'items-center', itemToneClasses(tone, disabled), className)}\n onClick={(event) => {\n event.stopPropagation();\n select();\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n select();\n }\n }}\n {...rest}\n >\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n {checked && <span className=\"size-1.5 rounded-full bg-current\" />}\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n </div>\n );\n}\n\n// ── Structure ──────────────────────────────────────────────────────────────────\n\nconst HEADING_CLASSES = OVERLAY_HEADING;\n\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Names the group. Rendered as a heading when set. */\n label?: string;\n}\n\nexport function MenuGroup({ children, label, className, ...rest }: MenuGroupProps) {\n const labelId = useId();\n return (\n <div role=\"group\" aria-labelledby={label ? labelId : undefined} className={className} {...rest}>\n {label && (\n <div id={labelId} className={HEADING_CLASSES}>\n {label}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nexport interface MenuLabelProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** A non-interactive heading inside the menu. Matches Figma's `Menu Heading`. */\nexport function MenuLabel({ children, className, ...rest }: MenuLabelProps) {\n return (\n <div className={clsx(HEADING_CLASSES, className)} {...rest}>\n {children}\n </div>\n );\n}\n\nexport interface MenuSeparatorProps extends HTMLAttributes<HTMLDivElement> {}\n\n/** Matches Figma's `Menu Separator`. Was a bare unlabelled `div` before 0.4.0. */\nexport function MenuSeparator({ className, ...rest }: MenuSeparatorProps) {\n return (\n <div\n role=\"separator\"\n aria-orientation=\"horizontal\"\n className={clsx(OVERLAY_SEPARATOR, className)}\n {...rest}\n />\n );\n}\n\nexport interface MenuShortcutProps extends HTMLAttributes<HTMLSpanElement> {\n children: ReactNode;\n}\n\n/** Trailing keyboard hint, for use outside an item's `shortcut` prop. */\nexport function MenuShortcut({ children, className, ...rest }: MenuShortcutProps) {\n return (\n <span\n className={clsx('ml-auto pl-4 text-body-tiny text-default-tertiary', className)}\n {...rest}\n >\n {children}\n </span>\n );\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\n\nimport { composeRefs } from '../../lib/slot';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useFloatingPanel } from './floating';\nimport { MENU_PANEL_CLASSES, MenuContext, useMenu, useMenuState } from './menu-core';\nimport { useOverlayDismiss } from './overlay';\nimport { Portal } from './portal';\n\ninterface MenubarContextValue {\n /** Which top-level menu is open, by value. `null` when none is. */\n openValue: string | null;\n setOpenValue: (value: string | null) => void;\n claimMenuIndex: () => number;\n resetMenuIndices: () => void;\n barRoving: ReturnType<typeof useRovingFocus>;\n baseId: string;\n}\n\nconst MenubarContext = createContext<MenubarContextValue | null>(null);\n\nfunction useMenubar(part: string): MenubarContextValue {\n const value = useContext(MenubarContext);\n if (!value) throw new Error(`<${part}> must be used inside <Menubar>`);\n return value;\n}\n\nexport interface MenubarProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Names the menubar. Required by the APG. */\n label: string;\n}\n\n/**\n * An application menu bar — a horizontal row of menus, as in a desktop app.\n *\n * Two things distinguish it from a row of `DropdownMenu`s, and both are in the APG:\n *\n * - **The bar is one tab stop.** Left/Right move between the top-level menus; Tab leaves the\n * bar entirely. A row of independent dropdowns is N tab stops.\n * - **Only one menu is open at a time**, and once any is open, moving along the bar switches\n * directly to the next menu rather than closing and reopening.\n *\n * Items and the vertical keyboard contract come from `menu-core`, shared with\n * `DropdownMenu` and `ContextMenu`.\n */\nexport function Menubar({ children, label, className, ...rest }: MenubarProps) {\n const baseId = useId();\n const [openValue, setOpenValue] = useState<string | null>(null);\n const cursor = useRef(0);\n\n const barRoving = useRovingFocus({\n orientation: 'horizontal',\n loop: true,\n onEscape: () => setOpenValue(null),\n });\n\n const context = useMemo<MenubarContextValue>(\n () => ({\n openValue,\n setOpenValue,\n claimMenuIndex: () => cursor.current++,\n resetMenuIndices: () => {\n cursor.current = 0;\n },\n barRoving,\n baseId,\n }),\n [openValue, barRoving, baseId],\n );\n\n context.resetMenuIndices();\n\n return (\n <MenubarContext.Provider value={context}>\n <div\n role=\"menubar\"\n aria-label={label}\n aria-orientation=\"horizontal\"\n data-slot=\"menubar\"\n className={clsx('flex items-center gap-0.5', className)}\n // Deliberately no `onBlur` close. `MenubarContent` is portaled, so focus moving into\n // an open menu leaves the bar's subtree — a containment check here closed the menu\n // the instant it opened. Dismissal is handled where it can see both the bar and the\n // panel: Escape via the roving hook, outside-press via `useOverlayDismiss`.\n {...barRoving.containerProps}\n {...rest}\n >\n {children}\n </div>\n </MenubarContext.Provider>\n );\n}\n\nexport interface MenubarMenuProps {\n children: ReactNode;\n /** Identifies this menu within the bar. */\n value: string;\n}\n\n/** One menu in the bar. Wraps a `MenubarTrigger` and a `MenubarContent`. */\nexport function MenubarMenu({ children, value }: MenubarMenuProps) {\n const bar = useMenubar('MenubarMenu');\n const index = bar.claimMenuIndex();\n\n const open = bar.openValue === value;\n const menu = useMenuState({\n open,\n setOpen: (next) => bar.setOpenValue(next ? value : null),\n });\n\n const scope = useMemo(() => ({ value, index }), [value, index]);\n\n return (\n <MenuContext.Provider value={menu}>\n <MenubarMenuScope.Provider value={scope}>{children}</MenubarMenuScope.Provider>\n </MenuContext.Provider>\n );\n}\n\nconst MenubarMenuScope = createContext<{ value: string; index: number } | null>(null);\n\nfunction useMenubarMenu(part: string) {\n const value = useContext(MenubarMenuScope);\n if (!value) throw new Error(`<${part}> must be used inside <MenubarMenu>`);\n return value;\n}\n\nexport interface MenubarTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n}\n\nexport function MenubarTrigger({ children, className, ...rest }: MenubarTriggerProps) {\n const bar = useMenubar('MenubarTrigger');\n const menu = useMenu('MenubarTrigger');\n const scope = useMenubarMenu('MenubarTrigger');\n const [node, setNode] = useState<HTMLButtonElement | null>(null);\n\n // The roving hook supplies its own `ref`, so it has to be composed with the local one\n // rather than spread — a second `ref` in the JSX silently wins and the trigger never\n // registers.\n const { ref: rovingRef, ...itemProps } = bar.barRoving.itemProps(scope.index, {\n label: typeof children === 'string' ? children : undefined,\n });\n\n // Registered so `MenubarContent` can anchor to it.\n useEffect(() => {\n triggerNodes.set(scope.value, node);\n return () => {\n triggerNodes.delete(scope.value);\n };\n }, [scope.value, node]);\n\n return (\n <button\n ref={composeRefs<HTMLButtonElement>(setNode, rovingRef)}\n type=\"button\"\n role=\"menuitem\"\n id={menu.triggerId}\n aria-haspopup=\"menu\"\n aria-expanded={menu.open}\n aria-controls={menu.open ? menu.menuId : undefined}\n {...itemProps}\n tabIndex={itemProps.tabIndex}\n onClick={() => menu.setOpen(!menu.open)}\n onFocus={() => {\n itemProps.onFocus();\n // Arrowing along the bar with a menu already open switches directly to this one.\n if (bar.openValue !== null && bar.openValue !== scope.value) {\n bar.setOpenValue(scope.value);\n }\n }}\n onPointerEnter={() => {\n if (bar.openValue !== null) bar.setOpenValue(scope.value);\n }}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n menu.pendingEdge.current = event.key === 'ArrowUp' ? 'end' : 'start';\n menu.setOpen(true);\n }\n }}\n className={clsx(\n 'rounded-md px-2.5 py-1.5 text-body-sm text-default transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n menu.open ? 'bg-default-secondary' : 'hover:bg-default-secondary',\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n );\n}\n\n/** Module-level so `MenubarContent` can find its trigger without another context layer. */\nconst triggerNodes = new Map<string, HTMLElement | null>();\n\nexport interface MenubarContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function MenubarContent({ children, className, ...rest }: MenubarContentProps) {\n const bar = useMenubar('MenubarContent');\n const menu = useMenu('MenubarContent');\n const scope = useMenubarMenu('MenubarContent');\n const panelRef = useRef<HTMLDivElement | null>(null);\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n\n menu.resetIndices();\n\n // Where focus lands when this panel closes. `useOverlayDismiss` reads it at unmount, so\n // it has to be the value from the render that *caused* the close — which is why it is a\n // ref written during render rather than state.\n //\n // Closing the bar outright — an item selected, Escape, a press outside — returns focus\n // to this menu's trigger, per the APG. Switching to a sibling menu must not: the\n // sibling's trigger already has focus, and pulling it back here fires this trigger's\n // `onFocus`, which reopens this menu and closes the one the user just moved to. That is\n // the whole \"only one menu is open at a time\" contract inverting itself, and it fired on\n // every route into a sibling — arrow keys, hover and click alike.\n const returnFocus = useRef<HTMLElement | null>(null);\n returnFocus.current = bar.openValue === null ? (triggerNodes.get(scope.value) ?? null) : null;\n\n const { refs, floatingStyles } = useFloatingPanel({\n open: menu.open,\n onOpenChange: menu.setOpen,\n side: 'bottom',\n align: 'start',\n sideOffset: 4,\n });\n\n useEffect(() => {\n refs.setReference(triggerNodes.get(scope.value) ?? null);\n }, [refs, scope.value, menu.open]);\n\n useOverlayDismiss({\n onDismiss: () => menu.setOpen(false),\n panelRef,\n active: menu.open,\n trapFocus: false,\n lockScroll: false,\n inertBackground: false,\n autoFocus: false,\n returnFocus,\n });\n\n const wasOpen = useRef(false);\n useEffect(() => {\n if (menu.open && panelNode && !wasOpen.current) {\n menu.roving.moveToEdge(menu.pendingEdge.current);\n menu.pendingEdge.current = 'start';\n wasOpen.current = true;\n }\n if (!menu.open) wasOpen.current = false;\n }, [menu.open, panelNode, menu.roving, menu.pendingEdge]);\n\n if (!menu.open) return null;\n\n return (\n <Portal>\n <div\n ref={composeRefs<HTMLDivElement>(panelRef, (node) => setPanelNode(node), refs.setFloating)}\n id={menu.menuId}\n role=\"menu\"\n tabIndex={-1}\n aria-orientation=\"vertical\"\n aria-labelledby={menu.triggerId}\n style={floatingStyles}\n className={clsx('z-popover', MENU_PANEL_CLASSES, className)}\n {...menu.roving.containerProps}\n onKeyDown={(event) => {\n menu.roving.containerProps.onKeyDown(event);\n // Left/Right inside an open menu move along the bar, per the APG.\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n event.preventDefault();\n const trigger = triggerNodes.get(scope.value);\n trigger?.focus();\n // Re-dispatch on the bar so its horizontal roving handles the move.\n trigger?.dispatchEvent(\n new KeyboardEvent('keydown', { key: event.key, bubbles: true }),\n );\n }\n if (event.key === 'Tab') menu.setOpen(false);\n }}\n {...rest}\n >\n {children}\n </div>\n </Portal>\n );\n}\n\nexport {\n MenuItem as MenubarItem,\n MenuCheckboxItem as MenubarCheckboxItem,\n MenuRadioGroup as MenubarRadioGroup,\n MenuRadioItem as MenubarRadioItem,\n MenuGroup as MenubarGroup,\n MenuLabel as MenubarLabel,\n MenuSeparator as MenubarSeparator,\n MenuShortcut as MenubarShortcut,\n} from './menu-core';\n","import { useRef, type ReactNode, type RefObject } from 'react';\nimport clsx from 'clsx';\nimport { LuX } from 'react-icons/lu';\n\nimport { ScrollArea } from '../cards/scroll-area';\nimport { IconButton } from '../forms/icon-button';\nimport { OVERLAY_SCRIM, useOverlayDismiss } from './overlay';\nimport { Portal } from './portal';\n\nexport type DrawerSide = 'right' | 'left';\n\nexport interface DrawerProps {\n open: boolean;\n /** Fired with `false` on Escape, an outside press, or the close button. */\n onOpenChange: (open: boolean) => void;\n /** Header content (left side). The copies this replaces differ only here — a status badge +\n * title in one, an avatar + title + category in another — so it is a slot, not props. */\n header: ReactNode;\n children: ReactNode;\n footer?: ReactNode;\n /** `between` when the footer has a left-aligned secondary action. */\n footerAlign?: 'end' | 'between';\n /** Panel width. Defaults to the `w-[440px] max-w-[90vw]` shared by every existing drawer. */\n width?: string;\n /** Which edge the panel slides in from. Default `right`. */\n side?: DrawerSide;\n /**\n * Accessible name for the dialog. **Required** as of 0.4.0.\n *\n * It was optional through 0.3.0 while `Modal.label` was required, which meant the\n * public API allowed a `role=\"dialog\" aria-modal=\"true\"` element with no accessible\n * name at all — a screen reader announced \"dialog\" and nothing else. Unlike `Modal`\n * there is no `DrawerTitle` part to infer a name from, because `header` is a free\n * slot, so the string is the only place it can come from.\n */\n label: string;\n className?: string;\n /** Call `preventDefault()` to keep the drawer open — e.g. unsaved input. */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** Call `preventDefault()` to keep the drawer open. */\n onInteractOutside?: (event: PointerEvent) => void;\n /** Focus this on open instead of the first tabbable element. */\n initialFocus?: RefObject<HTMLElement | null>;\n}\n\n/**\n * Side panel. Handles Esc, traps Tab focus, locks background scroll, marks the rest of\n * the page inert, and restores focus to the trigger on close.\n */\nexport function Drawer(props: DrawerProps) {\n if (!props.open) return null;\n return (\n <Portal>\n <DrawerShell {...props} />\n </Portal>\n );\n}\n\n/**\n * Split out for the same reason as `ModalShell`: the Esc handler and the focus trap\n * must not stay mounted behind a closed drawer, which is what would happen if\n * `useOverlayDismiss` ran above the `open` early exit.\n */\nfunction DrawerShell({\n onOpenChange,\n header,\n children,\n footer,\n footerAlign = 'end',\n width = 'w-[440px] max-w-[90vw]',\n side = 'right',\n label,\n className,\n onEscapeKeyDown,\n onInteractOutside,\n initialFocus,\n}: Omit<DrawerProps, 'open'>) {\n const panelRef = useRef<HTMLElement | null>(null);\n\n useOverlayDismiss({\n onDismiss: () => onOpenChange(false),\n panelRef,\n initialFocus,\n onEscapeKeyDown,\n onInteractOutside,\n });\n\n return (\n <div\n className={clsx(\n 'fixed inset-0 z-overlay flex',\n side === 'right' ? 'justify-end' : 'justify-start',\n OVERLAY_SCRIM,\n )}\n >\n <aside\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={label}\n className={clsx('relative flex h-full flex-col bg-default shadow-500', width, className)}\n >\n <div className=\"flex items-start justify-between gap-3 border-b border-default p-6\">\n <div className=\"min-w-0\">{header}</div>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Close\"\n onClick={() => onOpenChange(false)}\n >\n <LuX size={18} aria-hidden />\n </IconButton>\n </div>\n\n <ScrollArea axis=\"vertical\" label={label} className=\"min-h-0 flex-1\">\n <div className=\"space-y-6 p-6\">{children}</div>\n </ScrollArea>\n\n {footer && (\n <div\n className={clsx(\n 'flex items-center gap-2 border-t border-default px-6 py-4',\n footerAlign === 'between' ? 'justify-between' : 'justify-end',\n )}\n >\n {footer}\n </div>\n )}\n </aside>\n </div>\n );\n}\n","import { forwardRef, useEffect, useRef, useState, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { composeRefs } from '../../lib/slot';\n\nexport type ScrollAreaAxis = 'vertical' | 'horizontal' | 'both';\n\nexport interface ScrollAreaProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n axis?: ScrollAreaAxis;\n /**\n * Accessible name for the scrollable region. Strongly recommended — a scroll container\n * that becomes focusable (see below) needs to announce what it is.\n */\n label?: string;\n}\n\nconst OVERFLOW: Record<ScrollAreaAxis, string> = {\n vertical: 'overflow-y-auto overflow-x-hidden',\n horizontal: 'overflow-x-auto overflow-y-hidden',\n both: 'overflow-auto',\n};\n\nexport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\n/**\n * A scrollable region with styled scrollbars.\n *\n * **Native scrolling, deliberately.** shadcn/Radix replaces the scrollbar with a rendered\n * one, which looks tidier and costs real accessibility: an overlay scrollbar has to\n * reimplement keyboard scrolling, momentum, trackpad and pen behaviour, and the OS\n * \"click the track to page\" convention — and it drops out entirely if the JS fails. Styling\n * `::-webkit-scrollbar` plus `scrollbar-width`/`scrollbar-color` gets most of the look with\n * none of that risk, and degrades to a normal scrollbar where unsupported.\n *\n * The one thing this *does* add is the piece browsers get wrong: a scroll container is not\n * keyboard focusable by default in Chrome or Safari, so a keyboard-only user cannot scroll\n * an overflowing `<div>` at all unless something inside it is focusable. This measures its\n * own content and sets `tabIndex={0}` only while it actually overflows, so the region is\n * scrollable with the arrow keys without adding a pointless tab stop when it does not.\n */\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(function ScrollArea(\n { children, axis = 'vertical', label, className, ...rest },\n ref,\n) {\n const localRef = useRef<HTMLDivElement>(null);\n const [overflows, setOverflows] = useState(false);\n\n useEffect(() => {\n const node = localRef.current;\n if (!node) return;\n\n const measure = () => {\n const vertical = node.scrollHeight > node.clientHeight + 1;\n const horizontal = node.scrollWidth > node.clientWidth + 1;\n setOverflows(\n axis === 'vertical' ? vertical : axis === 'horizontal' ? horizontal : vertical || horizontal,\n );\n };\n\n measure();\n\n // Feature-detected: `ResizeObserver` is absent in jsdom, in Safari before 13.1, and\n // during any server render, and an unguarded `new ResizeObserver` throws outright. The\n // measurement above has already run, so without the observer the tab stop is simply\n // decided once at mount rather than tracked — degraded, not broken.\n if (typeof ResizeObserver === 'undefined') return;\n\n // Content and box size both matter, so both are observed. On the element it catches the\n // box; on the first child it catches content growth.\n const observer = new ResizeObserver(measure);\n observer.observe(node);\n if (node.firstElementChild) observer.observe(node.firstElementChild);\n return () => observer.disconnect();\n }, [axis, children]);\n\n return (\n <div\n ref={composeRefs<HTMLDivElement>(localRef, ref)}\n // `role=\"region\"` only once it is focusable and named, so an ordinary non-overflowing\n // wrapper does not add a landmark to the page for nothing.\n role={overflows && label ? 'region' : undefined}\n aria-label={overflows ? label : undefined}\n tabIndex={overflows ? 0 : undefined}\n data-slot=\"scroll-area\"\n className={clsx(\n OVERFLOW[axis],\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n SCROLLBAR_CLASSES,\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n});\n","import type { ReactNode } from 'react';\n\nimport { Button } from '../forms/button';\nimport { Modal, ModalBody, ModalDescription, ModalFooter, ModalHeader, ModalTitle } from './modal';\nimport type { ModalSize, ModalTone } from './modal';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n title: string;\n subtitle?: string;\n /**\n * Adds a tinted glyph to the header. Defaults to `default` (no glyph) so existing\n * call sites look unchanged; opt in per dialog rather than deriving it from\n * `confirmVariant`, which would silently restyle every destructive confirm.\n */\n tone?: ModalTone;\n size?: ModalSize;\n confirmLabel?: string;\n cancelLabel?: string;\n confirmVariant?: 'primary' | 'danger';\n /** Disables the confirm button and swaps its label — the double-submit guard. */\n isConfirming?: boolean;\n /** Label shown on the confirm button while `isConfirming`. */\n confirmingLabel?: string;\n /** Optional body — a warning callout, a consequences list, or a failed-attempt error. */\n children?: ReactNode;\n className?: string;\n onConfirm: () => void;\n /** Fired with `false` on cancel, Escape, or an outside press. */\n onOpenChange: (open: boolean) => void;\n}\n\n/**\n * The in-app replacement for `window.confirm`: a title, an optional body, and a\n * cancel/confirm pair.\n *\n * Kept as a preset rather than folded into `Modal` because it carries *behaviour*, not\n * just layout — the `isConfirming` guard that disables the button and swaps its label\n * is the thing call sites get wrong when they hand-roll a confirm. For any other\n * shape, compose `Modal` and its parts directly.\n */\nexport function ConfirmDialog({\n open,\n title,\n subtitle,\n tone = 'default',\n size = 'md',\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n confirmVariant = 'primary',\n isConfirming = false,\n confirmingLabel = 'Working…',\n children,\n className,\n onConfirm,\n onOpenChange,\n}: ConfirmDialogProps) {\n return (\n // `alertdialog`, not `dialog`: this interrupts to ask a yes/no question, so the body\n // should be announced on open rather than waiting to be browsed to. The name comes\n // from `ModalTitle` via `aria-labelledby`, so there is no `label` to keep in sync.\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n role=\"alertdialog\"\n size={size}\n className={className}\n >\n <ModalHeader tone={tone} divider={Boolean(children)}>\n <ModalTitle>{title}</ModalTitle>\n {subtitle && <ModalDescription>{subtitle}</ModalDescription>}\n </ModalHeader>\n {/* Guarded: 0.2.0 always rendered a body, so a childless confirm carried 40px of\n dead space plus a stray rule. */}\n {children && <ModalBody>{children}</ModalBody>}\n <ModalFooter>\n <Button variant=\"neutral\" size=\"md\" onClick={() => onOpenChange(false)}>\n {cancelLabel}\n </Button>\n <Button variant={confirmVariant} size=\"md\" disabled={isConfirming} onClick={onConfirm}>\n {isConfirming ? confirmingLabel : confirmLabel}\n </Button>\n </ModalFooter>\n </Modal>\n );\n}\n","import { useState } from 'react';\n\nimport { Button } from '../forms/button';\nimport { Textarea } from '../forms/textarea';\nimport { Modal, ModalBody, ModalDescription, ModalFooter, ModalHeader, ModalTitle } from './modal';\nimport type { ModalSize, ModalTone } from './modal';\n\nexport interface NoteConfirmModalProps {\n open: boolean;\n title: string;\n subtitle?: string;\n tone?: ModalTone;\n size?: ModalSize;\n confirmLabel: string;\n cancelLabel?: string;\n confirmVariant?: 'primary' | 'danger';\n /** Block confirmation until the note has content. */\n requireNote?: boolean;\n notePlaceholder?: string;\n submittingLabel?: string;\n isSubmitting?: boolean;\n className?: string;\n /** Fired with `false` on cancel, Escape, or an outside press. */\n onOpenChange: (open: boolean) => void;\n onConfirm: (note: string) => void;\n /**\n * Asked before an Escape or outside press throws away a note that has content.\n * Return `false` to keep the dialog open. Defaults to `window.confirm`.\n */\n onDiscardNote?: (note: string) => boolean;\n}\n\n/**\n * Confirm dialog that collects a free-text note — approvals, rejections, information\n * requests. The note is trimmed before it reaches `onConfirm`.\n *\n * Kept as a preset because it owns state, and a composition cannot.\n */\nexport function NoteConfirmModal({ open, ...rest }: NoteConfirmModalProps) {\n // The shell split is what resets the note. Before 0.3.0 this component had no `open`\n // prop and callers mounted it conditionally, so the typed note was discarded for free.\n // Now that it stays mounted, unmounting the shell is what clears it — otherwise a\n // rejection note would reappear the next time the dialog opened.\n if (!open) return null;\n return <NoteConfirmModalShell {...rest} />;\n}\n\nfunction NoteConfirmModalShell({\n title,\n subtitle,\n tone = 'default',\n size = 'md',\n confirmLabel,\n cancelLabel = 'Cancel',\n confirmVariant = 'primary',\n requireNote = false,\n notePlaceholder = 'Add a note…',\n submittingLabel = 'Saving…',\n isSubmitting = false,\n className,\n onOpenChange,\n onConfirm,\n onDiscardNote,\n}: Omit<NoteConfirmModalProps, 'open'>) {\n const [note, setNote] = useState('');\n const disabled = isSubmitting || (requireNote && !note.trim());\n\n /**\n * Escape and an outside press both unmount the shell, which is what clears the note —\n * so before 0.4.0 either one silently destroyed whatever the user had typed, with no\n * warning and no undo. On a rejection-reason dialog that is real work lost.\n */\n const guardDiscard = (event: { preventDefault: () => void }) => {\n if (!note.trim()) return;\n const confirmed = onDiscardNote\n ? onDiscardNote(note)\n : typeof window !== 'undefined' &&\n window.confirm('Discard your note? It will not be saved.');\n if (!confirmed) event.preventDefault();\n };\n\n return (\n <Modal\n open\n onOpenChange={onOpenChange}\n size={size}\n className={className}\n onEscapeKeyDown={guardDiscard}\n onInteractOutside={guardDiscard}\n >\n <ModalHeader tone={tone}>\n <ModalTitle>{title}</ModalTitle>\n {subtitle && <ModalDescription>{subtitle}</ModalDescription>}\n </ModalHeader>\n <ModalBody>\n <Textarea\n value={note}\n onChange={(e) => setNote(e.target.value)}\n placeholder={notePlaceholder}\n rows={4}\n />\n </ModalBody>\n <ModalFooter>\n <Button variant=\"neutral\" size=\"md\" onClick={() => onOpenChange(false)}>\n {cancelLabel}\n </Button>\n <Button variant={confirmVariant} size=\"md\" disabled={disabled} onClick={() => onConfirm(note.trim())}>\n {isSubmitting ? submittingLabel : confirmLabel}\n </Button>\n </ModalFooter>\n </Modal>\n );\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type Ref,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuEllipsis } from 'react-icons/lu';\n\nimport { Slot, composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { IconButton } from '../forms/icon-button';\nimport { useFloatingPanel, type FloatingAlign, type FloatingSide } from './floating';\nimport { MENU_PANEL_CLASSES, MenuContext, useMenu, useMenuState } from './menu-core';\nimport { useOverlayDismiss } from './overlay';\nimport { Portal } from './portal';\n\n/**\n * Overflow / row-actions menu, rebuilt in 0.4.0.\n *\n * The previous version declared `role=\"menu\"` and `role=\"menuitem\"` and implemented none of\n * the WAI-ARIA menu contract. Announcing a pattern you do not implement is worse than\n * announcing nothing, because a screen reader tells the user which keys should work. Fixed:\n * arrow keys, Home/End and typeahead; a roving tabindex (every item used to be a natively\n * tabbable `<button>`, so Tab walked all of them); focus moving into the menu on open and\n * back to the trigger on close; a portal, so the panel is no longer clipped by `Card`'s\n * `overflow-hidden` or `DataTable`'s `overflow-x-auto` — both named in its own doc comment\n * as the reason it exists; collision handling instead of a static `left`/`right`; correct\n * ARIA ownership; and `open`/`onOpenChange`, where open state used to be unreachable.\n *\n * The items and keyboard model now live in `menu-core`, shared with `ContextMenu` and\n * `Menubar`.\n *\n * Not implemented: submenus. Doing them properly needs hover intent and a safe-travel\n * polygon between trigger and panel, and a half-built version is worse than none — nest a\n * second `DropdownMenu` in the meantime.\n */\n\nexport interface DropdownMenuProps {\n children: ReactNode;\n /** Controlled open state. Omit for uncontrolled. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * The trigger element, for Floating UI to measure.\n *\n * Kept out of the shared menu context because only the trigger-anchored menus have one — a\n * `ContextMenu` positions at pointer coordinates and has no trigger element at all.\n */\ninterface TriggerNodeContextValue {\n triggerNode: HTMLElement | null;\n setTriggerNode: (node: HTMLElement | null) => void;\n}\n\nconst TriggerNodeContext = createContext<TriggerNodeContextValue | null>(null);\n\nfunction useTriggerNode(): TriggerNodeContextValue {\n const value = useContext(TriggerNodeContext);\n if (!value) throw new Error('DropdownMenu parts must be used inside <DropdownMenu>');\n return value;\n}\n\nexport function DropdownMenu({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n}: DropdownMenuProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const menu = useMenuState({ open, setOpen });\n // State, not a ref: `DropdownMenuContent` must re-render once the trigger exists so\n // Floating UI can measure it. A ref write would leave the panel positioned at 0,0.\n const [triggerNode, setTriggerNode] = useState<HTMLElement | null>(null);\n const anchor = useMemo(() => ({ triggerNode, setTriggerNode }), [triggerNode]);\n\n return (\n <MenuContext.Provider value={menu}>\n <TriggerNodeContext.Provider value={anchor}>{children}</TriggerNodeContext.Provider>\n </MenuContext.Provider>\n );\n}\n\n// ── Trigger ────────────────────────────────────────────────────────────────────\n\nexport interface DropdownMenuTriggerProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n /** Render the child element instead of the default overflow button. */\n asChild?: boolean;\n /** Accessible name for the default `⋯` button. Ignored when `asChild` is set. */\n label?: string;\n}\n\nexport function DropdownMenuTrigger({\n children,\n asChild = false,\n label = 'Open menu',\n ...rest\n}: DropdownMenuTriggerProps) {\n const menu = useMenu('DropdownMenuTrigger');\n const anchor = useTriggerNode();\n\n const triggerProps = {\n id: menu.triggerId,\n 'aria-haspopup': 'menu' as const,\n 'aria-expanded': menu.open,\n 'aria-controls': menu.open ? menu.menuId : undefined,\n onClick: (event: ReactMouseEvent) => {\n event.stopPropagation();\n menu.setOpen(!menu.open);\n },\n onKeyDown: (event: ReactKeyboardEvent) => {\n // ArrowDown/Up open the menu and land on the near or far end, per the APG.\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n menu.pendingEdge.current = event.key === 'ArrowUp' ? 'end' : 'start';\n menu.setOpen(true);\n }\n },\n // Stopped at the trigger so the menu works inside a clickable table row — the\n // behaviour the 0.2.0 `RowMenu` had and the reason this component exists.\n onMouseDown: (event: ReactMouseEvent) => event.stopPropagation(),\n ...rest,\n };\n\n if (asChild) {\n return (\n <Slot ref={composeRefs(anchor.setTriggerNode)} {...triggerProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <IconButton\n ref={composeRefs(anchor.setTriggerNode) as Ref<HTMLButtonElement>}\n variant=\"neutral\"\n size=\"sm\"\n aria-label={label}\n {...triggerProps}\n >\n {children ?? <LuEllipsis className=\"size-4\" aria-hidden />}\n </IconButton>\n );\n}\n\n// ── Content ────────────────────────────────────────────────────────────────────\n\nexport interface DropdownMenuContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n sideOffset?: number;\n}\n\nexport function DropdownMenuContent({\n children,\n side = 'bottom',\n align = 'end',\n sideOffset = 6,\n className,\n ...rest\n}: DropdownMenuContentProps) {\n const menu = useMenu('DropdownMenuContent');\n const anchor = useTriggerNode();\n const panelRef = useRef<HTMLDivElement | null>(null);\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n\n // Must run before any item's render body, so indices are reassigned from zero on every\n // pass. Content is the direct parent of every item, so its render body is guaranteed to\n // run immediately before theirs.\n menu.resetIndices();\n\n const { refs, floatingStyles } = useFloatingPanel({\n open: menu.open,\n onOpenChange: menu.setOpen,\n side,\n align,\n sideOffset,\n });\n\n // Set in an effect rather than during render: `setReference` mutates Floating UI's\n // internal state, and calling it mid-render breaks under StrictMode double-invocation.\n useEffect(() => {\n refs.setReference(anchor.triggerNode);\n }, [refs, anchor.triggerNode]);\n\n useOverlayDismiss({\n onDismiss: () => menu.setOpen(false),\n panelRef,\n active: menu.open,\n // A menu is not modal: the page behind stays readable and interactive, so none of the\n // dialog-grade side effects apply. Only Escape, outside-press and focus restore.\n trapFocus: false,\n lockScroll: false,\n inertBackground: false,\n // The menu owns its own initial focus below; a generic \"first tabbable element\" scan\n // would fight the roving tabindex, which exposes exactly one item at a time.\n autoFocus: false,\n });\n\n // Keyed on the panel node rather than on `open`: `Portal` gates its children behind a\n // mounted flag for SSR safety, so on the render where the menu opens the items do not\n // exist yet, and an effect watching `open` alone fires against an empty item list.\n const wasOpen = useRef(false);\n useEffect(() => {\n if (menu.open && panelNode && !wasOpen.current) {\n menu.roving.moveToEdge(menu.pendingEdge.current);\n menu.pendingEdge.current = 'start';\n wasOpen.current = true;\n }\n if (!menu.open) wasOpen.current = false;\n }, [menu.open, panelNode, menu.roving, menu.pendingEdge]);\n\n if (!menu.open) return null;\n\n return (\n <Portal>\n <div\n ref={composeRefs<HTMLDivElement>(\n panelRef,\n (node) => setPanelNode(node),\n refs.setFloating,\n )}\n id={menu.menuId}\n role=\"menu\"\n // Programmatically focusable but out of the tab sequence: the fallback focus target\n // for an empty menu, and it keeps key events on the panel.\n tabIndex={-1}\n aria-orientation=\"vertical\"\n aria-labelledby={menu.triggerId}\n style={floatingStyles}\n className={clsx('z-popover', MENU_PANEL_CLASSES, className)}\n {...menu.roving.containerProps}\n onKeyDown={(event) => {\n menu.roving.containerProps.onKeyDown(event);\n // Tab must leave the menu rather than walk it, so it closes first and lets the\n // browser move focus on from the trigger.\n if (event.key === 'Tab') menu.setOpen(false);\n }}\n {...rest}\n >\n {children}\n </div>\n </Portal>\n );\n}\n\n// ── Items, re-exported under the DropdownMenu* names ───────────────────────────\n// The implementations live in `menu-core` and are shared with ContextMenu and Menubar.\n\nexport {\n MenuItem as DropdownMenuItem,\n MenuCheckboxItem as DropdownMenuCheckboxItem,\n MenuRadioGroup as DropdownMenuRadioGroup,\n MenuRadioItem as DropdownMenuRadioItem,\n MenuGroup as DropdownMenuGroup,\n MenuLabel as DropdownMenuLabel,\n MenuSeparator as DropdownMenuSeparator,\n MenuShortcut as DropdownMenuShortcut,\n} from './menu-core';\n\nexport type {\n MenuItemProps as DropdownMenuItemProps,\n MenuItemTone as DropdownMenuItemTone,\n MenuCheckboxItemProps as DropdownMenuCheckboxItemProps,\n MenuRadioGroupProps as DropdownMenuRadioGroupProps,\n MenuRadioItemProps as DropdownMenuRadioItemProps,\n MenuGroupProps as DropdownMenuGroupProps,\n MenuLabelProps as DropdownMenuLabelProps,\n MenuSeparatorProps as DropdownMenuSeparatorProps,\n MenuShortcutProps as DropdownMenuShortcutProps,\n} from './menu-core';\n","import { createContext, useContext, type HTMLAttributes, type ReactNode } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type CardSize = 'sm' | 'md' | 'lg';\nexport type CardRadius = 'lg' | 'xl' | '2xl';\nexport type CardTone = 'default' | 'brand' | 'positive' | 'warning' | 'danger';\nexport type CardFooterAlign = 'start' | 'between' | 'end';\n\nconst RADIUS: Record<CardRadius, string> = {\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n};\n\nconst TONE: Record<CardTone, string> = {\n default: 'border-default bg-default',\n brand: 'border-brand-tertiary bg-brand-tertiary',\n positive: 'border-positive-tertiary bg-positive-tertiary',\n warning: 'border-warning-tertiary bg-warning-tertiary',\n // The one asymmetry: danger keeps the strong `border-danger` rather than the\n // tertiary border, because it is the only tone that has to read as an alarm from\n // across a dashboard. Byte-identical to the deleted AlertCard's danger surface.\n danger: 'border-danger bg-danger-tertiary',\n};\n\n/**\n * Header and footer share one padding ladder, and it now matches `BODY_BOX` on both axes.\n *\n * It used to match horizontally and not vertically — `px-4 py-3` against the body's `p-4` —\n * so a header sat 4px tighter than the body it capped, and stacking a header on a body put\n * two different rhythms in one card. The horizontal inset was already the value that\n * mattered for aligning a title over its content; the vertical one was simply out of step.\n */\nconst BOX: Record<CardSize, string> = {\n sm: 'px-3 py-3',\n md: 'px-4 py-4',\n lg: 'px-5 py-5',\n};\n\nconst BODY_BOX: Record<CardSize, string> = {\n sm: 'gap-3 p-3',\n md: 'gap-4 p-4',\n lg: 'gap-5 p-5',\n};\n\nconst TITLE_SIZE: Record<CardSize, string> = {\n sm: 'text-body-xs',\n md: 'text-body-sm',\n lg: 'text-subheading-sm',\n};\n\n/**\n * One step below the title at every size.\n *\n * `CardDescription` was frozen at `text-body-tiny` while `CardTitle` scaled, so `size=\"lg\"`\n * put an 11px description under a 16px title and `size=\"sm\"` put 11px under 13px — the ratio\n * broke at both ends of the ladder. The size comes from the enclosing `CardHeader` through\n * context rather than a prop, because a description that has to be told its own size at every\n * call site is a size that will drift.\n */\nconst DESCRIPTION_SIZE: Record<CardSize, string> = {\n sm: 'text-body-tiny',\n md: 'text-body-tiny',\n lg: 'text-body-xs',\n};\n\nconst FOOTER_ALIGN: Record<CardFooterAlign, string> = {\n start: 'justify-start',\n between: 'justify-between',\n end: 'justify-end',\n};\n\n/**\n * Set by `CardHeader` so `CardDescription` tracks its sibling title's size.\n *\n * Deliberately only carries the size, and only from the header: the body has its own\n * ladder and nothing inside it reads this.\n */\nconst CardHeaderContext = createContext<CardSize>('md');\n\n// ── Card ───────────────────────────────────────────────────────────────────────\n\nexport interface CardProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** `2xl` suits detail pages, `xl` section panels, `lg` dense or nested cards. */\n radius?: CardRadius;\n /**\n * Surface tint. This is a prop rather than a `className` because a tone has to\n * un-set the base `border-default bg-default` pair, not add to it.\n */\n tone?: CardTone;\n}\n\n/**\n * The card shell. Composed from `CardHeader`, `CardBody` and `CardFooter` — or from\n * nothing at all, if you want content to bleed to the edges (drop `CardBody` and put\n * a `DataTable` straight inside).\n *\n * Replaces `SectionCard` and the two monolithic cards that shipped beside it,\n * `AlertCard` and `BenchmarkCard`. Both of those are now documented compositions; see\n * the Cards page. The vocabulary follows shadcn/ui so it is already familiar, with\n * `CardBody` in place of its `CardContent`.\n */\nexport function Card({ children, radius = '2xl', tone = 'default', className, ...rest }: CardProps) {\n return (\n <div\n data-slot=\"card\"\n // `overflow-hidden` is load-bearing: it clips a header's border-b to the\n // rounded corner. Removing it leaves the rule poking past the radius.\n className={cn('flex flex-col overflow-hidden border', RADIUS[radius], TONE[tone], className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n// ── CardHeader ─────────────────────────────────────────────────────────────────\n\nexport interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: CardSize;\n /** Bottom rule separating the header from the body. */\n divider?: boolean;\n}\n\n/**\n * Header row. Holds `CardTitle`, `CardDescription` and an optional `CardAction`.\n *\n * The `has-[…]` selector switches to a two-column grid only when a `CardAction` is\n * present, which is what lets title, description and action share a header with no\n * wrapper div and no stray gap when the action is absent.\n */\nexport function CardHeader({\n children,\n size = 'md',\n divider = true,\n className,\n ...rest\n}: CardHeaderProps) {\n return (\n <CardHeaderContext.Provider value={size}>\n <div\n data-slot=\"card-header\"\n className={cn(\n 'grid auto-rows-min items-center gap-x-3 gap-y-0.5',\n 'has-[[data-slot=card-action]]:grid-cols-[1fr_auto]',\n BOX[size],\n divider && 'border-b border-default',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </CardHeaderContext.Provider>\n );\n}\n\n// ── CardTitle / CardDescription / CardAction ───────────────────────────────────\n\nexport interface CardTitleProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n size?: CardSize;\n /** Heading level. Defaults to `p`; use h2/h3 where the page has a real hierarchy. */\n as?: 'h2' | 'h3' | 'h4' | 'p';\n}\n\nexport function CardTitle({ children, size = 'md', as: Tag = 'p', className, ...rest }: CardTitleProps) {\n return (\n <Tag\n data-slot=\"card-title\"\n // min-w-0 belongs here, not on the parent: a grid item defaults to\n // min-width:auto, so `truncate` on a title would not work without it.\n className={cn('min-w-0 font-semibold text-default', TITLE_SIZE[size], className)}\n {...rest}\n >\n {children}\n </Tag>\n );\n}\n\nexport interface CardDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {\n children: ReactNode;\n /** Overrides the size inherited from the enclosing `CardHeader`. */\n size?: CardSize;\n}\n\nexport function CardDescription({ children, size, className, ...rest }: CardDescriptionProps) {\n const inherited = useContext(CardHeaderContext);\n\n return (\n <p\n data-slot=\"card-description\"\n className={cn(\n 'min-w-0 text-default-secondary',\n DESCRIPTION_SIZE[size ?? inherited],\n className,\n )}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\nexport interface CardActionProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** Right-hand slot in a `CardHeader` — a button, a count, a status badge, a menu. */\nexport function CardAction({ children, className, ...rest }: CardActionProps) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn('col-start-2 row-span-2 row-start-1 shrink-0 self-center justify-self-end', className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n// ── CardBody ───────────────────────────────────────────────────────────────────\n\nexport interface CardBodyProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: CardSize;\n}\n\n/**\n * The content region. A vertical stack by default.\n *\n * Because this file uses `cn`, `className` genuinely overrides the base — so\n * `className=\"flex-row items-center\"` gives you a row, and\n * `className=\"grid grid-cols-3\"` a grid. That is what makes the `AlertCard` and\n * `BenchmarkCard` rebuilds possible without a `layout` prop.\n */\nexport function CardBody({ children, size = 'md', className, ...rest }: CardBodyProps) {\n return (\n <div data-slot=\"card-body\" className={cn('flex flex-col', BODY_BOX[size], className)} {...rest}>\n {children}\n </div>\n );\n}\n\n// ── CardFooter ─────────────────────────────────────────────────────────────────\n\nexport interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: CardSize;\n divider?: boolean;\n align?: CardFooterAlign;\n}\n\n/** Action row at the foot of a card. Mirrors `ModalFooter` and `Drawer`'s footer. */\nexport function CardFooter({\n children,\n size = 'md',\n divider = true,\n align = 'end',\n className,\n ...rest\n}: CardFooterProps) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n 'flex items-center gap-2',\n BOX[size],\n FOOTER_ALIGN[align],\n divider && 'border-t border-default',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuChevronDown } from 'react-icons/lu';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\n\nexport type AccordionType = 'single' | 'multiple';\n\ninterface AccordionContextValue {\n isOpen: (value: string) => boolean;\n toggle: (value: string) => void;\n baseId: string;\n claimIndex: () => number;\n roving: ReturnType<typeof useRovingFocus>;\n headingLevel: 2 | 3 | 4;\n}\n\nconst AccordionContext = createContext<AccordionContextValue | null>(null);\nconst AccordionItemContext = createContext<{ value: string; disabled: boolean } | null>(null);\n\nfunction useAccordion(part: string): AccordionContextValue {\n const context = useContext(AccordionContext);\n if (!context) throw new Error(`<${part}> must be used inside <Accordion>`);\n return context;\n}\n\nexport interface AccordionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n children: ReactNode;\n /** `single` closes the open item when another opens. Default `single`. */\n type?: AccordionType;\n /** Open item value(s) — a string for `single`, an array for `multiple`. */\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n /** Allow closing the open item in `single` mode. Default `true`. */\n collapsible?: boolean;\n /**\n * Heading level for each item's trigger. Default `3`.\n *\n * Each trigger is wrapped in a real heading, per the APG, so the accordion appears in\n * the document outline and a screen reader can jump between sections by heading. The\n * right level depends on what surrounds it, which only the caller knows.\n */\n headingLevel?: 2 | 3 | 4;\n}\n\n/**\n * Accordion. Matches Figma's `Accordion` / `Accordion Item` (`State: Closed | Open`).\n *\n * Width is deliberately not set — Figma's own note on `Accordion Item` says the 640px in\n * the component set is a container artefact and the parent should own width, so this is\n * `w-full` and nothing more.\n */\nexport function Accordion({\n children,\n type = 'single',\n value: valueProp,\n defaultValue,\n onValueChange,\n collapsible = true,\n headingLevel = 3,\n className,\n ...rest\n}: AccordionProps) {\n const baseId = useId();\n const cursor = useRef(0);\n\n const [value, setValue] = useControllableState<string | string[]>({\n value: valueProp,\n defaultValue: defaultValue ?? (type === 'multiple' ? [] : ''),\n onChange: onValueChange,\n });\n\n const isOpen = useCallback(\n (itemValue: string) =>\n Array.isArray(value) ? value.includes(itemValue) : value === itemValue,\n [value],\n );\n\n const toggle = useCallback(\n (itemValue: string) => {\n if (type === 'multiple') {\n const list = Array.isArray(value) ? value : [];\n setValue(list.includes(itemValue) ? list.filter((v) => v !== itemValue) : [...list, itemValue]);\n return;\n }\n const open = value === itemValue;\n // Without `collapsible`, clicking the open item is a no-op rather than closing it —\n // which is what you want when the accordion must always show something.\n setValue(open ? (collapsible ? '' : itemValue) : itemValue);\n },\n [type, value, setValue, collapsible],\n );\n\n const roving = useRovingFocus({ orientation: 'vertical', loop: true });\n\n cursor.current = 0;\n const claimIndex = useCallback(() => cursor.current++, []);\n\n const context = useMemo<AccordionContextValue>(\n () => ({ isOpen, toggle, baseId, claimIndex, roving, headingLevel }),\n [isOpen, toggle, baseId, claimIndex, roving, headingLevel],\n );\n\n return (\n <AccordionContext.Provider value={context}>\n <div\n data-slot=\"accordion\"\n className={clsx('w-full', className)}\n {...roving.containerProps}\n {...rest}\n >\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\nexport interface AccordionItemProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n value: string;\n disabled?: boolean;\n}\n\nexport function AccordionItem({\n children,\n value,\n disabled = false,\n className,\n ...rest\n}: AccordionItemProps) {\n const ctx = useAccordion('AccordionItem');\n const itemContext = useMemo(() => ({ value, disabled }), [value, disabled]);\n\n return (\n <AccordionItemContext.Provider value={itemContext}>\n <div\n data-slot=\"accordion-item\"\n data-state={ctx.isOpen(value) ? 'open' : 'closed'}\n className={clsx('border-b border-default last:border-b-0', className)}\n {...rest}\n >\n {children}\n </div>\n </AccordionItemContext.Provider>\n );\n}\n\nexport interface AccordionTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n /** Hide the chevron — for a trigger that supplies its own affordance. */\n hideIndicator?: boolean;\n}\n\nexport function AccordionTrigger({\n children,\n hideIndicator = false,\n className,\n ...rest\n}: AccordionTriggerProps) {\n const ctx = useAccordion('AccordionTrigger');\n const item = useContext(AccordionItemContext);\n if (!item) throw new Error('<AccordionTrigger> must be used inside <AccordionItem>');\n\n const index = ctx.claimIndex();\n const itemProps = ctx.roving.itemProps(index, {\n disabled: item.disabled,\n label: typeof children === 'string' ? children : undefined,\n });\n\n const open = ctx.isOpen(item.value);\n const Heading = `h${ctx.headingLevel}` as 'h3';\n\n return (\n // The heading carries no styling of its own — it exists so the accordion shows up in\n // the document outline, which is how screen reader users navigate between sections.\n <Heading className=\"m-0\">\n <button\n type=\"button\"\n id={`${ctx.baseId}-trigger-${item.value}`}\n aria-expanded={open}\n aria-controls={`${ctx.baseId}-content-${item.value}`}\n disabled={item.disabled}\n {...itemProps}\n tabIndex={itemProps.tabIndex}\n onClick={() => !item.disabled && ctx.toggle(item.value)}\n className={clsx(\n 'flex w-full items-center justify-between gap-3 py-4 text-left',\n 'text-body-sm font-semibold text-default transition-colors',\n 'hover:text-brand',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:text-disabled',\n className,\n )}\n {...rest}\n >\n <span className=\"min-w-0 flex-1\">{children}</span>\n {!hideIndicator && (\n <LuChevronDown\n aria-hidden\n className={clsx(\n 'size-4 shrink-0 text-icon-default-secondary transition-transform',\n open && 'rotate-180',\n )}\n />\n )}\n </button>\n </Heading>\n );\n}\n\nexport interface AccordionContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function AccordionContent({ children, className, ...rest }: AccordionContentProps) {\n const ctx = useAccordion('AccordionContent');\n const item = useContext(AccordionItemContext);\n if (!item) throw new Error('<AccordionContent> must be used inside <AccordionItem>');\n\n // Unmounted rather than height-collapsed: a `height: 0` panel keeps its content\n // focusable and announceable, so keyboard users tab into a closed section.\n if (!ctx.isOpen(item.value)) return null;\n\n return (\n <div\n id={`${ctx.baseId}-content-${item.value}`}\n role=\"region\"\n aria-labelledby={`${ctx.baseId}-trigger-${item.value}`}\n data-slot=\"accordion-content\"\n className={clsx('pb-4 text-body-sm text-default-secondary', className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","import {\n createContext,\n useContext,\n useId,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Slot } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\ninterface CollapsibleContextValue {\n open: boolean;\n setOpen: (open: boolean) => void;\n triggerId: string;\n contentId: string;\n disabled: boolean;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | null>(null);\n\nfunction useCollapsible(part: string): CollapsibleContextValue {\n const context = useContext(CollapsibleContext);\n if (!context) throw new Error(`<${part}> must be used inside <Collapsible>`);\n return context;\n}\n\nexport interface CollapsibleProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n}\n\n/**\n * A show/hide region with a trigger. The single-item primitive behind `Accordion`.\n *\n * The whole point is the wiring, which is easy to get wrong by hand: the trigger needs\n * `aria-expanded` and `aria-controls`, the panel needs an id and a matching\n * `aria-labelledby`, and the panel must be genuinely removed from the accessibility tree\n * when closed — `height: 0` with `overflow: hidden` leaves its content focusable and\n * announceable, so a keyboard user tabs into a collapsed section.\n */\nexport function Collapsible({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n disabled = false,\n className,\n ...rest\n}: CollapsibleProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const baseId = useId();\n\n return (\n <CollapsibleContext.Provider\n value={{\n open,\n setOpen,\n triggerId: `${baseId}-trigger`,\n contentId: `${baseId}-content`,\n disabled,\n }}\n >\n <div data-slot=\"collapsible\" data-state={open ? 'open' : 'closed'} className={className} {...rest}>\n {children}\n </div>\n </CollapsibleContext.Provider>\n );\n}\n\nexport interface CollapsibleTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children?: ReactNode;\n asChild?: boolean;\n}\n\nexport function CollapsibleTrigger({\n children,\n asChild = false,\n className,\n ...rest\n}: CollapsibleTriggerProps) {\n const ctx = useCollapsible('CollapsibleTrigger');\n\n const triggerProps = {\n id: ctx.triggerId,\n 'aria-expanded': ctx.open,\n 'aria-controls': ctx.contentId,\n 'data-state': ctx.open ? 'open' : 'closed',\n onClick: () => !ctx.disabled && ctx.setOpen(!ctx.open),\n className,\n ...rest,\n };\n\n if (asChild) {\n return (\n <Slot aria-disabled={ctx.disabled || undefined} {...triggerProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button type=\"button\" disabled={ctx.disabled} {...triggerProps}>\n {children}\n </button>\n );\n}\n\nexport interface CollapsibleContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /**\n * Keep the content mounted while closed, hidden with `hidden`. Default `false`.\n *\n * `hidden` — not `height: 0` — is what keeps hidden content out of the tab sequence and\n * the accessibility tree, so this stays safe. Use it to preserve form state or scroll\n * position across collapses.\n */\n keepMounted?: boolean;\n}\n\nexport function CollapsibleContent({\n children,\n keepMounted = false,\n className,\n ...rest\n}: CollapsibleContentProps) {\n const ctx = useCollapsible('CollapsibleContent');\n\n if (!ctx.open && !keepMounted) return null;\n\n return (\n <div\n id={ctx.contentId}\n role=\"region\"\n aria-labelledby={ctx.triggerId}\n hidden={!ctx.open}\n data-state={ctx.open ? 'open' : 'closed'}\n className={className}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport interface AspectRatioProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Width ÷ height. `16 / 9` for video, `1` for a square, `4 / 3` for a photo. Default `1`. */\n ratio?: number;\n}\n\n/**\n * Holds a fixed width-to-height ratio for its content.\n *\n * Uses the CSS `aspect-ratio` property rather than the old padding-top percentage hack, so\n * the child is a normal in-flow element instead of being absolutely positioned inside a\n * zero-height box. The ratio is an inline style because it is a per-instance numeric value —\n * a Tailwind class cannot express `16 / 9` without an arbitrary-value escape at every call\n * site.\n */\nexport const AspectRatio = forwardRef<HTMLDivElement, AspectRatioProps>(function AspectRatio(\n { children, ratio = 1, className, style, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n data-slot=\"aspect-ratio\"\n style={{ aspectRatio: ratio, ...style }}\n className={clsx('w-full overflow-hidden [&>*]:size-full [&>img]:object-cover', className)}\n {...rest}\n >\n {children}\n </div>\n );\n});\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuChevronLeft, LuChevronRight } from 'react-icons/lu';\nimport { IconButton } from '../forms/icon-button';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\ninterface CarouselContextValue {\n index: number;\n setIndex: (index: number) => void;\n count: number;\n registerSlide: () => number;\n resetSlides: () => void;\n baseId: string;\n loop: boolean;\n paused: boolean;\n setPaused: (paused: boolean) => void;\n hasAutoplay: boolean;\n}\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nfunction useCarousel(part: string): CarouselContextValue {\n const value = useContext(CarouselContext);\n if (!value) throw new Error(`<${part}> must be used inside <Carousel>`);\n return value;\n}\n\nexport interface CarouselProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Names the carousel region. Required — a nameless region is not navigable. */\n label: string;\n index?: number;\n defaultIndex?: number;\n onIndexChange?: (index: number) => void;\n /** Number of slides. Needed up front for the controls; `CarouselSlide` count is checked against it. */\n count: number;\n loop?: boolean;\n /** Advance every N ms. Omit for a manual carousel. */\n autoplayInterval?: number;\n}\n\n/**\n * A slide carousel.\n *\n * Carousels are one of the most reliably inaccessible patterns on the web, so the parts that\n * look like polish here are the requirements:\n *\n * - **`aria-roledescription=\"carousel\"`** on a named region, so it is announced as a carousel\n * rather than as an anonymous group of divs.\n * - **Slides are `role=\"group\"` with `aria-roledescription=\"slide\"` and an\n * \"N of M\" label** — position is otherwise invisible to anyone not seeing the dots.\n * - **Off-screen slides are `hidden`**, not merely translated out of view. A slide moved with\n * `transform` keeps its links in the tab order, so keyboard users tab into content they\n * cannot see. This is the single most common carousel bug.\n * - **Autoplay stops on hover, on focus, and permanently once the user takes control**, and\n * there is a visible pause button whenever autoplay is on — required by WCAG 2.2.2 for any\n * motion lasting more than five seconds.\n * - **`prefers-reduced-motion` disables autoplay entirely**, rather than just shortening the\n * transition.\n */\nexport function Carousel({\n children,\n label,\n index: indexProp,\n defaultIndex = 0,\n onIndexChange,\n count,\n loop = false,\n autoplayInterval,\n className,\n ...rest\n}: CarouselProps) {\n const [index, setIndex] = useControllableState({\n value: indexProp,\n defaultValue: defaultIndex,\n onChange: onIndexChange,\n });\n\n const baseId = useId();\n const cursor = useRef(0);\n const [paused, setPaused] = useState(false);\n const [userTookControl, setUserTookControl] = useState(false);\n\n const hasAutoplay = autoplayInterval !== undefined && autoplayInterval > 0;\n\n const context = useMemo<CarouselContextValue>(\n () => ({\n index,\n setIndex: (next) => {\n // Any deliberate move stops autoplay for good. Resuming after a user has navigated\n // yanks the content out from under them.\n setUserTookControl(true);\n setIndex(next);\n },\n count,\n registerSlide: () => cursor.current++,\n resetSlides: () => {\n cursor.current = 0;\n },\n baseId,\n loop,\n paused,\n setPaused,\n hasAutoplay,\n }),\n [index, setIndex, count, baseId, loop, paused, hasAutoplay],\n );\n\n context.resetSlides();\n\n useEffect(() => {\n if (!hasAutoplay || paused || userTookControl) return;\n // Autoplay is motion the user did not ask for, so it does not start at all when they\n // have asked for less of it.\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\n\n const timer = setInterval(() => {\n setIndex(index === count - 1 ? (loop ? 0 : index) : index + 1);\n }, autoplayInterval);\n return () => clearInterval(timer);\n }, [hasAutoplay, paused, userTookControl, autoplayInterval, index, count, loop, setIndex]);\n\n return (\n <CarouselContext.Provider value={context}>\n {/* The APG carousel pattern puts Left/Right on the region itself, so slides can be\n paged from anywhere inside without first tabbing to the controls. The region is not\n focusable and does not need to be — the keys arrive by bubbling from whatever inside\n it has focus. */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <div\n // `region` + roledescription is what makes this announce as a carousel.\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label={label}\n data-slot=\"carousel\"\n className={clsx('relative', className)}\n onPointerEnter={() => hasAutoplay && setPaused(true)}\n onPointerLeave={() => hasAutoplay && setPaused(false)}\n onFocus={() => hasAutoplay && setPaused(true)}\n onBlur={(event) => {\n if (hasAutoplay && !event.currentTarget.contains(event.relatedTarget as Node)) {\n setPaused(false);\n }\n }}\n onKeyDown={(event) => {\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n context.setIndex(index === 0 ? (loop ? count - 1 : 0) : index - 1);\n }\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n context.setIndex(index === count - 1 ? (loop ? 0 : index) : index + 1);\n }\n }}\n {...rest}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\nexport interface CarouselViewportProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function CarouselViewport({ children, className, ...rest }: CarouselViewportProps) {\n const carousel = useCarousel('CarouselViewport');\n return (\n <div\n id={`${carousel.baseId}-viewport`}\n data-slot=\"carousel-viewport\"\n className={clsx('overflow-hidden', className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport interface CarouselSlideProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function CarouselSlide({ children, className, ...rest }: CarouselSlideProps) {\n const carousel = useCarousel('CarouselSlide');\n const slideIndex = carousel.registerSlide();\n const active = slideIndex === carousel.index;\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n // Position stated explicitly — without it, only the dots convey where you are.\n aria-label={`${slideIndex + 1} of ${carousel.count}`}\n // `hidden`, not a transform. An off-screen slide that is merely translated keeps its\n // links focusable, so Tab walks into invisible content.\n hidden={!active}\n data-slot=\"carousel-slide\"\n className={className}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport interface CarouselControlsProps extends HTMLAttributes<HTMLDivElement> {\n /** Show the dot indicators. Default `true`. */\n showDots?: boolean;\n}\n\nexport function CarouselControls({ showDots = true, className, ...rest }: CarouselControlsProps) {\n const carousel = useCarousel('CarouselControls');\n const { index, count, loop } = carousel;\n\n const go = useCallback(\n (next: number) => {\n const wrapped = ((next % count) + count) % count;\n carousel.setIndex(loop ? wrapped : Math.min(Math.max(next, 0), count - 1));\n },\n [carousel, count, loop],\n );\n\n return (\n <div\n className={clsx('mt-3 flex items-center justify-between gap-3', className)}\n {...rest}\n >\n <IconButton\n variant=\"neutral\"\n size=\"sm\"\n aria-label=\"Previous slide\"\n aria-controls={`${carousel.baseId}-viewport`}\n disabled={!loop && index === 0}\n onClick={() => go(index - 1)}\n >\n <LuChevronLeft aria-hidden size={16} />\n </IconButton>\n\n {showDots && (\n <div role=\"group\" aria-label={`Slide ${index + 1} of ${count}`} className=\"flex items-center gap-2\">\n {Array.from({ length: count }, (_, i) => (\n <button\n key={i}\n type=\"button\"\n aria-label={`Go to slide ${i + 1}`}\n aria-current={i === index ? 'true' : undefined}\n onClick={() => go(i)}\n className={clsx(\n 'size-2 rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 focus-visible:ring-offset-default',\n i === index ? 'bg-brand' : 'bg-default-tertiary hover:bg-neutral-secondary',\n )}\n />\n ))}\n </div>\n )}\n\n <div className=\"flex items-center gap-1.5\">\n {/* Required by WCAG 2.2.2 whenever autoplay is on: any motion lasting more than five\n seconds needs a visible, keyboard-reachable way to stop it. */}\n {carousel.hasAutoplay && (\n <IconButton\n variant=\"neutral\"\n size=\"sm\"\n aria-label={carousel.paused ? 'Start automatic slide show' : 'Stop automatic slide show'}\n onClick={() => carousel.setPaused(!carousel.paused)}\n >\n <span aria-hidden className=\"text-body-tiny font-semibold\">\n {carousel.paused ? '▶' : '❚❚'}\n </span>\n </IconButton>\n )}\n <IconButton\n variant=\"neutral\"\n size=\"sm\"\n aria-label=\"Next slide\"\n aria-controls={`${carousel.baseId}-viewport`}\n disabled={!loop && index === count - 1}\n onClick={() => go(index + 1)}\n >\n <LuChevronRight aria-hidden size={16} />\n </IconButton>\n </div>\n </div>\n );\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { ScrollArea } from './scroll-area';\nimport clsx from 'clsx';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type ResizableDirection = 'horizontal' | 'vertical';\n\ninterface ResizableContextValue {\n direction: ResizableDirection;\n /** First pane's size, as a percentage of the container. */\n size: number;\n setSize: (size: number) => void;\n min: number;\n max: number;\n containerRef: React.RefObject<HTMLDivElement | null>;\n baseId: string;\n dragging: boolean;\n setDragging: (dragging: boolean) => void;\n}\n\nconst ResizableContext = createContext<ResizableContextValue | null>(null);\n\nfunction useResizable(part: string): ResizableContextValue {\n const value = useContext(ResizableContext);\n if (!value) throw new Error(`<${part}> must be used inside <Resizable>`);\n return value;\n}\n\nexport interface ResizableProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n direction?: ResizableDirection;\n /** First pane's size as a percentage. Controlled. */\n size?: number;\n defaultSize?: number;\n onSizeChange?: (size: number) => void;\n /** Percentage bounds. Defaults `10` and `90`. */\n min?: number;\n max?: number;\n}\n\n/**\n * Two resizable panes with a draggable divider.\n *\n * This is the APG **window splitter** pattern, and the handle is the whole component as far\n * as accessibility goes. A `<div>` with pointer listeners — the usual implementation — is\n * completely unusable without a mouse. `ResizableHandle` is therefore a real focusable\n * control with:\n *\n * - `role=\"separator\"` plus `aria-valuenow`/`valuemin`/`valuemax`, so the current split is\n * announced as a percentage rather than being invisible;\n * - `tabIndex={0}` and arrow keys to move it in 1% steps, Shift+arrow in 10%, Home/End to\n * the bounds, and Enter to collapse and restore;\n * - `aria-controls` pointing at the pane it resizes.\n *\n * Sizes are percentages, not pixels, so the split survives a container resize — a pixel\n * split silently becomes wrong the moment the window changes.\n */\nexport function Resizable({\n children,\n direction = 'horizontal',\n size: sizeProp,\n defaultSize = 50,\n onSizeChange,\n min = 10,\n max = 90,\n className,\n ...rest\n}: ResizableProps) {\n const [size, setSize] = useControllableState({\n value: sizeProp,\n defaultValue: defaultSize,\n onChange: onSizeChange,\n });\n\n const containerRef = useRef<HTMLDivElement>(null);\n const baseId = useId();\n const [dragging, setDragging] = useState(false);\n\n const context = useMemo<ResizableContextValue>(\n () => ({\n direction,\n size,\n setSize: (next) => setSize(Math.min(Math.max(next, min), max)),\n min,\n max,\n containerRef,\n baseId,\n dragging,\n setDragging,\n }),\n [direction, size, setSize, min, max, baseId, dragging],\n );\n\n return (\n <ResizableContext.Provider value={context}>\n <div\n ref={containerRef}\n data-slot=\"resizable\"\n className={clsx(\n 'flex w-full',\n direction === 'horizontal' ? 'flex-row' : 'flex-col',\n // While dragging, suppress selection and pointer events inside the panes so the\n // gesture cannot start selecting text or hovering things it passes over.\n dragging && 'select-none [&_*]:pointer-events-none',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </ResizableContext.Provider>\n );\n}\n\nexport interface ResizablePanelProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** `first` is the pane the handle sizes; `second` fills the remainder. */\n which: 'first' | 'second';\n}\n\nexport function ResizablePanel({ children, which, className, ...rest }: ResizablePanelProps) {\n const ctx = useResizable('ResizablePanel');\n const axis = ctx.direction === 'horizontal' ? 'width' : 'height';\n\n return (\n // A panel holds arbitrary content, which may be entirely static — so it needs the tab\n // stop `ScrollArea` adds while overflowing, not just the scrollbar styling.\n <ScrollArea\n axis=\"both\"\n id={which === 'first' ? `${ctx.baseId}-first` : `${ctx.baseId}-second`}\n data-slot=\"resizable-panel\"\n style={which === 'first' ? { [axis]: `${ctx.size}%` } : { flex: '1 1 0%' }}\n className={clsx('min-h-0 min-w-0', className)}\n {...rest}\n >\n {children}\n </ScrollArea>\n );\n}\n\nexport interface ResizableHandleProps extends HTMLAttributes<HTMLDivElement> {\n /** Names the splitter. Default `Resize panels`. */\n label?: string;\n /** Show the grip dots. Default `true`. */\n withGrip?: boolean;\n}\n\nexport function ResizableHandle({\n label = 'Resize panels',\n withGrip = true,\n className,\n ...rest\n}: ResizableHandleProps) {\n const ctx = useResizable('ResizableHandle');\n const horizontal = ctx.direction === 'horizontal';\n const collapsedFrom = useRef<number | null>(null);\n\n const fromPointer = useCallback(\n (clientX: number, clientY: number) => {\n const container = ctx.containerRef.current;\n if (!container) return;\n const rect = container.getBoundingClientRect();\n const ratio = horizontal\n ? (clientX - rect.left) / rect.width\n : (clientY - rect.top) / rect.height;\n ctx.setSize(ratio * 100);\n },\n [ctx, horizontal],\n );\n\n useEffect(() => {\n if (!ctx.dragging) return;\n\n const onMove = (event: PointerEvent) => fromPointer(event.clientX, event.clientY);\n const onUp = () => ctx.setDragging(false);\n\n // Listeners on the window, not the handle: the pointer routinely leaves the 8px handle\n // mid-drag, and a handle-scoped listener would drop the gesture.\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n window.addEventListener('pointercancel', onUp);\n return () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n window.removeEventListener('pointercancel', onUp);\n };\n }, [ctx, fromPointer]);\n\n return (\n // A *focusable* separator is the APG window-splitter pattern, and the whole point of this\n // component: without the tab stop and the arrow keys below, a split view can only be\n // resized with a mouse. ARIA explicitly allows a focusable separator, which is what\n // carries `aria-valuenow`; jsx-a11y models `separator` as always non-interactive.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex, jsx-a11y/no-noninteractive-element-interactions\n <div\n role=\"separator\"\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n aria-label={label}\n aria-orientation={horizontal ? 'vertical' : 'horizontal'}\n aria-valuenow={Math.round(ctx.size)}\n aria-valuemin={ctx.min}\n aria-valuemax={ctx.max}\n aria-controls={`${ctx.baseId}-first`}\n data-slot=\"resizable-handle\"\n onPointerDown={(event) => {\n event.preventDefault();\n ctx.setDragging(true);\n }}\n onKeyDown={(event) => {\n const step = event.shiftKey ? 10 : 1;\n const decrease = horizontal ? 'ArrowLeft' : 'ArrowUp';\n const increase = horizontal ? 'ArrowRight' : 'ArrowDown';\n\n if (event.key === decrease) {\n event.preventDefault();\n ctx.setSize(ctx.size - step);\n } else if (event.key === increase) {\n event.preventDefault();\n ctx.setSize(ctx.size + step);\n } else if (event.key === 'Home') {\n event.preventDefault();\n ctx.setSize(ctx.min);\n } else if (event.key === 'End') {\n event.preventDefault();\n ctx.setSize(ctx.max);\n } else if (event.key === 'Enter') {\n // Collapse/restore, so the splitter is useful without dragging at all.\n event.preventDefault();\n if (collapsedFrom.current === null) {\n collapsedFrom.current = ctx.size;\n ctx.setSize(ctx.min);\n } else {\n ctx.setSize(collapsedFrom.current);\n collapsedFrom.current = null;\n }\n }\n }}\n className={clsx(\n 'group relative flex shrink-0 items-center justify-center bg-divider transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand',\n 'hover:bg-brand-tertiary',\n horizontal ? 'w-px cursor-col-resize' : 'h-px cursor-row-resize',\n className,\n )}\n {...rest}\n >\n {/* An invisible padded hit area, so the 1px rule is grabbable without being 8px of\n visible chrome. */}\n <span\n aria-hidden\n className={clsx('absolute', horizontal ? 'inset-y-0 -inset-x-1.5' : '-inset-y-1.5 inset-x-0')}\n />\n {withGrip && (\n <span\n aria-hidden\n className={clsx(\n 'relative z-raised flex items-center justify-center rounded-full border border-default bg-default',\n 'opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100',\n horizontal ? 'h-6 w-2.5' : 'h-2.5 w-6',\n )}\n >\n <span className={clsx('rounded-full bg-default-tertiary', horizontal ? 'h-2.5 w-px' : 'h-px w-2.5')} />\n </span>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\n/**\n * Two genuinely different heading contexts, which the source markup distinguished:\n *\n * `page` 24px title / 14px subtitle — an in-body page heading (settings, users,\n * alerts), i.e. the old `text-2xl` + `mt-1 text-body-sm` block.\n * `toolbar` 20px title / 13px subtitle — inside a `PageToolbar`, where the bar is\n * only 72px tall. Flattening these into one size would have grown ten\n * toolbar titles by 4px.\n * `section` 18px — a panel or card heading.\n */\nexport type PageHeadingSize = 'page' | 'toolbar' | 'section';\n\nconst TITLE: Record<PageHeadingSize, string> = {\n // `text-2xl` was stock Tailwind rather than the design tokens. Same 24px, now on-token.\n page: 'text-heading font-semibold text-default',\n toolbar: 'text-heading-sm font-semibold leading-snug text-default',\n // Was `text-lg` — stock Tailwind's 18px, off the type scale. Snapped DOWN to 16 rather\n // than up to 20, because 20 is already `toolbar`: rounding up would have made two of the\n // three sizes identical and collapsed the ramp to page 24 / toolbar 20 / section 20.\n section: 'text-subheading-sm font-semibold text-default',\n};\n\nconst SUBTITLE: Record<PageHeadingSize, string> = {\n page: 'mt-1 text-body-sm text-default-secondary',\n toolbar: 'text-body-xs text-default-secondary',\n section: 'mt-1 text-body-sm text-default-secondary',\n};\n\nexport interface PageHeadingProps {\n title: ReactNode;\n subtitle?: ReactNode;\n size?: PageHeadingSize;\n /** Heading level. Defaults to `h1` for page/toolbar and `h2` for section. */\n as?: 'h1' | 'h2' | 'h3';\n /** Right-aligned action cluster. When set, the heading becomes a flex row. */\n actions?: ReactNode;\n /** Clamp a long title to one line — needed when the title is user data, e.g. an article headline. */\n truncateTitle?: boolean;\n className?: string;\n}\n\n/**\n * Page or section title with an optional subtitle underneath.\n *\n * Replaces nine copies of the `<h1>` + `<p className=\"mt-1 …\">` block, plus the\n * heading halves of `SettingsTabs` and `my-account/tabs`.\n *\n * Emitting a real heading element matters: `reviewer-detail`,\n * `settings-audit-log`'s table area and `widget-gallery` render their titles as\n * `<p>`/`<div>` today, so `getByRole('heading')` finds nothing there — an\n * accessibility gap the e2e specs currently work around.\n */\nexport function PageHeading({\n title,\n subtitle,\n size = 'page',\n as,\n actions,\n truncateTitle,\n className,\n}: PageHeadingProps) {\n const Tag = as ?? (size === 'section' ? 'h2' : 'h1');\n\n const heading = (\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <Tag className={clsx(TITLE[size], truncateTitle && 'truncate')}>{title}</Tag>\n {subtitle && <p className={SUBTITLE[size]}>{subtitle}</p>}\n </div>\n );\n\n if (!actions) return className ? <div className={className}>{heading}</div> : heading;\n\n return (\n <div className={clsx('flex items-start justify-between gap-4', className)}>\n {heading}\n <div className=\"flex shrink-0 items-center gap-2\">{actions}</div>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type PageToolbarSize = 'sm' | 'md';\n\nexport interface PageToolbarProps {\n children: ReactNode;\n /** Allow the row to wrap when the action cluster is wide (entity-detail has seven buttons). */\n wrap?: boolean;\n /**\n * The bar's **own** height and padding. `sm` suits a secondary bar under the main toolbar.\n *\n * Not to be confused with `FilterBar.size`, which sets the density of the controls\n * *inside* the row. Same literals, different subject: a bar sizes itself, a row of\n * controls sizes its children. `PageToolbar` passes nothing down.\n */\n size?: PageToolbarSize;\n className?: string;\n}\n\nconst SIZE: Record<PageToolbarSize, string> = {\n sm: 'min-h-[56px] px-4 py-3 md:px-7',\n md: 'min-h-[72px] px-4 py-4 md:px-7',\n};\n\n/**\n * The sticky top bar on a full-bleed detail or list screen: title block on the\n * left, actions on the right.\n *\n * Replaces ten copies of this class string. Three of those copies used the\n * responsive `px-4 py-4 md:px-7` and seven used a fixed `px-7 py-4`; the responsive\n * variant is adopted here, which is a deliberate improvement below `md` where the\n * fixed 28px padding was cramped.\n */\nexport function PageToolbar({ children, wrap, size = 'md', className }: PageToolbarProps) {\n return (\n <div\n className={clsx(\n 'flex shrink-0 items-center justify-between gap-4 border-b border-default bg-default',\n SIZE[size],\n wrap && 'flex-wrap gap-2',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { ControlSizeProvider } from '../forms/control-size';\n\nexport type FilterBarSize = 'sm' | 'md';\n\nexport interface FilterBarProps {\n children: ReactNode;\n /** Right-aligned slot for a result count or a secondary action. */\n trailing?: ReactNode;\n /**\n * Row density. Sets the gap between controls **and** the default `size` of the controls\n * inside — an Input, Select, Combobox, DatePicker or Button that is not given its own\n * `size` inherits this one. Pass `size` on a child to opt it out.\n *\n * `sm` is for a filter row inside a card or drawer: 8px gaps and 24px controls.\n */\n size?: FilterBarSize;\n className?: string;\n}\n\nconst GAP: Record<FilterBarSize, string> = {\n sm: 'gap-2',\n md: 'gap-3',\n};\n\n/**\n * Row of search inputs and filter selects above a table.\n *\n * Replaces nine copies of `flex flex-wrap items-center gap-3`.\n *\n * Through 0.4.0 `size` set only the gap, so every caller had to repeat it on each control\n * and the page documenting this component got it wrong: its `size=\"sm\"` example put a 24px\n * Input beside a 36px Select. A container with a size prop should mean it, so the size now\n * reaches the controls through `ControlSizeProvider`.\n */\nexport function FilterBar({ children, trailing, size = 'md', className }: FilterBarProps) {\n return (\n <ControlSizeProvider size={size}>\n <div className={clsx('flex flex-wrap items-center', GAP[size], className)}>\n {children}\n {/* Was a fixed `gap-2`, which disagreed with the row itself at `md`. */}\n {trailing && <div className={clsx('ml-auto flex items-center', GAP[size])}>{trailing}</div>}\n </div>\n </ControlSizeProvider>\n );\n}\n","import { useId, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type TabsVariant = 'underline' | 'pill';\nexport type TabsSize = 'sm' | 'md';\nexport type TabsOrientation = 'horizontal' | 'vertical';\n/**\n * `automatic` selects as focus moves, which is the APG default and right when panels are\n * cheap. `manual` requires Enter/Space — use it when switching tab triggers a fetch, so\n * arrowing across five tabs does not fire five requests.\n */\nexport type TabsActivation = 'automatic' | 'manual';\n\nexport interface TabItem<K extends string = string> {\n key: K;\n label: string;\n /** Renders a count chip after the label. */\n count?: number;\n disabled?: boolean;\n}\n\nexport interface TabsProps<K extends string = string> {\n items: TabItem<K>[];\n /** Controlled selection. Omit and pass `defaultValue` for uncontrolled. */\n value?: K;\n defaultValue?: K;\n onValueChange?: (key: K) => void;\n /**\n * `underline` is the detail-page form (entity detail, reviewer detail, role detail).\n * `pill` is the filter-style form used by the reviewer queue.\n */\n variant?: TabsVariant;\n /** `md` is the page-level strip; `sm` suits a tab strip inside a card or drawer. */\n size?: TabsSize;\n orientation?: TabsOrientation;\n activation?: TabsActivation;\n /**\n * Shared prefix for the generated tab and panel ids. Pass the same value to `TabsPanel`\n * to wire `aria-controls` / `aria-labelledby`. Generated when omitted.\n */\n idPrefix?: string;\n /** Names the tab strip. Required by the APG when there is more than one on a page. */\n label?: string;\n className?: string;\n}\n\n/**\n * Per-variant sizing. The two variants have genuinely different geometry — a pill has\n * a background to pad against, an underline only has a baseline — so this is a nested\n * map rather than one shared scale.\n */\nconst SIZE: Record<TabsVariant, Record<TabsSize, { strip: string; tab: string }>> = {\n underline: {\n sm: { strip: 'gap-4', tab: 'px-0.5 py-1.5 text-body-xs' },\n md: { strip: 'gap-6', tab: 'px-0.5 py-2.5 text-body-sm' },\n },\n pill: {\n sm: { strip: 'gap-1', tab: 'rounded-md px-2.5 py-1.5 text-body-tiny' },\n md: { strip: 'gap-1.5', tab: 'rounded-lg px-3.5 py-2 text-body-xs' },\n },\n};\n\nexport const tabId = (prefix: string, key: string) => `${prefix}-tab-${key}`;\nexport const tabPanelId = (prefix: string, key: string) => `${prefix}-panel-${key}`;\n\n/**\n * Tab strip.\n *\n * Reworked in 0.4.0. It previously carried `role=\"tablist\"`, `role=\"tab\"` and\n * `aria-selected` with **no `onKeyDown` at all** — no Arrow keys, no Home/End, no roving\n * tabindex, no `aria-controls`, and no `role=\"tabpanel\"` counterpart anywhere in the\n * library. That combination is worse than shipping no ARIA: a screen reader announces\n * \"tab 3 of 5\", the user presses the arrow keys it implies, and nothing happens. Every\n * tab was also individually tabbable, so Tab walked the strip instead of leaving it.\n *\n * The `underline` active colour is `background-brand` (#0C2D58), which is what Figma\n * specifies.\n */\nexport function Tabs<K extends string = string>({\n items,\n value: valueProp,\n defaultValue,\n onValueChange,\n variant = 'underline',\n size = 'md',\n orientation = 'horizontal',\n activation = 'automatic',\n idPrefix,\n label,\n className,\n}: TabsProps<K>) {\n const generatedPrefix = useId();\n const prefix = idPrefix ?? generatedPrefix;\n\n const [value, setValue] = useControllableState<K>({\n value: valueProp,\n defaultValue: defaultValue ?? items[0]?.key,\n onChange: onValueChange as ((next: K) => void) | undefined,\n });\n\n const isPill = variant === 'pill';\n const s = SIZE[variant][size];\n\n const selectedIndex = Math.max(\n 0,\n items.findIndex((item) => item.key === value),\n );\n\n const roving = useRovingFocus({\n orientation: orientation === 'vertical' ? 'vertical' : 'horizontal',\n loop: true,\n defaultIndex: selectedIndex,\n });\n\n return (\n <div\n role=\"tablist\"\n aria-label={label}\n aria-orientation={orientation}\n className={clsx(\n 'flex shrink-0',\n // The strip's own children are the tab stops, so it needs no tab stop of its own.\n orientation === 'vertical' ? 'flex-col' : clsx('overflow-x-auto', SCROLLBAR_CLASSES),\n s.strip,\n !isPill && (orientation === 'vertical' ? 'border-r border-default' : 'border-b border-default'),\n className,\n )}\n {...roving.containerProps}\n >\n {items.map((tab, index) => {\n const active = tab.key === value;\n const itemProps = roving.itemProps(index, { disabled: tab.disabled, label: tab.label });\n\n return (\n <button\n key={tab.key}\n type=\"button\"\n role=\"tab\"\n id={tabId(prefix, tab.key)}\n aria-selected={active}\n aria-controls={tabPanelId(prefix, tab.key)}\n disabled={tab.disabled}\n {...itemProps}\n // Selection, not focus, owns the tab stop: Tab must land on the *selected*\n // tab, which is not necessarily the one the arrow keys last visited.\n tabIndex={active ? 0 : -1}\n onFocus={() => {\n itemProps.onFocus();\n // Automatic activation: focus and selection move together.\n if (activation === 'automatic' && !tab.disabled) setValue(tab.key);\n }}\n onClick={() => !tab.disabled && setValue(tab.key)}\n onKeyDown={(event) => {\n if (activation === 'manual' && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n setValue(tab.key);\n }\n }}\n className={clsx(\n 'flex shrink-0 items-center gap-1.5 whitespace-nowrap transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n s.tab,\n isPill\n ? clsx(\n 'font-medium',\n active\n ? 'bg-brand text-brand-on-brand'\n : 'text-default-secondary hover:bg-default-secondary',\n )\n : clsx(\n 'leading-snug',\n active\n ? 'border-b-2 border-brand-emphasis font-semibold text-brand-emphasis'\n : 'font-normal text-default-secondary hover:text-default',\n ),\n )}\n >\n {tab.label}\n {tab.count !== undefined && (\n <span\n className={clsx(\n 'rounded-md px-1.5 py-px text-body-tiny font-medium leading-snug',\n active && isPill\n ? 'bg-brand-hover text-brand-on-brand'\n : 'bg-default-secondary text-default-secondary',\n )}\n >\n {tab.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport interface TabsPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** The `key` of the tab this panel belongs to. */\n tabKey: string;\n /** Must match the `idPrefix` given to `Tabs`. */\n idPrefix: string;\n /** Whether this panel's tab is the selected one. */\n active: boolean;\n children: ReactNode;\n /**\n * Keep the panel mounted while hidden. Default `false`. Mounting all panels preserves\n * scroll position and form state across tab switches at the cost of rendering them all.\n */\n keepMounted?: boolean;\n}\n\n/**\n * The `role=\"tabpanel\"` half of the pattern, which the library had no equivalent of —\n * so `aria-controls` on a tab pointed at nothing and there was no labelled region for a\n * screen reader to move into.\n *\n * `tabIndex={0}` is deliberate and required: when a panel contains no focusable element,\n * it must be reachable itself, otherwise Tab from the selected tab skips the content\n * entirely.\n */\nexport function TabsPanel({\n tabKey,\n idPrefix,\n active,\n children,\n keepMounted = false,\n className,\n ...rest\n}: TabsPanelProps) {\n if (!active && !keepMounted) return null;\n\n return (\n <div\n role=\"tabpanel\"\n id={tabPanelId(idPrefix, tabKey)}\n aria-labelledby={tabId(idPrefix, tabKey)}\n hidden={!active}\n tabIndex={0}\n className={clsx('focus-visible:outline-none', className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","import { type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\n\nexport type NavItemSize = 'sm' | 'md';\nexport type NavItemVariant = 'card' | 'plain';\n\nexport interface NavItemProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * Leading glyph. Optional, but when `collapsed` it is the only thing left to look at, so\n * a row without one falls back to a monogram taken from the label.\n */\n icon?: ReactNode;\n label: string;\n /**\n * The row you are on — the current route. Paints the brand fill and, under `asChild`, sets\n * `aria-current=\"page\"`; it also reflects to `data-state=\"active\"`.\n *\n * Not the same thing as focus, though Figma's `MenuButton` names this variant\n * `state=focussed`. That is a misnomer to fix on the design side: keyboard focus is the\n * ring below, it is transient and can land on any row, and if it painted the brand fill\n * too there would be no way to see which row is the current one while tabbing past it.\n */\n isActive?: boolean;\n /** Red indicator dot at top-right corner (e.g. unread count) */\n indicator?: boolean;\n /** Collapsed mode — label is visually hidden but stays in the accessibility tree. */\n collapsed?: boolean;\n /** Row height. `sm` suits a dense secondary nav or a nested group. */\n size?: NavItemSize;\n /**\n * Row weight.\n *\n * `card` gives every inactive row its own border and surface — right for a short primary\n * rail of eight or ten destinations, where each row is a target in its own right.\n * `plain` drops both, so an inactive row is just text: right for a long grouped nav,\n * where thirty bordered pills read as thirty cards rather than a list.\n *\n * A variant decides what a row looks like **at rest, and nothing else**. Hover and the\n * current-row fill are one vocabulary shared by both — see `STATE`. Through 0.5.0 each\n * variant defined its own, and `plain`'s was invisible against the rail it was written for.\n */\n variant?: NavItemVariant;\n /**\n * Render the single child element as the row, so the row itself is the link or button.\n *\n * `NavItem` is presentational by default — a `<span>` with hover styling. That is fine\n * inside a router `NavLink`, which is how `src/sidebar/` uses it, but on its own it is a\n * nav row that looks interactive and cannot be focused or activated. `asChild` is the\n * fix for anyone using it outside that wrapper:\n *\n * <NavItem asChild icon={<LuHouse />} label=\"Home\">\n * <NavLink to=\"/\" />\n * </NavItem>\n */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * `md` is Figma's `MenuButton` in every dimension: 44px tall, 12px radius, 12px gap, 14px\n * padding-x. `square` is the collapsed footprint — the design does not stretch a collapsed row\n * to the rail width, it centres a 44×44 button, which is exactly `px-3.5` either side of a\n * 16px icon.\n *\n * The label is the one deliberate departure. Figma specifies Body Base (16px); this is\n * `text-body-sm` (14px), because 16px rows read as oversized against everything else in a\n * product shell. The design file is the authority on the box and the colours, not on this.\n *\n * `sm` has no counterpart in the design file; it is a code-only density for long navs.\n */\nconst SIZE: Record<NavItemSize, { box: string; label: string; square: string }> = {\n sm: { box: 'h-9 gap-2 rounded-lg px-3 py-1.5', label: 'text-body-xs', square: 'w-9' },\n md: { box: 'h-11 gap-3 rounded-xl px-3.5 py-2.5', label: 'text-body-sm', square: 'w-11' },\n};\n\n/**\n * Up to two characters standing in for a missing icon in the collapsed rail.\n *\n * Two rather than one because any nav long enough to be worth collapsing collides on first\n * letters — the docs' own sidebar has Button beside Badges and Input beside Icons. Multiple\n * words give one initial each (\"Color Tokens\" → \"CT\"); a single word gives its first two\n * (\"Button\" → \"Bu\"), which stays readable rather than shouting. Words that open with\n * punctuation are skipped, so \"Cards & Containers\" is \"CC\" and not \"C&\".\n */\nfunction monogram(label: string): string {\n const words = label.split(/\\s+/).filter((word) => /^[\\p{L}\\p{N}]/u.test(word));\n const [first, second] = words;\n // A label of nothing but symbols has no initials to take; show its first character.\n if (!first) return Array.from(label.trim())[0]?.toUpperCase() ?? '';\n if (second) return (Array.from(first)[0] + Array.from(second)[0]).toUpperCase();\n const [a, b] = Array.from(first);\n return a.toUpperCase() + (b ?? '').toLowerCase();\n}\n\n/**\n * What a row looks like when you are on it, and when you hover one you are not — shared by\n * both variants and declared nowhere else. Selection means one thing in this library.\n *\n * Through 0.5.0 each variant carried its own pair, and `plain`'s hover was\n * `hover:bg-default-hover` — a generic app-surface token resolving to `--prim-gray-100`,\n * which is the same #F5F5F5 as the `bg-default-secondary` rail a sidebar row sits on. Plain\n * rows therefore had **no visible hover at all** in light mode, and `plain`'s active\n * `bg-brand-tertiary` (#F1F7FD) was a 1.02:1 step against that same rail. The bug survived\n * because the docs demo every variant on `bg-default` — white — where the collision does\n * not occur.\n */\nconst STATE = {\n // Figma MenuButton `state=hover`. No border change: Figma holds it at #D9D9D9 through\n // hover and moves only the fill and the text.\n hover: 'hover:bg-brand-tertiary-hover hover:text-brand',\n // Figma MenuButton `state=focussed`, which is that file's name for selected — see the\n // `isActive` doc comment. Hovering the current row darkens it rather than reverting it to\n // the pale hover tint, which would read as the row losing its selection under the cursor.\n active: 'bg-brand text-brand-on-brand hover:bg-brand-hover',\n} as const;\n\n/** The resting appearance — the whole of the difference between the two variants. */\nconst VARIANT: Record<NavItemVariant, { active: string; inactive: string }> = {\n card: {\n // `border-transparent` holds the 1px so the icon and label do not shift outward when a\n // row becomes the current one — the same trick, for the same reason, as `button.tsx`.\n // `bg-brand` still paints edge to edge, since backgrounds clip to the border box.\n active: clsx('border border-transparent', STATE.active),\n inactive: clsx('border border-default bg-default text-default-secondary', STATE.hover),\n },\n plain: {\n active: STATE.active,\n inactive: clsx('text-default-secondary', STATE.hover),\n },\n};\n\nexport function NavItem({\n icon,\n label,\n isActive = false,\n indicator = false,\n collapsed = false,\n size = 'md',\n variant = 'card',\n asChild = false,\n children,\n className,\n ...rest\n}: NavItemProps) {\n const s = SIZE[size];\n const v = VARIANT[variant];\n\n const rootProps = {\n // Only meaningful when `asChild` renders a real link — a decorative span with\n // aria-current would be a lie.\n 'aria-current': asChild && isActive ? ('page' as const) : undefined,\n // Same attribute the disclosure components and `TableRow` use, so the state is\n // addressable from a consumer's CSS. `active` rather than `selected`: a nav row is where\n // you *are* (`aria-current=\"page\"`), which is a different thing from a row you have\n // *picked* (`aria-selected`) — `TableRow` is the latter and says `selected`.\n 'data-state': isActive ? ('active' as const) : undefined,\n className: clsx(\n 'relative flex items-center transition-colors',\n // Unconditional: a row can also become focusable by the caller putting it inside a\n // link, which is how `src/sidebar/` uses it. A ring that only appears under `asChild`\n // leaves that case with no visible focus at all.\n // The offset is `default-secondary`, not `default`: a nav row's home is the sidebar\n // rail, and `ring-offset-default` is #FFFFFF, so a focused `plain` row drew a 1px white\n // halo on the #F5F5F5 rail. The offset itself is load-bearing — in dark mode\n // `ring-brand` and `bg-brand` are both #F1F7FD, so without it a focused *active* row\n // would have no visible ring at its inner edge.\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default-secondary',\n s.box,\n // Expanded rows fill the nav; a collapsed one is a centred square, not a stretched row.\n collapsed ? clsx('justify-center', s.square) : 'w-full',\n isActive ? v.active : v.inactive,\n className,\n ),\n ...rest,\n };\n\n const content = (\n <>\n {icon != null ? (\n <span aria-hidden className=\"shrink-0 [&_svg]:size-4\">\n {icon}\n </span>\n ) : (\n // Icons are optional, but the collapsed rail hides the label — so a row with neither\n // renders as an empty box. Through 0.5.0 that is exactly what a nav without icons\n // collapsed to, the docs site's own 36-row sidebar included. The monogram is\n // decorative in the same way the icon is: the `sr-only` label below still names the\n // row.\n collapsed && (\n <span\n aria-hidden\n // `min-w-4` rather than `size-4`: the box matches the 16px an icon would take,\n // but a wide pair like \"MW\" is allowed to outgrow it rather than be clipped.\n className=\"flex h-4 min-w-4 shrink-0 items-center justify-center text-body-tiny font-semibold leading-none tracking-tight\"\n >\n {monogram(label)}\n </span>\n )\n )}\n {/* `collapsed` hides the label visually but keeps it in the accessibility tree.\n Through 0.3.0 the span was not rendered at all and no `aria-label` replaced it,\n so a collapsed sidebar was nine unlabelled icon links — the icon itself carries\n no name, being decorative. */}\n <span\n className={clsx(\n 'min-w-0 truncate font-regular leading-snug',\n s.label,\n collapsed ? 'sr-only' : 'flex-1',\n )}\n >\n {label}\n </span>\n {indicator && (\n <span\n // The dot is the only carrier of \"there is something new here\", so it needs a\n // name of its own rather than being purely decorative.\n role=\"status\"\n aria-label=\"Unread\"\n className=\"absolute -right-px -top-px size-2 rounded-full bg-danger\"\n />\n )}\n </>\n );\n\n if (asChild) {\n // The child element becomes the row itself, so the icon/label/indicator go inside it\n // and its own children (usually nothing, since the label comes from `label`) are\n // discarded in favour of the composed content.\n return (\n <Slot wrapChildren={() => content} {...rootProps}>\n {children}\n </Slot>\n );\n }\n\n return <span {...rootProps}>{content}</span>;\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type EyebrowLabelVariant = 'uppercase' | 'plain';\n\nexport interface EyebrowLabelProps {\n children: ReactNode;\n /**\n * `uppercase` is the dominant form (nine of twelve source copies).\n * `plain` covers the entity-detail / reviewer-detail variant, whose label text is\n * already capitalised in the source string.\n */\n variant?: EyebrowLabelVariant;\n className?: string;\n}\n\n/**\n * Small semibold label above a group of fields.\n *\n * Replaces twelve copies across three variants:\n * `mb-2 text-body-tiny font-semibold uppercase tracking-wide …` (×9)\n * `text-[11px] font-semibold … tracking-wide` (×5, entity/reviewer detail)\n * `text-body-tiny font-semibold uppercase tracking-wider` (×2, entity onboarding)\n *\n * `text-body-tiny` is 11px, so the `text-[11px]` variant collapses into it exactly.\n * The `tracking-wider` copies become `tracking-wide` — a 0.0125em difference at 11px,\n * i.e. sub-pixel.\n */\nexport function EyebrowLabel({ children, variant = 'uppercase', className }: EyebrowLabelProps) {\n return (\n <p\n className={clsx(\n 'text-body-tiny font-semibold tracking-wide text-default-secondary',\n variant === 'uppercase' && 'uppercase',\n className,\n )}\n >\n {children}\n </p>\n );\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\n\nexport type SeparatorOrientation = 'horizontal' | 'vertical';\n\nexport interface SeparatorProps extends HTMLAttributes<HTMLDivElement> {\n orientation?: SeparatorOrientation;\n /**\n * `true` when the rule is purely visual, which is the common case. A decorative\n * separator is `role=\"none\"` and stays out of the accessibility tree; a semantic one\n * is `role=\"separator\"` and announces a break between groups.\n */\n decorative?: boolean;\n}\n\n/**\n * A hairline rule. Matches Figma's `Menu Separator`, generalised to both orientations.\n *\n * Drawn as a filled element rather than a border, because a 1px border on a flex child\n * collapses to nothing at some zoom levels while a `1px` height does not — which is why\n * the preset carries a `divider` background token separate from `border-default`.\n */\nexport const Separator = forwardRef<HTMLDivElement, SeparatorProps>(function Separator(\n { orientation = 'horizontal', decorative = true, className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n role={decorative ? 'none' : 'separator'}\n aria-orientation={decorative ? undefined : orientation}\n data-slot=\"separator\"\n className={clsx(\n 'shrink-0 bg-divider',\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px',\n className,\n )}\n {...rest}\n />\n );\n});\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport type KbdSize = 'sm' | 'md';\n\nexport interface KbdProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n size?: KbdSize;\n}\n\nconst SIZE: Record<KbdSize, string> = {\n sm: 'h-4 min-w-4 px-1 text-body-tiny',\n md: 'h-5 min-w-5 px-1.5 text-body-xs',\n};\n\n/**\n * A keyboard key. Matches Figma's `Menu Shortcut`.\n *\n * Renders a real `<kbd>` so assistive tech announces it as key input rather than as a\n * stray glyph — `⌘K` read as plain text is \"place of interest sign K\".\n *\n * Pass one key per element and let the caller supply the joiner, so a shortcut reads as\n * separate keys instead of one run-together string:\n *\n * <Kbd>⌘</Kbd><Kbd>K</Kbd>\n */\nexport const Kbd = forwardRef<HTMLElement, KbdProps>(function Kbd(\n { children, size = 'md', className, ...rest },\n ref,\n) {\n return (\n <kbd\n ref={ref}\n data-slot=\"kbd\"\n className={clsx(\n 'inline-flex items-center justify-center rounded border border-default bg-default-secondary',\n 'font-medium tabular-nums text-default-secondary',\n SIZE[size],\n className,\n )}\n {...rest}\n >\n {children}\n </kbd>\n );\n});\n","import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { LuChevronRight } from 'react-icons/lu';\nimport { Slot } from '../../lib/slot';\n\nexport interface BreadcrumbProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n /** Names the landmark. Default `Breadcrumb`. */\n label?: string;\n}\n\n/**\n * Breadcrumb trail.\n *\n * A `<nav>` wrapping an ordered list, which is the whole semantic point: the order *is* the\n * hierarchy, so `<ol>` says something `<div>` cannot, and the landmark lets a screen reader\n * user jump to the trail without walking the header.\n *\n * The separators are `aria-hidden` and generated by the list, not passed in — a chevron\n * announced between every crumb is noise, and the `/` characters people usually hand-type\n * get read out one by one.\n */\nexport const Breadcrumb = forwardRef<HTMLElement, BreadcrumbProps>(function Breadcrumb(\n { children, label = 'Breadcrumb', className, ...rest },\n ref,\n) {\n return (\n <nav ref={ref} aria-label={label} data-slot=\"breadcrumb\" {...rest}>\n <ol className={clsx('flex flex-wrap items-center gap-1.5 p-0 text-body-xs', className)}>\n {children}\n </ol>\n </nav>\n );\n});\n\nexport interface BreadcrumbItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n children: ReactNode;\n /**\n * The page you are on. Renders as plain text with `aria-current=\"page\"` rather than a\n * link — a link to the current page is a dead control, and the APG says the last crumb\n * should not be one.\n */\n current?: boolean;\n /** Render a router `Link` instead of an `<a>`. */\n asChild?: boolean;\n /** Suppress the leading separator. Set automatically on the first item you render. */\n first?: boolean;\n}\n\nexport const BreadcrumbItem = forwardRef<HTMLAnchorElement, BreadcrumbItemProps>(\n function BreadcrumbItem({ children, current = false, asChild = false, first = false, className, ...rest }, ref) {\n return (\n <li className=\"flex items-center gap-1.5\">\n {!first && (\n <LuChevronRight aria-hidden className=\"size-3.5 shrink-0 text-icon-default-tertiary\" />\n )}\n {current ? (\n <span aria-current=\"page\" className={clsx('font-medium text-default', className)}>\n {children}\n </span>\n ) : asChild ? (\n <Slot\n className={clsx(\n 'rounded text-default-secondary transition-colors hover:text-brand',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n className,\n )}\n {...rest}\n >\n {children}\n </Slot>\n ) : (\n <a\n ref={ref}\n className={clsx(\n 'rounded text-default-secondary transition-colors hover:text-brand',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n className,\n )}\n {...rest}\n >\n {children}\n </a>\n )}\n </li>\n );\n },\n);\n\nexport interface BreadcrumbEllipsisProps extends HTMLAttributes<HTMLSpanElement> {}\n\n/**\n * Stands in for collapsed middle crumbs on a deep trail.\n *\n * A `<span>`, not a button: it is a truncation marker, and making it a disabled control\n * puts an unusable stop in the tab order. If the hidden crumbs need to be reachable, wrap\n * this in a `DropdownMenuTrigger` and list them.\n */\nexport const BreadcrumbEllipsis = forwardRef<HTMLSpanElement, BreadcrumbEllipsisProps>(\n function BreadcrumbEllipsis({ className, ...rest }, ref) {\n return (\n <li className=\"flex items-center gap-1.5\">\n <LuChevronRight aria-hidden className=\"size-3.5 shrink-0 text-icon-default-tertiary\" />\n <span\n ref={ref}\n aria-label=\"Collapsed items\"\n className={clsx('px-0.5 text-default-tertiary', className)}\n {...rest}\n >\n …\n </span>\n </li>\n );\n },\n);\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { LuChevronLeft, LuChevronRight } from 'react-icons/lu';\n\nexport type PaginationType = 'default' | 'dots';\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** 1-based. */\n page: number;\n /** Total number of pages. Values below 1 render nothing. */\n pageCount: number;\n onPageChange: (page: number) => void;\n /** Matches Figma's `Type` axis. `dots` is the compact carousel form. */\n type?: PaginationType;\n /** How many numbered pages to show either side of the current one. Default `1`. */\n siblingCount?: number;\n /** Names the nav landmark. Default `Pagination`. */\n label?: string;\n}\n\nconst GAP = '…';\n\n/**\n * Builds the visible page list with ellipses.\n *\n * Always returns first and last, the current page, and `siblingCount` either side. The\n * window is widened rather than allowed to shrink near the ends, so the control does not\n * change width as the user pages through — a row of buttons that reflows under the cursor\n * is how you mis-click.\n */\nexport function paginationRange(\n page: number,\n pageCount: number,\n siblingCount = 1,\n): (number | typeof GAP)[] {\n // first + last + current + 2 siblings + 2 possible gaps\n const totalSlots = siblingCount * 2 + 5;\n if (pageCount <= totalSlots) {\n return Array.from({ length: pageCount }, (_, i) => i + 1);\n }\n\n const left = Math.max(page - siblingCount, 1);\n const right = Math.min(page + siblingCount, pageCount);\n\n const showLeftGap = left > 3;\n const showRightGap = right < pageCount - 2;\n\n if (!showLeftGap && showRightGap) {\n const count = siblingCount * 2 + 3;\n return [...Array.from({ length: count }, (_, i) => i + 1), GAP, pageCount];\n }\n\n if (showLeftGap && !showRightGap) {\n const count = siblingCount * 2 + 3;\n return [1, GAP, ...Array.from({ length: count }, (_, i) => pageCount - count + 1 + i)];\n }\n\n return [\n 1,\n GAP,\n ...Array.from({ length: right - left + 1 }, (_, i) => left + i),\n GAP,\n pageCount,\n ];\n}\n\nconst ARROW_BASE = clsx(\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-lg border transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:border-disabled disabled:bg-disabled disabled:text-disabled',\n 'border-default bg-default text-default hover:bg-default-secondary hover:text-brand',\n);\n\n/**\n * Pagination. Matches Figma's `Pagination` (`Type: Default | Dots`), `Pagination Page`\n * (`State: Default | Hover | Current | Current Hover`), `Pagination Next` / `Previous`\n * (`Default | Hover | Disabled`) and `Pagination dots` (`Active | Inactive`).\n *\n * `DataTable` had no pager at all, so every consumer built one. Notes on the semantics:\n *\n * - A `<nav>` landmark with a name, so it is reachable by landmark navigation.\n * - `aria-current=\"page\"` on the active page. It is the only non-visual signal of which\n * page you are on; the filled background is not announced.\n * - Each page button is named \"Page 3\", not \"3\" — a bare number read out of context tells\n * a screen reader user nothing about what activating it does.\n * - The ellipsis is inert text, not a disabled button, so it is skipped rather than\n * announced as an unavailable control.\n */\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n pageCount,\n onPageChange,\n type = 'default',\n siblingCount = 1,\n label = 'Pagination',\n className,\n ...rest\n },\n ref,\n) {\n if (pageCount < 1) return null;\n\n const go = (next: number) => {\n const clamped = Math.min(Math.max(next, 1), pageCount);\n if (clamped !== page) onPageChange(clamped);\n };\n\n return (\n <nav\n ref={ref}\n aria-label={label}\n data-slot=\"pagination\"\n className={clsx('flex items-center gap-1.5', className)}\n {...rest}\n >\n <button\n type=\"button\"\n aria-label=\"Previous page\"\n disabled={page <= 1}\n onClick={() => go(page - 1)}\n className={ARROW_BASE}\n >\n <LuChevronLeft aria-hidden className=\"size-4\" />\n </button>\n\n {type === 'dots' ? (\n // The dots form has no room for numbers, so the list itself is the only place the\n // position can be stated — hence the live-region-free but explicitly named group.\n <span\n role=\"group\"\n aria-label={`Page ${page} of ${pageCount}`}\n className=\"flex items-center gap-2 px-2\"\n >\n {Array.from({ length: pageCount }, (_, i) => i + 1).map((n) => (\n <button\n key={n}\n type=\"button\"\n aria-label={`Page ${n}`}\n aria-current={n === page ? 'page' : undefined}\n onClick={() => go(n)}\n className={clsx(\n 'size-2 rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 focus-visible:ring-offset-default',\n n === page ? 'bg-brand' : 'bg-default-tertiary hover:bg-neutral-secondary',\n )}\n />\n ))}\n </span>\n ) : (\n paginationRange(page, pageCount, siblingCount).map((entry, index) =>\n entry === GAP ? (\n <span\n key={`gap-${index}`}\n aria-hidden\n className=\"inline-flex size-9 items-center justify-center text-body-sm text-default-tertiary\"\n >\n {GAP}\n </span>\n ) : (\n <button\n key={entry}\n type=\"button\"\n aria-label={`Page ${entry}`}\n aria-current={entry === page ? 'page' : undefined}\n onClick={() => go(entry)}\n className={clsx(\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-lg border text-body-sm tabular-nums transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n entry === page\n ? 'border-brand bg-brand font-semibold text-brand-on-brand'\n : 'border-default bg-default text-default hover:bg-default-secondary hover:text-brand',\n )}\n >\n {entry}\n </button>\n ),\n )\n )}\n\n <button\n type=\"button\"\n aria-label=\"Next page\"\n disabled={page >= pageCount}\n onClick={() => go(page + 1)}\n className={ARROW_BASE}\n >\n <LuChevronRight aria-hidden className=\"size-4\" />\n </button>\n </nav>\n );\n});\n","import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\n\nexport type NavigationMenuOrientation = 'horizontal' | 'vertical';\nexport type NavigationMenuVariant = 'pill' | 'link';\n\nexport interface NavigationMenuProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n orientation?: NavigationMenuOrientation;\n /** Names the nav landmark. Required when a page has more than one `<nav>`. */\n label: string;\n}\n\n/**\n * A navigation landmark wrapping a list of links. Matches Figma's `Navigation Pill List`\n * and `Navigation Button List`.\n *\n * Why the `<nav>` + `<ul>` + `<li>` nesting rather than a flat row of anchors: the list is\n * what makes a screen reader announce \"list, 5 items\" and lets the user jump the whole\n * block. A bare row of links is announced one at a time with no sense of how many there\n * are or where the set ends. The `label` is required for the same reason — an unnamed\n * landmark in a page with a sidebar *and* a top bar is not navigable.\n */\nexport const NavigationMenu = forwardRef<HTMLElement, NavigationMenuProps>(\n function NavigationMenu({ children, orientation = 'horizontal', label, className, ...rest }, ref) {\n return (\n <nav ref={ref} aria-label={label} data-slot=\"navigation-menu\" {...rest}>\n <ul\n className={clsx(\n 'flex list-none p-0',\n orientation === 'vertical' ? 'flex-col gap-1' : 'flex-row items-center gap-1',\n className,\n )}\n >\n {children}\n </ul>\n </nav>\n );\n },\n);\n\nexport interface NavigationMenuItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n children: ReactNode;\n /** Matches Figma's `State: Active`. Sets `aria-current=\"page\"`. */\n active?: boolean;\n variant?: NavigationMenuVariant;\n /** Render a router `Link` instead of an `<a>`. */\n asChild?: boolean;\n /** Leading glyph. Marked decorative automatically. */\n icon?: ReactNode;\n}\n\n/**\n * A single navigation link. Matches Figma's `Navigation Pill` and `Navigation Button`\n * (`State: Default | Active | Hover`).\n *\n * `aria-current=\"page\"` is the point: the filled pill is not announced, so without it a\n * screen reader user cannot tell which page they are on.\n */\nexport const NavigationMenuItem = forwardRef<HTMLAnchorElement, NavigationMenuItemProps>(\n function NavigationMenuItem(\n { children, active = false, variant = 'pill', asChild = false, icon, className, ...rest },\n ref,\n ) {\n const content = (\n <>\n {icon && (\n <span aria-hidden className=\"shrink-0 [&_svg]:size-4\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 truncate\">{children}</span>\n </>\n );\n\n const linkProps = {\n 'aria-current': active ? ('page' as const) : undefined,\n className: clsx(\n 'inline-flex items-center gap-2 whitespace-nowrap transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n variant === 'pill'\n ? clsx(\n 'rounded-lg px-3 py-1.5 text-body-xs font-medium',\n active\n ? 'bg-brand text-brand-on-brand'\n : 'text-default-secondary hover:bg-default-secondary hover:text-default',\n )\n : clsx(\n 'rounded px-1 py-0.5 text-body-sm',\n active\n ? 'font-semibold text-brand'\n : 'text-default-secondary hover:text-default',\n ),\n className,\n ),\n ...rest,\n };\n\n return (\n <li>\n {asChild ? (\n <Slot wrapChildren={() => content} {...linkProps}>\n {children}\n </Slot>\n ) : (\n <a ref={ref} {...linkProps}>\n {content}\n </a>\n )}\n </li>\n );\n },\n);\n","import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\n\n/**\n * The type ramp as components, mirroring Figma's `Text*` primitives one-for-one:\n * `Text`, `Text Strong`, `Text Emphasis`, `Text Small`, `Text Code`, `Text Link`,\n * `Text Heading`, `Text Subheading`, `Text Subtitle`, `Text Title Page`,\n * `Text Title Hero`, `Text List`, `Text List Item`, `Text Link List`.\n *\n * These existed in Figma with settled styles and had no code counterpart, so every\n * consumer reached for a raw `text-body-sm text-default` triplet and the ramp drifted.\n * Each component pins the size/weight/colour combination and nothing else, so layout\n * stays the caller's job.\n *\n * All of them take `asChild`, because the right element is contextual — a `Heading` is an\n * `<h2>` on a page and an `<h3>` inside a card, and only the caller knows the outline.\n */\n\ntype BaseProps = HTMLAttributes<HTMLElement> & {\n children?: ReactNode;\n asChild?: boolean;\n};\n\n/** Factory for the plain ramp entries — identical except for element and classes. */\nfunction textComponent(\n displayName: string,\n defaultElement: 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'strong' | 'em' | 'code',\n classes: string,\n) {\n const Component = forwardRef<HTMLElement, BaseProps>(function TextComponent(\n { children, asChild = false, className, ...rest },\n ref,\n ) {\n const Root = (asChild ? Slot : defaultElement) as 'p';\n return (\n <Root ref={ref as never} className={clsx(classes, className)} {...rest}>\n {children}\n </Root>\n );\n });\n Component.displayName = displayName;\n return Component;\n}\n\n// ── Body ───────────────────────────────────────────────────────────────────────\n\nexport type TextProps = BaseProps;\n\n/** `Text` — the default body paragraph. */\nexport const Text = textComponent('Text', 'p', 'text-body text-default');\n\n/** `Text Small` — secondary body copy. */\nexport const TextSmall = textComponent('TextSmall', 'p', 'text-body-sm text-default-secondary');\n\n/** `Text Tiny` — the smallest readable step; captions and table meta. */\nexport const TextTiny = textComponent('TextTiny', 'p', 'text-body-tiny text-default-secondary');\n\n/** `Text Strong` — emphasis by weight, in a real `<strong>`. */\nexport const TextStrong = textComponent('TextStrong', 'strong', 'font-semibold text-default');\n\n/** `Text Emphasis` — emphasis by slant, in a real `<em>`. */\nexport const TextEmphasis = textComponent('TextEmphasis', 'em', 'italic text-default');\n\n/** `Text Code` — inline monospace. */\nexport const TextCode = textComponent(\n 'TextCode',\n 'code',\n 'rounded border border-default bg-default-secondary px-1 py-0.5 font-mono text-body-xs text-default',\n);\n\n// ── Headings ───────────────────────────────────────────────────────────────────\n\n/** `Text Title Hero` — the largest step, one per page at most. */\nexport const TitleHero = textComponent('TitleHero', 'h1', 'text-title-hero font-bold text-default');\n\n/** `Text Title Page` — page title. */\nexport const TitlePage = textComponent('TitlePage', 'h1', 'text-title font-bold text-default');\n\n/** `Text Subtitle` — a lead paragraph under a title; regular weight by design. */\nexport const Subtitle = textComponent('Subtitle', 'p', 'text-subtitle text-default-secondary');\n\n/** `Text Heading` — section heading. */\nexport const Heading = textComponent('Heading', 'h2', 'text-heading font-semibold text-default');\n\n/** `Text Subheading` — subsection heading; regular weight, matching Figma. */\nexport const Subheading = textComponent('Subheading', 'h3', 'text-subheading text-default');\n\n// ── Link ───────────────────────────────────────────────────────────────────────\n\nexport interface TextLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n children?: ReactNode;\n asChild?: boolean;\n}\n\n/**\n * `Text Link`. Underlined rather than colour-only: colour alone is not a sufficient\n * distinction for a link inside a run of text (WCAG 1.4.1).\n */\nexport const TextLink = forwardRef<HTMLAnchorElement, TextLinkProps>(function TextLink(\n { children, asChild = false, className, ...rest },\n ref,\n) {\n const Root = (asChild ? Slot : 'a') as 'a';\n return (\n <Root\n ref={ref}\n className={clsx(\n 'rounded text-brand underline decoration-1 underline-offset-2 transition-colors',\n 'hover:text-brand-secondary',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n className,\n )}\n {...rest}\n >\n {children}\n </Root>\n );\n});\n\n// ── Lists ──────────────────────────────────────────────────────────────────────\n\nexport type TextListVariant = 'bulleted' | 'numbered' | 'plain';\nexport type TextListDensity = 'default' | 'compact';\n\nexport interface TextListProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n variant?: TextListVariant;\n /** Matches Figma's `Density` axis on `Text List` / `Text Link List`. */\n density?: TextListDensity;\n}\n\nconst LIST_MARKER: Record<TextListVariant, string> = {\n bulleted: 'list-disc pl-5',\n numbered: 'list-decimal pl-5',\n plain: 'list-none pl-0',\n};\n\n/** `Text List` — a real `<ul>`/`<ol>`, so item count is announced. */\nexport const TextList = forwardRef<HTMLElement, TextListProps>(function TextList(\n { children, variant = 'bulleted', density = 'default', className, ...rest },\n ref,\n) {\n const Root = (variant === 'numbered' ? 'ol' : 'ul') as 'ul';\n return (\n <Root\n ref={ref as never}\n className={clsx(\n 'text-body text-default',\n LIST_MARKER[variant],\n density === 'compact' ? 'space-y-0.5' : 'space-y-1.5',\n className,\n )}\n {...rest}\n >\n {children}\n </Root>\n );\n});\n\nexport type TextListItemProps = HTMLAttributes<HTMLLIElement> & { children?: ReactNode };\n\n/** `Text List Item`. */\nexport const TextListItem = forwardRef<HTMLLIElement, TextListItemProps>(function TextListItem(\n { children, className, ...rest },\n ref,\n) {\n return (\n <li ref={ref} className={clsx('text-body text-default', className)} {...rest}>\n {children}\n </li>\n );\n});\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { WidgetTitle } from './widget-title';\nimport type { WidgetTitleSize } from './widget-title';\n\nexport type WidgetHeaderEyebrowVariant = 'uppercase' | 'plain';\n\nexport interface WidgetHeaderProps {\n eyebrow?: string;\n eyebrowVariant?: WidgetHeaderEyebrowVariant;\n title: string;\n titleSize?: WidgetTitleSize;\n subtitle?: string;\n badge?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\n// uppercase: 11px/medium/tracked, matches Variation 2 mockups · plain: 13px/regular, matches Variation 1's small label line\nconst eyebrowStyles: Record<WidgetHeaderEyebrowVariant, string> = {\n uppercase: 'text-body-tiny font-medium uppercase tracking-[0.66px] text-default-secondary',\n plain: 'text-body-xs leading-[1.4] text-default-secondary',\n};\n\nexport function WidgetHeader({\n eyebrow,\n eyebrowVariant = 'uppercase',\n title,\n titleSize,\n subtitle,\n badge,\n action,\n className,\n}: WidgetHeaderProps) {\n return (\n <div className={clsx('flex items-start justify-between gap-2', className)}>\n <div className=\"min-w-0 flex-1\">\n {eyebrow && <p className={eyebrowStyles[eyebrowVariant]}>{eyebrow}</p>}\n <WidgetTitle size={titleSize}>{title}</WidgetTitle>\n {subtitle && (\n <p className=\"mt-1 text-body-xs text-default-secondary leading-snug\">{subtitle}</p>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {badge}\n {action}\n </div>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport type WidgetTitleSize = 'sm' | 'md' | 'lg';\n\nexport interface WidgetTitleProps {\n children: ReactNode;\n size?: WidgetTitleSize;\n className?: string;\n}\n\n// sm: 16px/semibold (default) · md: 18px/bold (Variation 2 mockups) · lg: 20px/semibold (Variation 1 mockups)\nconst sizeStyles: Record<WidgetTitleSize, string> = {\n sm: 'text-subheading-sm font-semibold leading-none',\n // Was `text-[18px]`, which had no step on the type scale (Scale 04 = 16, Scale 05 = 20).\n // Now 20px, so `md` and `lg` are the same size and separate on weight alone — bold vs\n // semibold. That is the intended trade for getting off an off-scale literal.\n md: 'text-subheading font-bold leading-normal',\n lg: 'text-subheading font-semibold leading-[1.2]',\n};\n\nexport function WidgetTitle({ children, size = 'sm', className }: WidgetTitleProps) {\n return (\n <h3 className={clsx(sizeStyles[size], 'text-default', className)}>\n {children}\n </h3>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport interface WidgetFooterProps {\n caption?: string;\n subcaption?: string;\n action?: ReactNode;\n className?: string;\n}\n\nexport function WidgetFooter({ caption, subcaption, action, className }: WidgetFooterProps) {\n return (\n <div className={clsx('flex items-center gap-3', className)}>\n {caption && (\n <div className=\"flex items-stretch gap-3 flex-1 min-w-0\">\n <div className=\"w-0.5 shrink-0 self-stretch rounded-full bg-brand\" />\n <div className=\"min-w-0\">\n <p className=\"text-body-sm font-medium text-default leading-snug\">\n {caption}\n </p>\n {subcaption && (\n <p className=\"mt-0.5 text-body-xs text-default-secondary\">{subcaption}</p>\n )}\n </div>\n </div>\n )}\n {action && <div className=\"ml-auto shrink-0\">{action}</div>}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { StatusTone } from '../status/status-badge';\n\nconst DOT_TONE: Record<StatusTone, string> = {\n neutral: 'bg-status-dot-neutral',\n info: 'bg-status-dot-info',\n warning: 'bg-status-dot-warning',\n caution: 'bg-status-dot-caution',\n accent: 'bg-status-dot-accent',\n positive: 'bg-status-dot-positive',\n danger: 'bg-status-dot-danger',\n};\n\nexport interface StatTileProps {\n label: string;\n value: string | number;\n /** Status tone for the leading dot. Prefer this over `dotColor`. */\n tone?: StatusTone;\n /**\n * @deprecated Pass `tone` instead. A raw colour here bypasses the token layer,\n * which is how competing status palettes drift apart.\n */\n dotColor?: string;\n className?: string;\n}\n\nexport function StatTile({ label, value, tone, dotColor, className }: StatTileProps) {\n const showDot = Boolean(tone || dotColor);\n\n return (\n <div\n className={clsx(\n 'flex flex-col gap-2 rounded-xl border border-default bg-default p-4',\n className,\n )}\n >\n <div className=\"flex items-center gap-1.5\">\n {showDot && (\n <span\n className={clsx('size-2 shrink-0 rounded-full', tone && DOT_TONE[tone])}\n style={tone ? undefined : { backgroundColor: dotColor }}\n />\n )}\n <span className=\"text-body-xs font-medium text-default-secondary whitespace-nowrap\">\n {label}\n </span>\n </div>\n <span className=\"text-heading font-semibold text-default leading-none\">{value}</span>\n </div>\n );\n}\n","import clsx from 'clsx';\n\nexport type StatNumberSize = 'sm' | 'md' | 'lg';\n\nexport type StatNumberWeight = 'medium' | 'bold';\n\nexport interface StatNumberProps {\n value: string | number;\n unit?: string;\n size?: StatNumberSize;\n weight?: StatNumberWeight;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex color, overrides the default text color via inline style. Use when the exact source color doesn't match a design token. */\n color?: string;\n className?: string;\n}\n\n// 32 / 40 / 48px — the --typo-scale-07/08/09 steps. These read `text-scale-0*` until\n// 0.3.0, which the preset never defined, so every size emitted no font-size at all.\nconst sizeStyles: Record<StatNumberSize, string> = {\n sm: 'text-subtitle',\n md: 'text-subtitle-lg',\n lg: 'text-title',\n};\n\nconst weightStyles: Record<StatNumberWeight, string> = {\n medium: 'font-medium',\n bold: 'font-bold',\n};\n\nexport function StatNumber({ value, unit, size = 'md', weight = 'bold', color, className }: StatNumberProps) {\n return (\n <p\n className={clsx(sizeStyles[size], weightStyles[weight], 'leading-none', !color && 'text-default', className)}\n style={color ? { color } : undefined}\n >\n {value}\n {unit && (\n <span className=\"ml-1 text-subheading font-medium text-default-secondary\">{unit}</span>\n )}\n </p>\n );\n}\n","import clsx from 'clsx';\n\nexport type ScoreValueSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl';\nexport type ScoreValueWeight = 'normal' | 'semibold' | 'bold';\nexport type ScoreTone = 'brand' | 'positive' | 'warning' | 'danger' | 'neutral' | 'default';\nexport type ScoreValueTone = ScoreTone | 'auto';\n\n/**\n * The four tones the automatic ramp can produce.\n *\n * Narrower than `ScoreTone` on purpose: a ramp position is always one of these, so the\n * result is directly assignable to `ProgressBarTone` too — which is what lets a caller\n * tone a bar and its score from one `getScoreTone` call.\n */\nexport type ScoreRampTone = 'positive' | 'neutral' | 'warning' | 'danger';\n\n/** Which end of the scale is the bad end. */\nexport type ScoreDirection = 'higher-is-worse' | 'higher-is-better';\n\nexport interface ScoreThresholds {\n /** At or above this, the score is `danger`. */\n danger: number;\n /** At or above this, `warning`. */\n warning: number;\n /** At or above this, `neutral`. Below it, `positive`. */\n neutral: number;\n}\n\n/**\n * Default ramp, on a 0–100 scale read as \"higher is worse\" — the risk case.\n *\n * 0.2.0's ramp had only four stops and resolved 65–79 to `brand` (the blue brand\n * colour), which left `warning` and `positive` unreachable without passing `tone`\n * by hand. This is a real five-stop ramp.\n */\nexport const DEFAULT_SCORE_THRESHOLDS: ScoreThresholds = { danger: 80, warning: 65, neutral: 50 };\n\n/**\n * Resolve a numeric score to a tone.\n *\n * Was `getRiskTone` in 0.2.0, with the thresholds and the direction both hardcoded.\n */\nexport function getScoreTone(\n score: number,\n {\n direction = 'higher-is-worse',\n thresholds = DEFAULT_SCORE_THRESHOLDS,\n }: { direction?: ScoreDirection; thresholds?: ScoreThresholds } = {},\n): ScoreRampTone {\n // Flip the score, not the comparisons — one ramp, read from either end.\n const v = direction === 'higher-is-better' ? 100 - score : score;\n if (v >= thresholds.danger) return 'danger';\n if (v >= thresholds.warning) return 'warning';\n if (v >= thresholds.neutral) return 'neutral';\n return 'positive';\n}\n\n// 13 / 14 / 16 / 20 / 32px\nconst SIZE: Record<ScoreValueSize, string> = {\n sm: 'text-body-xs',\n md: 'text-body-sm',\n lg: 'text-subheading-sm',\n xl: 'text-subheading',\n '2xl': 'text-subtitle',\n};\n\nconst WEIGHT: Record<ScoreValueWeight, string> = {\n normal: 'font-normal',\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nconst TONE: Record<ScoreTone, string> = {\n brand: 'text-brand',\n positive: 'text-positive',\n warning: 'text-warning',\n danger: 'text-danger',\n neutral: 'text-default-secondary',\n default: 'text-default',\n};\n\nexport interface ScoreValueProps {\n value: string | number;\n /** Trailing caption — `/100`, `High`, `of target`. */\n label?: string;\n size?: ScoreValueSize;\n weight?: ScoreValueWeight;\n /** `auto` derives the tone from `value` via {@link getScoreTone}. */\n tone?: ScoreValueTone;\n direction?: ScoreDirection;\n thresholds?: ScoreThresholds;\n className?: string;\n}\n\n/**\n * A scored number with an optional caption and a tone that can track its value.\n *\n * Was `RiskScore`. Nothing about it was ever risk-specific except the name and the\n * direction of its ramp, so both are now parameters: use it for a risk score, a\n * compliance score, a match confidence, a utilisation percentage.\n *\n * Not to be confused with `StatNumber`, which is the *large display* number with a\n * unit (32–48px, for tiles and widget headlines). `ScoreValue` is the inline one with\n * a label and a tone ramp.\n */\nexport function ScoreValue({\n value,\n label,\n size = 'md',\n weight = 'bold',\n tone = 'auto',\n direction = 'higher-is-worse',\n thresholds = DEFAULT_SCORE_THRESHOLDS,\n className,\n}: ScoreValueProps) {\n // A numeric-looking string still resolves. In 0.2.0 `tone=\"auto\"` fell back to\n // `default` for any string, so callers passing `score=\"82\"` silently got no tone.\n const numeric = typeof value === 'number' ? value : Number(value);\n const resolved: ScoreTone =\n tone === 'auto'\n ? Number.isFinite(numeric)\n ? getScoreTone(numeric, { direction, thresholds })\n : 'default'\n : tone;\n\n return (\n <span className={clsx('inline-flex items-baseline gap-1', className)}>\n <span className={clsx(SIZE[size], WEIGHT[weight], TONE[resolved])}>{value}</span>\n {label && <span className=\"text-body-xs text-default-secondary whitespace-nowrap\">{label}</span>}\n </span>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type TileGridColumns = 2 | 3 | 4 | 5 | 6;\n\n/**\n * Responsive column counts. Every source copy started two-up on mobile and stepped\n * to its full count at one breakpoint.\n *\n * The twelve source grids disagreed on which: seven used `lg:`, three used `md:`.\n * Standardising on `lg:` matches eight of them byte-for-byte and is the safer choice\n * — five tiles at `md` (768px) was cramped. `alerts`, `settings-users` and\n * `settings-organization` therefore stay two-up slightly longer on tablets than\n * before; that is the one deliberate layout change here.\n *\n * Six keeps its intermediate `sm:grid-cols-3` step, matching entities-listing —\n * without it, six tiles would stack 2×3 on tablet instead of 3×2.\n */\nexport type TileGridBreakpoint = 'sm' | 'md' | 'lg';\n\nconst COLUMNS: Record<TileGridBreakpoint, Record<TileGridColumns, string>> = {\n sm: {\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 sm:grid-cols-3',\n 4: 'grid-cols-2 sm:grid-cols-4',\n 5: 'grid-cols-2 sm:grid-cols-5',\n 6: 'grid-cols-2 sm:grid-cols-6',\n },\n md: {\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 md:grid-cols-3',\n 4: 'grid-cols-2 md:grid-cols-4',\n 5: 'grid-cols-2 md:grid-cols-5',\n 6: 'grid-cols-2 sm:grid-cols-3 md:grid-cols-6',\n },\n lg: {\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-2 lg:grid-cols-4',\n 5: 'grid-cols-2 lg:grid-cols-5',\n 6: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-6',\n },\n};\n\nexport interface TileGridProps {\n children: ReactNode;\n columns?: TileGridColumns;\n /**\n * Breakpoint at which the grid reaches its full column count. `lg` is the default\n * and correct for a full-width page. Narrow contexts — a stat row inside a panel,\n * as on the article detail page — legitimately need `sm`.\n */\n at?: TileGridBreakpoint;\n className?: string;\n}\n\n/**\n * A responsive grid of equal-width tiles.\n *\n * Was `StatTileGrid`, which read as a `StatTile`-specific component. It has never been\n * coupled to one: no context, no cloning, no constraint on `children`. It takes any\n * nodes — `StatTile`s, `Card`s, chart tiles — and only owns the column counts and the\n * `gap-3`. The rename says so.\n */\nexport function TileGrid({\n children,\n columns = 4,\n at = 'lg',\n className,\n}: TileGridProps) {\n return <div className={clsx('grid gap-3', COLUMNS[at][columns], className)}>{children}</div>;\n}\n","/**\n * Chart colour.\n *\n * SVG paints via the `stroke` / `fill` *attributes*, which cannot take a Tailwind\n * class — so charts resolve a `tone` to a CSS variable reference instead of a utility.\n * That keeps them on the token layer; 0.2.0's charts defaulted to raw hex (`#0c2d58`,\n * `rgba(140,155,176,0.5)`) and drifted from it.\n *\n * Every chart still accepts an explicit `color` string for genuinely data-driven\n * colour — a series whose colour comes from the data, not from semantics.\n */\nexport type ChartTone = 'brand' | 'info' | 'positive' | 'warning' | 'danger' | 'neutral';\n\nexport const CHART_TONE: Record<ChartTone, string> = {\n brand: 'var(--color-background-brand-default)',\n info: 'var(--status-info-dot)',\n positive: 'var(--color-background-positive-default)',\n warning: 'var(--color-background-warning-default)',\n danger: 'var(--color-background-danger-default)',\n neutral: 'var(--color-background-neutral-default)',\n};\n\n/** The muted track/rest colour behind a highlighted series. */\nexport const CHART_TRACK = 'var(--color-background-default-tertiary)';\n\n/**\n * Ordered sequence for multi-series charts, so two donuts in the same product never\n * assign different colours to the same first category. Semantic tones come first\n * because a chart with two or three series is usually still saying something.\n */\nexport const CHART_SEQUENCE: ChartTone[] = ['brand', 'info', 'positive', 'warning', 'danger', 'neutral'];\n\n/** Resolve an explicit colour, else a tone, else the sequence position. */\nexport function resolveChartColor(color: string | undefined, tone: ChartTone | undefined, index = 0): string {\n if (color) return color;\n if (tone) return CHART_TONE[tone];\n return CHART_TONE[CHART_SEQUENCE[index % CHART_SEQUENCE.length]];\n}\n","import clsx from 'clsx';\nimport { resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type BarChartOrientation = 'vertical' | 'horizontal';\nexport type BarChartSize = 'sm' | 'md' | 'lg';\n\n/** Thickness of one bar / one group slot, and the label type step. */\nconst SIZE: Record<BarChartSize, { band: number; gap: number; label: string }> = {\n sm: { band: 14, gap: 6, label: 'text-body-tiny' },\n md: { band: 20, gap: 8, label: 'text-body-xs' },\n lg: { band: 28, gap: 10, label: 'text-body-xs' },\n};\n\nexport interface BarChartSeries {\n label: string;\n /** One value per category. */\n values: number[];\n tone?: ChartTone;\n color?: string;\n}\n\nexport interface BarChartProps {\n /** Category names — the axis labels. */\n categories: string[];\n series: BarChartSeries[];\n orientation?: BarChartOrientation;\n /** Stack series on top of each other instead of placing them side by side. */\n stacked?: boolean;\n size?: BarChartSize;\n /** Overall length of the value axis, in px. */\n length?: number;\n /** Show the category labels along the axis. */\n showLabels?: boolean;\n /** Print each bar's value at the end of the bar. Horizontal orientation only. */\n showValues?: boolean;\n radius?: number;\n label?: string;\n className?: string;\n}\n\n/**\n * Grouped or stacked bars, in either orientation.\n *\n * Horizontal is the orientation the library was missing and the one that actually suits\n * category data, because long category names get a full line of width rather than being\n * rotated or truncated under a vertical bar.\n *\n * Deliberately axis-light: one baseline, no gridlines, no ticks. For anything needing\n * real axes or interaction, this is the wrong component.\n */\nexport function BarChart({\n categories,\n series,\n orientation = 'horizontal',\n stacked = false,\n size = 'md',\n length = 240,\n showLabels = true,\n showValues = false,\n radius = 3,\n label,\n className,\n}: BarChartProps) {\n const { band, gap, label: labelClass } = SIZE[size];\n if (categories.length === 0 || series.length === 0) return null;\n\n // Stacked bars share one band per category; grouped bars split it between series.\n const perCategory = stacked ? band : band * series.length + gap * (series.length - 1);\n\n const categoryTotals = categories.map((_, ci) =>\n stacked\n ? series.reduce((sum, s) => sum + Math.max(0, s.values[ci] ?? 0), 0)\n : Math.max(...series.map((s) => Math.max(0, s.values[ci] ?? 0))),\n );\n const max = Math.max(...categoryTotals, 1);\n\n const horizontal = orientation === 'horizontal';\n\n return (\n <div\n className={clsx('flex w-full min-w-0', horizontal ? 'flex-col gap-2' : 'flex-row items-end gap-3', className)}\n role={label ? 'img' : undefined}\n aria-label={label}\n // Without a label the chart is decoration and its bars are noise in the a11y tree.\n // Every other chart in the family had this fallback; BarChart was the one that did\n // not, so an unlabelled one announced each bar's markup.\n aria-hidden={label ? undefined : true}\n >\n {categories.map((category, ci) => {\n const bars = series.map((s, si) => ({\n key: s.label,\n value: Math.max(0, s.values[ci] ?? 0),\n color: resolveChartColor(s.color, s.tone, si),\n }));\n\n return (\n <div\n key={category}\n className={clsx('flex min-w-0', horizontal ? 'flex-col gap-1' : 'h-full flex-col justify-end gap-1.5')}\n style={horizontal ? undefined : { width: perCategory }}\n >\n {showLabels && horizontal && (\n <span className={clsx('truncate text-default-secondary', labelClass)}>{category}</span>\n )}\n\n <div\n className={clsx('flex', horizontal ? 'items-center gap-2' : 'w-full flex-1 items-end justify-center')}\n style={horizontal ? undefined : { height: length }}\n >\n <div\n className={clsx('flex min-w-0', stacked ? 'gap-0' : '')}\n style={\n horizontal\n ? { width: length, flexDirection: stacked ? 'row' : 'column', gap: stacked ? 0 : gap }\n : {\n height: '100%',\n width: perCategory,\n flexDirection: stacked ? 'column-reverse' : 'row',\n alignItems: 'flex-end',\n gap: stacked ? 0 : gap,\n }\n }\n >\n {bars.map((bar) => {\n const extent = `${(bar.value / max) * 100}%`;\n return (\n <div\n key={bar.key}\n title={`${category} · ${bar.key}: ${bar.value}`}\n className=\"transition-all\"\n style={{\n backgroundColor: bar.color,\n borderRadius: radius,\n ...(horizontal\n ? { width: extent, height: stacked ? band : band }\n : { height: extent, width: stacked ? perCategory : band }),\n }}\n />\n );\n })}\n </div>\n {showValues && horizontal && (\n <span className={clsx('shrink-0 tabular-nums text-default-secondary', labelClass)}>\n {categoryTotals[ci]}\n </span>\n )}\n </div>\n\n {showLabels && !horizontal && (\n <span className={clsx('truncate text-center text-default-secondary', labelClass)}>{category}</span>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { CHART_TRACK, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type DonutChartSize = 'sm' | 'md' | 'lg';\n\n/** Diameter and default ring thickness, in px. */\nconst SIZE: Record<DonutChartSize, { box: number; thickness: number }> = {\n sm: { box: 88, thickness: 10 },\n md: { box: 128, thickness: 14 },\n lg: { box: 180, thickness: 20 },\n};\n\nexport interface DonutSegment {\n label: string;\n value: number;\n /** Token-backed colour. Falls back to the segment's position in the chart sequence. */\n tone?: ChartTone;\n /** Explicit colour, for data-driven series. */\n color?: string;\n}\n\nexport interface DonutChartProps {\n segments: DonutSegment[];\n size?: DonutChartSize;\n /** Ring thickness in px. Overrides the `size` preset. */\n thickness?: number;\n /** Large text at the centre — a total, a percentage. */\n centerValue?: ReactNode;\n /** Caption beneath `centerValue`. */\n centerLabel?: ReactNode;\n /** Gap between segments, in degrees. */\n gap?: number;\n /** Accessible description. */\n label?: string;\n className?: string;\n}\n\n/**\n * A proportional ring.\n *\n * Drawn with `stroke-dasharray` on circles rather than arc paths: one element per\n * segment, no trigonometry, and the segments stay crisp at any thickness.\n */\nexport function DonutChart({\n segments,\n size = 'md',\n thickness,\n centerValue,\n centerLabel,\n gap = 2,\n label,\n className,\n}: DonutChartProps) {\n const { box, thickness: presetThickness } = SIZE[size];\n const ring = thickness ?? presetThickness;\n const radius = (box - ring) / 2;\n const circumference = 2 * Math.PI * radius;\n const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0);\n\n // A gap is only meaningful between two or more visible segments.\n const visible = segments.filter((s) => s.value > 0);\n const gapLength = visible.length > 1 ? (gap / 360) * circumference : 0;\n\n let offset = 0;\n\n return (\n <div className={clsx('relative inline-flex shrink-0 items-center justify-center', className)}>\n <svg\n width={box}\n height={box}\n viewBox={`0 0 ${box} ${box}`}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n // -90° so the first segment starts at twelve o'clock rather than three.\n className=\"block -rotate-90\"\n >\n <circle cx={box / 2} cy={box / 2} r={radius} fill=\"none\" stroke={CHART_TRACK} strokeWidth={ring} />\n {total > 0 &&\n segments.map((segment, i) => {\n const fraction = Math.max(0, segment.value) / total;\n const length = Math.max(0, fraction * circumference - gapLength);\n const dash = `${length} ${circumference - length}`;\n const thisOffset = offset;\n offset += fraction * circumference;\n if (segment.value <= 0) return null;\n return (\n <circle\n key={segment.label}\n cx={box / 2}\n cy={box / 2}\n r={radius}\n fill=\"none\"\n stroke={resolveChartColor(segment.color, segment.tone, i)}\n strokeWidth={ring}\n strokeDasharray={dash}\n strokeDashoffset={-thisOffset}\n strokeLinecap=\"butt\"\n />\n );\n })}\n </svg>\n {(centerValue != null || centerLabel != null) && (\n <div className=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n {centerValue != null && (\n <span className=\"text-subheading-sm font-bold leading-none text-default\">{centerValue}</span>\n )}\n {centerLabel != null && (\n <span className=\"mt-0.5 text-body-tiny text-default-secondary\">{centerLabel}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { CHART_TRACK, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type RadialGaugeSize = 'sm' | 'md' | 'lg';\n\nconst SIZE: Record<RadialGaugeSize, { box: number; thickness: number; value: string }> = {\n sm: { box: 72, thickness: 8, value: 'text-body-sm' },\n md: { box: 104, thickness: 11, value: 'text-subheading-sm' },\n lg: { box: 148, thickness: 15, value: 'text-subheading' },\n};\n\nexport interface RadialGaugeProps {\n value: number;\n /** Top of the scale. */\n max?: number;\n size?: RadialGaugeSize;\n tone?: ChartTone;\n color?: string;\n /** Ring thickness in px. Overrides the `size` preset. */\n thickness?: number;\n /**\n * Sweep in degrees. 360 is a full ring; 270 leaves a gap at the bottom, which reads\n * more like a dial than a pie.\n */\n sweep?: number;\n /** Centre content. Defaults to the value; pass `null` for an empty ring. */\n children?: ReactNode;\n /** Caption beneath the centre value. */\n centerLabel?: ReactNode;\n label?: string;\n className?: string;\n}\n\n/**\n * A single-value arc — a score ring, a utilisation dial, a completion meter.\n *\n * The shape the library had no form for: `ProgressBar` covers linear progress and\n * `DonutChart` compares parts of a whole, but neither draws \"one number against its\n * ceiling\" in a round frame.\n */\nexport function RadialGauge({\n value,\n max = 100,\n size = 'md',\n tone = 'brand',\n color,\n thickness,\n sweep = 270,\n children,\n centerLabel,\n label,\n className,\n}: RadialGaugeProps) {\n const preset = SIZE[size];\n const box = preset.box;\n const ring = thickness ?? preset.thickness;\n const radius = (box - ring) / 2;\n const circumference = 2 * Math.PI * radius;\n\n const clampedSweep = Math.min(360, Math.max(1, sweep));\n const arc = (clampedSweep / 360) * circumference;\n const fraction = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;\n const stroke = resolveChartColor(color, tone);\n\n // Rotate so the arc is centred on twelve o'clock: -90° puts the start at the top,\n // then half the unswept remainder brings it back round.\n const rotation = -90 + (360 - clampedSweep) / 2;\n\n return (\n <div className={clsx('relative inline-flex shrink-0 items-center justify-center', className)}>\n <svg\n width={box}\n height={box}\n viewBox={`0 0 ${box} ${box}`}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className=\"block\"\n style={{ transform: `rotate(${rotation}deg)` }}\n >\n <circle\n cx={box / 2}\n cy={box / 2}\n r={radius}\n fill=\"none\"\n stroke={CHART_TRACK}\n strokeWidth={ring}\n strokeDasharray={`${arc} ${circumference - arc}`}\n strokeLinecap=\"round\"\n />\n <circle\n cx={box / 2}\n cy={box / 2}\n r={radius}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={ring}\n strokeDasharray={`${arc * fraction} ${circumference - arc * fraction}`}\n strokeLinecap=\"round\"\n className=\"transition-all\"\n />\n </svg>\n <div className=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n {children === undefined ? (\n <span className={clsx('font-bold leading-none text-default', preset.value)}>{value}</span>\n ) : (\n children\n )}\n {centerLabel != null && (\n <span className=\"mt-0.5 text-body-tiny text-default-secondary\">{centerLabel}</span>\n )}\n </div>\n </div>\n );\n}\n","import { useId } from 'react';\nimport clsx from 'clsx';\nimport { CHART_TONE, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type SparklineVariant = 'line' | 'area';\nexport type SparklineSize = 'sm' | 'md' | 'lg';\n\n/** Size presets, so callers stop passing bare pixel pairs. */\nconst SIZE: Record<SparklineSize, { width: number; height: number }> = {\n sm: { width: 80, height: 24 },\n md: { width: 120, height: 36 },\n lg: { width: 200, height: 56 },\n};\n\nexport interface SparklineProps {\n data: number[];\n variant?: SparklineVariant;\n /** Token-backed colour. Ignored when `color` is set. */\n tone?: ChartTone;\n /** Explicit colour, for series whose colour comes from the data. */\n color?: string;\n size?: SparklineSize;\n /** Overrides the `size` preset. */\n width?: number;\n height?: number;\n strokeWidth?: number;\n /** Dot on the final point — useful when the line is the \"current value\". */\n showEndDot?: boolean;\n /**\n * Stretch to fill the container instead of drawing at a fixed pixel size.\n *\n * The `size` preset still sets the viewBox, so it decides the sampling density; the SVG then\n * scales to the box it is given. Stroke width is held constant with `non-scaling-stroke`,\n * without which a non-uniform stretch would thin the line on one axis and thicken it on the\n * other.\n */\n fill?: boolean;\n /** Accessible description. Omit to keep the chart decorative. */\n label?: string;\n className?: string;\n}\n\n/**\n * A compact trend line, with no axes and no interaction.\n *\n * `variant=\"area\"` adds the gradient fill beneath the line that 0.2.0 had no way to\n * draw, which is what makes a sparkline readable at `lg` where a bare 1.5px stroke\n * looks thin.\n */\nexport function Sparkline({\n data,\n variant = 'line',\n tone = 'brand',\n color,\n size = 'md',\n width,\n height,\n strokeWidth = 1.5,\n showEndDot = false,\n fill: stretch = false,\n label,\n className,\n}: SparklineProps) {\n const gradientId = useId();\n if (data.length < 2) return null;\n\n const w = width ?? SIZE[size].width;\n const h = height ?? SIZE[size].height;\n const stroke = resolveChartColor(color, tone);\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n const pad = strokeWidth;\n const innerH = h - pad * 2;\n const innerW = w - pad * 2;\n\n const coords = data.map((v, i) => ({\n x: pad + (i / (data.length - 1)) * innerW,\n y: pad + innerH - ((v - min) / range) * innerH,\n }));\n const points = coords.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(' ');\n // Close the path down to the baseline so the fill has something to fill.\n const areaPath = `M ${points.split(' ').join(' L ')} L ${coords[coords.length - 1].x.toFixed(2)},${h} L ${coords[0].x.toFixed(2)},${h} Z`;\n const last = coords[coords.length - 1];\n\n return (\n <svg\n width={stretch ? undefined : w}\n height={stretch ? undefined : h}\n viewBox={`0 0 ${w} ${h}`}\n preserveAspectRatio={stretch ? 'none' : undefined}\n fill=\"none\"\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={clsx('block', stretch ? 'h-full w-full' : 'shrink-0', className)}\n >\n {variant === 'area' && (\n <>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={stroke} stopOpacity={0.24} />\n <stop offset=\"100%\" stopColor={stroke} stopOpacity={0} />\n </linearGradient>\n </defs>\n <path d={areaPath} fill={`url(#${gradientId})`} />\n </>\n )}\n <polyline\n points={points}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n // Holds the line at `strokeWidth` under a non-uniform stretch. Harmless when not\n // stretching, since the scale is 1:1 there.\n vectorEffect={stretch ? 'non-scaling-stroke' : undefined}\n fill=\"none\"\n />\n {showEndDot && (\n <circle\n cx={last.x}\n cy={last.y}\n // A stretched circle would become an ellipse, so the dot is drawn in viewBox units\n // and sized from the smaller axis to stay visually round enough at either extreme.\n r={strokeWidth * 1.6}\n fill={stroke}\n stroke={CHART_TONE.neutral}\n strokeWidth={0}\n />\n )}\n </svg>\n );\n}\n","import clsx from 'clsx';\nimport { CHART_TRACK, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type MiniBarChartSize = 'sm' | 'md' | 'lg';\nexport type MiniBarChartOrientation = 'vertical' | 'horizontal';\n\nconst SIZE: Record<MiniBarChartSize, { width: number; height: number; gap: number }> = {\n sm: { width: 80, height: 32, gap: 2 },\n md: { width: 120, height: 48, gap: 3 },\n lg: { width: 200, height: 72, gap: 4 },\n};\n\nexport interface MiniBarChartProps {\n bars: number[];\n /** Colour of the highlighted bars. */\n tone?: ChartTone;\n color?: string;\n /** Colour of the un-highlighted bars. Defaults to the muted track token. */\n restColor?: string;\n /**\n * Which bars are highlighted. A number or list of indices; negatives count from the\n * end, so `-1` is the last bar. Pass `[]` to highlight none.\n *\n * Replaces 0.2.0's `highlightLastBar` boolean, which could only ever mean `-1`.\n */\n highlight?: number | number[];\n size?: MiniBarChartSize;\n /** Overrides the `size` preset. */\n width?: number;\n height?: number;\n gap?: number;\n orientation?: MiniBarChartOrientation;\n radius?: number;\n /**\n * Stretch to fill the container instead of drawing at a fixed pixel size.\n *\n * The `size` preset still sets the viewBox, so it decides the bar-to-gap proportions; the\n * SVG then scales to whatever box it is given. Without this a widget body could only hold a\n * chart at a hardcoded width, which stops being the right width as soon as the widget\n * reflows.\n */\n fill?: boolean;\n label?: string;\n className?: string;\n}\n\n/** A compact bar series with no axes — a distribution or a per-period count. */\nexport function MiniBarChart({\n bars,\n tone = 'brand',\n color,\n restColor = CHART_TRACK,\n highlight = -1,\n size = 'md',\n width,\n height,\n gap,\n orientation = 'vertical',\n radius = 2,\n fill: stretch = false,\n label,\n className,\n}: MiniBarChartProps) {\n if (bars.length === 0) return null;\n\n const preset = SIZE[size];\n const w = width ?? preset.width;\n const h = height ?? preset.height;\n const g = gap ?? preset.gap;\n const fill = resolveChartColor(color, tone);\n\n const highlighted = new Set(\n (Array.isArray(highlight) ? highlight : [highlight]).map((i) => (i < 0 ? bars.length + i : i)),\n );\n\n const max = Math.max(...bars) || 1;\n const vertical = orientation === 'vertical';\n // The cross-axis is divided between bars; the value axis carries the magnitude.\n const span = vertical ? w : h;\n const extent = vertical ? h : w;\n const barThickness = (span - g * (bars.length - 1)) / bars.length;\n\n return (\n <svg\n width={stretch ? undefined : w}\n height={stretch ? undefined : h}\n viewBox={`0 0 ${w} ${h}`}\n // `none` so the bars fill the box on both axes rather than letterboxing inside it —\n // there is no geometry here whose aspect ratio has to be preserved, only rectangles.\n preserveAspectRatio={stretch ? 'none' : undefined}\n fill=\"none\"\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={clsx('block', stretch ? 'h-full w-full' : 'shrink-0', className)}\n >\n {bars.map((v, i) => {\n const magnitude = Math.max(2, (v / max) * extent);\n const offset = i * (barThickness + g);\n return (\n <rect\n key={i}\n x={(vertical ? offset : 0).toFixed(2)}\n // Vertical bars grow up from the baseline; horizontal ones out from the left.\n y={(vertical ? extent - magnitude : offset).toFixed(2)}\n width={(vertical ? barThickness : magnitude).toFixed(2)}\n height={(vertical ? magnitude : barThickness).toFixed(2)}\n fill={highlighted.has(i) ? fill : restColor}\n rx={radius}\n />\n );\n })}\n </svg>\n );\n}\n","import clsx from 'clsx';\nimport { LegendDot, type LegendDotShape, type LegendDotSize } from './legend-dot';\nimport { resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type ChartLegendOrientation = 'vertical' | 'horizontal';\n\nexport interface ChartLegendItem {\n label: string;\n /** Trailing value. Omit for a legend that only names the series. */\n count?: number | string;\n /** Token-backed colour. Falls back to the item's position in the chart sequence. */\n tone?: ChartTone;\n /** Explicit colour, for data-driven series. */\n color?: string;\n}\n\nexport interface ChartLegendProps {\n items: ChartLegendItem[];\n /**\n * `vertical` spreads each row to fill its container, so the counts align in a column\n * beside a donut. `horizontal` wraps inline, for a legend under a bar chart.\n */\n orientation?: ChartLegendOrientation;\n size?: LegendDotSize;\n shape?: LegendDotShape;\n className?: string;\n}\n\n/** Series names, swatches and optional values. */\nexport function ChartLegend({\n items,\n orientation = 'vertical',\n size = 'md',\n shape = 'dot',\n className,\n}: ChartLegendProps) {\n const horizontal = orientation === 'horizontal';\n\n return (\n <div\n className={clsx(\n horizontal ? 'flex flex-wrap items-center gap-x-4 gap-y-2' : 'flex flex-col gap-3',\n className,\n )}\n >\n {items.map((item, i) => (\n <div\n key={item.label}\n className={clsx('flex items-center gap-2', horizontal ? 'min-w-0' : 'justify-between')}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n {/* Resolved here, not in LegendDot, so the sequence fallback can use the\n item's position — matching how DonutChart colours its segments. */}\n <LegendDot color={resolveChartColor(item.color, item.tone, i)} size={size} shape={shape} />\n <span className=\"truncate text-body-xs text-default-secondary\">{item.label}</span>\n </div>\n {item.count != null && (\n <span className=\"shrink-0 text-body-xs font-semibold tabular-nums text-default\">{item.count}</span>\n )}\n </div>\n ))}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type LegendDotSize = 'sm' | 'md';\n/** `line` is the swatch for a line series; `dot` and `square` for areas and bars. */\nexport type LegendDotShape = 'dot' | 'square' | 'line';\n\nconst SHAPE: Record<LegendDotShape, Record<LegendDotSize, string>> = {\n dot: { sm: 'size-1.5 rounded-full', md: 'size-2 rounded-full' },\n square: { sm: 'size-1.5 rounded-[2px]', md: 'size-2 rounded-[3px]' },\n line: { sm: 'h-0.5 w-3 rounded-full', md: 'h-0.5 w-4 rounded-full' },\n};\n\nexport interface LegendDotProps {\n /** Token-backed colour. Ignored when `color` is set. */\n tone?: ChartTone;\n /** Explicit colour, for data-driven series. */\n color?: string;\n size?: LegendDotSize;\n shape?: LegendDotShape;\n className?: string;\n}\n\n/** The colour swatch beside a series name. */\nexport function LegendDot({ tone, color, size = 'md', shape = 'dot', className }: LegendDotProps) {\n return (\n <span\n className={clsx('inline-block shrink-0', SHAPE[shape][size], className)}\n style={{ backgroundColor: resolveChartColor(color, tone) }}\n aria-hidden\n />\n );\n}\n","import clsx from 'clsx';\nimport { LuTrendingDown, LuTrendingUp } from 'react-icons/lu';\n\nexport type TrendLabelWeight = 'semibold' | 'bold';\nexport type TrendLabelSize = 'sm' | 'md' | 'lg';\n/**\n * Which direction is the good one.\n *\n * A delta component cannot infer this: +4% on-time delivery is good, +4% unit cost is\n * not. 0.2.0 had no such prop, so the only way to render a \"rising is bad\" delta was to\n * pass a raw hex — which is exactly what the deleted `BenchmarkCard` did, inverting its\n * own `positiveColor` default to red to compensate.\n */\nexport type TrendDirection = 'up-is-good' | 'up-is-bad';\n\nconst SIZE: Record<TrendLabelSize, string> = {\n sm: 'text-body-xs',\n md: 'text-body-sm',\n lg: 'text-subheading-sm',\n};\n\nconst ICON_SIZE: Record<TrendLabelSize, string> = {\n sm: 'size-3',\n md: 'size-3.5',\n lg: 'size-4',\n};\n\nconst weightBySize: Record<TrendLabelSize, TrendLabelWeight> = {\n sm: 'semibold',\n md: 'semibold',\n lg: 'bold',\n};\n\nconst WEIGHT: Record<TrendLabelWeight, string> = {\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nexport interface TrendLabelProps {\n value: number;\n suffix?: string;\n size?: TrendLabelSize;\n weight?: TrendLabelWeight;\n direction?: TrendDirection;\n /** Trend arrow. On by default — the docs described one long before there was one. */\n showArrow?: boolean;\n /** Explicit colour, for the rare data-driven case. Overrides the direction logic. */\n color?: string;\n className?: string;\n}\n\n/** A signed delta with a direction arrow, toned by whether the movement is good news. */\nexport function TrendLabel({\n value,\n suffix = '%',\n size = 'md',\n weight,\n direction = 'up-is-good',\n showArrow = true,\n color,\n className,\n}: TrendLabelProps) {\n const rising = value > 0;\n // Zero is neither good nor bad. 0.2.0 rendered it as a green \"+0%\".\n const flat = value === 0;\n const good = direction === 'up-is-good' ? rising : !rising;\n const Arrow = rising ? LuTrendingUp : LuTrendingDown;\n\n return (\n <span\n className={clsx(\n 'inline-flex items-center gap-1 whitespace-nowrap',\n SIZE[size],\n WEIGHT[weight ?? weightBySize[size]],\n !color && (flat ? 'text-default-secondary' : good ? 'text-positive' : 'text-danger'),\n className,\n )}\n style={color ? { color } : undefined}\n >\n {showArrow && !flat && <Arrow className={clsx('shrink-0', ICON_SIZE[size])} aria-hidden />}\n {rising ? '+' : ''}\n {value}\n {suffix}\n </span>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type ListRowDensity = 'default' | 'compact';\nexport type ListRowDivider = 'none' | 'top' | 'bottom';\n\nconst DENSITY: Record<ListRowDensity, { pad: string; gap: string; title: string; description: string }> = {\n default: {\n pad: 'py-4',\n gap: 'gap-3',\n title: 'text-body-sm font-semibold text-default',\n description: 'text-body-xs text-default-secondary',\n },\n compact: {\n pad: 'py-2.5',\n gap: 'gap-2',\n title: 'text-body-xs font-semibold text-default',\n description: 'text-body-tiny text-default-secondary',\n },\n};\n\nconst DIVIDER: Record<ListRowDivider, string> = {\n none: '',\n top: 'border-t border-default',\n bottom: 'border-b border-default',\n};\n\nexport interface ListRowProps {\n /** Left of the title, on the title line — an icon badge, avatar, checkbox, file chip. */\n leading?: ReactNode;\n title?: ReactNode;\n /** Inline after the title — a Required/Optional chip, a count, a tag. */\n titleMeta?: ReactNode;\n /** Muted line under the title. */\n description?: ReactNode;\n /** Right end of the title line — a `StatusBadge`, a score, a timestamp. */\n meta?: ReactNode;\n /** Right-hand column spanning the whole row, vertically centred — actions, a `Toggle`. */\n trailing?: ReactNode;\n /** Full-width block below the title line — a `FileRow`, a `FileDropZone`, an alert, a nested list. */\n footer?: ReactNode;\n density?: ListRowDensity;\n divider?: ListRowDivider;\n /** Render an `<li>` instead of a `<div>` — use inside a `<ul>`/`<ol>`. */\n as?: 'div' | 'li';\n onClick?: () => void;\n /**\n * Accessible name for a clickable row. Strongly recommended whenever `onClick` is set:\n * without it the name is the concatenation of every slot's text.\n */\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * The generic list row: six slots and no opinion about what goes in them.\n *\n * Replaces `DocumentRow` and `DocumentChecklistRow`, which baked one product's\n * document-upload flow — its status vocabulary, its five raw-hex pills and its\n * unicode-glyph labels — into the library. Every feature of those rows is reachable by\n * composing this with `FileRow`, `FileDropZone` and `StatusBadge`; see the docs.\n */\nexport function ListRow({\n leading,\n title,\n titleMeta,\n description,\n meta,\n trailing,\n footer,\n density = 'default',\n divider = 'none',\n as: Tag = 'div',\n onClick,\n 'aria-label': ariaLabel,\n className,\n}: ListRowProps) {\n const d = DENSITY[density];\n const hasTitleLine = Boolean(leading || title != null || titleMeta || meta);\n\n return (\n <Tag\n className={clsx(\n 'flex w-full items-start',\n d.pad,\n DIVIDER[divider],\n onClick &&\n 'cursor-pointer rounded-lg transition-colors hover:bg-default-secondary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand',\n className,\n )}\n onClick={onClick}\n // Unlike a <tr>, a div/li has no conflicting implicit role, so button is correct here.\n role={onClick ? 'button' : undefined}\n // Without this the row's accessible name is the concatenation of everything inside\n // it — title, meta, description, footer and the label of any nested control.\n aria-label={onClick ? ariaLabel : undefined}\n tabIndex={onClick ? 0 : undefined}\n onKeyDown={\n onClick\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick();\n }\n }\n : undefined\n }\n >\n <div className={clsx('flex min-w-0 flex-1 flex-col', d.gap)}>\n {hasTitleLine && (\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n {leading}\n {title != null && <span className={clsx('truncate', d.title)}>{title}</span>}\n {titleMeta && <span className=\"shrink-0\">{titleMeta}</span>}\n </div>\n {meta && <span className=\"shrink-0\">{meta}</span>}\n </div>\n )}\n {description && <p className={d.description}>{description}</p>}\n {/* Both slots stop click and key propagation when the row itself is clickable.\n The JSDoc on `trailing` and `footer` advertises putting a `Toggle` or a\n `Button` in them, and through 0.3.0 activating that control fired the nested\n handler *and* the row's `onClick` — so toggling a switch also navigated. */}\n {footer && (\n // These two wrappers are propagation barriers, not controls — they add no\n // behaviour of their own and must not be focusable or take a role.\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div onClick={stopIfInteractive} onKeyDown={stopIfInteractive}>\n {footer}\n </div>\n )}\n </div>\n {trailing && (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n className=\"ml-3 flex shrink-0 items-center self-center\"\n onClick={stopIfInteractive}\n onKeyDown={stopIfInteractive}\n >\n {trailing}\n </div>\n )}\n </Tag>\n );\n}\n\n/**\n * Keeps an interaction with a nested control from also triggering the row.\n *\n * Note the remaining limitation: a focusable descendant inside `role=\"button\"` is invalid\n * ARIA regardless of propagation, so a row that is *itself* clickable and *also* contains\n * controls is a compromise. Prefer either a clickable row with static content, or a static\n * row whose title is its own button.\n */\nfunction stopIfInteractive(event: { stopPropagation: () => void }) {\n event.stopPropagation();\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface FileRowProps {\n name: string;\n /** Muted second line — size, upload date, uploader. */\n detail?: ReactNode;\n /** Leading chip showing the file extension, e.g. `\"PDF\"`. Ignored when `leading` is set. */\n fileType?: string;\n /** Custom leading node — overrides `fileType`. */\n leading?: ReactNode;\n /** The canonical action. Renders a text link before `actions`. */\n onDownload?: () => void;\n downloadLabel?: string;\n /** Everything else on the right — `Button`s, a `DropdownMenu`. */\n actions?: ReactNode;\n className?: string;\n}\n\n/** The extension chip. Lifted unchanged from the deleted `DocumentRow`. */\nfunction FileTypeBadge({ type }: { type: string }) {\n return (\n <span className=\"flex size-[34px] shrink-0 items-center justify-center rounded-md bg-brand-tertiary text-body-tiny font-semibold text-brand\">\n {type}\n </span>\n );\n}\n\n/**\n * One attached file: name, optional detail line, and actions.\n *\n * This strip was hardcoded inline inside both `DocumentRow` and\n * `DocumentChecklistRow`. Nothing about it is document-specific — it is the same row\n * for a generated export, an invoice or an evidence attachment.\n */\nexport function FileRow({\n name,\n detail,\n fileType,\n leading,\n onDownload,\n downloadLabel = 'Download',\n actions,\n className,\n}: FileRowProps) {\n const lead = leading ?? (fileType ? <FileTypeBadge type={fileType} /> : null);\n\n return (\n <div\n className={clsx(\n 'flex items-center gap-3 rounded-lg border border-default bg-default px-3 py-2.5',\n className,\n )}\n >\n {lead}\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"truncate text-body-sm font-medium text-default\">{name}</span>\n {detail && <span className=\"text-body-xs text-default-secondary\">{detail}</span>}\n </div>\n {(onDownload || actions) && (\n <div className=\"flex shrink-0 items-center gap-3\">\n {onDownload && (\n <button\n type=\"button\"\n onClick={onDownload}\n className=\"text-body-xs font-medium text-brand hover:underline\"\n >\n {downloadLabel}\n </button>\n )}\n {actions}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type ScoredRowAlign = 'center' | 'end';\n/** 8 / 12 / 20 / 48px — the four gaps the source mockups actually used. */\nexport type ScoredRowGap = 'sm' | 'md' | 'lg' | 'xl';\n\nconst GAP: Record<ScoredRowGap, string> = {\n sm: 'gap-2',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-12',\n};\n\nconst ALIGN: Record<ScoredRowAlign, string> = {\n center: 'items-center',\n end: 'items-end',\n};\n\nexport interface ScoredRowProps {\n /** Leading visual — an `EntityIconBadge`, an `Avatar`, a rank number, or nothing. */\n leading?: ReactNode;\n title: ReactNode;\n subtitle?: ReactNode;\n /** Fixed-width column between the title block and the meter. */\n aside?: ReactNode;\n /** The bar. Put a `<ProgressBar>` here — the row does not choose one for you. */\n meter?: ReactNode;\n /** Right-hand value — a `<ScoreValue>`, a `<TrendLabel>`, a `<Badge>`, a button. */\n trailing?: ReactNode;\n /** CSS width values. Omit one and that slot flexes instead. */\n titleWidth?: string;\n asideWidth?: string;\n meterWidth?: string;\n trailingWidth?: string;\n gap?: ScoredRowGap;\n /** Gap between `leading` and the title block. Defaults to `gap`. */\n leadingGap?: ScoredRowGap;\n align?: ScoredRowAlign;\n className?: string;\n}\n\n/**\n * A row with a title block, an optional bar and a right-hand value.\n *\n * Was `EntityRow`. The rename is the smaller half of the change: the old component\n * hardcoded `RiskScore`, `WidgetProgressBar`, `TrendLabel` and `getRiskTone`, which\n * locked it to one scoring domain and forced 32 props — including four raw\n * `CSSProperties` escape hatches and a magic `nameWidth = '133px'` — to make it fit\n * anything else. The score and the bar are now slots, so the caller decides.\n */\nexport function ScoredRow({\n leading,\n title,\n subtitle,\n aside,\n meter,\n trailing,\n titleWidth,\n asideWidth,\n meterWidth,\n trailingWidth,\n gap = 'md',\n leadingGap,\n align = 'center',\n className,\n}: ScoredRowProps) {\n return (\n <div className={clsx('flex w-full', ALIGN[align], GAP[gap], className)}>\n <div\n className={clsx(\n 'flex min-w-0',\n ALIGN[align],\n GAP[leadingGap ?? gap],\n titleWidth ? 'shrink-0' : 'flex-1',\n )}\n style={titleWidth ? { width: titleWidth } : undefined}\n >\n {leading}\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-body-sm font-medium leading-none text-default\">{title}</p>\n {subtitle && <p className=\"mt-0.5 truncate text-body-xs text-default-secondary\">{subtitle}</p>}\n </div>\n </div>\n\n {aside && (\n <div\n className={clsx('min-w-0', asideWidth ? 'shrink-0' : 'flex-1')}\n style={asideWidth ? { width: asideWidth } : undefined}\n >\n {aside}\n </div>\n )}\n\n {meter && (\n <div\n className={clsx('min-w-0', meterWidth ? 'shrink-0' : 'flex-1')}\n style={meterWidth ? { width: meterWidth } : undefined}\n >\n {meter}\n </div>\n )}\n\n {trailing && (\n <div className=\"shrink-0 text-right\" style={trailingWidth ? { width: trailingWidth } : undefined}>\n {trailing}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { ProgressBar } from '../feedback/progress-bar';\nimport type { ProgressBarTone } from '../feedback/progress-bar';\nimport { ScoreValue, getScoreTone } from '../stats/score-value';\nimport type { ScoreDirection, ScoreValueSize, ScoreValueWeight } from '../stats/score-value';\n\nexport interface NumberedListItem {\n title: string;\n /** Second line under the title — a region, a category, an id. */\n subtitle?: string;\n score: number;\n /** Bar and value colour for this row. `auto` derives it from `score`. */\n tone?: ProgressBarTone | 'auto';\n}\n\nexport type NumberedListGap = 'sm' | 'md';\n\nexport interface NumberedListProps {\n items: NumberedListItem[];\n /** Which end of the scale is bad, for rows resolving `tone` automatically. */\n direction?: ScoreDirection;\n scoreSize?: ScoreValueSize;\n scoreWeight?: ScoreValueWeight;\n /** First ordinal. Set it to continue a list across a page boundary. */\n startAt?: number;\n gap?: NumberedListGap;\n className?: string;\n}\n\nconst GAP: Record<NumberedListGap, string> = {\n sm: 'gap-2',\n md: 'gap-3',\n};\n\n/**\n * A ranked leaderboard: ordinal, title, score, and a full-width bar under each row.\n *\n * Was `RankedRow`, which was one row and made the caller supply both the `<ol>` and every\n * `rank` by hand — so a filtered or re-sorted list silently kept stale numbers. Owning the\n * list means the ordinal is derived from position and cannot disagree with the order on\n * screen. It also puts it at the same granularity as `StepsList`, its neighbour.\n *\n * It still hardcodes `ProgressBar` and `ScoreValue`, and that is the point: a leaderboard\n * row *is* those three things. Where the pieces need to vary, reach for `ScoredRow`, whose\n * slots take arbitrary content.\n */\nexport function NumberedList({\n items,\n direction = 'higher-is-worse',\n scoreSize = 'md',\n scoreWeight = 'bold',\n startAt = 1,\n gap = 'md',\n className,\n}: NumberedListProps) {\n return (\n <ol className={clsx('flex list-none flex-col p-0', GAP[gap], className)}>\n {items.map((item, index) => {\n const tone =\n !item.tone || item.tone === 'auto'\n ? getScoreTone(item.score, { direction })\n : item.tone;\n\n return (\n <li key={`${item.title}-${index}`} className=\"flex w-full shrink-0 flex-col gap-1.5\">\n <div className=\"flex w-full items-center justify-between\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n {/* Fixed width so the titles align whether the ordinal is 1 or 10. */}\n <span className=\"w-[14px] shrink-0 text-body-xs font-bold text-default-secondary\">\n {startAt + index}\n </span>\n <div className=\"flex min-w-0 flex-col gap-px\">\n <span className=\"truncate text-body-sm font-medium leading-none text-default\">\n {item.title}\n </span>\n {item.subtitle && (\n <span className=\"text-body-tiny text-default-tertiary\">{item.subtitle}</span>\n )}\n </div>\n </div>\n <ScoreValue\n value={item.score}\n size={scoreSize}\n weight={scoreWeight}\n tone={tone}\n className=\"ml-2 shrink-0\"\n />\n </div>\n <ProgressBar value={item.score} tone={tone} aria-label={`${item.title} score`} />\n </li>\n );\n })}\n </ol>\n );\n}\n","import { useId } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type ProgressBarTone = 'brand' | 'positive' | 'warning' | 'danger' | 'neutral';\nexport type ProgressBarSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/** 4 / 6 / 8 / 12px. `sm` is 0.2.0's only height, and stays the default. */\nconst SIZE: Record<ProgressBarSize, string> = {\n xs: 'h-1',\n sm: 'h-1.5',\n md: 'h-2',\n lg: 'h-3',\n};\n\nconst FILL: Record<ProgressBarTone, string> = {\n brand: 'bg-brand',\n positive: 'bg-positive',\n warning: 'bg-warning',\n danger: 'bg-danger',\n neutral: 'bg-neutral',\n};\n\nexport interface ProgressBarProps {\n /** 0–100. Values outside the range are clamped. */\n value: number;\n tone?: ProgressBarTone;\n size?: ProgressBarSize;\n /** Caption above the bar. Also becomes the accessible name. */\n label?: string;\n /** Show the percentage at the right of the label row. */\n showValue?: boolean;\n /** CSS radius override, e.g. `'1px'` for a square-ended bar. Defaults to fully round. */\n radius?: string;\n /** Accessible name when there is no visible `label`. */\n 'aria-label'?: string;\n /**\n * Applied to the track. This is how you set a fixed width — `className=\"w-16\"`.\n * It genuinely overrides the base `w-full` because this file uses `cn`.\n */\n className?: string;\n}\n\n/**\n * A horizontal progress / proportion bar.\n *\n * Was `WidgetProgressBar` in 0.2.0, which fixed the height at 6px and lived under\n * `widgets/` despite being a general-purpose primitive — so `TableCellProgress`\n * hand-rolled a second copy rather than reuse it. It also had no ARIA at all.\n */\nexport function ProgressBar({\n value,\n tone = 'brand',\n size = 'sm',\n label,\n showValue = false,\n radius,\n 'aria-label': ariaLabel,\n className,\n}: ProgressBarProps) {\n const clamped = Math.min(100, Math.max(0, value));\n const rounded = radius ? undefined : 'rounded-full';\n const labelId = useId();\n\n const track = (\n <div\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n // The doc comment on `label` promised it \"also becomes the accessible name\", and\n // through 0.3.0 it did the opposite: setting `label` *suppressed* `aria-label` while\n // the caption rendered as an unlabelled sibling `<span>` with no id, so\n // `<ProgressBar label=\"Risk score\" />` produced a progressbar with no name at all.\n aria-labelledby={label ? labelId : undefined}\n aria-label={label ? undefined : ariaLabel}\n className={cn('w-full overflow-hidden bg-default-tertiary', SIZE[size], rounded, className)}\n style={radius ? { borderRadius: radius } : undefined}\n >\n <div\n className={cn('h-full transition-all', rounded, FILL[tone])}\n style={{ width: `${clamped}%`, ...(radius ? { borderRadius: radius } : undefined) }}\n />\n </div>\n );\n\n // No caption row means no wrapper — the bar must stay a direct child of whatever\n // laid it out, so a parent's `flex-1` or grid placement still applies to it.\n if (!label && !showValue) return track;\n\n return (\n <div>\n <div className=\"mb-1.5 flex items-center justify-between gap-2\">\n {label && (\n <span id={labelId} className=\"text-body-xs text-default-secondary\">\n {label}\n </span>\n )}\n {showValue && (\n <span className=\"ml-auto text-body-xs font-medium tabular-nums text-default\">\n {Math.round(clamped)}%\n </span>\n )}\n </div>\n {track}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface IconTextRowProps {\n icon: ReactNode;\n title: string;\n detail: string;\n className?: string;\n}\n\n/**\n * A circular icon badge, a title, and one line of detail.\n *\n * Feature lists, empty-state explanations, onboarding intros, \"what happens next\"\n * steps. Was `FeatureRow`, which named it after the one screen it was extracted from.\n */\nexport function IconTextRow({ icon, title, detail, className }: IconTextRowProps) {\n return (\n <div className={clsx('flex items-start gap-3', className)}>\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-brand\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <p className=\"text-body-sm font-semibold text-default\">{title}</p>\n <p className=\"mt-0.5 text-body-xs text-default-secondary\">{detail}</p>\n </div>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { LuCheck } from 'react-icons/lu';\n\nexport type ChecklistRowState = 'done' | 'active' | 'pending';\n\nexport interface ChecklistRowProps {\n label: string;\n state: ChecklistRowState;\n className?: string;\n}\n\n/**\n * One step in a progress checklist: a done tick, a spinning active ring, or an empty\n * pending ring.\n *\n * Shared by the event-onboarding \"building your dashboard\" screen and the\n * intelligence page's processing checklist. Both drove the same three states; only\n * the onboarding copy had the animated ring, which is the better treatment and is\n * adopted for both.\n *\n * Renders an `<li>` — callers must wrap it in a list, which is what both sources did.\n */\nexport function ChecklistRow({ label, state, className }: ChecklistRowProps) {\n return (\n <li className={clsx('flex items-center gap-3', className)}>\n <span className=\"flex size-5 shrink-0 items-center justify-center\">\n {state === 'done' ? (\n <LuCheck className=\"size-4 text-positive\" strokeWidth={2.5} aria-hidden />\n ) : (\n <span\n className={clsx(\n 'size-3.5 rounded-full border-2',\n state === 'active'\n ? 'animate-pulse border-brand-emphasis border-t-transparent'\n : 'border-disabled',\n )}\n />\n )}\n </span>\n <span\n className={clsx(\n 'text-body-sm',\n state === 'pending' ? 'text-default-tertiary' : 'font-semibold text-default',\n )}\n >\n {label}\n </span>\n </li>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface StepsListProps {\n steps: ReactNode[];\n className?: string;\n}\n\n/**\n * Ordered list of instructions with small filled number bullets.\n *\n * Was `NumberedStepsList`. Renamed in 0.5.0 because `NumberedList` — the ranked\n * leaderboard — also numbers its rows, and two components whose names both led with\n * \"Numbered\" gave no hint which was which. The distinction is what the numbers *mean*:\n * here they are sequence (\"do this, then this\"), there they are rank.\n *\n * The bullet was `bg-[#e7edfb] text-[#1d4ed8]` — a pale blue pair that is not in the\n * token set. It now uses the brand-tertiary background and brand text, which is the\n * documented treatment for a subtle brand-tinted chip.\n */\nexport function StepsList({ steps, className }: StepsListProps) {\n return (\n <ol className={clsx('flex flex-col gap-1.5', className)}>\n {steps.map((step, i) => (\n // `text-[12px]` was off the type scale; 12 sits midway between Scale 01 (11) and\n // Scale 02 (13), so it rounds up to 13 like every other snap in this pass.\n <li key={i} className=\"flex items-start gap-2 text-body-xs text-default\">\n <span className=\"mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-[9px] font-bold text-brand\">\n {i + 1}\n </span>\n {step}\n </li>\n ))}\n </ol>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type DetailItemLayout = 'stacked' | 'inline';\nexport type DetailItemSpan = 1 | 2 | 'full';\n\nexport interface DetailItemProps {\n label: string;\n value: ReactNode;\n /** Optional second line under the value. */\n detail?: ReactNode;\n /**\n * `stacked` puts the label above the value (detail pages, review summaries).\n * `inline` puts a fixed-width label beside it (drawer detail rows).\n */\n layout?: DetailItemLayout;\n /**\n * Columns to occupy inside a `DetailGrid`. `full` spans the row — for a long value\n * such as an alias list or a legal name that would otherwise truncate.\n */\n span?: DetailItemSpan;\n /**\n * Label column width for the `inline` layout. A `min-w`/`max-w` pair rather than a\n * fixed `w-`, so a long label wraps instead of colliding with the value.\n */\n labelWidth?: string;\n className?: string;\n}\n\nconst SPAN: Record<DetailItemSpan, string> = {\n 1: '',\n 2: 'sm:col-span-2',\n full: 'col-span-full',\n};\n\n/**\n * A label/value pair.\n *\n * Was `MetaField` — an internal codename that said nothing about the shape. Consolidates\n * the same pair from six places: an entity-detail overview grid, a reviewer-detail metric\n * column, three `DetailRow` copies in drawers, and `ReviewMeta` in two onboarding wizards.\n *\n * An empty value renders an em dash, which is what every source copy did by hand. Note\n * that the check is for `null`/`undefined`/`''` only — `0` and `false` are real values and\n * render as themselves.\n */\nexport function DetailItem({\n label,\n value,\n detail,\n layout = 'stacked',\n span = 1,\n labelWidth = 'min-w-[96px] max-w-[140px]',\n className,\n}: DetailItemProps) {\n const shown = value === null || value === undefined || value === '' ? '—' : value;\n\n if (layout === 'inline') {\n return (\n <div className={clsx('flex gap-3 text-body-xs', SPAN[span], className)}>\n <span className={clsx('shrink-0 text-default-secondary', labelWidth)}>{label}</span>\n {/* `detail` used to be dropped silently in this branch. */}\n <span className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"text-default\">{shown}</span>\n {detail && <span className=\"text-default-secondary\">{detail}</span>}\n </span>\n </div>\n );\n }\n\n return (\n <div className={clsx('flex min-w-0 flex-col gap-0.5', SPAN[span], className)}>\n <p className=\"text-body-tiny font-medium text-default-secondary\">{label}</p>\n <p className=\"text-body-sm font-medium text-default\">{shown}</p>\n {detail && <p className=\"text-body-xs text-default-secondary\">{detail}</p>}\n </div>\n );\n}\n\nexport type DetailGridColumns = 2 | 3 | 4 | 'auto';\n\nexport interface DetailGridProps {\n children: ReactNode;\n columns?: DetailGridColumns;\n className?: string;\n}\n\nconst COLUMNS: Record<DetailGridColumns, string> = {\n // Fills the row whatever its width, and reflows to fewer columns as it narrows.\n auto: 'grid-cols-[repeat(auto-fit,minmax(180px,1fr))]',\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-4',\n};\n\n/**\n * Wrapper for a set of `DetailItem`s.\n *\n * A real grid, not the `flex flex-wrap` it was as `MetaFieldGrid`. Under flex-wrap every\n * item had to carry its own width (`sm:w-[262px]` was the documented idiom) and whatever\n * space was left over at the end of a row stayed empty — so a three-item row in a wide\n * card had a ragged gap on the right. `1fr` tracks divide the row exactly, and an item\n * that genuinely needs more room asks for it with `span` instead of a magic width.\n */\nexport function DetailGrid({ children, columns = 'auto', className }: DetailGridProps) {\n return (\n <div className={clsx('grid gap-x-4 gap-y-4', COLUMNS[columns], className)}>{children}</div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { LuCheck } from 'react-icons/lu';\n\nexport type CheckedGroupListColumns = 1 | 2 | 3;\n\n/** One labelled group of ticked items. */\nexport interface CheckedGroup {\n label: string;\n items: string[];\n}\n\nexport interface CheckedGroupListProps {\n groups: CheckedGroup[];\n columns?: CheckedGroupListColumns;\n /** Leading glyph for every item. Defaults to a check; pass `null` for none. */\n icon?: ReactNode | null;\n emptyLabel?: string;\n className?: string;\n}\n\nconst COLUMNS: Record<CheckedGroupListColumns, string> = {\n 1: 'columns-1',\n 2: 'columns-2',\n 3: 'columns-3',\n};\n\n/**\n * A read-only, grouped list of ticked items in a balanced multi-column flow.\n *\n * Was `PermissionGrid` — RBAC-specific naming for a generic shape, and not a grid\n * either: groups pack tightly down each column rather than aligning to shared row\n * heights, so a tall group beside a short one leaves no ragged gap.\n * `break-inside-avoid` keeps each group whole within a column.\n *\n * Granted permissions, included plan features, completed requirements, matched\n * criteria — anything that is \"these labels, grouped, all ticked\".\n */\nexport function CheckedGroupList({\n groups,\n columns = 2,\n icon,\n emptyLabel = 'None.',\n className,\n}: CheckedGroupListProps) {\n if (groups.length === 0) {\n return <p className={clsx('text-body-xs text-default-secondary', className)}>{emptyLabel}</p>;\n }\n\n // `undefined` means \"not passed\" → default check. `null` means \"explicitly none\".\n const glyph = icon === undefined ? <LuCheck className=\"size-3.5\" strokeWidth={2.5} aria-hidden /> : icon;\n\n return (\n <div className={clsx(COLUMNS[columns], 'gap-x-6', className)}>\n {groups.map((group) => (\n <div key={group.label} className=\"mb-5 break-inside-avoid last:mb-0\">\n <p className=\"mb-2 text-body-tiny font-semibold uppercase tracking-wide text-default-secondary\">\n {group.label}\n </p>\n <ul className=\"space-y-1.5\">\n {group.items.map((item) => (\n <li key={item} className=\"flex items-center gap-2 text-body-xs text-default\">\n {glyph && <span className=\"shrink-0\">{glyph}</span>}\n {item}\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n}\n","import { useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { LuChevronRight } from 'react-icons/lu';\n\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type TreeViewSize = 'sm' | 'md';\n\nexport interface TreeItemState {\n /** 1 for a root item. */\n level: number;\n hasChildren: boolean;\n expanded: boolean;\n selected: boolean;\n}\n\nexport interface TreeViewProps<T> {\n /** Root items. */\n items: readonly T[];\n getId: (item: T) => string;\n /** Children of an item. Omit (or return nothing) for a flat list. */\n getChildren?: (item: T) => readonly T[] | undefined;\n /**\n * The row content — a slot rather than props, so the caller decides what a node shows\n * (an avatar, a code, a status badge). The chevron, indentation and selection highlight\n * are drawn by the tree.\n */\n renderItem: (item: T, state: TreeItemState) => ReactNode;\n /** Accessible name of the tree. */\n label: string;\n /** Ids of expanded items. Controlled. */\n expanded?: string[];\n defaultExpanded?: string[];\n onExpandedChange?: (expanded: string[]) => void;\n /** Id of the selected item. Controlled. */\n selected?: string | null;\n defaultSelected?: string | null;\n /** Fired on click, Enter or Space. */\n onSelect?: (id: string, item: T) => void;\n size?: TreeViewSize;\n className?: string;\n}\n\ninterface FlatNode<T> {\n id: string;\n item: T;\n level: number;\n parentId: string | null;\n hasChildren: boolean;\n expanded: boolean;\n}\n\nconst ROW: Record<TreeViewSize, string> = {\n sm: 'min-h-8 py-1 text-body-xs',\n md: 'min-h-10 py-2 text-body-sm',\n};\n\n/** Indentation per level, in px. Data-driven, so it is an inline style rather than a class. */\nconst INDENT = 18;\n\n/**\n * An expandable tree — the ARIA tree pattern, with one tab stop.\n *\n * Focus is a roving tabindex over the *visible* rows, kept here rather than in\n * `useRovingFocus` because a tree gives Left and Right their own meaning: Right expands a\n * closed node or steps into an open one, Left collapses an open node or steps out to its\n * parent. Selection is separate from focus — arrowing does not select — so browsing a\n * controlled tree fires no `onSelect`.\n *\n * Children render inside a real `role=\"group\"`, which is what lets a screen reader announce\n * level and position without `aria-level` being guessed from indentation.\n */\nexport function TreeView<T>({\n items,\n getId,\n getChildren,\n renderItem,\n label,\n expanded: expandedProp,\n defaultExpanded = [],\n onExpandedChange,\n selected: selectedProp,\n defaultSelected = null,\n onSelect,\n size = 'md',\n className,\n}: TreeViewProps<T>) {\n const [expanded, setExpanded] = useControllableState<string[]>({\n value: expandedProp,\n defaultValue: defaultExpanded,\n onChange: onExpandedChange,\n });\n const [selected, setSelected] = useControllableState<string | null>({\n value: selectedProp,\n defaultValue: defaultSelected,\n });\n const [focusedId, setFocusedId] = useState<string | null>(null);\n const rowRefs = useRef(new Map<string, HTMLElement>());\n\n const expandedSet = useMemo(() => new Set(expanded), [expanded]);\n\n // Visible rows in document order — what the arrow keys walk.\n const visible = useMemo(() => {\n const out: FlatNode<T>[] = [];\n const walk = (nodes: readonly T[], level: number, parentId: string | null) => {\n for (const item of nodes) {\n const id = getId(item);\n const children = getChildren?.(item) ?? [];\n const isOpen = children.length > 0 && expandedSet.has(id);\n out.push({ id, item, level, parentId, hasChildren: children.length > 0, expanded: isOpen });\n if (isOpen) walk(children, level + 1, id);\n }\n };\n walk(items, 1, null);\n return out;\n }, [items, getId, getChildren, expandedSet]);\n\n // The single tab stop: the focused row if still visible, else the selection, else the first.\n const tabStop =\n visible.find((n) => n.id === focusedId)?.id ??\n visible.find((n) => n.id === selected)?.id ??\n visible[0]?.id;\n\n const focus = (id: string | undefined) => {\n if (!id) return;\n setFocusedId(id);\n rowRefs.current.get(id)?.focus();\n };\n\n const toggle = (id: string, open: boolean) => {\n setExpanded((prev) => (open ? [...prev.filter((x) => x !== id), id] : prev.filter((x) => x !== id)));\n };\n\n const choose = (node: FlatNode<T>) => {\n setSelected(node.id);\n onSelect?.(node.id, node.item);\n };\n\n const onKeyDown = (event: KeyboardEvent, node: FlatNode<T>) => {\n const index = visible.findIndex((n) => n.id === node.id);\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focus(visible[index + 1]?.id);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focus(visible[index - 1]?.id);\n break;\n case 'ArrowRight':\n event.preventDefault();\n if (node.hasChildren && !node.expanded) toggle(node.id, true);\n else if (node.expanded) focus(visible[index + 1]?.id);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n if (node.expanded) toggle(node.id, false);\n else if (node.parentId) focus(node.parentId);\n break;\n case 'Home':\n event.preventDefault();\n focus(visible[0]?.id);\n break;\n case 'End':\n event.preventDefault();\n focus(visible[visible.length - 1]?.id);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n choose(node);\n break;\n default:\n break;\n }\n };\n\n const renderLevel = (nodes: readonly T[], level: number): ReactNode =>\n nodes.map((item, i) => {\n const id = getId(item);\n const node = visible.find((n) => n.id === id);\n // Not visible means an ancestor is collapsed — but then this level is not rendered at all.\n if (!node) return null;\n const children = getChildren?.(item) ?? [];\n const isSelected = selected === id;\n\n return (\n <li\n key={id}\n role=\"treeitem\"\n aria-level={level}\n aria-setsize={nodes.length}\n aria-posinset={i + 1}\n aria-expanded={node.hasChildren ? node.expanded : undefined}\n aria-selected={isSelected}\n tabIndex={tabStop === id ? 0 : -1}\n ref={(el) => {\n if (el) rowRefs.current.set(id, el);\n else rowRefs.current.delete(id);\n }}\n onFocus={(event) => {\n // Only the row itself — focus bubbling up from a nested row must not steal it.\n if (event.target === event.currentTarget) setFocusedId(id);\n }}\n onKeyDown={(event) => {\n if (event.target === event.currentTarget) onKeyDown(event, node);\n }}\n className=\"outline-none [&:focus-visible>div]:ring-2 [&:focus-visible>div]:ring-inset [&:focus-visible>div]:ring-brand\"\n >\n {/* The row is a click target, but the keyboard contract lives on the treeitem above,\n which owns focus — the same split Combobox makes with its options. */}\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}\n <div\n onClick={() => {\n focus(id);\n choose(node);\n }}\n style={{ paddingLeft: 8 + (level - 1) * INDENT }}\n className={clsx(\n 'flex w-full cursor-pointer items-center gap-1.5 rounded-md pr-2 transition-colors',\n ROW[size],\n isSelected ? 'bg-brand-secondary text-default' : 'text-default hover:bg-default-secondary',\n )}\n >\n {node.hasChildren ? (\n // Not a button: the treeitem is the one tab stop, and Left/Right already toggle.\n // A pointer user still needs a target that toggles without selecting.\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions\n <span\n aria-hidden\n data-tree-toggle=\"\"\n onClick={(event) => {\n event.stopPropagation();\n toggle(id, !node.expanded);\n focus(id);\n }}\n className=\"flex size-5 shrink-0 items-center justify-center rounded text-icon-default-secondary hover:bg-default-tertiary\"\n >\n <LuChevronRight className={clsx('size-3.5 transition-transform', node.expanded && 'rotate-90')} />\n </span>\n ) : (\n <span aria-hidden className=\"size-5 shrink-0\" />\n )}\n <div className=\"min-w-0 flex-1\">\n {renderItem(item, {\n level,\n hasChildren: node.hasChildren,\n expanded: node.expanded,\n selected: isSelected,\n })}\n </div>\n </div>\n {node.expanded && (\n <ul role=\"group\" className=\"m-0 list-none p-0\">\n {renderLevel(children, level + 1)}\n </ul>\n )}\n </li>\n );\n });\n\n return (\n <ul role=\"tree\" aria-label={label} className={clsx('m-0 flex list-none flex-col p-0', className)}>\n {renderLevel(items, 1)}\n </ul>\n );\n}\n","import { forwardRef, type HTMLAttributes, type TdHTMLAttributes, type ThHTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { LuChevronDown, LuChevronsUpDown, LuChevronUp } from 'react-icons/lu';\nimport { cn } from '../../lib/cn';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\nexport type TableDensity = 'default' | 'compact';\nexport type TableSortDirection = 'ascending' | 'descending';\n\n/**\n * The composable table primitive, matching Figma's `Table` and `Table cell`.\n *\n * `DataTable` is the config-driven form — you give it `columns` and `rows` and it renders\n * everything. It is the right tool most of the time, and it is not going away. But it\n * cannot express a grouped header, a footer row, a colspan, or a cell layout outside its\n * `render` signature, so anything unusual meant abandoning it for a hand-rolled `<table>`\n * with none of the semantics. These parts are that escape hatch with the semantics kept.\n *\n * Figma's `Table cell` has a 32-value `Style` axis (lead checkbox, lead avatar, badges\n * multiple, trend positive/negative, action icons, star ratings, payment method…). Those\n * are *compositions*, not variants of one component — each is an existing library\n * component dropped into a cell — so they are expressed here as `TableCell` plus whatever\n * goes inside it, rather than 32 props.\n */\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Names the table. Required unless you render a `TableCaption`. */\n label?: string;\n density?: TableDensity;\n /** Equal-width columns driven by `<colgroup>`, matching `DataTable`. Default `false`. */\n fixed?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(function Table(\n { label, density = 'default', fixed = false, className, children, ...rest },\n ref,\n) {\n return (\n // The scroll container is separate from the table so the header stays inside the\n // scrolling region — a table that is its own scroll container cannot have a sticky\n // header.\n // The scroll wrapper is required for a <table>, which cannot itself scroll, so this\n // takes the scrollbar styling rather than ScrollArea.\n <div className={clsx('w-full overflow-x-auto', SCROLLBAR_CLASSES)}>\n <table\n ref={ref}\n aria-label={label}\n data-slot=\"table\"\n data-density={density}\n className={cn('w-full border-collapse', fixed && 'table-fixed', className)}\n {...rest}\n >\n {children}\n </table>\n </div>\n );\n});\n\nexport interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {}\n\n/**\n * A visible table title that also names the table. Prefer this over `label` when the\n * heading is on screen anyway — `DataTable` could not be named at all before 0.4.0.\n */\nexport const TableCaption = forwardRef<HTMLTableCaptionElement, TableCaptionProps>(\n function TableCaption({ className, ...rest }, ref) {\n return (\n <caption\n ref={ref}\n className={cn('px-4 py-3 text-left text-body-sm text-default-secondary', className)}\n {...rest}\n />\n );\n },\n);\n\nexport const TableHeader = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(\n function TableHeader({ className, ...rest }, ref) {\n return <thead ref={ref} className={cn('border-b border-default', className)} {...rest} />;\n },\n);\n\nexport const TableBody = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(\n function TableBody({ className, ...rest }, ref) {\n return <tbody ref={ref} className={className} {...rest} />;\n },\n);\n\nexport const TableFooter = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(\n function TableFooter({ className, ...rest }, ref) {\n return (\n <tfoot\n ref={ref}\n className={cn('border-t border-default bg-default-secondary font-medium', className)}\n {...rest}\n />\n );\n },\n);\n\nexport interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n selected?: boolean;\n}\n\nexport const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(function TableRow(\n { selected, className, ...rest },\n ref,\n) {\n return (\n <tr\n ref={ref}\n // `aria-selected` only when selection is actually in play — on a row that is not\n // part of a selectable set it is meaningless noise.\n aria-selected={selected}\n data-state={selected ? 'selected' : undefined}\n className={cn(\n 'border-b border-default last:border-b-0 transition-colors',\n selected ? 'bg-brand-tertiary' : 'hover:bg-default-secondary/50',\n className,\n )}\n {...rest}\n />\n );\n});\n\nexport interface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /**\n * Makes the header a sort control. `false` means sortable but not currently sorted.\n *\n * `aria-sort` goes on the `<th>` and must be present on exactly one column at a time —\n * it is the only non-visual signal of sort state, and `DataTable` had none.\n */\n sort?: TableSortDirection | false;\n onSort?: () => void;\n align?: 'left' | 'center' | 'right';\n /** Keeps the header visible while the body scrolls. */\n sticky?: boolean;\n}\n\nconst ALIGN = { left: 'text-left', center: 'text-center', right: 'text-right' } as const;\n\nexport const TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(function TableHead(\n { sort, onSort, align = 'left', sticky = false, className, children, ...rest },\n ref,\n) {\n const sortable = sort !== undefined && onSort !== undefined;\n\n return (\n <th\n ref={ref}\n // `scope=\"col\"` is what ties every cell beneath to this header when a screen reader\n // reads a cell out of context.\n scope=\"col\"\n aria-sort={sort === undefined ? undefined : sort === false ? 'none' : sort}\n className={cn(\n 'px-4 py-3 text-body-xs font-semibold text-default-secondary',\n ALIGN[align],\n sticky && 'sticky top-0 z-raised bg-default',\n className,\n )}\n {...rest}\n >\n {sortable ? (\n <button\n type=\"button\"\n onClick={onSort}\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded transition-colors hover:text-default',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n )}\n >\n {children}\n {sort === false ? (\n <LuChevronsUpDown aria-hidden className=\"size-3.5 opacity-50\" />\n ) : sort === 'ascending' ? (\n <LuChevronUp aria-hidden className=\"size-3.5\" />\n ) : (\n <LuChevronDown aria-hidden className=\"size-3.5\" />\n )}\n </button>\n ) : (\n children\n )}\n </th>\n );\n});\n\nexport interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {\n align?: 'left' | 'center' | 'right';\n /** Vertical rhythm. Matches `DataTable`'s `density`. */\n density?: TableDensity;\n /** Makes this the row's header cell — `scope=\"row\"`, for a table with row headers. */\n header?: boolean;\n}\n\nexport const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(function TableCell(\n { align = 'left', density = 'default', header = false, className, ...rest },\n ref,\n) {\n const Tag = header ? 'th' : 'td';\n return (\n <Tag\n ref={ref as never}\n scope={header ? 'row' : undefined}\n className={cn(\n density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n 'text-body-sm text-default',\n header && 'font-medium',\n ALIGN[align],\n className,\n )}\n {...rest}\n />\n );\n});\n","import clsx from 'clsx';\nimport type { Key, ReactNode } from 'react';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { ProgressBar } from '../feedback/progress-bar';\nimport type { ProgressBarTone } from '../feedback/progress-bar';\n\n// ── Column definition ──────────────────────────────────────────────────────────\n\nexport interface ColumnDef<T> {\n key: string;\n header: string;\n /**\n * CSS width value — e.g. `\"320px\"`, `\"10rem\"`. When `grow` is true this becomes the\n * column's floor: it counts toward the table's min-width, below which the wrapper\n * scrolls sideways rather than crushing the columns.\n */\n width: string;\n /**\n * When true the column absorbs the remaining table width.\n *\n * With no `grow` column, `table-fixed` distributes surplus width proportionally\n * across every column — the old flex layout left it blank on the right instead. Mark\n * whichever column should soak it up.\n */\n grow?: boolean;\n render: (row: T) => ReactNode;\n}\n\n// ── Density ────────────────────────────────────────────────────────────────────\n\nexport type DataTableDensity = 'default' | 'compact';\nexport type DataTableAlign = 'center' | 'top';\n\n/**\n * `default` is 0.2.0's spacing verbatim — ten call sites depend on it.\n *\n * `compact` is the audit / AI-widget density: an 11px semibold uppercase header over\n * 13px cells, which are `text-body-tiny` and `text-body-xs` exactly, so the type sizes\n * come across unchanged and only the padding really moves.\n */\nconst DENSITY: Record<DataTableDensity, { headerCell: string; headerText: string; bodyCell: string }> = {\n default: {\n headerCell: 'px-4 py-3',\n headerText: 'text-body-xs font-medium text-default-secondary whitespace-nowrap',\n bodyCell: 'px-4 py-[14px]',\n },\n compact: {\n headerCell: 'px-3 py-2',\n headerText:\n 'text-body-tiny font-semibold uppercase tracking-[0.4px] text-default-secondary whitespace-nowrap',\n bodyCell: 'px-3 py-2 text-body-xs text-default',\n },\n};\n\nconst ALIGN: Record<DataTableAlign, string> = {\n center: 'align-middle',\n top: 'align-top',\n};\n\n// ── DataTable ──────────────────────────────────────────────────────────────────\n\nexport interface DataTableProps<T> {\n columns: ColumnDef<T>[];\n rows: T[];\n getRowKey: (row: T, index: number) => Key;\n /** Row and header padding. `compact` also steps the header and cell type down. */\n density?: DataTableDensity;\n /** Vertical alignment of every body cell. Use `top` for multi-line or ragged cells. */\n align?: DataTableAlign;\n onRowClick?: (row: T) => void;\n /** Rendered as one full-width row when `rows` is empty. Omit to render nothing. */\n emptyLabel?: string;\n className?: string;\n}\n\n/**\n * A real `<table>` with `table-fixed` and a `<colgroup>`.\n *\n * 0.2.0 laid each row out as its own flex container sized `w-max`, so a `grow` column\n * sized itself per row and one long cell shunted that row's remaining columns out of\n * line with its neighbours. `table-fixed` resolves column widths once for the whole\n * table, which is the property the consuming app hand-rolled a separate audit table\n * to get.\n */\nexport function DataTable<T,>({\n columns,\n rows,\n getRowKey,\n density = 'default',\n align = 'center',\n onRowClick,\n emptyLabel,\n className,\n}: DataTableProps<T>) {\n const d = DENSITY[density];\n // Summed as a CSS expression rather than parsed as px, so any unit the caller used\n // (px, rem, ch) still yields a correct floor.\n const minWidth = columns.length ? `calc(${columns.map((c) => c.width).join(' + ')})` : undefined;\n\n return (\n <div className={clsx(// A wrapper element here is load-bearing for the table layout, and the rows are\n // focusable when clickable, so this takes the scrollbar styling rather than ScrollArea.\n clsx('overflow-x-auto rounded-xl border border-default bg-default', SCROLLBAR_CLASSES), className)}>\n <table className=\"w-full table-fixed border-collapse text-left\" style={{ minWidth }}>\n <colgroup>\n {columns.map((col) => (\n // A grow column gets no width, so table-fixed hands it the leftover space.\n // Its floor is already counted in the table's min-width.\n <col key={col.key} style={col.grow ? undefined : { width: col.width }} />\n ))}\n </colgroup>\n <thead>\n <tr className=\"bg-default-secondary\">\n {columns.map((col) => (\n <th key={col.key} scope=\"col\" className={clsx('overflow-hidden', d.headerCell, d.headerText)}>\n {col.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.length === 0\n ? emptyLabel && (\n <tr>\n <td\n colSpan={columns.length}\n className={clsx(d.bodyCell, 'text-center text-body-sm text-default-secondary')}\n >\n {emptyLabel}\n </td>\n </tr>\n )\n : rows.map((row, i) => (\n <tr\n key={getRowKey(row, i)}\n className={clsx(\n 'transition-colors hover:bg-default-secondary/50',\n i > 0 && 'border-t border-default',\n // outline, not ring: `ring-*` compiles to box-shadow, which browsers\n // do not paint on a <tr> under border-collapse: collapse.\n onRowClick &&\n 'cursor-pointer outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-brand',\n )}\n // Deliberately no role=\"button\" — it would override the implicit\n // role=\"row\" and detach every row from the table's accessibility\n // tree. The <th scope>/<td> markup supplies the real roles for free.\n tabIndex={onRowClick ? 0 : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n onKeyDown={\n onRowClick\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onRowClick(row);\n }\n }\n : undefined\n }\n >\n {columns.map((col) => (\n <td key={col.key} className={clsx('overflow-hidden', d.bodyCell, ALIGN[align])}>\n {col.render(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ── Cell components ────────────────────────────────────────────────────────────\n\n/**\n * Cell type scale.\n *\n * Named `size`, not `density`, and deliberately *not* inherited from the table: the two\n * real compact tables disagree about the mapping — the audit table wants default\n * padding with small cell text — so inheritance could not express it anyway, and it\n * would make these render one size inside a table and another outside one.\n */\nexport type TableCellSize = 'sm' | 'md';\n\nexport interface TableCellLeadTextProps {\n primary: string;\n secondary?: string;\n size?: TableCellSize;\n className?: string;\n}\n\n/** Primary text plus an optional muted subtitle — for lead entity/name cells. */\nexport function TableCellLeadText({ primary, secondary, size = 'md', className }: TableCellLeadTextProps) {\n return (\n <div className={clsx('flex flex-col gap-0.5', className)}>\n <span\n className={clsx(\n 'font-medium leading-snug text-default',\n size === 'sm' ? 'text-body-xs' : 'text-body-sm',\n )}\n >\n {primary}\n </span>\n {secondary && (\n <span\n className={clsx(\n 'font-normal leading-tight text-default-secondary',\n size === 'sm' ? 'text-body-tiny' : 'text-body-xs',\n )}\n >\n {secondary}\n </span>\n )}\n </div>\n );\n}\n\nexport interface TableCellTextProps {\n children: ReactNode;\n /** Muted (secondary) by default; pass false for the primary colour. */\n muted?: boolean;\n size?: TableCellSize;\n /** Ellipsise instead of wrapping, so every row keeps the same height. */\n truncate?: boolean;\n className?: string;\n}\n\n/** Plain text cell. */\nexport function TableCellText({\n children,\n muted = true,\n size = 'md',\n truncate = false,\n className,\n}: TableCellTextProps) {\n return (\n <span\n className={clsx(\n 'font-normal leading-snug',\n size === 'sm' ? 'text-body-tiny' : 'text-body-xs',\n truncate ? 'block truncate' : 'whitespace-nowrap',\n muted ? 'text-default-secondary' : 'text-default',\n className,\n )}\n >\n {children}\n </span>\n );\n}\n\nexport interface TableCellBadgeProps {\n label: string;\n className?: string;\n}\n\n/** Small outlined chip — entity type labels, categories. */\nexport function TableCellBadge({ label, className }: TableCellBadgeProps) {\n return (\n <span\n className={clsx(\n 'inline-flex items-center rounded-md border border-default bg-default-secondary px-2 py-0.5 text-body-tiny font-medium text-default-secondary whitespace-nowrap',\n className,\n )}\n >\n {label}\n </span>\n );\n}\n\nexport interface TableCellProgressProps {\n percent: number;\n /**\n * Bar colour. `brand` is 0.2.0's default and byte-identical to it — `bg-brand`\n * resolves to the same `--prim-brand-900` the old raw-hex default hardcoded.\n */\n tone?: ProgressBarTone;\n size?: TableCellSize;\n className?: string;\n}\n\n/** Mini progress bar with a percentage label below. */\nexport function TableCellProgress({\n percent,\n tone = 'brand',\n size = 'md',\n className,\n}: TableCellProgressProps) {\n const clamped = Math.min(100, Math.max(0, percent));\n return (\n <div className={clsx('flex flex-col gap-1', className)}>\n {/* Delegates to ProgressBar rather than hand-rolling a second bar, which is what\n 0.2.0 did — the two then disagreed on the track colour. */}\n <ProgressBar\n value={clamped}\n tone={tone}\n size=\"sm\"\n // `size` used to drive the label's font size, which was `text-[10px]` — off the type\n // scale, whose smallest step is 11px. The label is now `text-body-tiny` at both\n // sizes, so `size` drives the bar's width instead: 48 / 64px, both on the Space ramp.\n className={size === 'sm' ? 'w-12' : 'w-16'}\n aria-label={`${clamped}%`}\n />\n <span className=\"text-body-tiny leading-none text-default-secondary\">\n {percent}%\n </span>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { LuCircleCheckBig, LuInfo, LuTriangleAlert } from 'react-icons/lu';\n\nexport type InlineAlertTone = 'info' | 'warning' | 'danger' | 'positive';\n\nexport interface InlineAlertProps {\n tone: InlineAlertTone;\n children: ReactNode;\n /** Overrides the per-tone default glyph. Pass `null` for no icon. */\n icon?: ReactNode | null;\n className?: string;\n}\n\nconst toneStyles: Record<InlineAlertTone, string> = {\n info: 'border-brand-tertiary bg-brand-tertiary text-brand',\n warning: 'border-warning-tertiary bg-warning-tertiary text-warning',\n danger: 'border-danger-tertiary bg-danger-tertiary text-danger',\n positive: 'border-positive-tertiary bg-positive-tertiary text-positive',\n};\n\nconst toneIcons: Record<InlineAlertTone, ReactNode> = {\n info: <LuInfo className=\"size-4\" />,\n warning: <LuTriangleAlert className=\"size-4\" />,\n danger: <LuTriangleAlert className=\"size-4\" />,\n positive: <LuCircleCheckBig className=\"size-4\" />,\n};\n\n/** Banner for inline messaging — form errors, destructive-action warnings, success confirmations.\n *\n * Replaces four byte-identical raw-`amber-*` callouts, five competing error-text styles and a\n * standalone `Banner` component. `danger` renders as `role=\"alert\"`; the rest as `role=\"status\"`. */\nexport function InlineAlert({ tone, children, icon, className }: InlineAlertProps) {\n const glyph = icon === undefined ? toneIcons[tone] : icon;\n\n return (\n <div\n role={tone === 'danger' ? 'alert' : 'status'}\n className={clsx(\n 'flex items-start gap-3 rounded-xl border p-4 text-body-xs',\n toneStyles[tone],\n className,\n )}\n >\n {/* The glyph restates the tone the text already carries, so it is decoration —\n `react-icons` adds no `aria-hidden` of its own (verified in its `iconBase`), so\n without this the SVG lands in the a11y tree of a `role=\"alert\"` region. */}\n {glyph && (\n <span aria-hidden className=\"mt-px shrink-0\">\n {glyph}\n </span>\n )}\n <div className=\"min-w-0\">{children}</div>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type EmptyStateVariant = 'empty' | 'loading' | 'error';\nexport type EmptyStateSize = 'sm' | 'md' | 'lg';\n\n/**\n * Vertical padding. The eighteen source copies used `py-8`, with divergent siblings\n * at `py-10`, `py-12` and `py-16` — these three sizes absorb all four.\n */\nconst SIZES: Record<EmptyStateSize, string> = {\n sm: 'py-8',\n md: 'py-12',\n lg: 'py-16',\n};\n\nconst TONES: Record<EmptyStateVariant, string> = {\n empty: 'text-default-secondary',\n loading: 'text-default-secondary',\n error: 'text-danger',\n};\n\nexport interface EmptyStateProps {\n message: string;\n /** `error` is the only variant that changes colour; `loading` exists for intent. */\n variant?: EmptyStateVariant;\n size?: EmptyStateSize;\n icon?: ReactNode;\n /** A primary action, e.g. \"Add your first source\". */\n action?: ReactNode;\n className?: string;\n}\n\n/**\n * Centred placeholder for an empty list, a loading list, or a failed fetch.\n *\n * Replaces eighteen copies of `py-8 text-center text-body-sm\n * text-default-secondary` plus four divergent variants. Loading and empty were\n * always the same markup in this codebase, so they are one component with a\n * `variant` rather than two near-identical ones.\n *\n * `aria-live` is set for the loading and error variants so a screen reader announces\n * the state change instead of silently swapping list content.\n */\nexport function EmptyState({\n message,\n variant = 'empty',\n size = 'sm',\n icon,\n action,\n className,\n}: EmptyStateProps) {\n return (\n <div\n className={clsx(\n 'flex flex-col items-center justify-center gap-2 px-4 text-center text-body-sm',\n SIZES[size],\n TONES[variant],\n className,\n )}\n aria-live={variant === 'empty' ? undefined : 'polite'}\n >\n {icon && <span className=\"text-default-tertiary\">{icon}</span>}\n <p>{message}</p>\n {action}\n </div>\n );\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\n\nexport type SkeletonShape = 'line' | 'block' | 'circle';\n\nexport interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n shape?: SkeletonShape;\n /** Number of stacked lines. Only meaningful for `line`. */\n lines?: number;\n}\n\nconst SHAPE: Record<SkeletonShape, string> = {\n line: 'h-4 rounded',\n block: 'h-full w-full rounded-lg',\n circle: 'aspect-square rounded-full',\n};\n\n/**\n * Loading placeholder.\n *\n * `aria-hidden` and no role: a skeleton is a picture of content that does not exist yet,\n * so announcing it produces a burst of meaningless nodes. The *region* it sits in should\n * carry the loading state — `EmptyState variant=\"loading\"` or `aria-busy` on the\n * container — which is a decision only the caller can make.\n *\n * The pulse is suppressed by the preset's `prefers-reduced-motion` rule, leaving a plain\n * tinted block.\n */\nexport const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(function Skeleton(\n { shape = 'line', lines = 1, className, ...rest },\n ref,\n) {\n if (shape === 'line' && lines > 1) {\n return (\n <div ref={ref} aria-hidden data-slot=\"skeleton-group\" className=\"flex flex-col gap-2\" {...rest}>\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={clsx(\n 'animate-pulse bg-default-tertiary',\n SHAPE.line,\n // A ragged last line reads as a paragraph rather than a solid slab.\n index === lines - 1 ? 'w-3/5' : 'w-full',\n className,\n )}\n />\n ))}\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n aria-hidden\n data-slot=\"skeleton\"\n className={clsx('animate-pulse bg-default-tertiary', SHAPE[shape], className)}\n {...rest}\n />\n );\n});\n","import { forwardRef, useId, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { LuCircleCheckBig, LuInfo, LuTriangleAlert, LuX } from 'react-icons/lu';\nimport { IconButton } from '../forms/icon-button';\nimport type { InlineAlertTone } from './inline-alert';\n\nexport type BannerVariant = 'message' | 'alert';\n\n// `title` is omitted from the base attributes because the HTML `title` attribute is a\n// string that renders a native tooltip — the same collision that made 0.2.0's\n// `Modal.title` become `Modal.label`. Here the prop is the more useful one, so the\n// attribute gives way.\nexport interface BannerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Bold first line. Matches Figma's `Title`. */\n title: ReactNode;\n /** Supporting copy. Matches Figma's `Body`. */\n children?: ReactNode;\n /**\n * Matches Figma's `Variant` axis. `message` is informational; `alert` is urgent and is\n * announced immediately.\n */\n variant?: BannerVariant;\n tone?: InlineAlertTone;\n /** Replaces the tone glyph. Pass `null` to suppress it. Matches `Icon` / `Has Icon`. */\n icon?: ReactNode | null;\n /** Trailing action slot. Matches `Has Button`. */\n action?: ReactNode;\n /** Renders a dismiss button. Matches `Dismissible`. */\n onDismiss?: () => void;\n}\n\nconst TONE_STYLES: Record<InlineAlertTone, string> = {\n info: 'border-brand-tertiary bg-brand-tertiary text-default',\n positive: 'border-positive-tertiary bg-positive-tertiary text-default',\n warning: 'border-warning-tertiary bg-warning-tertiary text-default',\n danger: 'border-danger-tertiary bg-danger-tertiary text-default',\n};\n\nconst TONE_ICON_COLOR: Record<InlineAlertTone, string> = {\n info: 'text-icon-brand',\n positive: 'text-icon-positive',\n warning: 'text-icon-warning',\n danger: 'text-icon-danger',\n};\n\nconst TONE_ICON: Record<InlineAlertTone, ReactNode> = {\n info: <LuInfo aria-hidden className=\"size-5\" />,\n positive: <LuCircleCheckBig aria-hidden className=\"size-5\" />,\n warning: <LuTriangleAlert aria-hidden className=\"size-5\" />,\n danger: <LuTriangleAlert aria-hidden className=\"size-5\" />,\n};\n\n/**\n * A page- or section-level banner with a title, body, optional action and optional dismiss.\n *\n * This is Figma's `Notification` set (`Variant: Message | Alert`, with `Title`, `Body`,\n * `Has Icon`, `Has Button` and `Dismissible`). Worth being precise about the name: its\n * Figma keywords are \"message, alert, feedback, callout, banner\" — it is a *persistent,\n * in-flow* notice, **not** a toast. A toast is transient, stacked, and announced from a\n * live region that already exists; that is `Toast`, and it is a different component.\n *\n * `InlineAlert` remains the compact single-line form for use inside a form or a card.\n * `Banner` is the one with a heading and an action.\n *\n * `variant` drives the announcement, not just the styling: `alert` is `role=\"alert\"`\n * (interrupts), `message` is `role=\"status\"` (waits its turn).\n */\nexport const Banner = forwardRef<HTMLDivElement, BannerProps>(function Banner(\n {\n title,\n children,\n variant = 'message',\n tone = 'info',\n icon,\n action,\n onDismiss,\n className,\n ...rest\n },\n ref,\n) {\n const titleId = useId();\n const glyph = icon === undefined ? TONE_ICON[tone] : icon;\n\n return (\n <div\n ref={ref}\n role={variant === 'alert' ? 'alert' : 'status'}\n aria-labelledby={titleId}\n data-slot=\"banner\"\n className={clsx(\n 'flex w-full items-start gap-3 rounded-xl border p-4',\n TONE_STYLES[tone],\n className,\n )}\n {...rest}\n >\n {glyph && (\n <span aria-hidden className={clsx('mt-px shrink-0', TONE_ICON_COLOR[tone])}>\n {glyph}\n </span>\n )}\n <div className=\"min-w-0 flex-1\">\n <p id={titleId} className=\"text-body-sm font-semibold text-default\">\n {title}\n </p>\n {children && <div className=\"mt-1 text-body-xs text-default-secondary\">{children}</div>}\n {action && <div className=\"mt-3 flex items-center gap-2\">{action}</div>}\n </div>\n {onDismiss && (\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n // Named with the title, so several stacked banners do not all announce\n // \"Dismiss\" identically.\n aria-label={typeof title === 'string' ? `Dismiss: ${title}` : 'Dismiss'}\n onClick={onDismiss}\n className=\"-mr-1 -mt-1 shrink-0\"\n >\n <LuX aria-hidden size={16} />\n </IconButton>\n )}\n </div>\n );\n});\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { LuCircleCheckBig, LuInfo, LuTriangleAlert, LuX } from 'react-icons/lu';\nimport { IconButton } from '../forms/icon-button';\nimport { Portal } from '../overlays/portal';\nimport type { InlineAlertTone } from './inline-alert';\n\nexport type ToastTone = InlineAlertTone;\nexport type ToasterPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface ToastOptions {\n title: ReactNode;\n description?: ReactNode;\n tone?: ToastTone;\n /** Milliseconds before auto-dismiss. `0` keeps it until dismissed. Default `5000`. */\n duration?: number;\n action?: ReactNode;\n}\n\nexport interface ToastRecord extends ToastOptions {\n id: string;\n}\n\ninterface ToastContextValue {\n toast: (options: ToastOptions) => string;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\n/**\n * Queue a toast. Must be called under a `<Toaster>`.\n *\n * Returns the toast's id so a long-running action can dismiss its own \"Saving…\" toast when\n * it finishes.\n */\nexport function useToast(): ToastContextValue {\n const context = useContext(ToastContext);\n if (!context) throw new Error('useToast() must be used inside <Toaster>');\n return context;\n}\n\nconst TONE_ICON: Record<ToastTone, ReactNode> = {\n info: <LuInfo aria-hidden className=\"size-4\" />,\n positive: <LuCircleCheckBig aria-hidden className=\"size-4\" />,\n warning: <LuTriangleAlert aria-hidden className=\"size-4\" />,\n danger: <LuTriangleAlert aria-hidden className=\"size-4\" />,\n};\n\nconst TONE_ICON_COLOR: Record<ToastTone, string> = {\n info: 'text-icon-brand',\n positive: 'text-icon-positive',\n warning: 'text-icon-warning',\n danger: 'text-icon-danger',\n};\n\nconst POSITION: Record<ToasterPosition, string> = {\n 'top-left': 'top-4 left-4 items-start',\n 'top-center': 'top-4 left-1/2 -translate-x-1/2 items-center',\n 'top-right': 'top-4 right-4 items-end',\n 'bottom-left': 'bottom-4 left-4 items-start',\n 'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2 items-center',\n 'bottom-right': 'bottom-4 right-4 items-end',\n};\n\nexport interface ToasterProps {\n children: ReactNode;\n position?: ToasterPosition;\n /** Maximum simultaneous toasts. Oldest are dropped first. Default `4`. */\n max?: number;\n /** Default auto-dismiss for toasts that do not set their own. Default `5000`. */\n duration?: number;\n}\n\n/**\n * Provider plus the region toasts render into. Mount once, near the app root.\n *\n * The library had no toast and — more importantly — **no persistent live region at all**,\n * so nothing could announce an event that happened away from focus. The distinction that\n * matters here: a live region must already exist in the DOM before content is put into it.\n * A region that mounts at the same moment as its message is frequently not announced,\n * which is why the wrapper below renders unconditionally and only its children come and go.\n *\n * `aria-live=\"polite\"` on the container, and `role=\"alert\"` on individual `danger` toasts\n * so a failure interrupts rather than queueing behind a success message.\n */\nexport function Toaster({\n children,\n position = 'bottom-right',\n max = 4,\n duration = 5000,\n}: ToasterProps) {\n const [toasts, setToasts] = useState<ToastRecord[]>([]);\n const timers = useRef(new Map<string, ReturnType<typeof setTimeout>>());\n const counter = useRef(0);\n\n const dismiss = useCallback((id: string) => {\n const timer = timers.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timers.current.delete(id);\n }\n setToasts((current) => current.filter((entry) => entry.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => {\n for (const timer of timers.current.values()) clearTimeout(timer);\n timers.current.clear();\n setToasts([]);\n }, []);\n\n const toast = useCallback(\n (options: ToastOptions) => {\n // A monotonic counter rather than a random id: `Math.random()` in a render-adjacent\n // path is a hydration hazard, and the value only has to be unique within the session.\n counter.current += 1;\n const id = `toast-${counter.current}`;\n const record: ToastRecord = { tone: 'info', duration, ...options, id };\n\n setToasts((current) => [...current, record].slice(-max));\n\n if (record.duration && record.duration > 0) {\n timers.current.set(\n id,\n setTimeout(() => dismiss(id), record.duration),\n );\n }\n return id;\n },\n [duration, max, dismiss],\n );\n\n useEffect(() => {\n const map = timers.current;\n return () => {\n for (const timer of map.values()) clearTimeout(timer);\n map.clear();\n };\n }, []);\n\n const context = useMemo(() => ({ toast, dismiss, dismissAll }), [toast, dismiss, dismissAll]);\n\n return (\n <ToastContext.Provider value={context}>\n {children}\n <Portal>\n <div\n // Unconditionally rendered, and empty most of the time. See the note above: a\n // live region has to pre-exist its content to be announced reliably.\n aria-live=\"polite\"\n aria-atomic=\"false\"\n className={clsx(\n 'pointer-events-none fixed z-toast flex w-full max-w-[380px] flex-col gap-2',\n POSITION[position],\n )}\n >\n {toasts.map((entry) => (\n <ToastItem key={entry.id} toast={entry} onDismiss={() => dismiss(entry.id)} />\n ))}\n </div>\n </Portal>\n </ToastContext.Provider>\n );\n}\n\nfunction ToastItem({ toast, onDismiss }: { toast: ToastRecord; onDismiss: () => void }) {\n const tone = toast.tone ?? 'info';\n\n return (\n <div\n // The container is polite; a danger toast escalates to assertive so a failure is not\n // read out after two successes.\n role={tone === 'danger' ? 'alert' : 'status'}\n // Re-enabled per toast — the container is pointer-events-none so it never blocks\n // clicks on the page behind an empty region.\n className={clsx(\n 'pointer-events-auto flex w-full items-start gap-3 rounded-xl border border-default',\n 'bg-default p-4 shadow-400',\n )}\n >\n <span aria-hidden className={clsx('mt-px shrink-0', TONE_ICON_COLOR[tone])}>\n {TONE_ICON[tone]}\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-body-sm font-semibold text-default\">{toast.title}</p>\n {toast.description && (\n <p className=\"mt-0.5 text-body-xs text-default-secondary\">{toast.description}</p>\n )}\n {toast.action && <div className=\"mt-2 flex items-center gap-2\">{toast.action}</div>}\n </div>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label={typeof toast.title === 'string' ? `Dismiss: ${toast.title}` : 'Dismiss'}\n onClick={onDismiss}\n className=\"-mr-1 -mt-1 shrink-0\"\n >\n <LuX aria-hidden size={14} />\n </IconButton>\n </div>\n );\n}\n","import { forwardRef, useState } from 'react';\nimport { LuEye, LuEyeOff } from 'react-icons/lu';\n\nimport { Input, type InputProps } from './input';\n\nexport type PasswordInputProps = Omit<InputProps, 'type' | 'trailingIcon' | 'trailingAction'>;\n\n/** Password field with a show/hide visibility toggle. */\nexport const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>(function PasswordInput(props, ref) {\n const [visible, setVisible] = useState(false);\n\n return (\n <Input\n ref={ref}\n {...props}\n type={visible ? 'text' : 'password'}\n trailingAction={\n <button\n type=\"button\"\n aria-label={visible ? 'Hide password' : 'Show password'}\n onClick={() => setVisible((v) => !v)}\n className=\"flex items-center justify-center rounded transition-colors hover:text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n {visible ? (\n <LuEyeOff aria-hidden className=\"size-4\" />\n ) : (\n <LuEye aria-hidden className=\"size-4\" />\n )}\n </button>\n }\n />\n );\n});\n","import clsx from 'clsx';\nimport { LuArrowRight, LuSearch } from 'react-icons/lu';\n\nexport interface AIChatBarProps {\n placeholder?: string;\n className?: string;\n}\n\nexport function AIChatBar({\n placeholder = 'Ask Intelligence about any entity, supplier, or risk…',\n className,\n}: AIChatBarProps) {\n return (\n <div\n className={clsx(\n 'flex h-16 items-center gap-3 rounded-2xl border border-default bg-default px-6 shadow-panel',\n className,\n )}\n >\n <span aria-hidden className=\"shrink-0 text-icon-default-secondary\">\n <LuSearch className=\"size-4\" />\n </span>\n <p className=\"flex-1 text-body-sm text-default-tertiary truncate\">{placeholder}</p>\n <button\n type=\"button\"\n className=\"inline-flex shrink-0 items-center gap-2 rounded-xl bg-brand px-4 py-3 text-body-sm font-semibold text-brand-on-brand hover:bg-brand-hover transition-colors\"\n >\n Ask\n <LuArrowRight aria-hidden className=\"size-4\" />\n </button>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { LuArrowRight, LuCpu } from 'react-icons/lu';\n\nexport interface AISuggestionChipProps {\n prompt: string;\n onClick?: () => void;\n className?: string;\n}\n\nexport function AISuggestionChip({ prompt, onClick, className }: AISuggestionChipProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={clsx(\n 'flex h-12 w-full items-center gap-3 rounded-xl border border-default bg-default px-3 text-left hover:bg-default-hover transition-colors',\n className,\n )}\n >\n <span aria-hidden className=\"shrink-0 text-icon-brand\">\n <LuCpu className=\"size-4\" />\n </span>\n <span className=\"flex-1 text-body-sm text-default truncate\">{prompt}</span>\n <span aria-hidden className=\"shrink-0 text-icon-default-secondary\">\n <LuArrowRight className=\"size-3.5\" strokeWidth={2.5} />\n </span>\n </button>\n );\n}\n","import clsx from 'clsx';\nimport { TagPill } from '../status/tag-pill';\n\nexport interface QuickAction {\n label: string;\n value: string;\n}\n\nexport interface QuickActionsBarProps {\n actions: QuickAction[];\n active?: string;\n onSelect?: (value: string) => void;\n className?: string;\n}\n\nexport function QuickActionsBar({ actions, active, onSelect, className }: QuickActionsBarProps) {\n return (\n <div className={clsx('flex flex-wrap items-center gap-3', className)}>\n {actions.map((action) => {\n const isActive = active === action.value;\n return (\n <button\n key={action.value}\n type=\"button\"\n // `aria-pressed` because these are toggles, not navigation — through 0.3.0 the\n // `active` prop was conveyed by the pill's fill colour only.\n aria-pressed={isActive}\n onClick={() => onSelect?.(action.value)}\n // Was `focus:outline-none` with no replacement — the UA indicator removed and\n // nothing put back, a straight WCAG 2.4.7 failure.\n className=\"rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default\"\n >\n <TagPill label={action.label} tone={isActive ? 'brand' : 'default'} />\n </button>\n );\n })}\n </div>\n );\n}\n","/** Soft aurora atmosphere used by the public-facing screens (auth, event\n * onboarding) — mirrors AuroraBackground in pages/intelligence. Blobs are\n * corner-anchored so the effect scales from phones to kiosk displays.\n * Render inside a `relative overflow-hidden` container; content goes on top\n * with `relative`. */\nexport function AuroraBackdrop() {\n return (\n <div className=\"pointer-events-none absolute inset-0\" aria-hidden>\n <div className=\"absolute -left-24 -top-28\" style={{ width: 380, height: 380, background: 'radial-gradient(ellipse, rgba(249,133,133,0.45) 0%, transparent 70%)' }} />\n <div className=\"absolute -top-24 right-[-4%]\" style={{ width: 320, height: 320, background: 'radial-gradient(ellipse, rgba(254,160,160,0.4) 0%, transparent 70%)' }} />\n <div className=\"absolute bottom-[-10%] right-[14%]\" style={{ width: 420, height: 420, background: 'radial-gradient(ellipse, rgba(196,181,253,0.3) 0%, transparent 70%)' }} />\n <div className=\"absolute bottom-[-6%] left-[4%]\" style={{ width: 280, height: 280, background: 'radial-gradient(ellipse, rgba(147,197,253,0.25) 0%, transparent 70%)' }} />\n <div className=\"absolute left-[20%] top-[30%]\" style={{ width: 240, height: 240, background: 'radial-gradient(ellipse, rgba(173,216,255,0.18) 0%, transparent 70%)' }} />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["import_react","import_clsx","Slot","clsx","import_react","import_clsx","Spinner","size","clsx","import_react","import_jsx_runtime","size","import_jsx_runtime","clsx","Button","size","import_react","import_clsx","import_jsx_runtime","variantStyles","clsx","sizeStyles","IconButton","size","import_clsx","import_jsx_runtime","clsx","size","import_clsx","import_jsx_runtime","sizeStyles","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","size","import_react","import_clsx","import_jsx_runtime","size","clsx","Input","InputControl","import_react","import_clsx","import_jsx_runtime","Textarea","size","TextareaControl","clsx","import_react","import_clsx","import_react","import_react","import_react","import_clsx","import_clsx","clsx","clsx","import_react","import_react","lockScroll","import_react","import_jsx_runtime","SelectControl","size","clsx","Select","import_react","import_clsx","import_lu","import_jsx_runtime","inputBase","iconWrap","DatePicker","size","clsx","DateInput","import_clsx","import_lu","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_lu","import_jsx_runtime","SIZE","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Switch","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Toggle","size","clsx","ToggleGroupItem","import_react","import_clsx","import_jsx_runtime","InputOTP","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_lu","import_jsx_runtime","size","clsx","import_clsx","import_jsx_runtime","size","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","size","clsx","import_jsx_runtime","size","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","TONE_STYLES","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_jsx_runtime","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","sizeStyles","toneStyles","size","clsx","import_react","import_clsx","import_clsx","import_lu","import_jsx_runtime","size","clsx","import_jsx_runtime","LABEL_TEXT","Checkbox","size","clsx","import_react","import_clsx","import_jsx_runtime","RadioGroup","size","clsx","LABEL_TEXT","Radio","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","Slider","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Label","size","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","offset","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","HEIGHT","InputGroup","size","clsx","InputGroupInput","InputGroupAddon","InputGroupText","SearchInput","import_react","import_lu","import_jsx_runtime","SIZE","size","import_react","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_react","import_clsx","import_lu","import_jsx_runtime","clsx","import_jsx_runtime","offset","clsx","import_react","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_lu","import_react","import_clsx","import_jsx_runtime","ScrollArea","clsx","import_jsx_runtime","clsx","import_jsx_runtime","size","import_react","import_jsx_runtime","size","import_react","import_clsx","import_lu","import_jsx_runtime","clsx","import_react","import_jsx_runtime","FOOTER_ALIGN","size","import_react","import_clsx","import_lu","import_jsx_runtime","clsx","Heading","import_react","import_jsx_runtime","import_react","import_clsx","import_jsx_runtime","AspectRatio","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","size","clsx","import_clsx","import_jsx_runtime","size","clsx","import_clsx","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_jsx_runtime","GAP","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_jsx_runtime","SIZE","VARIANT","clsx","size","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","Separator","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Kbd","size","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","Breadcrumb","clsx","BreadcrumbItem","BreadcrumbEllipsis","import_react","import_clsx","import_lu","import_jsx_runtime","GAP","clsx","Pagination","import_react","import_clsx","import_jsx_runtime","NavigationMenu","clsx","NavigationMenuItem","import_react","import_clsx","import_jsx_runtime","clsx","TextLink","TextList","TextListItem","import_clsx","import_clsx","import_jsx_runtime","sizeStyles","size","clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","sizeStyles","size","clsx","import_clsx","import_jsx_runtime","SIZE","TONE","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","SIZE","size","labelClass","clsx","import_clsx","import_jsx_runtime","SIZE","size","offset","clsx","import_clsx","import_jsx_runtime","SIZE","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_jsx_runtime","SIZE","size","clsx","offset","import_clsx","import_clsx","import_jsx_runtime","size","clsx","import_jsx_runtime","size","clsx","import_clsx","import_lu","import_jsx_runtime","SIZE","WEIGHT","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","GAP","clsx","import_clsx","import_react","import_jsx_runtime","SIZE","size","import_jsx_runtime","GAP","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","COLUMNS","import_clsx","import_lu","import_jsx_runtime","COLUMNS","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","size","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","Table","clsx","TableCaption","TableHeader","TableBody","TableFooter","TableRow","ALIGN","TableHead","TableCell","import_clsx","import_jsx_runtime","DENSITY","ALIGN","clsx","size","import_clsx","import_lu","import_jsx_runtime","toneStyles","clsx","import_clsx","import_jsx_runtime","size","clsx","import_react","import_clsx","import_jsx_runtime","SHAPE","Skeleton","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","TONE_STYLES","TONE_ICON","Banner","clsx","import_react","import_clsx","import_lu","import_jsx_runtime","TONE_ICON","TONE_ICON_COLOR","clsx","import_react","import_lu","import_jsx_runtime","PasswordInput","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_lu","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/components/forms/button.tsx","../src/lib/cn.ts","../src/lib/focus-ring.ts","../src/lib/slot.tsx","../src/components/feedback/spinner.tsx","../src/components/forms/control-size.tsx","../src/components/forms/icon-button.tsx","../src/components/forms/button-group.tsx","../src/components/avatar/avatar.tsx","../src/components/avatar/avatar-group.tsx","../src/components/avatar/avatar-block.tsx","../src/components/forms/field.tsx","../src/components/forms/input.tsx","../src/components/forms/textarea.tsx","../src/components/forms/select.tsx","../src/lib/dev-warn.ts","../src/lib/use-controllable-state.ts","../src/lib/use-roving-focus.ts","../src/components/overlays/floating.tsx","../src/components/overlays/menu-styles.ts","../src/lib/scrollbar.ts","../src/components/overlays/overlay.ts","../src/components/overlays/overlay-stack.ts","../src/components/overlays/portal.tsx","../src/components/forms/date-picker.tsx","../src/components/forms/stepper.tsx","../src/components/forms/multiselect-card.tsx","../src/components/forms/switch.tsx","../src/lib/compose-event-handlers.ts","../src/components/forms/toggle.tsx","../src/components/forms/input-otp.tsx","../src/components/forms/file-drop-zone.tsx","../src/components/forms/tag-input.tsx","../src/components/status/badge.tsx","../src/components/forms/form-card.tsx","../src/components/status/role-badge.tsx","../src/components/forms/combobox.tsx","../src/components/forms/role-combo-box.tsx","../src/components/forms/country-select.tsx","../src/components/forms/time-zone-select.tsx","../src/components/forms/command.tsx","../src/components/status/status-badge.tsx","../src/components/status/status-dot.tsx","../src/components/status/status-chip.tsx","../src/components/status/count-badge.tsx","../src/components/status/tag-pill.tsx","../src/components/status/trail-chip.tsx","../src/components/status/user-status-pill.tsx","../src/components/status/check-indicator.tsx","../src/components/status/entity-icon-badge.tsx","../src/components/forms/checkbox.tsx","../src/components/forms/check-control.tsx","../src/components/forms/radio-group.tsx","../src/components/forms/radio-cards.tsx","../src/components/forms/checkbox-group.tsx","../src/components/forms/segmented-control.tsx","../src/components/forms/slider.tsx","../src/components/forms/label.tsx","../src/components/forms/calendar.tsx","../src/components/forms/input-group.tsx","../src/components/overlays/modal.tsx","../src/components/overlays/toaster-guard.ts","../src/components/overlays/tooltip.tsx","../src/components/overlays/popover.tsx","../src/components/overlays/hover-card.tsx","../src/components/overlays/context-menu.tsx","../src/components/overlays/menu-core.tsx","../src/components/overlays/menubar.tsx","../src/components/overlays/drawer.tsx","../src/components/cards/scroll-area.tsx","../src/components/overlays/confirm-dialog.tsx","../src/components/overlays/note-confirm-modal.tsx","../src/components/overlays/dropdown-menu.tsx","../src/components/overlays/scrim.tsx","../src/components/overlays/fullscreen-surface.tsx","../src/components/chrome/visually-hidden.tsx","../src/components/chrome/accessible-icon.tsx","../src/components/cards/card.tsx","../src/components/cards/accordion.tsx","../src/components/cards/collapsible.tsx","../src/components/cards/layout.tsx","../src/components/cards/aspect-ratio.tsx","../src/components/cards/carousel.tsx","../src/components/cards/resizable.tsx","../src/components/chrome/page-heading.tsx","../src/components/chrome/page-toolbar.tsx","../src/components/chrome/filter-bar.tsx","../src/components/chrome/tabs.tsx","../src/components/chrome/nav-item.tsx","../src/components/chrome/eyebrow-label.tsx","../src/components/chrome/separator.tsx","../src/components/chrome/kbd.tsx","../src/components/chrome/breadcrumb.tsx","../src/components/chrome/pagination.tsx","../src/components/chrome/navigation-menu.tsx","../src/components/chrome/typography.tsx","../src/components/widgets/widget-header.tsx","../src/components/widgets/widget-title.tsx","../src/components/widgets/widget-footer.tsx","../src/components/widgets/widget-grid.tsx","../src/lib/width-tier.ts","../src/lib/use-width-tier.ts","../src/components/stats/stat-tile.tsx","../src/components/stats/stat-number.tsx","../src/components/stats/score-value.tsx","../src/components/stats/tile-grid.tsx","../src/components/charts/chart-tone.ts","../src/components/charts/bar-chart.tsx","../src/components/charts/donut-chart.tsx","../src/components/charts/radial-gauge.tsx","../src/components/charts/sparkline.tsx","../src/components/charts/mini-bar-chart.tsx","../src/components/charts/chart-legend.tsx","../src/components/charts/legend-dot.tsx","../src/components/charts/trend-label.tsx","../src/components/lists/list-row.tsx","../src/components/lists/file-row.tsx","../src/components/lists/scored-row.tsx","../src/components/lists/numbered-list.tsx","../src/components/feedback/progress-bar.tsx","../src/components/lists/icon-text-row.tsx","../src/components/lists/checklist-row.tsx","../src/components/lists/steps-list.tsx","../src/components/lists/detail-item.tsx","../src/components/lists/description-list.tsx","../src/components/lists/checked-group-list.tsx","../src/components/lists/tree-view.tsx","../src/components/lists/table.tsx","../src/components/lists/data-table.tsx","../src/lib/use-element-width.ts","../src/components/feedback/empty-state.tsx","../src/components/feedback/skeleton.tsx","../src/components/lists/data-table-layout.ts","../src/components/lists/data-table-parts.tsx","../src/components/lists/data-table-cells.tsx","../src/components/feedback/inline-alert.tsx","../src/components/feedback/error-boundary.tsx","../src/components/feedback/banner.tsx","../src/components/feedback/toast.tsx","../src/components/forms/password-input.tsx","../src/components/ai/ai-chat-bar.tsx","../src/components/ai/ai-suggestion-chip.tsx","../src/components/ai/quick-actions-bar.tsx","../src/components/ai/chat.tsx","../src/components/decorative/aurora-backdrop.tsx"],"sourcesContent":["export { Button } from './components/forms/button';\nexport type { ButtonProps, ButtonVariant, ButtonSize } from './components/forms/button';\n\nexport { IconButton } from './components/forms/icon-button';\nexport type { IconButtonProps, IconButtonVariant } from './components/forms/icon-button';\n\nexport { ButtonGroup } from './components/forms/button-group';\nexport type { ButtonGroupProps, ButtonGroupItem, ButtonGroupVariant, ButtonGroupAlign } from './components/forms/button-group';\n\nexport { Avatar } from './components/avatar/avatar';\nexport type { AvatarProps, AvatarInitialProps, AvatarImageProps, AvatarSize, AvatarShape } from './components/avatar/avatar';\n\nexport { AvatarGroup } from './components/avatar/avatar-group';\nexport type { AvatarGroupProps, AvatarGroupSpacing } from './components/avatar/avatar-group';\n\nexport { AvatarBlock } from './components/avatar/avatar-block';\nexport type { AvatarBlockProps } from './components/avatar/avatar-block';\n\n\n// ── Field ──────────────────────────────────────────────────────────────────────\n// The label / description / error / control wiring. Every text field composes it, and\n// it is exported so controls the library does not wrap can share the same association.\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldGroup,\n FieldSet,\n FieldLegend,\n FieldSeparator,\n useFieldContext,\n useFieldControl,\n} from './components/forms/field';\nexport type {\n FieldProps,\n FieldLabelProps,\n FieldTextProps,\n FieldGroupProps,\n FieldSetProps,\n FieldLegendProps,\n FieldSeparatorProps,\n FieldOrientation,\n FieldContextValue,\n} from './components/forms/field';\n\nexport { Input, InputControl } from './components/forms/input';\nexport type { InputProps, InputControlProps, InputSize } from './components/forms/input';\n\n// Supplies a default `size` to the form controls beneath it. `FilterBar` is the built-in\n// provider; export it so an app can set a density for a form section of its own.\nexport { ControlSizeProvider, useControlSize } from './components/forms/control-size';\nexport type { ControlSizeProviderProps } from './components/forms/control-size';\n\nexport { Textarea, TextareaControl } from './components/forms/textarea';\nexport type { TextareaProps, TextareaControlProps } from './components/forms/textarea';\n\nexport { Select, SelectControl } from './components/forms/select';\nexport type {\n SelectProps,\n SelectControlProps,\n SelectOption,\n SelectOptionGroup,\n} from './components/forms/select';\n\nexport { DatePicker } from './components/forms/date-picker';\nexport type { DatePickerProps } from './components/forms/date-picker';\n\nexport { Stepper } from './components/forms/stepper';\nexport type { StepperProps, StepperSize, StepItem, StepStatus } from './components/forms/stepper';\n\nexport { MultiSelectCard } from './components/forms/multiselect-card';\nexport type {\n MultiSelectCardProps,\n MultiSelectCardSize,\n} from './components/forms/multiselect-card';\n\n/**\n * On/off setting. Was named `Toggle` through 0.3.0 — see the CHANGELOG rename table. The\n * name `Toggle` now belongs to the pressed-state button, as it does in shadcn/ui.\n */\nexport { Switch } from './components/forms/switch';\nexport type { SwitchProps, SwitchSize } from './components/forms/switch';\n\n/** Pressed-state button, and a group of them. New in 0.4.0. */\nexport { Toggle, ToggleGroup, ToggleGroupItem } from './components/forms/toggle';\nexport type {\n ToggleProps,\n ToggleSize,\n ToggleVariant,\n ToggleGroupProps,\n ToggleGroupItemProps,\n ToggleGroupType,\n} from './components/forms/toggle';\n\nexport { InputOTP } from './components/forms/input-otp';\nexport type { InputOTPProps, InputOTPMode } from './components/forms/input-otp';\n\nexport { FileDropZone, useFilePicker, formatFileSize } from './components/forms/file-drop-zone';\nexport type { FileDropZoneProps, UseFilePicker, UseFilePickerOptions } from './components/forms/file-drop-zone';\n\n/** Multi-value text field: typed or pasted values become removable chips. New in 0.7.0. */\nexport { TagInput } from './components/forms/tag-input';\nexport type { TagInputProps, TagInputParseResult } from './components/forms/tag-input';\n\nexport { FormCard, FormCardHeader, FormCardFooter } from './components/forms/form-card';\nexport type { FormCardHeaderProps, FormCardFooterProps } from './components/forms/form-card';\n\nexport { Badge } from './components/status/badge';\nexport type { BadgeProps, BadgeColor, BadgeSize, BadgeVariant } from './components/status/badge';\n\nexport { RoleBadge } from './components/status/role-badge';\nexport type { RoleBadgeProps, RoleBadgeTone } from './components/status/role-badge';\n\nexport { RoleComboBox, ROLE_COMBO_OPTIONS } from './components/forms/role-combo-box';\nexport type { RoleComboBoxProps, RoleOption } from './components/forms/role-combo-box';\n\n/** Single-select autocomplete. ARIA 1.2 combobox pattern. */\nexport { Combobox } from './components/forms/combobox';\nexport type { ComboboxProps, ComboboxOption } from './components/forms/combobox';\n\n/** Searchable country picker over Combobox. Value is an ISO 3166-1 alpha-2 code. */\nexport { CountrySelect, COUNTRY_CODES, countryOptions } from './components/forms/country-select';\nexport type { CountrySelectProps } from './components/forms/country-select';\n\n/** Searchable IANA time-zone picker over Combobox, labelled with the current UTC offset. */\nexport { TimeZoneSelect, timeZoneOptions, timeZoneOffset, currentZoneName } from './components/forms/time-zone-select';\nexport type { TimeZoneSelectProps } from './components/forms/time-zone-select';\n\n/** ⌘K command palette body. Compose with `Modal` for the usual overlay. */\nexport { Command } from './components/forms/command';\nexport type { CommandProps, CommandItem } from './components/forms/command';\n\n// ── Status & tags ──────────────────────────────────────────────────────────────\n\nexport { StatusBadge } from './components/status/status-badge';\nexport type { StatusBadgeProps, StatusTone, StatusBadgeSize } from './components/status/status-badge';\n\nexport { StatusDot } from './components/status/status-dot';\nexport type { StatusDotProps, StatusDotTone } from './components/status/status-dot';\n\nexport { StatusChip } from './components/status/status-chip';\nexport type { StatusChipProps } from './components/status/status-chip';\n\nexport { CountBadge } from './components/status/count-badge';\nexport type { CountBadgeProps } from './components/status/count-badge';\n\nexport { TagPill } from './components/status/tag-pill';\nexport type { TagPillProps, TagPillTone } from './components/status/tag-pill';\n\nexport { TrailChip } from './components/status/trail-chip';\nexport type { TrailChipProps } from './components/status/trail-chip';\n\nexport { UserStatusPill } from './components/status/user-status-pill';\nexport type { UserStatusPillProps, UserAccountStatus } from './components/status/user-status-pill';\n\nexport { CheckIndicator } from './components/status/check-indicator';\nexport type { CheckIndicatorProps, CheckIndicatorStatus } from './components/status/check-indicator';\n\nexport { EntityIconBadge } from './components/status/entity-icon-badge';\nexport type { EntityIconBadgeProps, EntityIconBadgeSize, EntityIconBadgeTone } from './components/status/entity-icon-badge';\n\n// ── Selection ──────────────────────────────────────────────────────────────────\n\nexport { Checkbox } from './components/forms/checkbox';\nexport type { CheckboxProps, CheckboxSize } from './components/forms/checkbox';\n\nexport { RadioGroup, Radio } from './components/forms/radio-group';\n\n/** Choose one option shown as a card. The single-select sibling of MultiSelectCard. New in 0.7.0. */\nexport { RadioCards, RadioCardsItem } from './components/forms/radio-cards';\nexport type { RadioCardsProps, RadioCardsItemProps, RadioCardsSize } from './components/forms/radio-cards';\n\n/** A fieldset of checkboxes sharing one value array. New in 0.7.0. */\nexport { CheckboxGroup, CheckboxGroupItem } from './components/forms/checkbox-group';\nexport type { CheckboxGroupProps, CheckboxGroupItemProps } from './components/forms/checkbox-group';\nexport type {\n RadioGroupProps,\n RadioProps,\n RadioGroupOrientation,\n} from './components/forms/radio-group';\n\nexport { SegmentedControl } from './components/forms/segmented-control';\nexport type { SegmentedControlProps, SegmentedControlOption } from './components/forms/segmented-control';\n\nexport { Slider } from './components/forms/slider';\nexport type { SliderProps } from './components/forms/slider';\n\nexport { Label } from './components/forms/label';\nexport type { LabelProps } from './components/forms/label';\n\nexport { Calendar } from './components/forms/calendar';\nexport type { CalendarProps, CalendarMode, DateRange } from './components/forms/calendar';\n\nexport {\n InputGroup,\n InputGroupInput,\n InputGroupAddon,\n InputGroupText,\n SearchInput,\n} from './components/forms/input-group';\nexport type {\n InputGroupProps,\n InputGroupInputProps,\n InputGroupAddonProps,\n InputGroupTextProps,\n InputGroupAlign,\n SearchInputProps,\n} from './components/forms/input-group';\n\n// ── Overlays ───────────────────────────────────────────────────────────────────\n\nexport {\n Modal,\n ModalTrigger,\n ModalClose,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalBody,\n ModalFooter,\n} from './components/overlays/modal';\nexport type {\n ModalProps,\n ModalSize,\n ModalTone,\n ModalFooterAlign,\n ModalHeaderProps,\n ModalTitleProps,\n ModalDescriptionProps,\n ModalBodyProps,\n ModalFooterProps,\n ModalTriggerProps,\n ModalCloseProps,\n} from './components/overlays/modal';\n\nexport { Tooltip } from './components/overlays/tooltip';\nexport type { TooltipProps } from './components/overlays/tooltip';\n\n/** Anchored panel for **interactive** content — unlike `Tooltip`, which cannot be entered. */\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverClose,\n PopoverAnchor,\n} from './components/overlays/popover';\nexport type {\n PopoverProps,\n PopoverTriggerProps,\n PopoverContentProps,\n} from './components/overlays/popover';\n\n/** Hover preview that can be entered. Supplementary by contract — hover has no touch equivalent. */\nexport { HoverCard } from './components/overlays/hover-card';\nexport type { HoverCardProps } from './components/overlays/hover-card';\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuGroup,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubTrigger,\n ContextMenuSubContent,\n} from './components/overlays/context-menu';\nexport type {\n ContextMenuProps,\n ContextMenuTriggerProps,\n ContextMenuContentProps,\n} from './components/overlays/context-menu';\n\nexport {\n Menubar,\n MenubarMenu,\n MenubarTrigger,\n MenubarContent,\n MenubarItem,\n MenubarCheckboxItem,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarGroup,\n MenubarLabel,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubTrigger,\n MenubarSubContent,\n} from './components/overlays/menubar';\nexport type {\n MenubarProps,\n MenubarMenuProps,\n MenubarTriggerProps,\n MenubarContentProps,\n} from './components/overlays/menubar';\n\nexport {\n Drawer,\n DrawerTrigger,\n DrawerClose,\n DrawerHeader,\n DrawerTitle,\n DrawerDescription,\n DrawerBody,\n DrawerFooter,\n} from './components/overlays/drawer';\nexport type {\n DrawerProps,\n DrawerSide,\n DrawerFooterAlign,\n DrawerTriggerProps,\n DrawerCloseProps,\n DrawerHeaderProps,\n DrawerTitleProps,\n DrawerDescriptionProps,\n DrawerBodyProps,\n DrawerFooterProps,\n} from './components/overlays/drawer';\n\nexport { ConfirmDialog } from './components/overlays/confirm-dialog';\nexport type { ConfirmDialogProps } from './components/overlays/confirm-dialog';\n\nexport { NoteConfirmModal } from './components/overlays/note-confirm-modal';\nexport type { NoteConfirmModalProps } from './components/overlays/note-confirm-modal';\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n} from './components/overlays/dropdown-menu';\nexport type {\n DropdownMenuProps,\n DropdownMenuTriggerProps,\n DropdownMenuContentProps,\n DropdownMenuItemProps,\n DropdownMenuItemTone,\n DropdownMenuCheckboxItemProps,\n DropdownMenuRadioGroupProps,\n DropdownMenuRadioItemProps,\n DropdownMenuGroupProps,\n DropdownMenuLabelProps,\n DropdownMenuSeparatorProps,\n DropdownMenuShortcutProps,\n DropdownMenuSubProps,\n DropdownMenuSubTriggerProps,\n DropdownMenuSubContentProps,\n} from './components/overlays/dropdown-menu';\n\n/** The dimming layer behind a custom overlay. New in 0.7.0. */\nexport { Scrim } from './components/overlays/scrim';\nexport type { ScrimProps } from './components/overlays/scrim';\n\n/** A modal surface that fills the viewport: full screen, expand a widget. New in 0.7.0. */\nexport { FullscreenSurface } from './components/overlays/fullscreen-surface';\nexport type { FullscreenSurfaceProps, FullscreenStacking } from './components/overlays/fullscreen-surface';\n\nexport { Portal, PortalContainerProvider, usePortalContainer } from './components/overlays/portal';\nexport type { PortalProps } from './components/overlays/portal';\n\n// ── Utilities ──────────────────────────────────────────────────────────────────\n\n/** Esc-to-close, Tab focus trap and focus restore — for building your own overlays. */\nexport { OVERLAY_SCRIM, useOverlayDismiss } from './components/overlays/overlay';\n\n/** `clsx` + `tailwind-merge` — for compositions where your className must win. */\nexport { cn } from './lib/cn';\n\n/**\n * What makes `asChild` work: renders its props onto its single child. Exported from 0.7.0\n * so a composition of your own can offer the same `asChild` contract.\n */\nexport { Slot, composeRefs } from './lib/slot';\nexport type { SlotProps } from './lib/slot';\n\n/** The library's keyboard focus ring, for controls you build yourself. New in 0.7.0. */\nexport { FOCUS_RING, FOCUS_RING_INSET } from './lib/focus-ring';\n\n/** Screen-reader-only content. New in 0.7.0. */\nexport { VisuallyHidden } from './components/chrome/visually-hidden';\nexport type { VisuallyHiddenProps } from './components/chrome/visually-hidden';\n\n/** An icon that means something on its own, named for assistive technology. New in 0.7.0. */\nexport { AccessibleIcon } from './components/chrome/accessible-icon';\nexport type { AccessibleIconProps } from './components/chrome/accessible-icon';\n\n// ── Cards & containers ─────────────────────────────────────────────────────────\n\nexport {\n Card,\n CardHeader,\n CardTitle,\n CardDescription,\n CardAction,\n CardBody,\n CardFooter,\n} from './components/cards/card';\nexport type {\n CardProps,\n CardSize,\n CardRadius,\n CardTone,\n CardFooterAlign,\n CardHeaderProps,\n CardTitleProps,\n CardDescriptionProps,\n CardActionProps,\n CardBodyProps,\n CardFooterProps,\n} from './components/cards/card';\n\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from './components/cards/accordion';\nexport type {\n AccordionProps,\n AccordionItemProps,\n AccordionTriggerProps,\n AccordionContentProps,\n AccordionType,\n} from './components/cards/accordion';\n\nexport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n} from './components/cards/collapsible';\nexport type {\n CollapsibleProps,\n CollapsibleTriggerProps,\n CollapsibleContentProps,\n} from './components/cards/collapsible';\n\n// Layout primitives, new in 0.7.0. Token-backed spacing props; layout only, no visual styling.\nexport { Box, Flex, Grid, Container, Section } from './components/cards/layout';\nexport type {\n BoxProps,\n FlexProps,\n FlexDirection,\n FlexAlign,\n FlexJustify,\n GridProps,\n GridColumnCount,\n GridBreakpoint,\n ContainerProps,\n ContainerSize,\n SectionProps,\n SectionSize,\n SpaceToken,\n} from './components/cards/layout';\n\nexport { AspectRatio } from './components/cards/aspect-ratio';\nexport type { AspectRatioProps } from './components/cards/aspect-ratio';\n\nexport { ScrollArea } from './components/cards/scroll-area';\nexport type { ScrollAreaProps, ScrollAreaAxis } from './components/cards/scroll-area';\n\n// The scrollbar styling on its own, for a component that must own its own overflow — a\n// table wrapper, a tab strip, a floating panel. Use `ScrollArea` for a region of content.\nexport { SCROLLBAR_CLASSES } from './lib/scrollbar';\n\nexport {\n Carousel,\n CarouselViewport,\n CarouselSlide,\n CarouselControls,\n} from './components/cards/carousel';\nexport type {\n CarouselProps,\n CarouselViewportProps,\n CarouselSlideProps,\n CarouselControlsProps,\n} from './components/cards/carousel';\n\nexport { Resizable, ResizablePanel, ResizableHandle } from './components/cards/resizable';\nexport type {\n ResizableProps,\n ResizablePanelProps,\n ResizableHandleProps,\n ResizableDirection,\n} from './components/cards/resizable';\n\n// ── Page chrome ────────────────────────────────────────────────────────────────\n\nexport { PageHeading } from './components/chrome/page-heading';\nexport type { PageHeadingProps, PageHeadingSize } from './components/chrome/page-heading';\n\nexport { PageToolbar } from './components/chrome/page-toolbar';\nexport type { PageToolbarProps, PageToolbarSize } from './components/chrome/page-toolbar';\n\nexport { FilterBar } from './components/chrome/filter-bar';\nexport type { FilterBarProps, FilterBarSize } from './components/chrome/filter-bar';\n\nexport {\n Tabs,\n TabsPanel,\n TabsList,\n TabsTrigger,\n TabsContent,\n tabId,\n tabPanelId,\n} from './components/chrome/tabs';\nexport type {\n TabsProps,\n TabsRootProps,\n TabsPanelProps,\n TabsListProps,\n TabsTriggerProps,\n TabsContentProps,\n TabItem,\n TabsVariant,\n TabsSize,\n TabsOrientation,\n TabsActivation,\n} from './components/chrome/tabs';\n\nexport { NavItem } from './components/chrome/nav-item';\nexport type {\n NavItemProps,\n NavItemSize,\n NavItemVariant,\n} from './components/chrome/nav-item';\n\nexport { EyebrowLabel } from './components/chrome/eyebrow-label';\nexport type { EyebrowLabelProps, EyebrowLabelVariant } from './components/chrome/eyebrow-label';\n\nexport { Separator } from './components/chrome/separator';\nexport type { SeparatorProps, SeparatorOrientation } from './components/chrome/separator';\n\nexport { Kbd } from './components/chrome/kbd';\nexport type { KbdProps, KbdSize } from './components/chrome/kbd';\n\nexport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbEllipsis,\n} from './components/chrome/breadcrumb';\nexport type {\n BreadcrumbProps,\n BreadcrumbItemProps,\n BreadcrumbEllipsisProps,\n} from './components/chrome/breadcrumb';\n\nexport { Pagination, PaginationBar, paginationRange } from './components/chrome/pagination';\nexport type { PaginationProps, PaginationBarProps, PaginationType } from './components/chrome/pagination';\n\nexport { NavigationMenu, NavigationMenuItem } from './components/chrome/navigation-menu';\nexport type {\n NavigationMenuProps,\n NavigationMenuItemProps,\n NavigationMenuOrientation,\n NavigationMenuVariant,\n} from './components/chrome/navigation-menu';\n\n// ── Typography ─────────────────────────────────────────────────────────────────\n// The type ramp as components, mirroring Figma's `Text*` primitives. Every one takes\n// `asChild`, because the right element depends on the surrounding document outline.\n\nexport {\n Text,\n TextSmall,\n TextTiny,\n TextStrong,\n TextEmphasis,\n TextCode,\n TextLink,\n TextList,\n TextListItem,\n Blockquote,\n Quote,\n TitleHero,\n TitlePage,\n Subtitle,\n Heading,\n Subheading,\n} from './components/chrome/typography';\nexport type {\n TextProps,\n TextTone,\n BlockquoteProps,\n TextLinkProps,\n TextListProps,\n TextListItemProps,\n TextListVariant,\n TextListDensity,\n} from './components/chrome/typography';\n\n// ── Widgets ────────────────────────────────────────────────────────────────────\n\nexport { WidgetHeader } from './components/widgets/widget-header';\nexport type { WidgetHeaderProps, WidgetHeaderEyebrowVariant } from './components/widgets/widget-header';\n\nexport { WidgetTitle } from './components/widgets/widget-title';\nexport type { WidgetTitleProps, WidgetTitleSize } from './components/widgets/widget-title';\n\nexport { WidgetFooter } from './components/widgets/widget-footer';\nexport type { WidgetFooterProps } from './components/widgets/widget-footer';\n\n/** The dashboard grid vocabulary and container-width tiers. New in 0.7.0, from SCIC. */\nexport {\n WidgetGrid,\n WidgetGridRow,\n WidgetGridItem,\n COL_SPAN,\n HEIGHT_CLASS,\n HEIGHT_PX,\n} from './components/widgets/widget-grid';\nexport type {\n WidgetGridProps,\n WidgetGridRowProps,\n WidgetGridItemProps,\n ColSize,\n WidgetHeight,\n} from './components/widgets/widget-grid';\nexport {\n GRID_TIERS,\n TIER_MIN_PX,\n TIER_COLS,\n COL_SPAN_BY_TIER,\n tierForWidth,\n nextTier,\n quantizeWidth,\n colsFor,\n slotWidthPx,\n} from './lib/width-tier';\nexport type { GridTier } from './lib/width-tier';\nexport { useWidthTier } from './lib/use-width-tier';\nexport type { UseWidthTierOptions, UseWidthTierResult } from './lib/use-width-tier';\n\n// ── Stats ──────────────────────────────────────────────────────────────────────\n\nexport { StatTile } from './components/stats/stat-tile';\nexport type { StatTileProps } from './components/stats/stat-tile';\n\nexport { StatNumber } from './components/stats/stat-number';\nexport type { StatNumberProps, StatNumberSize, StatNumberWeight } from './components/stats/stat-number';\n\nexport { ScoreValue, getScoreTone, DEFAULT_SCORE_THRESHOLDS } from './components/stats/score-value';\nexport type {\n ScoreValueProps,\n ScoreValueSize,\n ScoreValueWeight,\n ScoreValueTone,\n ScoreTone,\n ScoreRampTone,\n ScoreDirection,\n ScoreThresholds,\n} from './components/stats/score-value';\n\nexport { TileGrid } from './components/stats/tile-grid';\nexport type { TileGridProps, TileGridColumns, TileGridBreakpoint } from './components/stats/tile-grid';\n\n// ── Data visualisation ─────────────────────────────────────────────────────────\n\nexport { CHART_TONE, CHART_SEQUENCE, CHART_TRACK, resolveChartColor } from './components/charts/chart-tone';\nexport type { ChartTone } from './components/charts/chart-tone';\n\nexport { BarChart } from './components/charts/bar-chart';\nexport type {\n BarChartProps,\n BarChartSeries,\n BarChartOrientation,\n BarChartSize,\n} from './components/charts/bar-chart';\n\nexport { DonutChart } from './components/charts/donut-chart';\nexport type { DonutChartProps, DonutSegment, DonutChartSize } from './components/charts/donut-chart';\n\nexport { RadialGauge } from './components/charts/radial-gauge';\nexport type { RadialGaugeProps, RadialGaugeSize } from './components/charts/radial-gauge';\n\nexport { Sparkline } from './components/charts/sparkline';\nexport type { SparklineProps, SparklineVariant, SparklineSize } from './components/charts/sparkline';\n\nexport { MiniBarChart } from './components/charts/mini-bar-chart';\nexport type {\n MiniBarChartProps,\n MiniBarChartSize,\n MiniBarChartOrientation,\n} from './components/charts/mini-bar-chart';\n\nexport { ChartLegend } from './components/charts/chart-legend';\nexport type {\n ChartLegendProps,\n ChartLegendItem,\n ChartLegendOrientation,\n} from './components/charts/chart-legend';\n\nexport { LegendDot } from './components/charts/legend-dot';\nexport type { LegendDotProps, LegendDotSize, LegendDotShape } from './components/charts/legend-dot';\n\nexport { TrendLabel } from './components/charts/trend-label';\nexport type {\n TrendLabelProps,\n TrendLabelWeight,\n TrendLabelSize,\n TrendDirection,\n} from './components/charts/trend-label';\n\n// ── Lists & rows ───────────────────────────────────────────────────────────────\n\nexport { ListRow } from './components/lists/list-row';\nexport type { ListRowProps, ListRowDensity, ListRowDivider } from './components/lists/list-row';\n\nexport { FileRow } from './components/lists/file-row';\nexport type { FileRowProps } from './components/lists/file-row';\n\nexport { ScoredRow } from './components/lists/scored-row';\nexport type { ScoredRowProps, ScoredRowAlign, ScoredRowGap } from './components/lists/scored-row';\n\nexport { NumberedList } from './components/lists/numbered-list';\nexport type {\n NumberedListProps,\n NumberedListItem,\n NumberedListGap,\n} from './components/lists/numbered-list';\n\nexport { IconTextRow } from './components/lists/icon-text-row';\nexport type { IconTextRowProps } from './components/lists/icon-text-row';\n\nexport { ChecklistRow } from './components/lists/checklist-row';\nexport type { ChecklistRowProps, ChecklistRowState } from './components/lists/checklist-row';\n\nexport { StepsList } from './components/lists/steps-list';\nexport type { StepsListProps } from './components/lists/steps-list';\n\nexport { DetailItem, DetailGrid } from './components/lists/detail-item';\nexport type {\n DetailItemProps,\n DetailItemLayout,\n DetailItemSpan,\n DetailGridProps,\n DetailGridColumns,\n} from './components/lists/detail-item';\n\n/** Label/value rows as a real <dl>, with optional copy. New in 0.7.0, from SCIC. */\nexport { DescriptionList, DescriptionItem, CopyButton, EmailText } from './components/lists/description-list';\nexport type { DescriptionListProps, DescriptionItemProps, CopyButtonProps } from './components/lists/description-list';\n\nexport { CheckedGroupList } from './components/lists/checked-group-list';\nexport type {\n CheckedGroupListProps,\n CheckedGroupListColumns,\n CheckedGroup,\n} from './components/lists/checked-group-list';\n\n/** Expandable tree — ARIA tree pattern, one tab stop, rows as a render slot. */\nexport { TreeView } from './components/lists/tree-view';\nexport type { TreeViewProps, TreeItemState, TreeViewSize } from './components/lists/tree-view';\n\n// ── Table ──────────────────────────────────────────────────────────────────────\n// The composable primitive, for the tables `DataTable`'s column config cannot express —\n// grouped headers, footers, colspans. `DataTable` remains the right default.\n\nexport {\n Table,\n TableCaption,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n} from './components/lists/table';\nexport type {\n TableProps,\n TableCaptionProps,\n TableRowProps,\n TableHeadProps,\n TableCellProps,\n TableDensity,\n TableSortDirection,\n TableRowTone,\n} from './components/lists/table';\n\n// ── Data table ─────────────────────────────────────────────────────────────────\n// Lives in components/lists/ but is documented on its own page.\n\n// Rebuilt on TanStack Table in 0.7.0. The parts are exported for tables that lay out their\n// own toolbar or pager; `DataTable` renders all of them by default.\n\nexport {\n DataTable,\n DataTableColumnHeader,\n DataTablePagination,\n DataTableViewOptions,\n createSelectColumn,\n SELECT_COLUMN_ID,\n TableCellLeadText,\n TableCellText,\n TableCellBadge,\n TableCellProgress,\n} from './components/lists/data-table';\nexport type {\n DataTableProps,\n DataTableState,\n DataTableManual,\n DataTableSearchOptions,\n DataTableRowLinkProps,\n DataTableDensity,\n DataTableAlign,\n DataTableColumnAlign,\n DataTableColumnHeaderProps,\n DataTablePaginationProps,\n DataTableViewOptionsProps,\n CreateSelectColumnOptions,\n ColumnMobileRole,\n TableCellSize,\n TableCellLeadTextProps,\n TableCellTextProps,\n TableCellBadgeProps,\n TableCellProgressProps,\n} from './components/lists/data-table';\n\n// TanStack Table's column and state types, re-exported so a consumer types `columns` without a\n// direct dependency on `@tanstack/react-table`. `createColumnHelper` builds typed columns.\nexport { createColumnHelper } from '@tanstack/react-table';\nexport type {\n ColumnDef,\n ColumnFiltersState,\n PaginationState,\n Row,\n RowSelectionState,\n SortingState,\n VisibilityState,\n Column as DataTableColumn,\n Table as DataTableInstance,\n CellContext,\n HeaderContext,\n} from '@tanstack/react-table';\n\n/** Measures an element's width, for layouts that switch structure by available space. New in 0.7.0. */\nexport { useElementWidth } from './lib/use-element-width';\n\n// ── Feedback ───────────────────────────────────────────────────────────────────\n\nexport { InlineAlert } from './components/feedback/inline-alert';\nexport type { InlineAlertProps, InlineAlertTone } from './components/feedback/inline-alert';\n\nexport { EmptyState } from './components/feedback/empty-state';\nexport type { EmptyStateProps, EmptyStateVariant, EmptyStateSize } from './components/feedback/empty-state';\n\nexport { ProgressBar } from './components/feedback/progress-bar';\nexport type { ProgressBarProps, ProgressBarTone, ProgressBarSize } from './components/feedback/progress-bar';\n\nexport { Spinner } from './components/feedback/spinner';\nexport type { SpinnerProps, SpinnerSize } from './components/feedback/spinner';\n\n/** Contains a render error to its own subtree. New in 0.7.0. */\nexport { ErrorBoundary } from './components/feedback/error-boundary';\nexport type { ErrorBoundaryProps } from './components/feedback/error-boundary';\n\nexport { Skeleton } from './components/feedback/skeleton';\nexport type { SkeletonProps, SkeletonShape } from './components/feedback/skeleton';\n\n/** Persistent, in-flow notice with a title and an action — Figma's `Notification`. */\nexport { Banner } from './components/feedback/banner';\nexport type { BannerProps, BannerVariant } from './components/feedback/banner';\n\n/** Transient notifications. Mount `Toaster` once at the app root, then call `useToast()`. */\nexport { Toaster, useToast } from './components/feedback/toast';\nexport type {\n ToasterProps,\n ToasterPosition,\n ToastOptions,\n ToastRecord,\n ToastTone,\n} from './components/feedback/toast';\n\n// ── Forms ──────────────────────────────────────────────────────────────────────\n\nexport { PasswordInput } from './components/forms/password-input';\nexport type { PasswordInputProps } from './components/forms/password-input';\n\n// ── AI surfaces & decorative ───────────────────────────────────────────────────\n\nexport { AIChatBar } from './components/ai/ai-chat-bar';\nexport type { AIChatBarProps } from './components/ai/ai-chat-bar';\n\nexport { AISuggestionChip } from './components/ai/ai-suggestion-chip';\nexport type { AISuggestionChipProps } from './components/ai/ai-suggestion-chip';\n\nexport { QuickActionsBar } from './components/ai/quick-actions-bar';\nexport type { QuickActionsBarProps, QuickAction } from './components/ai/quick-actions-bar';\n\n/** Chat transcript pieces. New in 0.7.0, from SCIC. */\nexport { ChatBubble, TypingIndicator, AiAvatar } from './components/ai/chat';\nexport type { ChatBubbleProps, ChatBubbleSender, TypingIndicatorProps, AiAvatarProps } from './components/ai/chat';\n\nexport { AuroraBackdrop } from './components/decorative/aurora-backdrop';\n\n// Icons are not re-exported. Import them straight from `lucide-react` — the nine filled\n// 20×20 `Solid*` marks that used to live here were used by no component in this library,\n// only by its own documentation, and they were the one place the library shipped a second\n// icon set. Charts remain the sole exception to Lucide, because their SVG is geometry.\n","import { forwardRef, type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { Slot } from '../../lib/slot';\nimport { Spinner } from '../feedback/spinner';\nimport { useControlSize } from './control-size';\n\nexport type ButtonVariant = 'primary' | 'neutral' | 'subtle' | 'danger' | 'danger-subtle';\nexport type ButtonSize = 'lg' | 'md' | 'sm';\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n /**\n * Render the single child element instead of a `<button>` — e.g. a router `Link`, so a\n * navigation action can look like a button without nesting an anchor inside one.\n */\n asChild?: boolean;\n /**\n * Swaps the leading icon for a spinner and stops the button acting on a press.\n * `aria-busy` is set so assistive tech reports the pending state.\n *\n * From 0.7.0 this uses `aria-disabled`, not the native `disabled` attribute. A natively\n * disabled button loses focus, so pressing \"Save\" dropped keyboard focus to <body> the\n * moment the request started. Now focus stays on the button and moves on normally when it\n * finishes.\n */\n loading?: boolean;\n /** Announced while `loading`. Defaults to the button's own content. */\n loadingLabel?: string;\n}\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary: clsx(\n 'bg-brand border border-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n neutral: clsx(\n 'bg-default border border-default text-default',\n 'hover:bg-default-hover hover:text-brand',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n subtle: clsx(\n // border-transparent holds space so hover border doesn't shift layout\n 'bg-transparent border border-transparent text-neutral',\n 'hover:border-default hover:text-brand',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n danger: clsx(\n 'bg-danger border border-danger-secondary text-danger-on-danger',\n // border shifts from danger-secondary → danger-default on hover (Figma spec)\n 'hover:bg-danger-hover hover:border-danger',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n 'danger-subtle': clsx(\n // border-transparent base avoids layout shift when hover border appears\n 'bg-transparent border border-transparent text-danger',\n 'hover:bg-danger-tertiary-hover hover:border-danger',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n};\n\n// Horizontal padding is on the label span, not a nested div — through 0.3.0 the children\n// were wrapped in `<div className=\"px-1\">` *inside* the `<button>`, which is a block\n// element inside a phrasing-content context and knocked the flex baseline about.\nconst sizeStyles: Record<ButtonSize, string> = {\n lg: 'h-12 px-3 gap-1 rounded-2xl text-body font-semibold [&_svg]:size-5',\n md: 'h-9 px-2 gap-0.5 rounded-lg text-body-sm font-semibold [&_svg]:size-5',\n sm: 'h-6 px-1.5 pt-0.5 gap-0 rounded-full text-body-tiny font-semibold [&_svg]:size-4',\n};\n\nconst SPINNER_SIZE: Record<ButtonSize, 'sm' | 'md'> = {\n lg: 'md',\n md: 'sm',\n sm: 'sm',\n};\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = 'primary',\n size: sizeProp,\n leadingIcon,\n trailingIcon,\n asChild = false,\n loading = false,\n loadingLabel,\n disabled,\n type,\n children,\n className,\n onClick,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n // Inert to a press but still focusable: a loading button, or any disabled `asChild`\n // element (an `<a>` has no `disabled` attribute to fall back on).\n const softDisabled = loading || (asChild && Boolean(disabled));\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (softDisabled) {\n // Stops a router `<Link>` too: it skips navigation when the event is prevented.\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onClick?.(event);\n };\n\n const decorate = (content: ReactNode) => (\n <>\n {loading ? <Spinner size={SPINNER_SIZE[size]} label={loadingLabel} /> : leadingIcon}\n <span className=\"px-1\">{content}</span>\n {trailingIcon}\n </>\n );\n\n const rootProps = {\n // `cn`, so a caller's `className` (say `rounded-full`) beats the size's radius.\n className: cn(\n 'inline-flex items-center justify-center whitespace-nowrap transition-colors',\n FOCUS_RING,\n 'disabled:cursor-not-allowed aria-disabled:cursor-not-allowed',\n variantStyles[variant],\n sizeStyles[size],\n className,\n ),\n 'aria-busy': loading || undefined,\n 'data-variant': variant,\n 'data-size': size,\n 'aria-disabled': softDisabled || undefined,\n onClick: handleClick,\n ...props,\n };\n\n if (asChild) {\n // `aria-disabled`, not `disabled`: the child may be an `<a>`, which has no disabled\n // attribute, and removing the href would change what the element *is*. A disabled link\n // also leaves the tab order, as a disabled `<button>` does.\n return (\n <Slot\n ref={ref}\n wrapChildren={decorate}\n tabIndex={disabled ? -1 : undefined}\n {...rootProps}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n // Through 0.3.0 no default `type` was set, so `<Button onClick={…}>` inside a\n // `<form>` submitted it. Every other button in the library set `type=\"button\"`\n // explicitly; this one did not.\n type={type ?? 'button'}\n disabled={disabled}\n {...rootProps}\n >\n {decorate(children)}\n </button>\n );\n});\n","import { type ClassValue, clsx } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * Every `fontSize` key in `tailwind-preset.cjs`, in the same order.\n *\n * `tailwind-merge` decides whether a `text-*` class is a **font size** or a **text colour**\n * by pattern: it recognises t-shirt sizes (`text-sm`, `text-2xl`) and bare lengths, and files\n * everything else under colour. Every size in this design system is a word — `text-body-sm`,\n * `text-heading`, `text-scale-07` — so without this list twMerge calls them colours, and then\n * drops them when a real colour follows in the same string:\n *\n * cn('text-body-micro text-neutral-tertiary') // → 'text-neutral-tertiary'\n *\n * The size vanishes and the element inherits its parent's. That is not hypothetical: it is\n * why the sidebar's group headings rendered at the 16px body default for two releases while\n * the source said `text-body-tiny`, and why chasing the number in the source never moved it.\n *\n * Keep in sync with the preset — `cn.test.ts` fails if they drift.\n */\nconst FONT_SIZES = [\n 'body-micro',\n 'body-tiny',\n 'body-xs',\n 'body-sm',\n 'body',\n 'body-lg',\n 'heading-sm',\n 'heading',\n 'heading-lg',\n 'subheading-sm',\n 'subheading',\n 'subheading-lg',\n 'subtitle-sm',\n 'subtitle',\n 'subtitle-lg',\n 'title-sm',\n 'title',\n 'title-lg',\n 'title-hero',\n 'scale-01',\n 'scale-02',\n 'scale-03',\n 'scale-04',\n 'scale-05',\n 'scale-06',\n 'scale-07',\n 'scale-08',\n 'scale-09',\n 'scale-10',\n 'scale-12',\n] as const;\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: [...FONT_SIZES] }],\n },\n },\n});\n\n/**\n * `clsx` + `tailwind-merge`, taught this system's type scale.\n *\n * Use this instead of bare `clsx` in any component whose `className` prop is meant to\n * *override* a base utility — the composable `Card*` and `Modal*` parts, and anything\n * else built to be reshaped by its caller.\n *\n * Why it is necessary: `clsx` only concatenates. When two conflicting Tailwind\n * utilities both end up in the attribute, the winner is decided by *stylesheet order*,\n * not attribute order. Tailwind emits `flex-row` before `flex-col` and `gap-3` before\n * `gap-4`, so under plain `clsx`:\n *\n * <CardBody className=\"flex-row gap-3\" /> // base is 'flex flex-col gap-4 p-4'\n *\n * silently stays a column with a 4-unit gap. `twMerge` drops the losing class instead,\n * so the caller's intent wins.\n *\n * Everywhere else in the library `className` is purely additive, and plain `clsx`\n * remains correct — and cheaper. Do not sweep it out of those files.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * The keyboard focus ring, as one string, so every control draws the same one.\n *\n * Before 0.7.0 this exact class list was written out by hand in 18 places, with six\n * near-misses beside it (a missing offset colour, `ring-offset-2`). Use it in new and migrated\n * components rather than re-typing it.\n *\n * `FOCUS_RING` sits outside the element and needs room around it. Inside a scrolling or\n * `overflow-hidden` panel, such as a menu, a listbox or a table cell, the offset ring is clipped,\n * so items there use `FOCUS_RING_INSET`, which draws inside the element's own box.\n *\n * Highlight is not focus: menu and option items also tint their background when highlighted\n * (by pointer or by keyboard), but the tint alone does not meet WCAG 2.4.7 next to a hovered\n * sibling with the same tint. The ring is what marks the keyboard position.\n */\nexport const FOCUS_RING =\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default';\n\nexport const FOCUS_RING_INSET =\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-brand';\n","import {\n cloneElement,\n forwardRef,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport clsx from 'clsx';\n\n/**\n * `Slot` renders its own props onto its single child element instead of emitting a\n * wrapper of its own. It is what makes `asChild` work.\n *\n * Why the library needs it: before 0.4.0 there was no way to render a `Button` as a\n * router `<Link>`, or to use any component as a tooltip/popover anchor, because every\n * component hardcoded its host element. The usual workaround — a `component`/`as` prop —\n * multiplies generics across the whole surface and still cannot forward a ref through\n * two levels. Delegating to the child instead keeps the type surface flat.\n *\n * <Button asChild><Link to=\"/x\">Go</Link></Button>\n *\n * Merge rules, in order of who wins:\n * - `className` — concatenated, slot first, so the child's classes come last\n * - `style` — shallow-merged, child wins on conflicting keys\n * - `on*` — both run, slot's handler first; the child's runs even if the slot's\n * called `preventDefault`, matching normal DOM listener behaviour\n * - everything else — child wins, so a child's explicit `type` or `role` is never\n * clobbered by a default the slot happens to carry\n */\nexport interface SlotProps extends HTMLAttributes<HTMLElement> {\n /** The single element to merge into. */\n children?: ReactNode;\n /**\n * Rebuilds the child's children, so a component that decorates its content can keep\n * doing so through `asChild`.\n *\n * `Button` renders `leadingIcon`, a padded label span and `trailingIcon` around whatever\n * it is given. Without this, `<Button asChild><Link>Go</Link></Button>` would either drop\n * the icons (cloning the Link untouched) or drop \"Go\" (replacing the Link's children\n * outright). It receives the child's own children — \"Go\" — and returns the decorated\n * tree to place inside the child.\n */\n wrapChildren?: (childChildren: ReactNode) => ReactNode;\n}\n\nexport const Slot = forwardRef<HTMLElement, SlotProps>(function Slot(\n { children, wrapChildren, ...slotProps },\n forwardedRef,\n) {\n // A bare string, an array, or nothing at all — there is no element to merge into.\n // Rendering the children plain would silently drop every prop the slot carries\n // (including the ref and the ARIA wiring a trigger depends on), so this renders\n // nothing rather than something subtly broken.\n if (!isValidElement(children)) return null;\n\n const child = children as ReactElement<{ children?: ReactNode }>;\n\n const merged = {\n ...mergeProps(slotProps, child.props as Record<string, unknown>),\n ref: composeRefs(forwardedRef, getElementRef(child)),\n } as Record<string, unknown>;\n\n return wrapChildren\n ? cloneElement(child, merged, wrapChildren(child.props.children))\n : cloneElement(child, merged);\n});\n\nfunction mergeProps(\n slotProps: Record<string, unknown>,\n childProps: Record<string, unknown>,\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...slotProps };\n\n for (const key in childProps) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n if (/^on[A-Z]/.test(key)) {\n // Both handlers run. The slot's fires first so a component can set up state\n // before the consumer's own handler observes it.\n if (typeof slotValue === 'function' && typeof childValue === 'function') {\n merged[key] = (...args: unknown[]) => {\n (slotValue as (...a: unknown[]) => void)(...args);\n (childValue as (...a: unknown[]) => void)(...args);\n };\n } else {\n merged[key] = childValue ?? slotValue;\n }\n } else if (key === 'className') {\n merged[key] = clsx(slotValue as string, childValue as string);\n } else if (key === 'style') {\n merged[key] = { ...(slotValue as CSSProperties), ...(childValue as CSSProperties) };\n } else {\n merged[key] = childValue;\n }\n }\n\n return merged;\n}\n\n/**\n * React 19 exposes a `ref` on `props`; React 18 keeps it on the element. The peer range\n * is `>=18`, so both have to be read.\n */\nfunction getElementRef(element: ReactElement): Ref<unknown> | undefined {\n const asRecord = element as unknown as {\n ref?: Ref<unknown>;\n props?: { ref?: Ref<unknown> };\n };\n return asRecord.props?.ref ?? asRecord.ref;\n}\n\n/** Fan one node out to several refs, callback or object. */\nexport function composeRefs<T>(...refs: (Ref<T> | undefined)[]) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === 'function') {\n ref(node);\n } else {\n (ref as { current: T | null }).current = node;\n }\n }\n };\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\n\nexport type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {\n size?: SpinnerSize;\n /**\n * Accessible name. When omitted the spinner is marked decorative — correct when it sits\n * inside a control that already announces the pending state (`Button loading` sets\n * `aria-busy`), and wrong when the spinner is the only thing on screen.\n */\n label?: string;\n}\n\nconst SIZE: Record<SpinnerSize, string> = {\n xs: 'size-3 border',\n sm: 'size-4 border-[1.5px]',\n md: 'size-5 border-2',\n lg: 'size-8 border-2',\n};\n\n/**\n * Indeterminate loading indicator. `ProgressBar` is the determinate counterpart.\n *\n * The spin is a border-based ring rather than an SVG so it inherits `currentColor` and\n * needs no fill/stroke plumbing — it works on any button variant unchanged. The animation\n * is suppressed under `prefers-reduced-motion` by the preset's base rule, which leaves a\n * static ring; that is why the transparent segment is a full quarter and still legible\n * when frozen.\n */\nexport const Spinner = forwardRef<HTMLSpanElement, SpinnerProps>(function Spinner(\n { size = 'sm', label, className, ...rest },\n ref,\n) {\n return (\n <span\n ref={ref}\n role={label ? 'status' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={clsx(\n 'inline-block shrink-0 animate-spin rounded-full',\n 'border-current border-t-transparent',\n SIZE[size],\n className,\n )}\n {...rest}\n />\n );\n});\n","import { createContext, useContext, type ReactNode } from 'react';\nimport type { InputSize } from './input';\n\n/**\n * A default `size` for the form controls inside a container.\n *\n * `FilterBar size=\"sm\"` used to set only the gap between its children, so its own \"Sizes\"\n * example put a 24px Input beside a 36px Select and nothing in the API said the caller had\n * to size each control by hand. A container that has a size prop should mean it.\n *\n * Deliberately narrow: the context carries an `InputSize` and nothing else. It is not a\n * general \"component config\" channel — that is where implicit inheritance stops being\n * predictable. And an explicit `size` prop always wins, so the escape hatch is one prop on\n * the one control that needs to differ.\n *\n * `cloneElement` would have been the alternative and cannot work here: it never reaches a\n * control wrapped for layout (`<div className=\"w-56\"><Input /></div>`) or one nested inside\n * a consumer's own composite, and it would inject `size` into whatever element happens to\n * be the child — including a `<span>`, which React then warns about. Context is also how\n * the library already solves this shape, in `FieldContext`, `RadioGroupContext` and\n * `ToggleGroupContext`.\n */\nconst ControlSizeContext = createContext<InputSize | null>(null);\n\nexport interface ControlSizeProviderProps {\n size: InputSize;\n children: ReactNode;\n}\n\nexport function ControlSizeProvider({ size, children }: ControlSizeProviderProps) {\n return <ControlSizeContext.Provider value={size}>{children}</ControlSizeContext.Provider>;\n}\n\n/**\n * Resolve a control's size: an explicit prop, else the enclosing container's default,\n * else `md`.\n *\n * Call it unconditionally at the top of the component — it is a hook.\n */\nexport function useControlSize(explicit?: InputSize): InputSize {\n const inherited = useContext(ControlSizeContext);\n return explicit ?? inherited ?? 'md';\n}\n","import { forwardRef, type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { Slot } from '../../lib/slot';\nimport { type ButtonSize } from './button';\nimport { useControlSize } from './control-size';\n\nexport type IconButtonVariant = 'primary' | 'neutral' | 'subtle';\n\nexport interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: IconButtonVariant;\n size?: ButtonSize;\n /** Required for accessibility — no visible text label */\n 'aria-label': string;\n /** Render the single child element instead of a `<button>` — e.g. a router `Link`. */\n asChild?: boolean;\n children?: ReactNode;\n}\n\nconst variantStyles: Record<IconButtonVariant, string> = {\n primary: clsx(\n 'bg-brand border border-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n // Neutral uses secondary background (light gray) for visual weight without a text label\n neutral: clsx(\n 'bg-default-secondary border border-default text-default',\n // icon turns brand blue on hover (Figma spec)\n 'hover:bg-default-secondary-hover hover:text-brand',\n 'disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n subtle: clsx(\n 'bg-transparent text-neutral',\n // hover uses background-default-default-hover (#f5f5f5), icon turns brand blue (Figma spec)\n 'hover:bg-default-hover hover:text-brand',\n // disabled needs explicit border since there is no base border\n 'disabled:bg-disabled disabled:border disabled:border-disabled disabled:text-disabled-on-disabled',\n 'aria-disabled:bg-disabled aria-disabled:border aria-disabled:border-disabled aria-disabled:text-disabled-on-disabled',\n ),\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n lg: 'size-12 rounded-2xl [&_svg]:size-5',\n md: 'size-9 rounded-lg [&_svg]:size-5',\n sm: 'size-6 rounded-full [&_svg]:size-4',\n};\n\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n {\n variant = 'primary',\n size: sizeProp,\n asChild = false,\n type,\n disabled,\n onClick,\n children,\n className,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n // A disabled `asChild` element (say a router `<Link>`) has no `disabled` attribute, so it\n // has to refuse the press itself, as `Button` does.\n const softDisabled = asChild && Boolean(disabled);\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (softDisabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onClick?.(event);\n };\n\n const rootProps = {\n // `cn`, so a caller's `className` beats the size's radius and the variant's colours.\n className: cn(\n 'inline-flex shrink-0 items-center justify-center transition-colors',\n FOCUS_RING,\n 'disabled:cursor-not-allowed aria-disabled:cursor-not-allowed',\n variantStyles[variant],\n sizeStyles[size],\n className,\n ),\n 'data-variant': variant,\n 'data-size': size,\n 'aria-disabled': softDisabled || undefined,\n onClick: handleClick,\n ...props,\n };\n\n // No `wrapChildren` here: an icon button has no label span or icon slots to rebuild, so\n // the child's own content is already the whole thing.\n if (asChild) {\n return (\n <Slot ref={ref} tabIndex={disabled ? -1 : undefined} {...rootProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n // Without an explicit type, a button inside a <form> defaults to `submit` and an\n // icon button meant to reveal a password or open a menu submits the form instead.\n type={type ?? 'button'}\n disabled={disabled}\n {...rootProps}\n >\n {children}\n </button>\n );\n});\n","import { type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { type ButtonSize } from './button';\n\nexport type ButtonGroupVariant = 'primary' | 'neutral' | 'filter';\nexport type ButtonGroupAlign = 'justify' | 'start' | 'end' | 'center' | 'stack';\n\nexport interface ButtonGroupItem {\n value: string;\n label: ReactNode;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n disabled?: boolean;\n}\n\nexport interface ButtonGroupProps {\n items: ButtonGroupItem[];\n value: string;\n onChange: (value: string) => void;\n variant?: ButtonGroupVariant;\n size?: ButtonSize;\n align?: ButtonGroupAlign;\n /** Forwarded to the container as aria-label */\n 'aria-label'?: string;\n className?: string;\n}\n\nconst containerStyles: Record<ButtonGroupVariant, string> = {\n primary: 'bg-neutral-tertiary p-1 rounded-2xl',\n neutral: 'bg-neutral-tertiary p-1 rounded-2xl',\n filter: 'bg-default border border-default p-1 rounded-xl',\n};\n\nconst selectedStyles: Record<ButtonGroupVariant, string> = {\n primary: clsx(\n 'bg-brand border border-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n ),\n neutral: clsx(\n 'bg-default border border-default text-default',\n 'hover:bg-default-hover',\n ),\n filter: clsx(\n 'bg-brand text-brand-on-brand',\n 'hover:bg-brand-hover',\n ),\n};\n\nconst unselectedStyles: Record<ButtonGroupVariant, string> = {\n primary: clsx('bg-transparent text-neutral', 'hover:bg-neutral-tertiary-hover'),\n neutral: clsx('bg-transparent text-neutral', 'hover:bg-neutral-tertiary-hover'),\n filter: clsx('text-default-secondary', 'hover:text-default'),\n};\n\nconst itemSizeStyles: Record<ButtonSize, string> = {\n lg: 'h-12 px-3 gap-1 rounded-2xl text-body font-semibold [&_svg]:size-5',\n md: 'h-9 px-2 gap-0.5 rounded-lg text-body-sm font-semibold [&_svg]:size-5',\n sm: 'h-6 px-1.5 pt-0.5 gap-0 rounded-full text-body-tiny font-semibold [&_svg]:size-4',\n};\n\nconst containerAlignStyles: Record<ButtonGroupAlign, string> = {\n justify: 'flex flex-row items-center',\n start: 'flex flex-row items-center justify-start',\n end: 'flex flex-row items-center justify-end',\n center: 'flex flex-row items-center justify-center',\n stack: 'flex flex-col items-center',\n};\n\nexport function ButtonGroup({\n items,\n value,\n onChange,\n variant = 'primary',\n size = 'md',\n align = 'start',\n className,\n 'aria-label': ariaLabel,\n}: ButtonGroupProps) {\n const isJustify = align === 'justify';\n const isStack = align === 'stack';\n\n return (\n <div\n role=\"group\"\n aria-label={ariaLabel}\n className={clsx(\n containerStyles[variant],\n containerAlignStyles[align],\n className,\n )}\n >\n {items.map((item) => {\n const isSelected = item.value === value;\n return (\n <div\n key={item.value}\n className={clsx(isJustify && 'flex-1 min-w-0', isStack && 'w-full')}\n >\n <button\n type=\"button\"\n aria-pressed={isSelected}\n disabled={item.disabled}\n onClick={() => onChange(item.value)}\n className={clsx(\n 'inline-flex items-center justify-center whitespace-nowrap transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1',\n 'disabled:cursor-not-allowed disabled:text-disabled',\n (isJustify || isStack) && 'w-full',\n itemSizeStyles[size],\n isSelected ? selectedStyles[variant] : unselectedStyles[variant],\n )}\n >\n {item.leadingIcon}\n <div className='px-1'>{item.label}</div>\n {item.trailingIcon}\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n","import clsx from 'clsx';\n\nexport type AvatarSize = 'sm' | 'md' | 'lg';\nexport type AvatarShape = 'circle' | 'square';\n\nexport interface AvatarInitialProps {\n type?: 'initial';\n /** Single character — Figma spec: one letter only to avoid overflow */\n initial: string;\n size?: AvatarSize;\n shape?: AvatarShape;\n className?: string;\n}\n\nexport interface AvatarImageProps {\n type: 'image';\n src: string;\n alt?: string;\n size?: AvatarSize;\n shape?: AvatarShape;\n className?: string;\n}\n\nexport type AvatarProps = AvatarInitialProps | AvatarImageProps;\n\n// Figma sizes: lg=40px, md=32px, sm=24px\nconst sizeStyles: Record<AvatarSize, string> = {\n lg: 'size-10',\n md: 'size-8',\n sm: 'size-6',\n};\n\n// Figma text sizes for initials: body-medium at lg, scales down proportionally\nconst initialTextStyles: Record<AvatarSize, string> = {\n lg: 'text-body font-semibold',\n md: 'text-body-xs font-semibold',\n sm: 'text-body-tiny font-semibold',\n};\n\n// Figma shape radii: circle=full, square: lg/md=8px (rounded-lg), sm=4px (rounded)\nfunction getShapeClass(shape: AvatarShape, size: AvatarSize): string {\n if (shape === 'circle') return 'rounded-full';\n return size === 'sm' ? 'rounded' : 'rounded-lg';\n}\n\nexport function Avatar(props: AvatarProps) {\n const { size = 'lg', shape = 'circle', className } = props;\n\n const base = clsx(\n 'shrink-0 overflow-hidden',\n sizeStyles[size],\n getShapeClass(shape, size),\n className,\n );\n\n if (props.type === 'image') {\n return (\n <div className={base}>\n <img\n src={props.src}\n alt={props.alt ?? ''}\n className=\"size-full object-cover\"\n />\n </div>\n );\n }\n\n return (\n <div\n className={clsx(base, 'flex items-center justify-center')}\n style={{\n background:\n 'linear-gradient(135deg, var(--color-graphic-blue) 30%, var(--color-graphic-red) 100%)',\n }}\n >\n <span\n className={clsx(\n 'select-none leading-none text-brand-on-brand',\n initialTextStyles[size],\n )}\n >\n {props.initial.charAt(0).toUpperCase()}\n </span>\n </div>\n );\n}\n","import { type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport type AvatarGroupSpacing = 'spaced' | 'overlap';\n\nexport interface AvatarGroupProps {\n children: ReactNode;\n /** Number shown in the overflow badge — omit to hide the badge */\n overflow?: number;\n spacing?: AvatarGroupSpacing;\n className?: string;\n}\n\nexport function AvatarGroup({\n children,\n overflow,\n spacing = 'spaced',\n className,\n}: AvatarGroupProps) {\n return (\n <div\n className={clsx(\n 'flex items-center',\n spacing === 'spaced' ? 'gap-1' : '-space-x-2 isolate',\n className,\n )}\n >\n {children}\n {overflow !== undefined && (\n <div\n className={clsx(\n 'flex items-center justify-center',\n 'min-w-6 h-6 px-1 rounded-lg',\n 'bg-default-secondary text-default-secondary text-body-sm',\n spacing === 'overlap' && 'drop-shadow-sm',\n )}\n >\n +{overflow}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface AvatarBlockProps {\n children: ReactNode;\n title: string;\n description?: string;\n className?: string;\n}\n\nexport function AvatarBlock({ children, title, description, className }: AvatarBlockProps) {\n return (\n <div className={clsx('flex items-start gap-3', className)}>\n <div className=\"shrink-0\">{children}</div>\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"text-body font-semibold text-default-secondary\">\n {title}\n </span>\n {description && (\n <span className=\"text-body text-default-tertiary\">\n {description}\n </span>\n )}\n </div>\n </div>\n );\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n type HTMLAttributes,\n type LabelHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '../../lib/cn';\nimport type { InputSize } from './input';\n\n/**\n * The label / description / error / control wiring, in one place.\n *\n * This exists because of the single largest defect the 0.3.0 audit found. `Input`,\n * `Textarea`, `Select` and `DatePicker` all accepted `label`, `description`, `error` and\n * `hint`, rendered them, and then connected **none** of them:\n *\n * - `<label htmlFor={id}>` used the caller's `id` with no fallback. Omit `id` — the\n * common case — and `htmlFor` was `undefined`, so the label pointed at nothing.\n * Clicking it did nothing and assistive tech announced an unlabelled field.\n * - `description`, `error` and `hint` were bare `<p>` elements with no `id`, and no\n * control ever referenced them. A consumer could not fix this from outside either:\n * passing `aria-describedby` had nothing to point at.\n * - `error` drove the border colour and nothing else. No `aria-invalid`, no `role`, no\n * live region — so an async validation failure was completely silent.\n *\n * For scale: `aria-describedby`, `aria-invalid` and `aria-required` appeared nowhere in\n * `src/`, and `useId` was used exactly once in the whole library — in `Sparkline`, for an\n * SVG gradient.\n *\n * `Field` generates the ids and hands them down through context, so a control only has to\n * spread `useFieldControl()` onto its input element. It is also usable directly for\n * controls the library does not wrap, which is why the parts are exported.\n */\n\nexport interface FieldContextValue {\n controlId: string;\n /**\n * Id of the `FieldLabel`, for controls whose accessible name cannot come from a\n * `<label for>` association. A `<button>` is named by its own contents, so the Select\n * trigger has to point `aria-labelledby` at the label explicitly or it announces only\n * the chosen value.\n */\n labelId: string;\n descriptionId: string;\n errorId: string;\n hintId: string;\n hasDescription: boolean;\n hasError: boolean;\n hasHint: boolean;\n invalid: boolean;\n required: boolean;\n disabled: boolean;\n size: InputSize;\n}\n\nconst FieldContext = createContext<FieldContextValue | null>(null);\n\nexport function useFieldContext(): FieldContextValue | null {\n return useContext(FieldContext);\n}\n\n/**\n * Props for the control itself. Spread onto the `<input>`/`<select>`/`<textarea>`.\n *\n * `aria-describedby` deliberately lists description *and* message: a field can carry\n * both persistent guidance and a transient error, and a screen reader should read both\n * rather than have the error replace the instruction that explains the format.\n */\nexport function useFieldControl(): {\n id: string | undefined;\n 'aria-describedby': string | undefined;\n 'aria-invalid': true | undefined;\n 'aria-required': true | undefined;\n disabled: boolean | undefined;\n} {\n const field = useFieldContext();\n if (!field) {\n return {\n id: undefined,\n 'aria-describedby': undefined,\n 'aria-invalid': undefined,\n 'aria-required': undefined,\n disabled: undefined,\n };\n }\n\n const describedBy = [\n field.hasDescription && field.descriptionId,\n field.hasError && field.errorId,\n field.hasHint && !field.hasError && field.hintId,\n ]\n .filter(Boolean)\n .join(' ');\n\n return {\n id: field.controlId,\n 'aria-describedby': describedBy || undefined,\n 'aria-invalid': field.invalid || undefined,\n 'aria-required': field.required || undefined,\n disabled: field.disabled || undefined,\n };\n}\n\n// ── Field ──────────────────────────────────────────────────────────────────────\n\nexport type FieldOrientation = 'vertical' | 'horizontal';\n\nexport interface FieldProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Supply to control the id yourself; otherwise one is generated. */\n id?: string;\n size?: InputSize;\n invalid?: boolean;\n required?: boolean;\n disabled?: boolean;\n /** `horizontal` puts the label beside the control — for switches and checkboxes. */\n orientation?: FieldOrientation;\n /** Set when a `FieldDescription` is rendered. Inferred by the wrapped controls. */\n hasDescription?: boolean;\n hasError?: boolean;\n hasHint?: boolean;\n}\n\nconst GAP: Record<InputSize, string> = {\n lg: 'gap-2',\n md: 'gap-1',\n sm: 'gap-0.5',\n};\n\nexport function Field({\n children,\n id,\n size = 'md',\n invalid = false,\n required = false,\n disabled = false,\n orientation = 'vertical',\n hasDescription = false,\n hasError = false,\n hasHint = false,\n className,\n ...rest\n}: FieldProps) {\n const generated = useId();\n const controlId = id ?? generated;\n\n return (\n <FieldContext.Provider\n value={{\n controlId,\n labelId: `${controlId}-label`,\n descriptionId: `${controlId}-description`,\n errorId: `${controlId}-error`,\n hintId: `${controlId}-hint`,\n hasDescription,\n hasError,\n hasHint,\n invalid: invalid || hasError,\n required,\n disabled,\n size,\n }}\n >\n <div\n // role=\"group\" so the label of a fieldset-like cluster is inherited by every\n // control inside it, matching shadcn's Field.\n role={orientation === 'horizontal' ? 'group' : undefined}\n data-slot=\"field\"\n data-invalid={invalid || hasError || undefined}\n data-disabled={disabled || undefined}\n className={cn(\n orientation === 'horizontal'\n ? 'flex flex-row items-center justify-between gap-3'\n : cn('flex flex-col', GAP[size]),\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </FieldContext.Provider>\n );\n}\n\n// ── FieldLabel ─────────────────────────────────────────────────────────────────\n\nconst LABEL_TEXT: Record<InputSize, string> = {\n lg: 'text-body',\n md: 'text-body-sm',\n sm: 'text-body-tiny',\n};\n\nexport interface FieldLabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n children: ReactNode;\n}\n\nexport function FieldLabel({ children, className, htmlFor, ...rest }: FieldLabelProps) {\n const field = useFieldContext();\n\n return (\n <label\n id={field?.labelId}\n htmlFor={htmlFor ?? field?.controlId}\n data-slot=\"field-label\"\n className={cn(\n LABEL_TEXT[field?.size ?? 'md'],\n field?.disabled ? 'text-disabled' : 'text-default',\n // The required marker is CSS generated content, not a child element. An\n // `<span aria-hidden>*</span>` would be correct for accessible-name computation\n // (which skips aria-hidden) but it still lands in `textContent`, so every\n // `getByLabelText('Name')` — ours and every consumer's — would have to become\n // `/Name/`. Generated content is in neither, and the real signal is\n // `aria-required` on the control regardless.\n field?.required && \"after:ml-0.5 after:text-danger after:content-['*']\",\n className,\n )}\n {...rest}\n >\n {children}\n </label>\n );\n}\n\n// ── FieldDescription / FieldError / FieldHint ──────────────────────────────────\n\nexport interface FieldTextProps extends HTMLAttributes<HTMLParagraphElement> {\n children: ReactNode;\n}\n\n/** Persistent guidance, shown above the control and announced with it. */\nexport function FieldDescription({ children, className, ...rest }: FieldTextProps) {\n const field = useFieldContext();\n return (\n <p\n id={field?.descriptionId}\n data-slot=\"field-description\"\n className={cn(\n LABEL_TEXT[field?.size ?? 'md'],\n field?.disabled ? 'text-disabled' : 'text-default-secondary',\n className,\n )}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\n/**\n * Validation message. `role=\"alert\"` because an error that appears after submit —\n * asynchronously, without focus moving — is otherwise never announced at all.\n */\nexport function FieldError({ children, className, ...rest }: FieldTextProps) {\n const field = useFieldContext();\n return (\n <p\n id={field?.errorId}\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(LABEL_TEXT[field?.size ?? 'md'], 'text-danger', className)}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\n/** Neutral helper text. Suppressed while an error is showing, so the two never stack. */\nexport function FieldHint({ children, className, ...rest }: FieldTextProps) {\n const field = useFieldContext();\n return (\n <p\n id={field?.hintId}\n data-slot=\"field-hint\"\n className={cn(LABEL_TEXT[field?.size ?? 'md'], 'text-default-secondary', className)}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\n// ── Grouping ───────────────────────────────────────────────────────────────────\n\nexport interface FieldGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** Stacks several `Field`s with consistent rhythm. */\nexport function FieldGroup({ children, className, ...rest }: FieldGroupProps) {\n return (\n <div data-slot=\"field-group\" className={cn('flex flex-col gap-4', className)} {...rest}>\n {children}\n </div>\n );\n}\n\nexport interface FieldSetProps extends HTMLAttributes<HTMLFieldSetElement> {\n children: ReactNode;\n}\n\n/**\n * A real `<fieldset>`. Required for radio groups and checkbox groups: the group needs a\n * name of its own, and only `<legend>` gives it one that is announced before each option.\n */\nexport const FieldSet = forwardRef<HTMLFieldSetElement, FieldSetProps>(function FieldSet(\n { children, className, ...rest },\n ref,\n) {\n return (\n <fieldset\n ref={ref}\n data-slot=\"field-set\"\n className={cn('flex flex-col gap-3 border-0 p-0', className)}\n {...rest}\n >\n {children}\n </fieldset>\n );\n});\n\nexport interface FieldLegendProps extends HTMLAttributes<HTMLLegendElement> {\n children: ReactNode;\n /** `label` matches a field label's weight; `legend` is the larger section heading. */\n variant?: 'legend' | 'label';\n}\n\nexport function FieldLegend({\n children,\n variant = 'legend',\n className,\n ...rest\n}: FieldLegendProps) {\n return (\n <legend\n data-slot=\"field-legend\"\n className={cn(\n 'p-0',\n variant === 'legend'\n ? 'text-body font-semibold text-default'\n : 'text-body-sm text-default',\n className,\n )}\n {...rest}\n >\n {children}\n </legend>\n );\n}\n\nexport interface FieldSeparatorProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function FieldSeparator({ className, ...rest }: FieldSeparatorProps) {\n return (\n <div\n role=\"separator\"\n data-slot=\"field-separator\"\n className={cn('h-px w-full bg-divider', className)}\n {...rest}\n />\n );\n}\n","import { forwardRef, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldControl,\n} from './field';\n\nexport type InputSize = 'lg' | 'md' | 'sm';\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n label?: string;\n description?: string;\n /** Red border + message shown below the input. Also sets `aria-invalid`. */\n error?: string;\n /** Neutral helper text shown below the input (hidden when error is set) */\n hint?: string;\n size?: InputSize;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n /** Interactive trailing slot (e.g. a show/hide password button) — unlike\n * `trailingIcon` it receives pointer events. */\n trailingAction?: ReactNode;\n}\n\n// Figma sizes: lg=48px md=36px sm=24px\nconst inputBase: Record<InputSize, string> = {\n lg: 'h-12 px-5 py-3.5 text-body',\n md: 'h-9 px-4 py-2.5 text-body-sm',\n sm: 'h-6 px-3 py-[5px] text-body-tiny',\n};\n\n// Extra left padding to clear the leading icon\n// lg adds 8px for the explicit flex gap Figma uses on large; md/sm have no gap\nconst leadingPad: Record<InputSize, string> = {\n lg: 'pl-12',\n md: 'pl-8',\n sm: 'pl-6',\n};\n\n// Extra right padding to clear the trailing icon\nconst trailingPad: Record<InputSize, string> = {\n lg: 'pr-12',\n md: 'pr-8',\n sm: 'pr-6',\n};\n\n// Icon wrapper: absolutely positioned inside the input container\nconst iconWrap: Record<InputSize, { left: string; right: string; size: string }> = {\n lg: { left: 'left-4', right: 'right-4', size: 'size-5' },\n md: { left: 'left-3', right: 'right-3', size: 'size-4' },\n sm: { left: 'left-2', right: 'right-2', size: 'size-3' },\n};\n\n/**\n * Focus styling note: `focus-visible:` rather than `focus:`, and `ring-2 ring-brand` to\n * match the button family. Through 0.3.0 this used `focus:ring-1 ring-brand-secondary`,\n * which showed a ring on plain mouse clicks and was a third distinct focus treatment in a\n * library that already had two.\n */\nexport const inputControlClasses = (size: InputSize, invalid: boolean, disabled?: boolean) =>\n clsx(\n 'w-full rounded-lg border outline-none transition-colors',\n 'bg-default text-default',\n 'placeholder:text-default-tertiary',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n inputBase[size],\n disabled\n ? 'cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled'\n : invalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n // read-only is not disabled: the value still matters and is still selectable, but it\n // must not look editable. Nothing in the library styled this before 0.4.0.\n 'read-only:bg-default-secondary read-only:cursor-default',\n );\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n label,\n description,\n error,\n hint,\n size: sizeProp,\n leadingIcon,\n trailingIcon,\n trailingAction,\n className,\n disabled,\n required,\n id,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n const iw = iconWrap[size];\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n\n <div className=\"relative flex items-center\">\n {leadingIcon && (\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n iw.left,\n iw.size,\n 'flex items-center justify-center text-icon-default-secondary',\n )}\n >\n {leadingIcon}\n </span>\n )}\n <InputControl\n ref={ref}\n size={size}\n invalid={hasError}\n disabled={disabled}\n required={required}\n className={clsx(\n leadingIcon && leadingPad[size],\n (trailingIcon || trailingAction) && trailingPad[size],\n )}\n {...props}\n />\n {trailingIcon && !trailingAction && (\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n iw.right,\n iw.size,\n 'flex items-center justify-center text-icon-default-secondary',\n )}\n >\n {trailingIcon}\n </span>\n )}\n {trailingAction && (\n <span\n className={clsx(\n 'absolute',\n iw.right,\n 'flex items-center justify-center text-icon-default-secondary',\n )}\n >\n {trailingAction}\n </span>\n )}\n </div>\n\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n\n/**\n * The bare `<input>` with the field wiring applied and no label/message chrome — for\n * `InputGroup` and any composition that supplies its own `Field`.\n */\nexport interface InputControlProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: InputSize;\n invalid?: boolean;\n}\n\nexport const InputControl = forwardRef<HTMLInputElement, InputControlProps>(\n function InputControl({ size: sizeProp, invalid = false, className, ...props }, ref) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n return (\n <input\n ref={ref}\n // A container's default control size is reported so a test — and a caller reading\n // the DOM — can see which size actually won, rather than inferring it from classes.\n data-size={size}\n // Field wiring first so an explicit prop from the caller still wins.\n {...field}\n className={clsx(inputControlClasses(size, isInvalid, isDisabled), className)}\n {...props}\n />\n );\n },\n);\n","import { forwardRef, type TextareaHTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { type InputSize } from './input';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldControl,\n} from './field';\n\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n label?: string;\n description?: string;\n /** Red border + message shown below the control. Also sets `aria-invalid`. */\n error?: string;\n hint?: string;\n size?: InputSize;\n}\n\n// Figma: large textarea inner height ~80px, medium ~68px, small ~52px\nconst textareaBase: Record<InputSize, string> = {\n lg: 'min-h-20 px-4 py-3.5 text-body',\n md: 'min-h-[68px] px-3 py-2.5 text-body-sm',\n sm: 'min-h-[52px] px-2 py-[5px] text-body-tiny',\n};\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n { label, description, error, hint, size: sizeProp, className, disabled, required, id, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n <TextareaControl\n ref={ref}\n size={size}\n invalid={hasError}\n disabled={disabled}\n required={required}\n {...props}\n />\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n\nexport interface TextareaControlProps\n extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n size?: InputSize;\n invalid?: boolean;\n}\n\n/** The bare `<textarea>` with field wiring, for compositions that supply their own `Field`. */\nexport const TextareaControl = forwardRef<HTMLTextAreaElement, TextareaControlProps>(\n function TextareaControl({ size: sizeProp, invalid = false, className, ...props }, ref) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n return (\n <textarea\n ref={ref}\n data-size={size}\n {...field}\n className={clsx(\n 'w-full resize-y rounded-lg border outline-none transition-colors',\n 'bg-default text-default',\n 'placeholder:text-default-tertiary',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n textareaBase[size],\n isDisabled\n ? 'cursor-not-allowed resize-none border-disabled bg-disabled text-disabled placeholder:text-disabled'\n : isInvalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n 'read-only:cursor-default read-only:resize-none read-only:bg-default-secondary',\n className,\n )}\n {...props}\n />\n );\n },\n);\n","import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n} from 'react';\nimport clsx from 'clsx';\nimport { CheckIcon, ChevronDownIcon } from 'lucide-react';\n\nimport { devWarn } from '../../lib/dev-warn';\nimport { FOCUS_RING_INSET } from '../../lib/focus-ring';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useFloatingPanel } from '../overlays/floating';\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n OVERLAY_PANEL,\n OVERLAY_PANEL_SCROLL,\n overlayItemTone,\n} from '../overlays/menu-styles';\nimport { useOverlayDismiss } from '../overlays/overlay';\nimport { Portal } from '../overlays/portal';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldContext,\n useFieldControl,\n} from './field';\nimport { type InputSize } from './input';\n\nexport interface SelectOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectOptionGroup {\n label: string;\n options: SelectOption[];\n}\n\n/** Trigger geometry. `pr` = chevron right-offset + chevron width, the exact clearance. */\nconst selectBase: Record<InputSize, string> = {\n lg: 'h-12 pl-4 pr-9 text-body', // right-4 (16) + size-5 (20) = 36px\n md: 'h-9 pl-3 pr-7 text-body-sm', // right-3 (12) + size-4 (16) = 28px\n sm: 'h-6 pl-2 pr-5 text-body-tiny', // right-2 (8) + size-3 (12) = 20px\n};\n\nconst chevronPos: Record<InputSize, { right: string; size: string }> = {\n lg: { right: 'right-4', size: 'size-5' },\n md: { right: 'right-3', size: 'size-4' },\n sm: { right: 'right-2', size: 'size-3' },\n};\n\nfunction isGroup(entry: SelectOption | SelectOptionGroup): entry is SelectOptionGroup {\n return 'options' in entry;\n}\n\n/** Options in render order, so a roving index is just a position. */\nfunction flatten(entries: (SelectOption | SelectOptionGroup)[]): SelectOption[] {\n return entries.flatMap((entry) => (isGroup(entry) ? entry.options : [entry]));\n}\n\n// ── SelectControl ──────────────────────────────────────────────────────────────\n\nexport interface SelectControlProps\n extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'value' | 'defaultValue' | 'onChange' | 'children' | 'type'\n > {\n /** Flat options, or groups which render as a labelled `role=\"group\"`. */\n options: (SelectOption | SelectOptionGroup)[];\n value?: string | null;\n defaultValue?: string | null;\n onValueChange?: (value: string) => void;\n /**\n * Submits with a surrounding form. With `required`, the value posts through a visually\n * hidden real input, so an empty required select blocks submit like a native one (from\n * 0.7.0) — see the note on `Select`.\n */\n name?: string;\n size?: InputSize;\n invalid?: boolean;\n placeholder?: string;\n}\n\n/**\n * The bare trigger and its listbox, with field wiring and no label/message chrome — for\n * `Select` and any composition that supplies its own `Field`.\n */\nexport const SelectControl = forwardRef<HTMLButtonElement, SelectControlProps>(\n function SelectControl(\n {\n options,\n value: valueProp,\n defaultValue = null,\n onValueChange,\n name,\n size: sizeProp,\n invalid = false,\n placeholder = 'Select…',\n className,\n onKeyDown,\n ...props\n },\n ref,\n ) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const fieldContext = useFieldContext();\n\n const [value, setValue] = useControllableState<string | null>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: string | null) => void) | undefined,\n });\n\n const [open, setOpen] = useState(false);\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const valueId = `${baseId}-value`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const panelRef = useRef<HTMLDivElement | null>(null);\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n\n // Which end to land on when the panel opens. The trigger handles the key before the\n // panel exists, so the intent has to survive one render.\n const pendingEdge = useRef<'start' | 'end'>('start');\n\n const flat = flatten(options);\n const selected = flat.find((option) => option.value === value) ?? null;\n\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n const isRequired = Boolean(field['aria-required']) || Boolean(props['aria-required']);\n\n if (!fieldContext && !props['aria-label'] && !props['aria-labelledby']) {\n devWarn(\n 'SelectControl outside a Field needs aria-label or aria-labelledby; otherwise it is named only by its value.',\n );\n }\n\n /**\n * A roving tabindex, not `aria-activedescendant`.\n *\n * `Combobox` uses activedescendant because focus must stay in its text input — moving\n * it into the list would stop the user typing. A Select has no input, so real DOM\n * focus is available, and it brings three things with it: `useRovingFocus` already\n * implements arrows, Home/End, disabled-skipping, wrap **and typeahead** (which the\n * native `<select>` had and losing would be a regression); the browser scrolls the\n * focused option into view for free; and the options are genuinely focusable, so none\n * of the jsx-a11y suppressions the Combobox listbox needs apply here.\n */\n const roving = useRovingFocus({ orientation: 'vertical', loop: true, typeahead: true });\n\n const { refs, floatingStyles } = useFloatingPanel({\n open,\n onOpenChange: setOpen,\n side: 'bottom',\n align: 'start',\n sideOffset: 4,\n matchAnchorWidth: true,\n });\n\n useEffect(() => {\n refs.setReference(triggerRef.current);\n }, [refs, open]);\n\n useOverlayDismiss({\n onDismiss: () => setOpen(false),\n panelRef,\n active: open,\n // Not modal: the page behind stays readable and interactive. Only Escape,\n // outside-press and focus restore — the same four falses as DropdownMenu.\n trapFocus: false,\n lockScroll: false,\n inertBackground: false,\n // The listbox owns its initial focus below; a \"first tabbable element\" scan would\n // fight the roving tabindex, which exposes exactly one option at a time.\n autoFocus: false,\n });\n\n // Keyed on the panel node rather than on `open`: Portal gates its children behind a\n // mounted flag, so on the render where the panel opens the options do not exist yet.\n const wasOpen = useRef(false);\n useEffect(() => {\n if (open && panelNode && !wasOpen.current) {\n const index = selected ? flat.indexOf(selected) : -1;\n // Open onto the current selection when there is one — the native select did, and\n // it is the difference between \"resume\" and \"start over\" on a long list.\n if (index >= 0 && pendingEdge.current === 'start') roving.focusIndex(index);\n else roving.moveToEdge(pendingEdge.current);\n pendingEdge.current = 'start';\n wasOpen.current = true;\n }\n if (!open) wasOpen.current = false;\n // `flat`/`selected` are recomputed every render; including them would re-run this on\n // every keystroke and fight the roving focus it just set.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, panelNode, roving]);\n\n const commit = (option: SelectOption) => {\n if (option.disabled) return;\n setValue(option.value);\n setOpen(false);\n };\n\n const triggerKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || open) return;\n // Arrows open onto the near or far end, per the APG. Enter and Space arrive as a\n // click on a native button, so `onClick` already covers them.\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n pendingEdge.current = event.key === 'ArrowUp' ? 'end' : 'start';\n setOpen(true);\n }\n };\n\n let cursor = 0;\n\n const renderOption = (option: SelectOption, index: number) => {\n const isSelected = option.value === value;\n const itemProps = roving.itemProps(index, {\n disabled: option.disabled,\n label: option.label,\n });\n\n return (\n <div\n key={option.value}\n // `role=\"option\"` on a div rather than a <button>: the roving tabindex owns\n // focusability, and a native button would re-enter the tab sequence.\n role=\"option\"\n id={optionId(index)}\n aria-selected={isSelected}\n aria-disabled={option.disabled || undefined}\n {...itemProps}\n // Restated after the spread so jsx-a11y can see it — it cannot follow a\n // tabIndex that arrives through an object spread.\n tabIndex={itemProps.tabIndex}\n onClick={() => commit(option)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n commit(option);\n }\n }}\n className={clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE[size],\n 'items-center',\n overlayItemTone('default', !!option.disabled),\n // The tint is shared with hover, so the ring is what marks the keyboard position.\n FOCUS_RING_INSET,\n )}\n >\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {isSelected && (\n <CheckIcon className=\"size-3.5 shrink-0\" strokeWidth={3} aria-hidden />\n )}\n </div>\n );\n };\n\n const cp = chevronPos[size];\n\n return (\n <>\n <div className=\"relative flex items-center\">\n <button\n ref={composeRefs<HTMLButtonElement>(triggerRef, ref)}\n type=\"button\"\n /**\n * `role=\"combobox\"`, matching Radix Select. It is the role that permits\n * `aria-expanded`, `aria-controls`, `aria-required` and `aria-invalid` — all\n * of which `Field` supplies and none of which a plain `role=\"button\"` accepts.\n * `aria-activedescendant` is optional on a combobox and deliberately absent:\n * real focus moves into the listbox instead.\n */\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n // A <button> is named by its contents, so a `<label for>` association does not\n // name it the way it named the old <select>. Point at the label explicitly and\n // let the value follow it: \"Role Analyst\". The second id targets the value span\n // rather than the button itself — a self-reference is legal per spec but several\n // name-computation implementations decline to resolve it.\n aria-labelledby={fieldContext ? `${fieldContext.labelId} ${valueId}` : undefined}\n data-size={size}\n {...field}\n disabled={isDisabled}\n onClick={() => setOpen(!open)}\n onKeyDown={triggerKeyDown}\n className={clsx(\n 'w-full appearance-none rounded-lg border text-left outline-none transition-colors',\n 'bg-default text-default',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n selectBase[size],\n isDisabled\n ? 'cursor-not-allowed border-disabled bg-disabled text-disabled'\n : isInvalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n className,\n )}\n {...props}\n >\n <span\n id={valueId}\n className={clsx('block truncate', !selected && 'text-default-tertiary')}\n >\n {selected?.label ?? placeholder}\n </span>\n </button>\n\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n cp.right,\n cp.size,\n 'flex items-center justify-center',\n isDisabled ? 'text-icon-disabled' : 'text-icon-default-secondary',\n )}\n >\n <ChevronDownIcon className=\"size-full\" />\n </span>\n\n {/* Form participation. Not an `sr-only <select>`: that would duplicate every\n option into the accessibility tree, and a real <select> reaching focus would\n reopen the OS picker this component exists to replace. */}\n {name && !isRequired && <input type=\"hidden\" name={name} value={value ?? ''} />}\n {/* Required: a hidden input is exempt from constraint validation, so it could never\n block a submit. This is a real, invisible text input instead. The browser refuses\n to submit while it is empty and anchors its message at the control, and when it\n tries to focus the input, focus is handed to the trigger. It is out of the tab\n order and hidden from assistive tech, which already hears aria-required. */}\n {name && isRequired && (\n <input\n aria-hidden\n tabIndex={-1}\n name={name}\n value={value ?? ''}\n required\n disabled={isDisabled}\n onChange={() => {}}\n onFocus={() => triggerRef.current?.focus()}\n className=\"pointer-events-none absolute inset-x-0 bottom-0 h-px w-full opacity-0\"\n />\n )}\n </div>\n\n {open && (\n <Portal>\n <div\n ref={composeRefs<HTMLDivElement>(panelRef, setPanelNode, refs.setFloating)}\n id={listboxId}\n role=\"listbox\"\n // Focusable but out of the tab sequence: the fallback target for an empty\n // list, and it keeps key events on the panel.\n tabIndex={-1}\n aria-orientation=\"vertical\"\n aria-labelledby={fieldContext?.labelId}\n aria-required={field['aria-required']}\n aria-invalid={field['aria-invalid']}\n style={{ ...floatingStyles, width: 'var(--panel-anchor-width)' }}\n className={clsx('z-popover', OVERLAY_PANEL, OVERLAY_PANEL_SCROLL)}\n {...roving.containerProps}\n onKeyDown={(event) => {\n roving.containerProps.onKeyDown(event);\n // Tab leaves the control rather than walking the list, so close first and\n // let the browser move on from the trigger. No commit: arrowing to an\n // option is browsing, and only Enter, Space or a click chooses it.\n if (event.key === 'Tab') setOpen(false);\n }}\n >\n {options.map((entry, entryIndex) => {\n if (!isGroup(entry)) return renderOption(entry, cursor++);\n\n const headingId = `${baseId}-group-${entryIndex}`;\n return (\n <div key={`group-${entryIndex}`} role=\"group\" aria-labelledby={headingId}>\n <div id={headingId} className={OVERLAY_HEADING}>\n {entry.label}\n </div>\n {entry.options.map((option) => renderOption(option, cursor++))}\n </div>\n );\n })}\n </div>\n </Portal>\n )}\n </>\n );\n },\n);\n\n// ── Select ─────────────────────────────────────────────────────────────────────\n\nexport interface SelectProps extends SelectControlProps {\n label?: string;\n description?: string;\n /** Red border + message shown below the control. Also sets `aria-invalid`. */\n error?: string;\n hint?: string;\n required?: boolean;\n}\n\n/**\n * Single-select dropdown: a trigger and a portalled listbox.\n *\n * Through 0.4.0 this wrapped a native `<select>`, which was the right call for its keyboard\n * contract and the wrong one for everything visual: the option popup is drawn by the OS and\n * cannot be styled at all, so a Select never matched the `DropdownMenu` and `Combobox`\n * panels sitting beside it on the same filter row. It is now the same panel as those, and\n * the keyboard contract it used to inherit is implemented rather than borrowed — arrows,\n * Home/End, typeahead, Escape, and Tab that leaves without committing.\n *\n * Two consequences of dropping the native element, neither papered over:\n *\n * - **No OS picker on mobile.** The wheel/sheet a native select opens is gone.\n * - **`required` blocks submit again from 0.7.0**, for a select with a `name`. 0.5 and 0.6\n * posted through a hidden input, which constraint validation ignores. A required select\n * now posts through an invisible real input that the browser validates. In\n * react-hook-form, register it with `Controller` rather than `register`.\n *\n * Kept as our own component rather than Radix Select in 0.7.0, deliberately. Radix Select is\n * modal (it locks page scroll and hides the page while open), which is wrong for a form field,\n * and it needs pointer-capture polyfills to run in jsdom, so adopting it would have broken\n * every consumer's test suite.\n *\n * For a list long enough to need filtering, use `Combobox`.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n label,\n description,\n error,\n hint,\n size: sizeProp,\n className,\n disabled,\n required,\n id,\n ...props\n },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n\n <SelectControl ref={ref} size={size} invalid={hasError} disabled={disabled} {...props} />\n\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n","/**\n * A console warning in development builds only, once per message.\n *\n * Used where a component can render but not correctly, such as a table with no accessible\n * name. Read through `globalThis` so the library needs no Node typings and does not throw\n * where `process` does not exist. Every bundler the consumers use (Vite, Next, webpack)\n * replaces `process.env.NODE_ENV`, so production builds drop the check.\n */\nconst seen = new Set<string>();\n\nexport function devWarn(message: string): void {\n const env = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env?.NODE_ENV;\n if (env === 'production' || seen.has(message)) return;\n seen.add(message);\n console.warn(`[@platned/ui] ${message}`);\n}\n","import { useCallback, useRef, useState } from 'react';\n\nexport interface UseControllableStateOptions<T> {\n /** The controlled value. Passing anything other than `undefined` takes control. */\n value?: T;\n /** Initial value when uncontrolled. */\n defaultValue: T;\n /** Fired on every change, controlled or not. */\n onChange?: (value: T) => void;\n}\n\n/**\n * One state value that works controlled or uncontrolled, the way every Radix and\n * shadcn/ui control does.\n *\n * Before 0.4.0 nothing in this library supported an uncontrolled mode — `Checkbox`,\n * `Toggle`, `Tabs`, `SegmentedControl`, `ButtonGroup` and `MultiSelectCard` all *required*\n * a value plus a change handler, so the simplest possible use site still needed a\n * `useState` in the consumer. `DropdownMenu` had the opposite problem: its open state was\n * entirely internal, so a caller could neither open it programmatically nor observe it.\n *\n * Control is decided per render by whether `value` is `undefined`. A component that\n * starts controlled and later passes `undefined` will fall back to its internal value —\n * the same caveat React itself has with inputs, and for the same reason.\n */\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T, (next: T | ((prev: T) => T)) => void] {\n const [internal, setInternal] = useState<T>(defaultValue);\n\n const isControlled = value !== undefined;\n const current = isControlled ? value : internal;\n\n // Kept in a ref so `setValue` stays referentially stable across renders. Without this\n // every consumer that puts it in a dependency array re-subscribes on each render.\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const currentRef = useRef(current);\n currentRef.current = current;\n\n const isControlledRef = useRef(isControlled);\n isControlledRef.current = isControlled;\n\n const setValue = useCallback((next: T | ((prev: T) => T)) => {\n const resolved =\n typeof next === 'function' ? (next as (prev: T) => T)(currentRef.current) : next;\n\n if (resolved === currentRef.current) return;\n\n // A controlled component must not move its own value — the parent owns it and will\n // pass the new one back down. Only the notification goes out.\n if (!isControlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [current, setValue];\n}\n","import { useCallback, useEffect, useRef, useState, type KeyboardEvent } from 'react';\n\nexport type RovingOrientation = 'horizontal' | 'vertical' | 'both';\n\nexport interface UseRovingFocusOptions {\n /** Which arrow keys move focus. `both` accepts all four. Default `horizontal`. */\n orientation?: RovingOrientation;\n /** Wrap past the ends. Default `true`. */\n loop?: boolean;\n /** Jump to an item by typing the start of its label. Default `false`. */\n typeahead?: boolean;\n /** Item to start on. Default `0`. */\n defaultIndex?: number;\n /** Fired when the composite is exited with Escape — menus use it to close. */\n onEscape?: () => void;\n}\n\nexport interface RovingItemOptions {\n disabled?: boolean;\n /** Typeahead match target. Only read when `typeahead` is on. */\n label?: string;\n}\n\nexport interface RovingItemProps {\n ref: (node: HTMLElement | null) => void;\n tabIndex: 0 | -1;\n onFocus: () => void;\n 'data-roving-index': number;\n}\n\n/**\n * Arrow-key navigation with a roving tabindex, for any composite widget that owns a\n * single-stop tab sequence: `menu`, `tablist`, `listbox`, `radiogroup`, `toolbar`.\n *\n * Before 0.4.0 this library had **no arrow-key handling anywhere** — `ArrowDown`,\n * `Home` and `End` appeared in no file. `Tabs`, `DropdownMenu`, `ButtonGroup`,\n * `SegmentedControl` and `RoleComboBox` all announced a composite role to assistive tech\n * while behaving like a plain row of buttons: every item natively tabbable, arrows inert.\n * That is worse than shipping no role at all, because a screen reader tells the user\n * \"tab 3 of 5\" and then the keys it implies do nothing.\n *\n * Keyboard handling lives on the container and is delegated, rather than being attached\n * per item — one listener, and the item list can change length without re-binding.\n *\n * const roving = useRovingFocus({ orientation: 'vertical', loop: true, typeahead: true });\n *\n * <div role=\"menu\" {...roving.containerProps}>\n * {items.map((item, i) => (\n * <button\n * key={item.id}\n * role=\"menuitem\"\n * {...roving.itemProps(i, { disabled: item.disabled, label: item.label })}\n * />\n * ))}\n * </div>\n */\nexport function useRovingFocus({\n orientation = 'horizontal',\n loop = true,\n typeahead = false,\n defaultIndex = 0,\n onEscape,\n}: UseRovingFocusOptions = {}) {\n const [activeIndex, setActiveIndex] = useState(defaultIndex);\n\n const items = useRef<(HTMLElement | null)[]>([]);\n const meta = useRef<RovingItemOptions[]>([]);\n\n const search = useRef('');\n const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n },\n [],\n );\n\n const focusIndex = useCallback((index: number) => {\n const node = items.current[index];\n if (!node) return;\n setActiveIndex(index);\n node.focus();\n }, []);\n\n /** Walk from `start` in `step` until a registered, enabled item turns up. */\n const move = useCallback(\n (start: number, step: number) => {\n const total = items.current.length;\n if (total === 0) return;\n\n for (let i = 1; i <= total; i++) {\n let next = start + step * i;\n if (loop) {\n next = ((next % total) + total) % total;\n } else if (next < 0 || next >= total) {\n return;\n }\n if (items.current[next] && !meta.current[next]?.disabled) {\n focusIndex(next);\n return;\n }\n }\n },\n [loop, focusIndex],\n );\n\n const moveToEdge = useCallback(\n (from: 'start' | 'end') => {\n const total = items.current.length;\n if (total === 0) return;\n // Start just outside the range so `move` lands on the first enabled item inward.\n move(from === 'start' ? -1 : total, from === 'start' ? 1 : -1);\n },\n [move],\n );\n\n const runTypeahead = useCallback(\n (char: string) => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n search.current += char.toLowerCase();\n searchTimer.current = setTimeout(() => {\n search.current = '';\n }, 500);\n\n const total = items.current.length;\n const query = search.current;\n\n // Search forward from the item after the active one so repeated presses of the\n // same letter cycle through the matches instead of sticking on the first.\n for (let i = 1; i <= total; i++) {\n const index = (activeIndex + i) % total;\n if (meta.current[index]?.disabled) continue;\n const label = meta.current[index]?.label?.toLowerCase();\n if (label?.startsWith(query)) {\n focusIndex(index);\n return;\n }\n }\n },\n [activeIndex, focusIndex],\n );\n\n const onKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n const { key } = event;\n const vertical = orientation === 'vertical' || orientation === 'both';\n const horizontal = orientation === 'horizontal' || orientation === 'both';\n\n const next =\n (vertical && key === 'ArrowDown') || (horizontal && key === 'ArrowRight');\n const prev = (vertical && key === 'ArrowUp') || (horizontal && key === 'ArrowLeft');\n\n if (next || prev) {\n event.preventDefault();\n move(activeIndex, next ? 1 : -1);\n return;\n }\n\n if (key === 'Home') {\n event.preventDefault();\n moveToEdge('start');\n return;\n }\n\n if (key === 'End') {\n event.preventDefault();\n moveToEdge('end');\n return;\n }\n\n if (key === 'Escape' && onEscape) {\n onEscape();\n return;\n }\n\n // Single printable character, no modifier — a typeahead jump, not a shortcut.\n if (\n typeahead &&\n key.length === 1 &&\n key !== ' ' &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n runTypeahead(key);\n }\n },\n [orientation, activeIndex, move, moveToEdge, onEscape, typeahead, runTypeahead],\n );\n\n const itemProps = useCallback(\n (index: number, options: RovingItemOptions = {}): RovingItemProps => {\n meta.current[index] = options;\n return {\n ref: (node: HTMLElement | null) => {\n items.current[index] = node;\n },\n // The roving part: exactly one item is in the tab sequence, so Tab enters the\n // composite once and Tab again leaves it.\n tabIndex: index === activeIndex ? 0 : -1,\n onFocus: () => setActiveIndex(index),\n 'data-roving-index': index,\n };\n },\n [activeIndex],\n );\n\n return {\n activeIndex,\n setActiveIndex,\n focusIndex,\n moveToEdge,\n itemProps,\n containerProps: { onKeyDown },\n };\n}\n","import { useRef } from 'react';\nimport {\n arrow,\n autoUpdate,\n flip,\n offset,\n shift,\n size,\n useFloating,\n type Middleware,\n type Placement,\n} from '@floating-ui/react';\n\nexport type FloatingSide = 'top' | 'right' | 'bottom' | 'left';\nexport type FloatingAlign = 'start' | 'center' | 'end';\n\nexport interface UseFloatingPanelOptions {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Preferred edge of the trigger to sit on. Flips when there is no room. Default `bottom`. */\n side?: FloatingSide;\n /** Alignment along that edge. Default `center`. */\n align?: FloatingAlign;\n /** Gap between trigger and panel, in px. Default `6`. */\n sideOffset?: number;\n /** Nudge along the alignment axis, in px. Default `0`. */\n alignOffset?: number;\n /** Minimum gap to keep from the viewport edge, in px. Default `8`. */\n collisionPadding?: number;\n /** Render an arrow and position it. Default `false`. */\n withArrow?: boolean;\n /**\n * Constrain the panel to the space available and expose the trigger's width as\n * `--panel-anchor-width`, so a listbox can match its input. Default `false`.\n */\n matchAnchorWidth?: boolean;\n}\n\n/**\n * The one floating-panel configuration, shared by every popover-shaped component —\n * `DropdownMenu`, `Tooltip`, `Popover`, `HoverCard`, `ContextMenu`, `Combobox`, `Select`.\n *\n * Everything here is behaviour the hand-rolled version had none of. Panels were plain\n * `absolute top-full` with a static `left-0`/`right-0`, so there was no flipping when a\n * panel ran off the bottom of the viewport, no shifting when it ran off the side, no\n * repositioning on scroll or resize (nothing listened for either), and no way to ask for\n * anything other than \"below, aligned left or right\".\n *\n * `side`/`align` is the shadcn/Radix vocabulary rather than Floating UI's single\n * `placement` string, because it keeps the two axes independent at the call site and\n * `align=\"center\"` does not have to be spelled as an empty suffix.\n */\nexport function useFloatingPanel({\n open,\n onOpenChange,\n side = 'bottom',\n align = 'center',\n sideOffset = 6,\n alignOffset = 0,\n collisionPadding = 8,\n withArrow = false,\n matchAnchorWidth = false,\n}: UseFloatingPanelOptions) {\n const arrowRef = useRef<HTMLElement | null>(null);\n\n const placement: Placement = (align === 'center' ? side : `${side}-${align}`) as Placement;\n\n const floating = useFloating({\n open,\n onOpenChange,\n placement,\n // `fixed`, not the default `absolute`: inside a Modal these panels portal into the\n // dialog's scrolling content (see `PortalContainerProvider`), and an absolutely\n // positioned panel there would be clipped by its overflow. Radix's Popper does the same.\n strategy: 'fixed',\n // Only track while the panel is actually on screen. `autoUpdate` attaches scroll and\n // resize listeners plus a ResizeObserver, so leaving it running on a closed panel\n // would cost every consumer a listener per menu on the page.\n whileElementsMounted: autoUpdate,\n middleware: [\n offset({ mainAxis: sideOffset, crossAxis: alignOffset }),\n // `flip` before `shift`: try the opposite edge first, and only slide along the\n // current one if neither edge fits. The reverse order produces panels that cling to\n // the viewport edge when they had room to simply flip.\n flip({ padding: collisionPadding }),\n shift({ padding: collisionPadding }),\n matchAnchorWidth &&\n size({\n padding: collisionPadding,\n apply({ rects, elements, availableHeight }) {\n elements.floating.style.setProperty(\n '--panel-anchor-width',\n `${rects.reference.width}px`,\n );\n elements.floating.style.setProperty(\n '--panel-available-height',\n `${availableHeight}px`,\n );\n },\n }),\n withArrow && arrow({ element: arrowRef, padding: 4 }),\n ].filter(Boolean) as Middleware[],\n });\n\n return { ...floating, arrowRef };\n}\n","import clsx from 'clsx';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport type { InputSize } from '../forms/input';\n\n/**\n * The one option-list look, shared by every component that pops a panel of choices:\n * `DropdownMenu`, `ContextMenu`, `Menubar`, `Combobox`, `Command` and `Select`.\n *\n * Before this existed the four implementations had drifted: menus used `py-1` panels with\n * full-bleed square `px-3` items, while `Combobox` and `Command` used `p-1` panels with\n * inset `rounded-md px-2.5` ones. Menus moved, not the other two — a rounded highlight\n * needs the panel's own inset padding or its corners collide with the panel border on the\n * first and last item, and the inset form was already 2 of the 3 sites and the 2 newest.\n *\n * Strings, not components, and deliberately in its own module: `forms/` consumes these,\n * and importing `menu-core` from there would pull the whole menu component tree into the\n * bundle graph — tsup runs with no code splitting.\n */\n\n// ── Panel ──────────────────────────────────────────────────────────────────────\n\nexport const OVERLAY_PANEL = 'rounded-lg border border-default bg-default p-1 shadow-300';\n\n/** Menus need a floor width; anchored lists take their width from the trigger. */\nexport const OVERLAY_PANEL_MENU = clsx(OVERLAY_PANEL, 'min-w-[168px]');\n\n/**\n * Scroll cap for an anchored list. Prefers the collision-aware height `useFloatingPanel`\n * writes to `--panel-available-height` when `matchAnchorWidth` is set, falling back to\n * 16rem so the class is safe on a panel that never measured.\n */\nexport const OVERLAY_PANEL_SCROLL = clsx(\n 'max-h-[min(16rem,var(--panel-available-height,16rem))] overflow-y-auto',\n // A floating panel is already its own scroll container and keeps focus on the input or a\n // roving option, so it needs the scrollbar styling but not `ScrollArea`'s tab stop.\n SCROLLBAR_CLASSES,\n);\n\n// ── Item ───────────────────────────────────────────────────────────────────────\n\n/**\n * Carries no padding and no text size — those live in `OVERLAY_ITEM_SIZE`.\n *\n * `clsx` only concatenates, so a base carrying `px-3` beside a size carrying `px-2.5`\n * would resolve by stylesheet order rather than attribute order. Keeping each utility in\n * exactly one of the two strings makes the composition order-independent.\n */\nexport const OVERLAY_ITEM_BASE =\n 'flex w-full cursor-pointer select-none items-start gap-2 rounded-md text-left outline-none transition-colors';\n\nexport const OVERLAY_ITEM_SIZE: Record<InputSize, string> = {\n lg: 'px-3 py-2.5 text-body',\n md: 'px-2.5 py-2 text-body-sm',\n sm: 'px-2 py-1.5 text-body-tiny',\n};\n\nexport type OverlayItemTone = 'default' | 'danger';\n\n/** Hover and keyboard focus share one background — there is no separate active token. */\nexport function overlayItemTone(tone: OverlayItemTone, disabled: boolean) {\n if (disabled) return 'cursor-not-allowed text-disabled';\n return tone === 'danger'\n ? 'text-danger hover:bg-danger-tertiary focus:bg-danger-tertiary'\n : 'text-default hover:bg-default-secondary focus:bg-default-secondary';\n}\n\n/** Highlight driven by state rather than `:hover` — for lists using aria-activedescendant. */\nexport const OVERLAY_ITEM_ACTIVE = 'bg-default-secondary';\n\n// ── Group heading and separator ────────────────────────────────────────────────\n\nexport const OVERLAY_HEADING =\n 'px-2.5 py-1.5 text-body-tiny font-semibold uppercase tracking-wide text-default-tertiary';\n\n/** `-mx-1` cancels the panel's `p-1` so the rule still spans edge to edge. */\nexport const OVERLAY_SEPARATOR = '-mx-1 my-1 h-px bg-divider';\n","import clsx from 'clsx';\n\n/**\n * Styled native scrollbars, for the components that must own their own overflow and so\n * cannot delegate to `ScrollArea`.\n *\n * Two kinds qualify. A table wrapper, a tab strip or a stepper, where inserting another\n * element would break the layout or the `<table>` element relationship; and a floating panel\n * that is already its own scroll container. Both hold focusable children, so a keyboard user\n * can already reach and scroll them — which is the one thing `ScrollArea` adds beyond these\n * classes, and the one thing they do not need.\n *\n * Prefer `ScrollArea` for a scrolling *region* of content. Reach for this only when a wrapper\n * element is not an option, and say why at the call site.\n *\n * A plain string module rather than an export from `scroll-area.tsx`: `menu-styles.ts` needs\n * it, and importing a component module from a style module would pull the component into the\n * bundle graph for the sake of a class list.\n */\nexport const SCROLLBAR_CLASSES = clsx(\n // Firefox and the standard property.\n '[scrollbar-color:var(--color-background-default-tertiary)_transparent] [scrollbar-width:thin]',\n // WebKit/Blink.\n '[&::-webkit-scrollbar]:size-2',\n '[&::-webkit-scrollbar-track]:bg-transparent',\n '[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-default-tertiary',\n '[&::-webkit-scrollbar-thumb:hover]:bg-neutral-secondary',\n '[&::-webkit-scrollbar-corner]:bg-transparent',\n);\n","import { useEffect, useRef, type RefObject } from 'react';\nimport { tabbable } from 'tabbable';\nimport { isEscapeDeferred, useOverlayLayer } from './overlay-stack';\n\n/** The one scrim for every overlay primitive.\n *\n * Modal and Drawer both reference this constant, so there is a single place to change\n * the dimming behind a dialog. Backed by `--color-background-utilities-overlay`. */\nexport const OVERLAY_SCRIM = 'bg-overlay';\n\nexport interface UseOverlayDismissOptions {\n /** Called when the overlay should close. */\n onDismiss: () => void;\n /** The panel element — not the scrim. */\n panelRef: RefObject<HTMLElement | null>;\n /** Set `false` to suspend every behaviour without unmounting. Default `true`. */\n active?: boolean;\n /** Default `true`. */\n closeOnEscape?: boolean;\n /** Default `true`. */\n closeOnOutsidePress?: boolean;\n /** Keep Tab inside the panel. Default `true`. Turn off for non-modal surfaces. */\n trapFocus?: boolean;\n /** Default `true`. */\n lockScroll?: boolean;\n /** Mark sibling content `inert`. Default `true`. */\n inertBackground?: boolean;\n /**\n * Move focus into the panel on mount. Default `true`.\n *\n * Set `false` when the overlay manages its own entry point — a menu with a roving\n * tabindex exposes exactly one focusable item at a time, so a generic\n * \"focus the first tabbable element\" scan would fight it.\n */\n autoFocus?: boolean;\n /** Focus this instead of the first tabbable element. */\n initialFocus?: RefObject<HTMLElement | null>;\n /**\n * Restore focus here instead of wherever it was when the overlay opened.\n *\n * Passing the ref at all takes over the restore: a `current` of `null` means \"leave\n * focus alone\", not \"fall back to the previously focused element\". `Menubar` depends on\n * that — while it is switching from one menu to a sibling, focus already belongs to the\n * sibling and pulling it back to the closing menu's trigger reopens the menu.\n */\n returnFocus?: RefObject<HTMLElement | null>;\n /** Call `preventDefault()` to veto the close — e.g. a form with unsaved input. */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** Call `preventDefault()` to veto the close. */\n onInteractOutside?: (event: PointerEvent) => void;\n}\n\n/** Esc-to-close, a Tab focus trap, scroll lock, an inert background, and focus restore\n * for a mounted overlay. Pass the ref of the panel element (not the scrim).\n *\n * Rewritten in 0.4.0. The previous version handled Esc, Tab and focus restore, and had\n * the following defects — each is now covered by a test:\n *\n * - **One Escape closed every open overlay.** Each overlay put its own listener on\n * `document` and called `stopPropagation`, which stops propagation to other *nodes*,\n * not to sibling listeners on the same node. Dismissal is now gated on `isTopmost`\n * from the shared layer stack.\n * - **A text-selection drag dismissed the dialog.** Outside-press used `click`, whose\n * target for a drag is the nearest common ancestor — the scrim. Now `pointerdown`.\n * - **Forward Tab could walk out of the panel.** The trap only compared against the\n * last tabbable element; once focus was outside by any other route, Tab roamed the\n * background freely. A `focusin` guard now pulls focus back.\n * - **Fixed-position elements were excluded from the trap.** The visibility filter was\n * `offsetParent !== null`, which is `null` for `position: fixed`. Element collection\n * is delegated to `tabbable`, which also honours real tab order (a positive\n * `tabindex` reorders the sequence, so DOM order was the wrong answer), `inert`,\n * `[aria-disabled]`, `contenteditable`, `<summary>`, media with controls, and\n * descendants of a disabled `<fieldset>`.\n * - **Initial focus was a silent no-op for a content-only dialog.** It fell back to\n * focusing the panel, which does nothing without `tabIndex=\"-1\"`. The hook now sets\n * that itself, and retries once content arrives asynchronously.\n * - **Focus restore could land on a detached node**, resetting focus to `<body>`.\n * Now checked with `isConnected`.\n * - No opt-out existed for either dismissal route. Both are now vetoable.\n */\nexport function useOverlayDismiss({\n onDismiss,\n panelRef,\n active = true,\n closeOnEscape = true,\n closeOnOutsidePress = true,\n trapFocus = true,\n lockScroll = true,\n inertBackground = true,\n autoFocus = true,\n initialFocus,\n returnFocus,\n onEscapeKeyDown,\n onInteractOutside,\n}: UseOverlayDismissOptions): void {\n const { isTopmost } = useOverlayLayer(active, {\n lockScroll,\n inertBackground,\n panelRef,\n });\n\n // Read through refs so the listener effects do not re-subscribe on every render of a\n // consumer that passes inline callbacks — which is all of them.\n const handlers = useRef({ onDismiss, onEscapeKeyDown, onInteractOutside });\n handlers.current = { onDismiss, onEscapeKeyDown, onInteractOutside };\n\n const isTopmostRef = useRef(isTopmost);\n isTopmostRef.current = isTopmost;\n\n // ── Escape ───────────────────────────────────────────────────────────────────\n useEffect(() => {\n if (!active || !closeOnEscape) return;\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Escape') return;\n if (!isTopmostRef.current) return;\n\n // A Radix surface this panel sits in has already called preventDefault() to leave the key\n // to us (deferEscapeToInnerPopup), so for that event a veto is read off a view of it whose\n // preventDefault only records the call.\n if (isEscapeDeferred(event)) {\n let vetoed = false;\n handlers.current.onEscapeKeyDown?.(vetoable(event, () => (vetoed = true)));\n if (vetoed) return;\n } else {\n handlers.current.onEscapeKeyDown?.(event);\n if (event.defaultPrevented) return;\n }\n\n handlers.current.onDismiss();\n }\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [active, closeOnEscape]);\n\n // ── Outside press ────────────────────────────────────────────────────────────\n useEffect(() => {\n if (!active || !closeOnOutsidePress) return;\n\n function onPointerDown(event: PointerEvent) {\n if (!isTopmostRef.current) return;\n const panel = panelRef.current;\n if (!panel || panel.contains(event.target as Node)) return;\n\n handlers.current.onInteractOutside?.(event);\n if (event.defaultPrevented) return;\n\n handlers.current.onDismiss();\n }\n\n document.addEventListener('pointerdown', onPointerDown);\n return () => document.removeEventListener('pointerdown', onPointerDown);\n }, [active, closeOnOutsidePress, panelRef]);\n\n // ── Focus trap ───────────────────────────────────────────────────────────────\n useEffect(() => {\n if (!active || !trapFocus) return;\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Tab' || !isTopmostRef.current) return;\n const panel = panelRef.current;\n if (!panel) return;\n\n const items = tabbable(panel);\n if (items.length === 0) {\n // Nothing to cycle between, but Tab must still not escape the dialog.\n event.preventDefault();\n panel.focus({ preventScroll: true });\n return;\n }\n\n const first = items[0];\n const last = items[items.length - 1];\n const activeElement = document.activeElement;\n const inside = panel.contains(activeElement);\n\n if (event.shiftKey && (activeElement === first || !inside)) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && (activeElement === last || !inside)) {\n event.preventDefault();\n first.focus();\n }\n }\n\n // The keydown boundary check above only catches the moment focus is *about* to leave.\n // Focus can also arrive outside by a route Tab never sees — a click on the scrim, a\n // programmatic `.focus()`, or a round trip through the browser chrome. This pulls it\n // back whenever that happens.\n function onFocusIn(event: FocusEvent) {\n if (!isTopmostRef.current) return;\n const panel = panelRef.current;\n if (!panel) return;\n if (panel.contains(event.target as Node)) return;\n\n const items = tabbable(panel);\n (items[0] ?? panel).focus({ preventScroll: true });\n }\n\n document.addEventListener('keydown', onKeyDown);\n document.addEventListener('focusin', onFocusIn);\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n document.removeEventListener('focusin', onFocusIn);\n };\n }, [active, trapFocus, panelRef]);\n\n // ── Initial focus and restore ────────────────────────────────────────────────\n useEffect(() => {\n if (!active) return;\n\n const previouslyFocused = document.activeElement as HTMLElement | null;\n const panel = panelRef.current;\n let observer: MutationObserver | null = null;\n\n if (panel && autoFocus) {\n // A content-only dialog has nothing tabbable, and `focus()` on an element without\n // a tabindex silently does nothing. Making the panel itself focusable is what turns\n // the fallback below into a real focus move.\n if (!panel.hasAttribute('tabindex')) panel.setAttribute('tabindex', '-1');\n\n const focusTarget = () => {\n const explicit = initialFocus?.current;\n if (explicit) {\n explicit.focus({ preventScroll: true });\n return true;\n }\n const items = tabbable(panel);\n if (items.length > 0) {\n items[0].focus({ preventScroll: true });\n return true;\n }\n return false;\n };\n\n if (!focusTarget()) {\n panel.focus({ preventScroll: true });\n\n // Panel content can arrive after mount — a fetch, a Suspense boundary. Watch for\n // the first tabbable element and move focus onto it once, then stop.\n observer = new MutationObserver(() => {\n if (focusTarget()) {\n observer?.disconnect();\n observer = null;\n }\n });\n observer.observe(panel, { childList: true, subtree: true });\n }\n }\n\n return () => {\n observer?.disconnect();\n // Reading `returnFocus.current` at cleanup time is the intent, not an oversight:\n // the element to return focus to may not exist when the overlay mounts, and the\n // caller may repoint it while the overlay is open.\n //\n // A caller that passes the ref owns the decision outright, `null` included — `??`\n // here instead of the ternary made `{ current: null }` mean \"restore to whatever\n // was focused before\", the exact opposite of what the one caller passing it wanted.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const target = returnFocus ? returnFocus.current : previouslyFocused;\n // A detached node's `focus()` is a silent no-op that leaves focus on <body>, which\n // strands keyboard users at the top of the page. Better to leave focus where the\n // browser put it than to pretend.\n if (target?.isConnected) target.focus({ preventScroll: true });\n };\n }, [active, panelRef, initialFocus, returnFocus, autoFocus]);\n}\n\n/** `event`, except that `preventDefault()` calls `onVeto` and `defaultPrevented` reports it. */\nfunction vetoable(event: KeyboardEvent, onVeto: () => void): KeyboardEvent {\n let vetoed = false;\n return new Proxy(event, {\n get(target, key) {\n if (key === 'preventDefault') {\n return () => {\n vetoed = true;\n onVeto();\n };\n }\n if (key === 'defaultPrevented') return vetoed;\n const value: unknown = Reflect.get(target, key, target);\n return typeof value === 'function' ? value.bind(target) : value;\n },\n });\n}\n","import { useEffect, useRef, useState, type RefObject } from 'react';\n\n/**\n * A process-wide stack of the overlays currently mounted, plus the two document-level\n * side effects that belong to \"there is a dialog open\": scroll lock and an inert\n * background.\n *\n * Why a stack rather than per-overlay listeners. Before 0.4.0 every overlay attached its\n * own `keydown` handler to `document`. `useOverlayDismiss` called `e.stopPropagation()`\n * on Escape, which stops propagation *to other nodes* — it does not stop the other\n * listeners already registered on the same node. All of them were on `document`. So a\n * `DropdownMenu` open inside a `Modal` closed both on one Escape, and two stacked modals\n * closed together. Ordering has to be decided centrally, by asking \"am I topmost?\",\n * which is what this module answers.\n */\n\ntype Layer = { id: symbol };\n\nconst layers: Layer[] = [];\nconst listeners = new Set<() => void>();\n\nfunction notify() {\n for (const listener of listeners) listener();\n}\n\nfunction topmost(): symbol | undefined {\n return layers[layers.length - 1]?.id;\n}\n\n// ── Escape inside a Radix surface ─────────────────────────────────────────────\n\nconst deferredEscapes = new WeakSet<Event>();\n\n/**\n * For a Radix surface's `onEscapeKeyDown`: returns `true` and vetoes Radix's dismissal when the\n * Escape belongs to a popup open inside the surface instead.\n *\n * Radix layers listen for Escape on `document` in the capture phase, so they hear it before\n * anything inside them. A Select or Combobox open in a Modal lost the key to the Modal: one\n * Escape closed the dialog, and the Select's list stayed open over the page. The Escape is\n * claimed when a custom layer (Select's list) is open, or when it was pressed on an expanded\n * combobox, whose own key handler closes its list.\n *\n * Vetoing means `preventDefault()`, the only signal Radix reads, so the event is also recorded:\n * {@link isEscapeDeferred} lets `useOverlayDismiss` tell this veto apart from a real one.\n */\nexport function deferEscapeToInnerPopup(event: KeyboardEvent): boolean {\n const target = event.target;\n const fromOpenCombobox =\n target instanceof Element && target.closest('[role=\"combobox\"][aria-expanded=\"true\"]') !== null;\n if (layers.length === 0 && !fromOpenCombobox) return false;\n deferredEscapes.add(event);\n event.preventDefault();\n return true;\n}\n\n/** Whether a Radix surface passed this Escape on with {@link deferEscapeToInnerPopup}. */\nexport function isEscapeDeferred(event: Event): boolean {\n return deferredEscapes.has(event);\n}\n\n// ── Scroll lock ────────────────────────────────────────────────────────────────\n\nlet scrollLocks = 0;\nlet restoreBody: (() => void) | null = null;\n\nfunction lockScroll() {\n scrollLocks += 1;\n if (scrollLocks > 1 || typeof document === 'undefined') return;\n\n const { body, documentElement } = document;\n const previousOverflow = body.style.overflow;\n const previousPaddingRight = body.style.paddingRight;\n\n // Removing the scrollbar reflows the page a few pixels narrower, which reads as the\n // whole layout twitching sideways as the dialog appears. Pad by exactly the width the\n // scrollbar occupied to hold everything still.\n const scrollbarWidth = window.innerWidth - documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n const current = parseFloat(window.getComputedStyle(body).paddingRight) || 0;\n body.style.paddingRight = `${current + scrollbarWidth}px`;\n }\n body.style.overflow = 'hidden';\n\n restoreBody = () => {\n body.style.overflow = previousOverflow;\n body.style.paddingRight = previousPaddingRight;\n };\n}\n\nfunction unlockScroll() {\n scrollLocks = Math.max(0, scrollLocks - 1);\n if (scrollLocks === 0 && restoreBody) {\n restoreBody();\n restoreBody = null;\n }\n}\n\n// ── Inert background ───────────────────────────────────────────────────────────\n\nconst inerted = new Set<HTMLElement>();\n\n/**\n * Marks every top-level sibling of the overlay's own subtree `inert`, which removes it\n * from the accessibility tree *and* from the tab sequence in one attribute.\n *\n * `aria-modal=\"true\"` alone — all this library had before — is honoured by modern screen\n * readers for virtual-cursor browsing but does nothing about focus, and older AT ignores\n * it entirely. `inert` is the actual guarantee.\n */\nfunction applyInert(node: HTMLElement | null) {\n if (typeof document === 'undefined' || !node) return;\n\n // Walk up to whichever direct child of <body> contains this overlay, so the overlay's\n // own portal container is the one subtree left interactive.\n let root: HTMLElement = node;\n while (root.parentElement && root.parentElement !== document.body) {\n root = root.parentElement;\n }\n\n for (const child of Array.from(document.body.children)) {\n if (child === root || !(child instanceof HTMLElement)) continue;\n if (child.hasAttribute('inert')) continue;\n child.setAttribute('inert', '');\n inerted.add(child);\n }\n}\n\nfunction releaseInert() {\n for (const el of inerted) el.removeAttribute('inert');\n inerted.clear();\n}\n\n// ── Hook ───────────────────────────────────────────────────────────────────────\n\nexport interface UseOverlayLayerOptions {\n /** Prevent the page behind from scrolling. Default `true`. */\n lockScroll?: boolean;\n /**\n * Mark sibling content `inert`. Default `true`. Turn it off for non-modal surfaces —\n * a tooltip or a popover must leave the rest of the page usable.\n */\n inertBackground?: boolean;\n /**\n * Ref to the panel element, used to work out which subtree to leave interactive.\n *\n * Deliberately the ref object rather than the node: a node read during render is\n * always `null` on the first pass, and nothing re-renders the consumer once the ref\n * is attached, so the inert pass would never run. Effects read `.current` after the\n * DOM is committed, where it is populated.\n */\n panelRef?: RefObject<HTMLElement | null>;\n}\n\n/**\n * Registers a mounted overlay with the stack.\n *\n * Returns `isTopmost`, which every dismissal handler must gate on so only the frontmost\n * layer reacts to Escape or an outside pointer press.\n */\nexport function useOverlayLayer(\n active: boolean,\n {\n lockScroll: shouldLockScroll = true,\n inertBackground = true,\n panelRef,\n }: UseOverlayLayerOptions = {},\n): { isTopmost: boolean } {\n const id = useRef<symbol>();\n if (!id.current) id.current = Symbol('overlay-layer');\n\n const [isTopmost, setIsTopmost] = useState(false);\n\n useEffect(() => {\n if (!active) return;\n const self = id.current!;\n\n layers.push({ id: self });\n\n const sync = () => setIsTopmost(topmost() === self);\n listeners.add(sync);\n sync();\n notify();\n\n if (shouldLockScroll) lockScroll();\n\n return () => {\n const index = layers.findIndex((layer) => layer.id === self);\n if (index !== -1) layers.splice(index, 1);\n listeners.delete(sync);\n notify();\n if (shouldLockScroll) unlockScroll();\n };\n }, [active, shouldLockScroll]);\n\n useEffect(() => {\n if (!active || !inertBackground) return;\n // Only the bottom-most modal layer needs to set this: it already hides everything\n // outside the overlay tree, and every overlay above it portals into the same root.\n if (inerted.size === 0) applyInert(panelRef?.current ?? null);\n return () => {\n if (layers.length <= 1) releaseInert();\n };\n }, [active, inertBackground, panelRef]);\n\n return { isTopmost };\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport interface PortalProps {\n children: ReactNode;\n /**\n * Where to mount. Defaults to the nearest `PortalContainerProvider`, else `document.body`.\n *\n * Pass a container when the app renders inside a shadow root or a scoped theme\n * wrapper — the portal must stay inside whatever element the design tokens are\n * declared on, or every `var(--color-*)` resolves to nothing.\n */\n container?: HTMLElement | null;\n}\n\n/**\n * The default mount point for every `Portal` beneath it.\n *\n * A Radix modal (`Modal`, `Drawer`) traps focus inside its content, hides everything else\n * from assistive tech and treats a press anywhere else as \"outside\". A floating panel that\n * is not itself built on Radix, such as `Combobox`'s listbox or a `DatePicker` calendar,\n * would portal to `document.body` and land in exactly that \"everything else\": focus would be\n * pulled back out of it, and choosing an option would close the dialog. So each Radix modal\n * provides its own content node here, and those panels portal inside the dialog instead.\n * They position with `strategy: 'fixed'`, so the dialog's scroll container does not clip them.\n */\nconst PortalContainerContext = createContext<HTMLElement | null>(null);\n\nexport function PortalContainerProvider({\n container,\n children,\n}: {\n container: HTMLElement | null;\n children: ReactNode;\n}) {\n return (\n <PortalContainerContext.Provider value={container}>{children}</PortalContainerContext.Provider>\n );\n}\n\n/** The container a `Portal` here would mount into, for Radix parts that take `container`. */\nexport function usePortalContainer(): HTMLElement | null {\n return useContext(PortalContainerContext);\n}\n\n/**\n * Renders `children` outside the parent DOM hierarchy.\n *\n * Until 0.4.0 this library never called `createPortal` — `Modal`, `Drawer`,\n * `DropdownMenu`, `RoleComboBox` and the sidebar menu all rendered inline. Two concrete\n * failures came out of that:\n *\n * - `DropdownMenu` was positioned `absolute` inside a `relative` wrapper, so it was\n * clipped by `Card`'s `overflow-hidden` and by `DataTable`'s `overflow-x-auto` — the\n * two places its own doc comment said it was for.\n * - `position: fixed` resolves against the nearest ancestor with `transform`, `filter`,\n * `backdrop-filter`, `perspective`, `will-change` or `contain`, so a `Modal` opened\n * from inside any transformed ancestor was positioned against that ancestor rather\n * than the viewport, and `z-50` was scoped to a stacking context it did not control.\n *\n * Mounting is deferred to an effect so the server render and the first client render\n * agree — reaching for `document` during render breaks SSR and hydration.\n */\nexport function Portal({ children, container }: PortalProps) {\n const [mounted, setMounted] = useState(false);\n const contextContainer = useContext(PortalContainerContext);\n\n useEffect(() => setMounted(true), []);\n\n if (!mounted) return null;\n\n const target =\n container ?? contextContainer ?? (typeof document === 'undefined' ? null : document.body);\n if (!target) return null;\n\n return createPortal(children, target);\n}\n","import { forwardRef, type InputHTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { CalendarIcon } from 'lucide-react';\nimport { type InputSize } from './input';\nimport { useControlSize } from './control-size';\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldHint,\n FieldLabel,\n useFieldControl,\n} from './field';\n\nexport interface DatePickerProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n label?: string;\n description?: string;\n /** Red border + message shown below the control. Also sets `aria-invalid`. */\n error?: string;\n hint?: string;\n size?: InputSize;\n}\n\nconst inputBase: Record<InputSize, string> = {\n lg: 'h-12 px-5 py-3.5 pr-12 text-body',\n md: 'h-9 px-4 py-2.5 pr-8 text-body-sm',\n sm: 'h-6 px-3 py-[5px] pr-6 text-body-tiny',\n};\n\nconst iconWrap: Record<InputSize, { right: string; size: string }> = {\n lg: { right: 'right-4', size: 'size-5' },\n md: { right: 'right-3', size: 'size-4' },\n sm: { right: 'right-2', size: 'size-3' },\n};\n\n/**\n * A native `<input type=\"date\">`.\n *\n * The `::-webkit-calendar-picker-indicator` styling below is Chromium-only — on Firefox\n * and Safari the native affordance differs, so the drawn `CalendarIcon` sits alongside\n * whatever the platform renders rather than replacing it. That is a known limitation of\n * this component, not a bug to paper over: for a real month grid, range selection, locale\n * control or min/max navigation, use `Calendar` and `DateField` instead.\n */\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(function DatePicker(\n { label, description, error, hint, size: sizeProp, className, disabled, required, id, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasError = !!error;\n const iw = iconWrap[size];\n\n return (\n <Field\n id={id}\n size={size}\n disabled={disabled}\n required={required}\n hasDescription={!!description}\n hasError={hasError}\n hasHint={!!hint}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n {description && <FieldDescription>{description}</FieldDescription>}\n <div className=\"relative flex items-center\">\n <DateInput\n ref={ref}\n size={size}\n invalid={hasError}\n disabled={disabled}\n required={required}\n {...props}\n />\n <span\n aria-hidden\n className={clsx(\n 'pointer-events-none absolute',\n iw.right,\n iw.size,\n 'flex items-center justify-center',\n disabled ? 'text-icon-disabled' : 'text-icon-default-secondary',\n )}\n >\n <CalendarIcon className=\"size-full\" />\n </span>\n </div>\n {hasError && <FieldError>{error}</FieldError>}\n {!hasError && hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n});\n\ninterface DateInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n size?: InputSize;\n invalid?: boolean;\n}\n\nconst DateInput = forwardRef<HTMLInputElement, DateInputProps>(function DateInput(\n { size: sizeProp, invalid = false, className, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const field = useFieldControl();\n const isInvalid = invalid || !!field['aria-invalid'];\n const isDisabled = props.disabled ?? field.disabled;\n\n return (\n <input\n ref={ref}\n type=\"date\"\n {...field}\n className={clsx(\n 'w-full rounded-lg border outline-none transition-colors',\n 'bg-default text-default',\n 'focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n '[&::-webkit-calendar-picker-indicator]:opacity-0',\n '[&::-webkit-calendar-picker-indicator]:absolute',\n '[&::-webkit-calendar-picker-indicator]:right-0',\n '[&::-webkit-calendar-picker-indicator]:h-full',\n '[&::-webkit-calendar-picker-indicator]:w-10',\n '[&::-webkit-calendar-picker-indicator]:cursor-pointer',\n inputBase[size],\n isDisabled\n ? 'cursor-not-allowed border-disabled bg-disabled text-disabled'\n : isInvalid\n ? 'border-danger-secondary focus-visible:border-danger focus-visible:ring-danger'\n : 'border-default focus-visible:border-brand focus-visible:ring-brand',\n className,\n )}\n {...props}\n />\n );\n});\n","import clsx from 'clsx';\nimport { CheckIcon, ChevronRightIcon } from 'lucide-react';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\nexport type StepStatus = 'complete' | 'active' | 'upcoming';\n\nexport interface StepItem {\n label: string;\n status: StepStatus;\n}\n\nexport type StepperSize = 'sm' | 'md';\n\nexport interface StepperProps {\n steps: StepItem[];\n /** Matches Figma's `Size` axis on the `Stepper` component set. */\n size?: StepperSize;\n /** Names the list. Defaults to `Progress`. Override for a non-English UI. */\n label?: string;\n className?: string;\n}\n\n/**\n * Status words announced after each step's label.\n *\n * Step status was conveyed by colour plus an `aria-hidden` glyph only, so \"complete\" and\n * \"upcoming\" were indistinguishable to a screen reader — `aria-current=\"step\"` marked the\n * active one and nothing said which of the rest were done.\n */\nconst STATUS_TEXT: Record<StepStatus, string> = {\n complete: 'completed',\n active: 'current step',\n upcoming: 'not started',\n};\n\nconst SIZE: Record<StepperSize, { indicator: string; glyph: number; label: string }> = {\n sm: { indicator: 'size-4', glyph: 9, label: 'text-body-tiny' },\n md: { indicator: 'size-5', glyph: 11, label: 'text-body-xs' },\n};\n\nfunction StepIndicator({ status, size }: { status: StepStatus; size: StepperSize }) {\n const s = SIZE[size];\n\n if (status === 'complete') {\n return (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full bg-brand text-brand-on-brand',\n s.indicator,\n )}\n >\n <CheckIcon size={s.glyph} />\n </span>\n );\n }\n\n if (status === 'active') {\n return (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full border-2 border-brand-emphasis',\n s.indicator,\n )}\n >\n <span className=\"size-2.5 rounded-full bg-brand\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden\n className={clsx('shrink-0 rounded-full border-2 border-disabled', s.indicator)}\n />\n );\n}\n\nfunction ChevronSeparator() {\n return <ChevronRightIcon className=\"mx-1 size-4 shrink-0 text-default-tertiary\" aria-hidden />;\n}\n\nconst labelClass: Record<StepStatus, string> = {\n complete: 'text-brand font-semibold',\n active: 'text-brand font-semibold',\n upcoming: 'text-disabled font-regular',\n};\n\nexport function Stepper({ steps, size = 'md', label = 'Progress', className }: StepperProps) {\n const s = SIZE[size];\n\n return (\n // An <ol> cannot be wrapped without breaking the list relationship with its <li>s.\n <ol\n className={clsx('flex items-center overflow-x-auto', SCROLLBAR_CLASSES, className)}\n aria-label={label}\n >\n {steps.map((step, i) => (\n <li\n // Keyed by label rather than index, so reordering or inserting a step does not\n // reuse the wrong element's state.\n key={step.label}\n className=\"flex items-center\"\n aria-current={step.status === 'active' ? 'step' : undefined}\n >\n <span className=\"flex items-center gap-1.5\">\n <StepIndicator status={step.status} size={size} />\n <span className={clsx('whitespace-nowrap', s.label, labelClass[step.status])}>\n {step.label}\n </span>\n <span className=\"sr-only\">, {STATUS_TEXT[step.status]}</span>\n </span>\n {i < steps.length - 1 && <ChevronSeparator />}\n </li>\n ))}\n </ol>\n );\n}\n","import clsx from 'clsx';\nimport { type ReactNode } from 'react';\nimport { CheckIcon } from 'lucide-react';\n\n/** Matches Figma's `Size` axis on `Multiselect Card` (`Default | Small`). */\nexport type MultiSelectCardSize = 'default' | 'sm';\n\nexport interface MultiSelectCardProps {\n icon: ReactNode;\n title: string;\n description?: string;\n selected: boolean;\n onToggle: () => void;\n /**\n * Figma has had this axis since 0.2.0; the 0.3.0 CHANGELOG recorded it as \"left alone\n * pending a design decision\". `Default` and `Small` differ only in padding, icon box and\n * type step, so there was nothing to decide.\n */\n size?: MultiSelectCardSize;\n disabled?: boolean;\n className?: string;\n}\n\nconst SIZE: Record<\n MultiSelectCardSize,\n { pad: string; iconBox: string; icon: string; mark: string; gap: string; title: string }\n> = {\n default: {\n pad: 'p-4',\n iconBox: 'size-10 rounded-xl',\n icon: 'size-5',\n mark: 'size-5',\n gap: 'mt-3',\n title: 'text-body-sm',\n },\n sm: {\n pad: 'p-3',\n iconBox: 'size-8 rounded-lg',\n icon: 'size-4',\n mark: 'size-4',\n gap: 'mt-2',\n title: 'text-body-xs',\n },\n};\n\nexport function MultiSelectCard({\n icon,\n title,\n description,\n selected,\n onToggle,\n size = 'default',\n disabled = false,\n className,\n}: MultiSelectCardProps) {\n const s = SIZE[size];\n\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={selected}\n disabled={disabled}\n onClick={onToggle}\n className={clsx(\n 'relative w-full rounded-2xl border-2 text-left transition-all',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:opacity-60',\n s.pad,\n selected\n ? 'border-brand bg-brand-tertiary'\n : 'border-default bg-default hover:border-default-secondary',\n className,\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center',\n s.iconBox,\n selected ? 'bg-brand' : 'bg-brand-tertiary',\n )}\n >\n <span className={clsx(s.icon, selected ? 'text-icon-brand-on-brand' : 'text-icon-brand')}>\n {icon}\n </span>\n </span>\n\n {selected ? (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full bg-brand text-icon-brand-on-brand',\n s.mark,\n )}\n >\n <CheckIcon className=\"size-3\" strokeWidth={2.5} />\n </span>\n ) : (\n <span\n aria-hidden\n className={clsx('shrink-0 rounded-full border-2 border-default', s.mark)}\n />\n )}\n </div>\n\n <div className={s.gap}>\n <p className={clsx('font-semibold', s.title, selected ? 'text-brand' : 'text-default')}>\n {title}\n </p>\n {description && (\n <p className=\"mt-0.5 text-body-tiny text-default-secondary\">{description}</p>\n )}\n </div>\n </button>\n );\n}\n","import { forwardRef, useId, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { composeEventHandlers } from '../../lib/compose-event-handlers';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type SwitchSize = 'sm' | 'md';\n\nexport interface SwitchProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value' | 'type'> {\n /** Controlled. Omit and pass `defaultChecked` for uncontrolled. */\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Visible text beside the switch. Doubles as the accessible name. */\n label?: ReactNode;\n /** Second line under the label. Matches Figma's `Supporting text` axis. */\n description?: ReactNode;\n /** Track size. `sm` is 36×20, `md` is 44×24. */\n size?: SwitchSize;\n /**\n * Submits with a surrounding form, as `name=value` while on. New in 0.7.0: through 0.6 a\n * Switch posted nothing, so it could not take part in a plain form.\n */\n name?: string;\n /** The value posted while on. Default `\"on\"`, as for a native checkbox. */\n value?: string;\n required?: boolean;\n}\n\n/**\n * Track / knob geometry, straight from the Figma `_Toggle base` component (see the naming\n * note below). The knob sits on a 2px inset, so travel = track width − knob − (2 × inset).\n */\nconst SIZE: Record<SwitchSize, { track: string; knob: string; translate: string }> = {\n sm: { track: 'h-5 w-9', knob: 'size-4', translate: 'translate-x-4' },\n md: { track: 'h-6 w-11', knob: 'size-5', translate: 'translate-x-5' },\n};\n\n/**\n * An on/off switch — a setting that takes effect immediately, with no save step.\n *\n * **Renamed from `Toggle` in 0.4.0.** It was always a switch: `role=\"switch\"`,\n * `aria-checked`, and the track/knob geometry taken from Figma. The name was blocking,\n * because \"Toggle\" means something else in shadcn/ui and in most design systems — a\n * pressed-state *button*, like a bold button in a text toolbar. That component now exists\n * here under the name everyone expects, and the two are not interchangeable:\n *\n * - `Switch` — `role=\"switch\"`, \"on\"/\"off\", applies immediately. A setting.\n * - `Toggle` — `aria-pressed`, \"pressed\"/\"not pressed\". A button whose effect persists.\n *\n * Figma calls its set `Toggle` with a `Pressed` axis, but its geometry and `_Toggle base`\n * match this component exactly, so Figma's `Toggle` **is** this switch. Figma has no\n * pressed-button equivalent yet; that is a gap on the design side, recorded in the\n * CHANGELOG rather than papered over here.\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(function Switch(\n {\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n label,\n description,\n size = 'md',\n disabled = false,\n name,\n value = 'on',\n required,\n id,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n onClick,\n ...rest\n },\n ref,\n) {\n const [checked, setChecked] = useControllableState({\n value: checkedProp,\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n });\n\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n const s = SIZE[size];\n\n const control = (\n <button\n ref={ref}\n type=\"button\"\n role=\"switch\"\n id={controlId}\n aria-checked={checked}\n data-state={checked ? 'checked' : 'unchecked'}\n // With no visible label the switch would otherwise ship with no accessible name.\n aria-label={label ? undefined : ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={description ? descriptionId : undefined}\n disabled={disabled}\n onClick={composeEventHandlers(onClick, () => setChecked(!checked))}\n className={clsx(\n 'group flex items-center gap-2',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n disabled && 'cursor-not-allowed opacity-50',\n !description && !name && className,\n )}\n {...rest}\n >\n <span\n aria-hidden\n className={clsx(\n 'relative inline-flex shrink-0 rounded-full transition-colors',\n s.track,\n // The unchecked track is borderless per the spec. A border here would also shift\n // the knob's rendered inset by 1px between states, since the knob is positioned\n // against the padding box.\n disabled\n ? 'bg-disabled'\n : checked\n ? 'bg-brand group-hover:bg-brand-hover'\n : 'bg-default-secondary group-hover:bg-default-secondary-hover',\n )}\n >\n <span\n className={clsx(\n 'absolute left-0.5 top-0.5 rounded-full bg-default shadow-100 transition-transform',\n s.knob,\n checked ? s.translate : 'translate-x-0',\n )}\n />\n </span>\n {label && <span className=\"text-body-xs text-default\">{label}</span>}\n </button>\n );\n\n /*\n * Form participation: a real checkbox, invisible and out of the tab order and the\n * accessibility tree, mirroring the switch. A checkbox rather than a hidden input, so it\n * posts only while on and `required` is validated, exactly as a native checkbox would be.\n * Not Radix Switch: it measures its control with an unguarded ResizeObserver inside a form,\n * which crashes every consumer's jsdom tests that lack a polyfill.\n */\n const formInput = name ? (\n <input\n type=\"checkbox\"\n aria-hidden\n tabIndex={-1}\n name={name}\n value={value}\n checked={checked}\n required={required}\n disabled={disabled}\n onChange={() => {}}\n className=\"pointer-events-none absolute size-px opacity-0\"\n />\n ) : null;\n\n if (!description) {\n return formInput ? (\n <span className={clsx('relative inline-flex', className)}>\n {control}\n {formInput}\n </span>\n ) : (\n control\n );\n }\n\n return (\n <div className={clsx('relative flex flex-col', className)}>\n {control}\n {formInput}\n {/* Outside the button, so it is not folded into the accessible name — the same\n reasoning as `Checkbox` and `Radio`. Indented past the track. */}\n <span\n id={descriptionId}\n className={clsx(\n 'mt-0.5 text-body-tiny',\n size === 'md' ? 'pl-[52px]' : 'pl-[44px]',\n disabled ? 'text-disabled' : 'text-default-secondary',\n )}\n >\n {description}\n </span>\n </div>\n );\n});\n","/**\n * Runs a consumer's event handler, then the component's own, unless the consumer called\n * `preventDefault()`. The same contract Radix uses, so behaviour is uniform across the\n * library.\n *\n * Use it wherever a component has its own handler for an event that consumers may also pass.\n * The bug it exists for appeared in five 0.6 components: the built-in handler was written as\n * a JSX attribute and `{...rest}` was spread after it, so a consumer's `onClick` or `onKeyDown`\n * silently replaced the toggle, the arrow keys or the roving focus.\n */\nexport function composeEventHandlers<E extends { defaultPrevented: boolean }>(\n theirs: ((event: E) => void) | undefined,\n ours: (event: E) => void,\n): (event: E) => void {\n return (event) => {\n theirs?.(event);\n if (!event.defaultPrevented) ours(event);\n };\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useMemo,\n useRef,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\n\nexport type ToggleSize = 'sm' | 'md' | 'lg';\nexport type ToggleVariant = 'ghost' | 'outline';\n\nconst SIZE: Record<ToggleSize, string> = {\n sm: 'h-8 min-w-8 px-2 text-body-tiny [&_svg]:size-3.5',\n md: 'h-9 min-w-9 px-2.5 text-body-xs [&_svg]:size-4',\n lg: 'h-11 min-w-11 px-3 text-body-sm [&_svg]:size-5',\n};\n\nconst VARIANT: Record<ToggleVariant, string> = {\n ghost: 'border border-transparent bg-transparent',\n outline: 'border border-default bg-default',\n};\n\nexport interface ToggleProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'type'> {\n /** Controlled pressed state. Omit and pass `defaultPressed` for uncontrolled. */\n pressed?: boolean;\n defaultPressed?: boolean;\n onPressedChange?: (pressed: boolean) => void;\n size?: ToggleSize;\n variant?: ToggleVariant;\n children?: ReactNode;\n}\n\n/**\n * A button with a sticky pressed state — bold in a text toolbar, a map layer on/off, a\n * filter that stays applied.\n *\n * **New in 0.4.0, and not what `Toggle` used to be.** Through 0.3.0 this name belonged to\n * the on/off switch, which is now `Switch`. The two look similar and mean different things:\n *\n * - `Toggle` — `aria-pressed`. A *button*. \"Bold is pressed.\"\n * - `Switch` — `role=\"switch\"` + `aria-checked`. A *setting*. \"Notifications are on.\"\n *\n * `aria-pressed` rather than `aria-checked` is the whole distinction as far as assistive\n * tech is concerned, and it is why this is not just `Switch` with different styling.\n *\n * An icon-only toggle needs `aria-label`, exactly as `IconButton` does — there is no visible\n * text to name it.\n */\nexport const Toggle = forwardRef<HTMLButtonElement, ToggleProps>(function Toggle(\n {\n pressed: pressedProp,\n defaultPressed = false,\n onPressedChange,\n size = 'md',\n variant = 'ghost',\n disabled,\n children,\n className,\n onClick,\n ...rest\n },\n ref,\n) {\n const group = useContext(ToggleGroupContext);\n\n // Inside a ToggleGroup the group owns the state; standalone it owns its own.\n const [standalonePressed, setStandalonePressed] = useControllableState({\n value: pressedProp,\n defaultValue: defaultPressed,\n onChange: onPressedChange,\n });\n\n const pressed = group ? group.isPressed(rest.value as string) : standalonePressed;\n const isDisabled = disabled ?? group?.disabled;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n {...rest}\n // After the spread, so a consumer's handler runs alongside the toggle. Through 0.6\n // `rest` came last and an `onClick` replaced it, so the toggle stopped toggling.\n aria-pressed={pressed}\n data-state={pressed ? 'on' : 'off'}\n disabled={isDisabled}\n onClick={(event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n if (group) group.toggle(rest.value as string);\n else setStandalonePressed(!pressed);\n }}\n className={cn(\n 'inline-flex shrink-0 items-center justify-center gap-1.5 rounded-lg font-medium transition-colors',\n FOCUS_RING,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n SIZE[size],\n VARIANT[variant],\n // Pressed state styled from the attribute it is announced by.\n 'text-default-secondary hover:bg-default-secondary hover:text-default',\n 'aria-pressed:border-brand-tertiary aria-pressed:bg-brand-tertiary aria-pressed:text-brand',\n 'aria-pressed:hover:bg-brand-tertiary aria-pressed:hover:text-brand',\n className,\n )}\n >\n {children}\n </button>\n );\n});\n\n// ── ToggleGroup ────────────────────────────────────────────────────────────────\n\nexport type ToggleGroupType = 'single' | 'multiple';\n\ninterface ToggleGroupContextValue {\n isPressed: (value: string) => boolean;\n toggle: (value: string) => void;\n disabled?: boolean;\n /** Items claim a roving index in render order, which is their visual order. */\n claimIndex: () => number;\n roving: ReturnType<typeof useRovingFocus>;\n}\n\nconst ToggleGroupContext = createContext<ToggleGroupContextValue | null>(null);\n\nexport interface ToggleGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n children: ReactNode;\n /** `single` behaves like a radio group; `multiple` like a set of checkboxes. */\n type?: ToggleGroupType;\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n /** Names the group. Required by the APG for a toolbar-style group. */\n label: string;\n disabled?: boolean;\n orientation?: 'horizontal' | 'vertical';\n}\n\n/**\n * A set of related toggles sharing one selection.\n *\n * `role=\"group\"` with `aria-pressed` on each child, and a roving tabindex so the set is one\n * tab stop with arrow keys inside — the same contract `SegmentedControl` was missing before\n * 0.4.0.\n *\n * How this differs from the neighbours, since three components in this library now look\n * similar: `SegmentedControl` is a `radiogroup` for choosing *one* of a small set of views,\n * and always has exactly one selection. `ToggleGroup type=\"multiple\"` allows none or many.\n * `ToggleGroup type=\"single\"` allows none or one — the deselectable case a radio group\n * cannot express.\n */\nexport function ToggleGroup({\n children,\n type = 'single',\n value: valueProp,\n defaultValue,\n onValueChange,\n label,\n disabled,\n orientation = 'horizontal',\n className,\n ...rest\n}: ToggleGroupProps) {\n const [value, setValue] = useControllableState<string | string[]>({\n value: valueProp,\n defaultValue: defaultValue ?? (type === 'multiple' ? [] : ''),\n onChange: onValueChange,\n });\n\n const roving = useRovingFocus({\n orientation: orientation === 'vertical' ? 'vertical' : 'horizontal',\n loop: true,\n });\n\n const cursor = useRef(0);\n\n const context = useMemo<ToggleGroupContextValue>(\n () => ({\n isPressed: (itemValue) =>\n Array.isArray(value) ? value.includes(itemValue) : value === itemValue,\n toggle: (itemValue) => {\n if (type === 'multiple') {\n const list = Array.isArray(value) ? value : [];\n setValue(\n list.includes(itemValue) ? list.filter((v) => v !== itemValue) : [...list, itemValue],\n );\n return;\n }\n // Single mode deselects on re-press — the behaviour a radiogroup cannot offer.\n setValue(value === itemValue ? '' : itemValue);\n },\n disabled,\n claimIndex: () => cursor.current++,\n roving,\n }),\n [value, setValue, type, disabled, roving],\n );\n\n // Reset before the children's render bodies run, so indices restart from zero each pass.\n cursor.current = 0;\n\n return (\n <ToggleGroupContext.Provider value={context}>\n <div\n role=\"group\"\n aria-label={label}\n // No `aria-orientation`: `role=\"group\"` does not support it. The orientation only\n // affects which arrow keys move focus, which the roving hook already knows —\n // announcing it here would be an invalid attribute for the role.\n data-slot=\"toggle-group\"\n className={clsx(\n 'inline-flex gap-0.5',\n orientation === 'vertical' ? 'flex-col' : 'flex-row items-center',\n className,\n )}\n {...roving.containerProps}\n {...rest}\n >\n {children}\n </div>\n </ToggleGroupContext.Provider>\n );\n}\n\nexport interface ToggleGroupItemProps extends Omit<ToggleProps, 'pressed' | 'defaultPressed'> {\n value: string;\n}\n\n/** A `Toggle` wired to its `ToggleGroup`, with the roving tabindex applied. */\nexport const ToggleGroupItem = forwardRef<HTMLButtonElement, ToggleGroupItemProps>(\n function ToggleGroupItem({ value, children, onFocus, ...rest }, ref) {\n const group = useContext(ToggleGroupContext);\n if (!group) throw new Error('<ToggleGroupItem> must be used inside <ToggleGroup>');\n\n const index = group.claimIndex();\n const { ref: rovingRef, ...itemProps } = group.roving.itemProps(index, {\n disabled: rest.disabled ?? group.disabled,\n label: typeof children === 'string' ? children : undefined,\n });\n\n return (\n <Toggle\n ref={composeRefs<HTMLButtonElement>(ref, rovingRef)}\n value={value}\n {...rest}\n {...itemProps}\n // The roving focus handler and the caller's both run. 0.6 spread `rest` last, so an\n // `onFocus` here silently broke the arrow-key position.\n onFocus={(event) => {\n onFocus?.(event);\n itemProps.onFocus();\n }}\n // Restated after the spread so it is statically visible, and so a group of five\n // toggles is one tab stop rather than five.\n tabIndex={itemProps.tabIndex}\n >\n {children}\n </Toggle>\n );\n },\n);\n","import {\n forwardRef,\n useId,\n useRef,\n useState,\n type ClipboardEvent as ReactClipboardEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n} from 'react';\nimport clsx from 'clsx';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type InputOTPMode = 'numeric' | 'alphanumeric';\n\nexport interface InputOTPProps {\n /** Number of characters. Default `6`. */\n length?: number;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Fired once the last slot is filled. */\n onComplete?: (value: string) => void;\n mode?: InputOTPMode;\n /** Draws a gap after this many slots — `3` for a `123 456` code. */\n groupAfter?: number;\n /** Accessible name. Default `Verification code`. */\n label?: string;\n disabled?: boolean;\n invalid?: boolean;\n autoFocus?: boolean;\n className?: string;\n}\n\n/**\n * A one-time-code field — the boxed digits from a 2FA or email-verification flow.\n *\n * **One real input, N drawn boxes.** The obvious implementation is N separate `<input>`s,\n * and it is the wrong one: it makes the code N tab stops, breaks paste (the browser puts all\n * six characters in the first box), fights password managers and SMS autofill, and announces\n * \"edit text, blank\" six times. Instead there is a single input holding the whole value —\n * with `autocomplete=\"one-time-code\"`, so iOS and Android offer the code from the incoming\n * message — rendered transparently over the boxes, which are decorative.\n *\n * That means paste, autofill, undo, selection and screen readers all get the real value, and\n * the caret position simply drives which box is highlighted.\n */\nexport const InputOTP = forwardRef<HTMLInputElement, InputOTPProps>(function InputOTP(\n {\n length = 6,\n value: valueProp,\n defaultValue = '',\n onValueChange,\n onComplete,\n mode = 'numeric',\n groupAfter,\n label = 'Verification code',\n disabled = false,\n invalid = false,\n autoFocus = false,\n className,\n },\n ref,\n) {\n const [value, setValue] = useControllableState({\n value: valueProp,\n defaultValue,\n onChange: onValueChange,\n });\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const describedById = useId();\n\n const pattern = mode === 'numeric' ? /[^0-9]/g : /[^a-zA-Z0-9]/g;\n\n const commit = (next: string) => {\n const cleaned = next.replace(pattern, '').slice(0, length);\n setValue(cleaned);\n if (cleaned.length === length) onComplete?.(cleaned);\n };\n\n const chars = value.split('');\n // The caret sits on the first empty slot, or the last one when full.\n const activeIndex = Math.min(value.length, length - 1);\n\n return (\n <div className={clsx('inline-flex flex-col gap-1.5', className)}>\n {/* Clicking any box focuses the single real input. Not a control itself and not\n focusable — the input stretched across it is the control, and it is already keyboard\n reachable, so no key handler belongs here. */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}\n <div\n className=\"relative inline-flex items-center gap-2\"\n onClick={() => inputRef.current?.focus()}\n >\n <input\n ref={composeRefs<HTMLInputElement>(inputRef, ref)}\n type=\"text\"\n inputMode={mode === 'numeric' ? 'numeric' : 'text'}\n // The one attribute that makes SMS and email autofill work on mobile.\n autoComplete=\"one-time-code\"\n autoCorrect=\"off\"\n spellCheck={false}\n maxLength={length}\n value={value}\n disabled={disabled}\n // Off by default; opt-in for the case this exists for — a verification screen whose\n // only purpose is entering the code that just arrived.\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedById}\n onChange={(event) => commit(event.target.value)}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n onKeyDown={(event: ReactKeyboardEvent<HTMLInputElement>) => {\n // Arrow keys would move the caret into the middle of the value, which has no\n // meaning here — the code is filled left to right.\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') event.preventDefault();\n }}\n onPaste={(event: ReactClipboardEvent<HTMLInputElement>) => {\n // Handled explicitly so a pasted \"123-456\" or \"123 456\" still works.\n event.preventDefault();\n commit(event.clipboardData.getData('text'));\n }}\n // Transparent and stretched across the boxes: the real input stays where the\n // browser expects it (so autofill anchors correctly) while the boxes below are\n // what the user sees.\n className=\"absolute inset-0 z-raised w-full cursor-default bg-transparent text-transparent caret-transparent outline-none\"\n />\n\n {Array.from({ length }, (_, index) => (\n <span\n key={index}\n // Decorative: the input above holds the value and the accessible name.\n aria-hidden\n className={clsx(\n 'flex h-12 w-10 items-center justify-center rounded-lg border text-body font-semibold tabular-nums transition-colors',\n groupAfter && index === groupAfter && 'ml-3',\n disabled\n ? 'border-disabled bg-disabled text-disabled'\n : invalid\n ? 'border-danger-secondary bg-default text-default'\n : 'border-default bg-default text-default',\n focused &&\n !disabled &&\n index === activeIndex &&\n 'border-brand ring-2 ring-brand ring-offset-1 ring-offset-default',\n )}\n >\n {chars[index] ?? ''}\n </span>\n ))}\n </div>\n <span id={describedById} className=\"sr-only\">\n {`Enter the ${length}-character code. ${value.length} of ${length} entered.`}\n </span>\n </div>\n );\n});\n","import { useRef, useState, type InputHTMLAttributes, type RefObject } from 'react';\nimport clsx from 'clsx';\nimport { UploadIcon } from 'lucide-react';\n\nexport interface FileDropZoneProps {\n className?: string;\n /** Caption shown under \"Upload file\". Defaults to the generic document hint. */\n description?: string;\n accept?: string;\n /** Files above this size are rejected before any upload starts. */\n maxSizeBytes?: number;\n onFileSelected?: (file: File) => void;\n disabled?: boolean;\n}\n\nconst DEFAULT_ACCEPT = '.pdf,.jpg,.jpeg,.png';\nconst DEFAULT_MAX_SIZE_BYTES = 10 * 1024 * 1024;\n\n/** Human-readable byte count: \"820 KB\", \"1.4 MB\". New in 0.7.0, from SCIC. */\nexport function formatFileSize(bytes: number): string {\n const kb = bytes / 1024;\n if (kb < 1024) return `${Math.round(kb)} KB`;\n const mb = kb / 1024;\n return `${Number.isInteger(mb) ? mb : mb.toFixed(1)} MB`;\n}\n\nfunction matchesAccept(file: File, accept: string): boolean {\n const extensions = accept\n .split(',')\n .map((part) => part.trim().toLowerCase())\n .filter((part) => part.startsWith('.'));\n if (extensions.length === 0) {\n return true;\n }\n return extensions.some((extension) => file.name.toLowerCase().endsWith(extension));\n}\n\nexport interface UseFilePickerOptions {\n accept?: string;\n maxSizeBytes?: number;\n onFileSelected?: (file: File) => void;\n}\n\nexport interface UseFilePicker {\n /** Spread onto a hidden `<input type=\"file\">`, which must be rendered. */\n inputProps: InputHTMLAttributes<HTMLInputElement> & { ref: RefObject<HTMLInputElement> };\n /** Opens the native picker. */\n open: () => void;\n /** Runs the same accept and size checks on dropped files. */\n handleFiles: (files: FileList | null) => void;\n /** Validation message for the last rejected file, if any. */\n error: string | null;\n}\n\n/**\n * The accept-list and size validation behind every way into a file upload: the drop zone, and\n * any \"Replace\" button that skips it. One implementation, so the checks cannot drift apart.\n * New in 0.7.0, from SCIC.\n */\nexport function useFilePicker({\n accept = DEFAULT_ACCEPT,\n maxSizeBytes = DEFAULT_MAX_SIZE_BYTES,\n onFileSelected,\n}: UseFilePickerOptions = {}): UseFilePicker {\n const inputRef = useRef<HTMLInputElement>(null);\n const [error, setError] = useState<string | null>(null);\n\n function handleFiles(files: FileList | null) {\n const file = files?.[0];\n if (!file) return;\n if (!matchesAccept(file, accept)) {\n setError(`Unsupported file type. Allowed: ${accept}.`);\n return;\n }\n if (file.size > maxSizeBytes) {\n setError(`That file is ${formatFileSize(file.size)}. The limit is ${formatFileSize(maxSizeBytes)}.`);\n return;\n }\n setError(null);\n onFileSelected?.(file);\n }\n\n return {\n inputProps: {\n ref: inputRef,\n type: 'file',\n accept,\n className: 'sr-only',\n tabIndex: -1,\n onChange: (event) => {\n handleFiles(event.currentTarget.files);\n event.currentTarget.value = '';\n },\n },\n open: () => inputRef.current?.click(),\n handleFiles,\n error,\n };\n}\n\nexport function FileDropZone({\n className,\n description = 'Drag & drop or browse · PDF, JPG, PNG · up to 10 MB',\n accept = DEFAULT_ACCEPT,\n maxSizeBytes = DEFAULT_MAX_SIZE_BYTES,\n onFileSelected,\n disabled = false,\n}: FileDropZoneProps) {\n const [isDragging, setIsDragging] = useState(false);\n const picker = useFilePicker({ accept, maxSizeBytes, onFileSelected });\n const { error, handleFiles } = picker;\n const inputRef = picker.inputProps.ref;\n\n return (\n <>\n <input {...picker.inputProps} disabled={disabled} />\n <div\n role=\"button\"\n data-state={isDragging ? 'dragging' : undefined}\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n onClick={() => { if (!disabled) inputRef.current?.click(); }}\n onKeyDown={(e) => {\n if (!disabled && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n inputRef.current?.click();\n }\n }}\n onDragOver={(e) => { e.preventDefault(); if (!disabled) setIsDragging(true); }}\n onDragEnter={(e) => { e.preventDefault(); if (!disabled) setIsDragging(true); }}\n onDragLeave={() => setIsDragging(false)}\n onDrop={(e) => {\n e.preventDefault();\n setIsDragging(false);\n if (!disabled) handleFiles(e.dataTransfer.files);\n }}\n className={clsx(\n 'flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed py-4 px-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1',\n disabled\n ? 'cursor-not-allowed border-disabled bg-disabled'\n : clsx(\n 'cursor-pointer',\n isDragging\n ? 'border-brand bg-brand-tertiary'\n : 'border-default bg-default-secondary hover:border-brand hover:bg-brand-tertiary',\n ),\n className,\n )}\n >\n <span\n aria-hidden\n className={disabled ? 'text-disabled' : isDragging ? 'text-brand' : 'text-default-secondary'}\n >\n <UploadIcon className=\"size-5\" />\n </span>\n <span className={clsx('text-body-sm font-medium', disabled ? 'text-disabled' : 'text-default')}>Upload file</span>\n <span className=\"text-body-xs text-default-secondary text-center\">\n {description}\n </span>\n </div>\n {error && (\n <span role=\"alert\" className=\"text-body-xs text-danger\">\n {error}\n </span>\n )}\n </>\n );\n}\n","import { useEffect, useState, type ClipboardEvent, type KeyboardEvent } from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { Badge } from '../status/badge';\nimport { Field, FieldError, FieldHint, FieldLabel, useFieldControl } from './field';\n\nexport type TagInputParseResult = { value: string } | { error: string };\n\nexport interface TagInputProps {\n label?: string;\n hint?: string;\n /** An error from outside (e.g. the server). Takes precedence over a parse error. */\n error?: string;\n placeholder?: string;\n disabled?: boolean;\n required?: boolean;\n /** The committed chips, controlled. */\n value?: string[];\n /** The initial chips, uncontrolled. Default none. */\n defaultValue?: string[];\n /** Receives the whole next array when a chip is added or removed. */\n onValueChange?: (value: string[]) => void;\n /** Posts each chip with a surrounding form, as repeated fields of this name. */\n name?: string;\n /** Validates and normalises each token, e.g. lower-case an email or reject a bad one. */\n parse?: (raw: string) => TagInputParseResult;\n /** What separates tokens when typed or pasted. Default whitespace. A `g` or `y` flag is safe. */\n delimiter?: RegExp;\n maxTags?: number;\n /** Told whenever rejected text is sitting in the field, so a form can block saving. */\n onInvalidChange?: (invalid: boolean) => void;\n id?: string;\n className?: string;\n}\n\nconst defaultParse = (raw: string): TagInputParseResult => ({ value: raw.trim() });\n\n/**\n * A multi-value text field: type or paste values, and each becomes a removable chip. Emails,\n * domains, tags. New in 0.7.0, from SCIC (whose `onChange` is `onValueChange` here, matching\n * every other DS control).\n *\n * Controlled with `value`, or uncontrolled with `defaultValue`. With `name` it posts each chip\n * with a form, and `required` then blocks submit while there are none.\n *\n * Enter, the delimiter, blur and a delimited paste all commit. Backspace in an empty field removes\n * the last chip. Duplicates are ignored. A token `parse` rejects stays in the field with its error\n * rather than being dropped, so nothing the user typed silently disappears.\n *\n * Wired through `Field` like the other text fields: the label names the input, and the error or\n * hint describes it.\n */\nexport function TagInput({ label, hint, error, required, disabled, id, className, ...rest }: TagInputProps) {\n const [parseError, setParseError] = useState<string | null>(null);\n const shownError = error ?? parseError ?? undefined;\n\n return (\n <Field\n id={id}\n disabled={disabled}\n required={required}\n hasError={Boolean(shownError)}\n hasHint={Boolean(hint)}\n className={className}\n >\n {label && <FieldLabel>{label}</FieldLabel>}\n <TagInputControl disabled={disabled} required={required} invalid={Boolean(shownError)} onParseError={setParseError} {...rest} />\n {shownError ? <FieldError>{shownError}</FieldError> : hint && <FieldHint>{hint}</FieldHint>}\n </Field>\n );\n}\n\ninterface TagInputControlProps\n extends Omit<TagInputProps, 'label' | 'hint' | 'error' | 'id' | 'className'> {\n invalid: boolean;\n onParseError: (error: string | null) => void;\n}\n\nfunction TagInputControl({\n value: valueProp,\n defaultValue = [],\n onValueChange,\n name,\n required,\n parse = defaultParse,\n delimiter = /\\s+/,\n maxTags,\n onInvalidChange,\n placeholder,\n disabled,\n invalid,\n onParseError,\n}: TagInputControlProps) {\n const field = useFieldControl();\n const [values, setValues] = useControllableState<string[]>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange,\n });\n // A global or sticky pattern keeps `lastIndex` between `test` calls, so alternate keys would fail.\n const isDelimited = (text: string) => {\n delimiter.lastIndex = 0;\n return delimiter.test(text);\n };\n const [draft, setDraft] = useState('');\n const [rejected, setRejected] = useState<string | null>(null);\n\n useEffect(() => {\n onParseError(rejected);\n onInvalidChange?.(rejected !== null);\n }, [rejected, onParseError, onInvalidChange]);\n\n function commit(raw: string) {\n const tokens = raw\n .split(delimiter)\n .map((token) => token.trim())\n .filter(Boolean);\n if (!tokens.length) {\n setDraft('');\n return;\n }\n\n const next = [...values];\n let firstRejected: { token: string; error: string } | null = null;\n for (const token of tokens) {\n const result = parse(token);\n if ('error' in result) {\n firstRejected ??= { token, error: result.error };\n continue;\n }\n if (next.includes(result.value)) continue;\n if (maxTags !== undefined && next.length >= maxTags) {\n firstRejected ??= { token, error: `You can add up to ${maxTags}.` };\n continue;\n }\n next.push(result.value);\n }\n\n if (next.length !== values.length) setValues(next);\n setDraft(firstRejected?.token ?? '');\n setRejected(firstRejected?.error ?? null);\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n if (event.key === 'Enter' || (event.key.length === 1 && isDelimited(event.key))) {\n event.preventDefault();\n commit(draft);\n return;\n }\n if (event.key === 'Backspace' && draft === '' && values.length) {\n setValues(values.slice(0, -1));\n }\n }\n\n function handlePaste(event: ClipboardEvent<HTMLInputElement>) {\n const text = event.clipboardData.getData('text');\n if (!isDelimited(text.trim())) return;\n event.preventDefault();\n commit(`${draft}${text}`);\n }\n\n return (\n <div\n data-invalid={invalid || undefined}\n data-disabled={disabled || undefined}\n className={cn(\n 'flex min-h-9 flex-wrap items-center gap-1.5 rounded-lg border border-default bg-default px-2 py-1.5 transition-colors',\n 'focus-within:border-brand focus-within:ring-1 focus-within:ring-brand',\n 'data-[invalid]:border-danger data-[invalid]:focus-within:ring-danger',\n 'data-[disabled]:cursor-not-allowed data-[disabled]:border-disabled data-[disabled]:bg-disabled',\n )}\n >\n {values.map((value) => (\n <Badge\n key={value}\n label={value}\n size=\"sm\"\n onClose={disabled ? undefined : () => setValues(values.filter((existing) => existing !== value))}\n />\n ))}\n <input\n {...field}\n value={draft}\n disabled={disabled}\n placeholder={values.length ? undefined : placeholder}\n aria-invalid={invalid || undefined}\n // The chips are what is required, so the field only blocks submit while there are none.\n required={required && values.length === 0}\n onChange={(event) => {\n setDraft(event.target.value);\n setRejected(null);\n }}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={() => commit(draft)}\n className={clsx(\n 'min-w-[8rem] flex-1 bg-transparent px-1 text-body-sm text-default outline-none',\n 'placeholder:text-default-tertiary disabled:cursor-not-allowed',\n )}\n />\n {name && values.map((value) => <input key={value} type=\"hidden\" name={name} value={value} />)}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { XIcon } from 'lucide-react';\n\nexport type BadgeColor = 'gray' | 'red' | 'yellow' | 'lime' | 'green' | 'teal' | 'blue' | 'pink' | 'slate';\nexport type BadgeSize = 'sm' | 'lg';\nexport type BadgeVariant = 'default' | 'subtle';\n\nexport interface BadgeProps {\n label: string;\n color?: BadgeColor;\n size?: BadgeSize;\n variant?: BadgeVariant;\n indicator?: boolean;\n onClose?: () => void;\n className?: string;\n}\n\nconst defaultClasses: Record<BadgeColor, string> = {\n gray: 'bg-badge-gray text-badge-gray',\n red: 'bg-badge-red text-badge-red',\n yellow: 'bg-badge-yellow text-badge-yellow',\n lime: 'bg-badge-lime text-badge-lime',\n green: 'bg-badge-green text-badge-green',\n teal: 'bg-badge-teal text-badge-teal',\n blue: 'bg-badge-blue text-badge-blue',\n pink: 'bg-badge-pink text-badge-pink',\n slate: 'bg-badge-slate text-badge-slate',\n};\n\nconst subtleClasses: Record<BadgeColor, string> = {\n gray: 'border border-badge-gray text-default-secondary',\n red: 'border border-badge-red text-default-secondary',\n yellow: 'border border-badge-yellow text-default-secondary',\n lime: 'border border-badge-lime text-default-secondary',\n green: 'border border-badge-green text-default-secondary',\n teal: 'border border-badge-teal text-default-secondary',\n blue: 'border border-badge-blue text-default-secondary',\n pink: 'border border-badge-pink text-default-secondary',\n slate: 'border border-badge-slate text-default-secondary',\n};\n\nexport function Badge({\n label,\n color = 'gray',\n size = 'sm',\n variant = 'default',\n indicator = false,\n onClose,\n className,\n}: BadgeProps) {\n const isDefault = variant === 'default';\n\n return (\n <span\n data-variant={variant}\n className={clsx(\n 'inline-flex items-center rounded-full px-2 py-0.5',\n size === 'sm' ? 'gap-1' : 'gap-1.5',\n isDefault ? defaultClasses[color] : subtleClasses[color],\n className,\n )}\n >\n {indicator && (\n <span\n className={clsx(\n 'shrink-0 rounded-full bg-current',\n size === 'sm' ? 'h-1.5 w-1.5' : 'h-2 w-2',\n )}\n />\n )}\n <span\n className={clsx(\n 'whitespace-nowrap',\n size === 'sm'\n ? clsx('text-body-tiny', isDefault && 'font-semibold')\n : 'text-body-xs',\n )}\n >\n {label}\n </span>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className={clsx(\n 'inline-flex shrink-0 items-center justify-center rounded-full opacity-60 transition-opacity hover:opacity-100',\n size === 'sm' ? 'h-3 w-3' : 'h-4 w-4',\n )}\n // Was a hardcoded \"Remove\", so a row of five dismissible badges produced five\n // identically named buttons with nothing to tell them apart.\n aria-label={`Remove ${label}`}\n >\n <XIcon className=\"h-full w-full\" strokeWidth={2.5} aria-hidden />\n </button>\n )}\n </span>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react';\nimport { Button } from './button';\n\n// ── FormCard ───────────────────────────────────────────────────────────────────\n\nexport function FormCard({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={clsx(\n 'overflow-hidden rounded-xl border border-default bg-default',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// ── FormCardHeader ─────────────────────────────────────────────────────────────\n\nexport interface FormCardHeaderProps {\n title: string;\n subtitle?: string;\n}\n\nexport function FormCardHeader({ title, subtitle }: FormCardHeaderProps) {\n return (\n <div className=\"border-b border-default px-7 py-6\">\n <h2 className=\"text-heading-sm font-semibold text-default leading-snug\">{title}</h2>\n {subtitle && (\n <p className=\"mt-1 text-body-xs text-default-secondary\">{subtitle}</p>\n )}\n </div>\n );\n}\n\n// ── FormCardFooter ─────────────────────────────────────────────────────────────\n\nexport interface FormCardFooterProps {\n onSaveDraft?: () => void;\n onBack?: () => void;\n onContinue?: () => void;\n continueLabel?: string;\n /** The continue button's trailing glyph. Default an arrow; `null` for none (e.g. \"Submit\"). */\n continueIcon?: ReactNode | null;\n backDisabled?: boolean;\n continueDisabled?: boolean;\n /** Disable \"Save as draft\" while keeping it visible, e.g. while a draft save is in flight. */\n saveDraftDisabled?: boolean;\n}\n\nexport function FormCardFooter({\n onSaveDraft,\n onBack,\n onContinue,\n continueLabel = 'Continue',\n continueIcon,\n backDisabled = false,\n continueDisabled = false,\n saveDraftDisabled = false,\n}: FormCardFooterProps) {\n return (\n // Inline, NOT sticky: a sticky footer sits over the focused field once a phone keyboard\n // opens (WCAG 2.2 SC 2.4.11 Focus Not Obscured). Below `sm` Back/Continue share one\n // full-width row and the draft action wraps under them; DOM order stays draft → back →\n // continue for keyboards. Ported from SCIC in 0.7.0.\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t border-default px-4 py-4 sm:px-7 sm:py-5\">\n {/* Rendered only when it can do something. Through 0.6 it rendered disabled wherever no\n handler was passed, which read as an unfinished feature rather than one that does not\n apply here. */}\n {onSaveDraft ? (\n <Button\n variant=\"neutral\"\n size=\"md\"\n onClick={onSaveDraft}\n disabled={saveDraftDisabled}\n className=\"order-last w-full justify-center sm:order-none sm:w-auto\"\n >\n Save as draft\n </Button>\n ) : (\n <span className=\"hidden sm:block\" />\n )}\n <div className=\"flex w-full items-center gap-2 sm:w-auto\">\n {!backDisabled && (\n <Button\n variant=\"neutral\"\n size=\"md\"\n leadingIcon={<ArrowLeftIcon aria-hidden size={16} />}\n onClick={onBack}\n className=\"flex-1 justify-center sm:flex-none\"\n >\n Back\n </Button>\n )}\n <Button\n variant=\"primary\"\n size=\"md\"\n trailingIcon={continueIcon === null ? undefined : (continueIcon ?? <ArrowRightIcon aria-hidden size={16} />)}\n onClick={onContinue}\n disabled={continueDisabled}\n className=\"flex-1 justify-center sm:flex-none\"\n >\n {continueLabel}\n </Button>\n </div>\n </div>\n );\n}\n","import clsx from 'clsx';\n\n/**\n * The nine-hue categorical palette from `badge.css`, which is what roles want: a role is a\n * *category*, not a severity, so it must not borrow the semantic tones — a `danger`-coloured\n * role badge would imply the role itself is a problem.\n */\nexport type RoleBadgeTone =\n | 'slate'\n | 'blue'\n | 'green'\n | 'yellow'\n | 'red'\n | 'pink'\n | 'teal'\n | 'lime'\n | 'gray';\n\nexport interface RoleBadgeProps {\n role: string;\n size?: 'sm' | 'md';\n /**\n * Override the name-map lookup. Use this for roles the map does not know, in preference to\n * `color` — it stays on the token layer and re-themes with the rest of the badge palette.\n */\n tone?: RoleBadgeTone;\n /**\n * @deprecated Bypasses the design tokens — pass `tone` instead. Raw 6-digit hex; text uses\n * the hex and the background a 12% tint of it. Kept for role colours that genuinely come\n * from API data rather than from the design system.\n */\n color?: string | null;\n}\n\n/**\n * Role → palette hue.\n *\n * Through 0.4.0 this was ten hardcoded hex pairs, thirteen of whose twenty values sat off\n * the palette entirely. `Compliance Lead` was the worst: `#5b3da8`, a violet with no ramp in\n * `Color Primitives` at all — a gap `status.css` had already documented for `accent`.\n *\n * Hues were chosen by comparing the original hex against the resolved palette, not by eye.\n * Several land almost exactly:\n *\n * Auditor / Viewer #f5f5f5 / #757575 → gray #f5f5f5 / #757575 (exact)\n * admin family #e9eff7 / #0c2d58 → slate #f1f1f5 / #0c2d58 (text exact)\n * Entity Manager #fbe6cf / #9a6206 → yellow #feedcf / #996100\n * Intelligence Analyst #fde2e7 / #a3284a → red #fce9eb / #bb223a\n * Reviewer #dbeafe / #1d4ed8 → blue\n * Requester #e6f4ea / #1f7a3d → green\n *\n * `Compliance Lead` is the one reassignment rather than a match. Violet has no equivalent at\n * all, and of its two neighbours blue was already Reviewer's — so it takes pink, the nearest\n * remaining hue. `teal` and `lime` are deliberately left free for roles added later.\n */\nconst ROLE_TONES: Record<string, RoleBadgeTone> = {\n 'Super Admin': 'slate',\n 'Admin': 'slate',\n 'User': 'slate',\n 'Compliance Lead': 'pink',\n 'Reviewer': 'blue',\n 'Requester': 'green',\n 'Entity Manager': 'yellow',\n 'Intelligence Analyst': 'red',\n 'Auditor': 'gray',\n 'Viewer': 'gray',\n};\n\nconst FALLBACK_TONE: RoleBadgeTone = 'gray';\n\n/**\n * `bg-badge-*` resolves to `--badge-*-bg` and `text-badge-*` to `--badge-*-text`, so each\n * pair is the label/on-label duo the palette was designed around.\n */\nconst TONE_STYLES: Record<RoleBadgeTone, string> = {\n slate: 'bg-badge-slate text-badge-slate',\n blue: 'bg-badge-blue text-badge-blue',\n green: 'bg-badge-green text-badge-green',\n yellow: 'bg-badge-yellow text-badge-yellow',\n red: 'bg-badge-red text-badge-red',\n pink: 'bg-badge-pink text-badge-pink',\n teal: 'bg-badge-teal text-badge-teal',\n lime: 'bg-badge-lime text-badge-lime',\n gray: 'bg-badge-gray text-badge-gray',\n};\n\nconst HEX6 = /^#[0-9a-fA-F]{6}$/;\n\nexport function RoleBadge({ role, size = 'sm', tone, color }: RoleBadgeProps) {\n // The raw-hex path stays for data-driven colour, but it no longer wins by default: a\n // caller has to opt into leaving the token layer.\n const rawColor = color && HEX6.test(color) ? color : undefined;\n const resolved = tone ?? ROLE_TONES[role] ?? FALLBACK_TONE;\n\n return (\n <span\n data-tone={tone}\n className={clsx(\n 'inline-flex items-center rounded-full font-medium whitespace-nowrap',\n size === 'sm' ? 'px-2 py-0.5 text-body-tiny' : 'px-3 py-1 text-body-xs',\n !rawColor && TONE_STYLES[resolved],\n )}\n style={rawColor ? { backgroundColor: `${rawColor}1F`, color: rawColor } : undefined}\n >\n {role}\n </span>\n );\n}\n","import {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { CheckIcon, ChevronDownIcon } from 'lucide-react';\n\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { useFloatingPanel } from '../overlays/floating';\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_ACTIVE,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n OVERLAY_PANEL,\n OVERLAY_PANEL_SCROLL,\n} from '../overlays/menu-styles';\nimport { Portal } from '../overlays/portal';\nimport { useFieldControl } from './field';\nimport { useControlSize } from './control-size';\nimport type { InputSize } from './input';\n\nexport interface ComboboxOption<T = string> {\n value: T;\n label: string;\n description?: string;\n disabled?: boolean;\n /** Optional group heading. Options sharing a group are rendered together. */\n group?: string;\n}\n\nexport interface ComboboxProps<T extends string = string> {\n options: ComboboxOption<T>[];\n value?: T | null;\n defaultValue?: T | null;\n onValueChange?: (value: T | null) => void;\n /** Accessible name. Required unless the combobox is inside a `Field` with a label. */\n label?: string;\n placeholder?: string;\n size?: InputSize;\n disabled?: boolean;\n invalid?: boolean;\n /** Allow clearing back to `null` by selecting the chosen option again. Default `true`. */\n clearable?: boolean;\n /** Override the filter. Default is a case-insensitive substring match on `label`. */\n filter?: (option: ComboboxOption<T>, query: string) => boolean;\n /** Shown when nothing matches. */\n emptyMessage?: ReactNode;\n /** Custom option rendering. Receives the option and whether it is selected. */\n renderOption?: (option: ComboboxOption<T>, selected: boolean) => ReactNode;\n className?: string;\n}\n\nconst HEIGHT: Record<InputSize, string> = {\n lg: 'h-12 px-4 text-body',\n md: 'h-9 px-3 text-body-sm',\n sm: 'h-6 px-2 text-body-tiny',\n};\n\n/**\n * Single-select combobox with a text filter — an autocomplete.\n *\n * Implements the ARIA 1.2 combobox pattern, which is specific about a few things that are\n * easy to get wrong and were all wrong in the `RoleComboBox` this replaces:\n *\n * - **`role=\"combobox\"` belongs on the text input**, not on a wrapping `<div>`. The div\n * version means the state attributes sit on an element the user never focuses.\n * - **`aria-activedescendant`, not focus, tracks the highlighted option.** Focus stays in\n * the input the whole time — moving DOM focus into the list breaks typing. This is the\n * one place a roving tabindex is the *wrong* answer, which is why this does not use\n * `useRovingFocus`.\n * - **`aria-controls` points at the listbox**, which therefore needs a stable id.\n * - The listbox is portaled, so it is not clipped by a `Card` or a scrolling container.\n *\n * For a command palette — filter over *actions* rather than a value — use `Command`.\n */\nexport function Combobox<T extends string = string>({\n options,\n value: valueProp,\n defaultValue = null,\n onValueChange,\n label,\n placeholder = 'Select…',\n size: sizeProp,\n disabled = false,\n invalid = false,\n clearable = true,\n filter,\n emptyMessage = 'No matches',\n renderOption,\n className,\n}: ComboboxProps<T>) {\n const size = useControlSize(sizeProp);\n const [value, setValue] = useControllableState<T | null>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: T | null) => void) | undefined,\n });\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const field = useFieldControl();\n\n const matches = useMemo(() => {\n const predicate =\n filter ?? ((option: ComboboxOption<T>, q: string) =>\n option.label.toLowerCase().includes(q.toLowerCase()));\n return query ? options.filter((option) => predicate(option, query)) : options;\n }, [options, query, filter]);\n\n const selected = options.find((option) => option.value === value) ?? null;\n\n // What the input displays: the query while filtering, the selection otherwise.\n const displayValue = open ? query : (selected?.label ?? '');\n\n const close = useCallback((restoreFocus = true) => {\n setOpen(false);\n setQuery('');\n if (restoreFocus) inputRef.current?.focus();\n }, []);\n\n const commit = (option: ComboboxOption<T>) => {\n if (option.disabled) return;\n setValue(clearable && option.value === value ? null : option.value);\n close();\n };\n\n const move = (delta: number) => {\n if (matches.length === 0) return;\n setActiveIndex((current) => {\n let next = current;\n for (let i = 0; i < matches.length; i++) {\n next = (next + delta + matches.length) % matches.length;\n if (!matches[next]?.disabled) break;\n }\n return next;\n });\n };\n\n const { refs, floatingStyles } = useFloatingPanel({\n open,\n onOpenChange: setOpen,\n side: 'bottom',\n align: 'start',\n sideOffset: 4,\n matchAnchorWidth: true,\n });\n\n useEffect(() => {\n refs.setReference(rootRef.current);\n }, [refs, open]);\n\n // Reset the highlight whenever the result set changes, so it never points past the end.\n useEffect(() => {\n setActiveIndex(0);\n }, [query, options]);\n\n // Keep the highlighted option in view. `aria-activedescendant` moves the virtual cursor but\n // does not scroll, which DOM focus would have done for free.\n useEffect(() => {\n if (!open) return;\n const node = listRef.current?.querySelector(`#${CSS.escape(optionId(activeIndex))}`);\n // Feature-detected: `scrollIntoView` is absent in jsdom and in some embedded webviews,\n // and an unguarded call there throws during render of an otherwise working combobox.\n if (node instanceof Element && typeof node.scrollIntoView === 'function') {\n node.scrollIntoView({ block: 'nearest' });\n }\n });\n\n useEffect(() => {\n if (!open) return;\n function onPointerDown(event: PointerEvent) {\n const withinRoot = rootRef.current?.contains(event.target as Node);\n const withinList = listRef.current?.contains(event.target as Node);\n if (!withinRoot && !withinList) close(false);\n }\n document.addEventListener('pointerdown', onPointerDown);\n return () => document.removeEventListener('pointerdown', onPointerDown);\n }, [open, close]);\n\n let renderedGroup: string | undefined;\n\n return (\n <div ref={rootRef} className={clsx('relative w-full', className)}>\n <div\n className={clsx(\n 'flex w-full items-center gap-2 rounded-lg border transition-colors',\n HEIGHT[size],\n 'focus-within:ring-2 focus-within:ring-offset-1 focus-within:ring-offset-default',\n disabled\n ? 'cursor-not-allowed border-disabled bg-disabled'\n : invalid || field['aria-invalid']\n ? 'border-danger-secondary focus-within:border-danger focus-within:ring-danger'\n : 'border-default bg-default focus-within:border-brand focus-within:ring-brand',\n )}\n >\n <input\n ref={inputRef}\n // ARIA 1.2: the role goes on the input the user actually focuses.\n role=\"combobox\"\n type=\"text\"\n autoComplete=\"off\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={open && matches.length > 0 ? optionId(activeIndex) : undefined}\n aria-label={label}\n {...field}\n disabled={disabled}\n value={displayValue}\n placeholder={selected ? selected.label : placeholder}\n onChange={(event) => {\n setQuery(event.target.value);\n if (!open) setOpen(true);\n }}\n onFocus={() => !disabled && setOpen(true)}\n onKeyDown={(event) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (!open) setOpen(true);\n else move(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (!open) setOpen(true);\n else move(-1);\n break;\n case 'Home':\n if (open) {\n event.preventDefault();\n setActiveIndex(0);\n }\n break;\n case 'End':\n if (open) {\n event.preventDefault();\n setActiveIndex(matches.length - 1);\n }\n break;\n case 'Enter':\n if (open && matches[activeIndex]) {\n event.preventDefault();\n commit(matches[activeIndex]);\n }\n break;\n case 'Escape':\n event.preventDefault();\n close();\n break;\n case 'Tab':\n // Tab commits nothing and closes — the value only changes on Enter or click,\n // so tabbing away cannot silently pick whatever happened to be highlighted.\n if (open) close(false);\n break;\n default:\n break;\n }\n }}\n className={clsx(\n 'min-w-0 flex-1 bg-transparent text-default outline-none',\n 'placeholder:text-default-tertiary',\n 'disabled:cursor-not-allowed disabled:text-disabled',\n )}\n />\n <ChevronDownIcon\n aria-hidden\n className={clsx(\n 'shrink-0 transition-transform',\n size === 'sm' ? 'size-3' : 'size-4',\n disabled ? 'text-icon-disabled' : 'text-icon-default-secondary',\n open && 'rotate-180',\n )}\n />\n </div>\n\n {open && (\n <Portal>\n <div\n ref={(node) => {\n listRef.current = node;\n refs.setFloating(node);\n }}\n id={listboxId}\n role=\"listbox\"\n aria-label={label}\n style={{ ...floatingStyles, width: 'var(--panel-anchor-width)' }}\n className={clsx('z-popover', OVERLAY_PANEL, OVERLAY_PANEL_SCROLL)}\n >\n {matches.length === 0 && (\n <p className=\"px-2.5 py-2 text-body-xs text-default-secondary\">{emptyMessage}</p>\n )}\n {matches.map((option, index) => {\n const isSelected = option.value === value;\n const isActive = index === activeIndex;\n const groupHeading = option.group !== renderedGroup ? option.group : undefined;\n renderedGroup = option.group;\n\n return (\n <div key={String(option.value)}>\n {groupHeading && (\n <div\n role=\"presentation\"\n className={OVERLAY_HEADING}\n >\n {groupHeading}\n </div>\n )}\n {/* Options are deliberately not focusable and carry no key handler. In the\n ARIA 1.2 combobox pattern focus never leaves the input — moving it into\n the list would stop the user typing — and `aria-activedescendant`\n carries the highlight instead, with the input owning every key.\n jsx-a11y cannot model that, so it sees an unreachable option; it is\n reachable, just not by DOM focus. */}\n {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus, jsx-a11y/click-events-have-key-events */}\n <div\n id={optionId(index)}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={option.disabled || undefined}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => commit(option)}\n onPointerEnter={() => !option.disabled && setActiveIndex(index)}\n className={clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE.md,\n 'items-center',\n option.disabled\n ? 'cursor-not-allowed text-disabled'\n : isActive\n ? clsx(OVERLAY_ITEM_ACTIVE, 'text-default')\n : 'text-default',\n )}\n >\n {renderOption ? (\n renderOption(option, isSelected)\n ) : (\n <>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{option.label}</span>\n {option.description && (\n <span className=\"block truncate text-body-tiny text-default-secondary\">\n {option.description}\n </span>\n )}\n </span>\n {isSelected && (\n <CheckIcon aria-hidden className=\"size-3.5 shrink-0 text-brand\" strokeWidth={3} />\n )}\n </>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </Portal>\n )}\n </div>\n );\n}\n","import { RoleBadge } from '../status/role-badge';\nimport { Combobox, type ComboboxOption } from './combobox';\nimport type { InputSize } from './input';\n\nexport interface RoleOption {\n role: string;\n description: string;\n}\n\nexport const ROLE_COMBO_OPTIONS: RoleOption[] = [\n { role: 'Reviewer', description: 'Reviews onboarding requests' },\n { role: 'Admin', description: 'Full org control' },\n { role: 'Compliance Lead', description: 'Owns compliance' },\n { role: 'Requester', description: 'Creates onboarding requests' },\n { role: 'Viewer', description: 'Read-only access' },\n { role: 'User', description: 'Default user access' },\n];\n\nexport interface RoleComboBoxProps {\n value: string;\n onChange: (role: string) => void;\n options?: RoleOption[];\n /** Accessible name. Defaults to `Role`. */\n label?: string;\n size?: InputSize;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Role picker.\n *\n * Rebuilt in 0.4.0 as a thin wrapper over `Combobox`, which is all it should ever have been.\n * The version it replaces was the least correct component in the library and is worth\n * recording, because every one of these was a category of bug rather than a detail:\n *\n * - `role=\"combobox\"` sat on a `<div>` while the real `<input>` had no role and none of the\n * state attributes. Under ARIA 1.2 the role belongs on the input.\n * - The `role=\"listbox\"` had no `id`, so `aria-controls` could not point at it, and there\n * was no `aria-activedescendant` at all.\n * - No arrow keys, no Home/End, no wrap. The **selected** option had no `tabIndex`, so it\n * was mouse-only, while every *other* option was individually tabbable.\n * - Escape worked on the trigger but not on the search input or the options, and closing\n * never returned focus to the trigger.\n * - The tick was a literal `✓` text node, announced as \"check mark\" mid-option.\n * - It bypassed the token system entirely — `border-blue-500`, `bg-white`, `bg-blue-50`,\n * `text-blue-600`, `text-sm` — and built its className with a template literal. Both are\n * explicitly against the rules in CLAUDE.md, and the raw colours meant it would not theme.\n *\n * It stays a preset rather than becoming `Combobox` usage at every call site only because it\n * renders a `RoleBadge` per option, which `renderOption` exists for.\n */\nexport function RoleComboBox({\n value,\n onChange,\n options = ROLE_COMBO_OPTIONS,\n label = 'Role',\n size = 'md',\n disabled = false,\n className,\n}: RoleComboBoxProps) {\n const comboboxOptions: ComboboxOption[] = options.map((option) => ({\n value: option.role,\n label: option.role,\n description: option.description,\n }));\n\n return (\n <Combobox\n options={comboboxOptions}\n value={value}\n onValueChange={(next) => next && onChange(next)}\n label={label}\n size={size}\n disabled={disabled}\n // A role is always set — there is no \"no role\" state — so re-selecting must not clear.\n clearable={false}\n emptyMessage=\"No roles match\"\n className={className}\n renderOption={(option) => (\n <>\n <RoleBadge role={option.value} size=\"sm\" />\n <span className=\"min-w-0 flex-1 truncate text-body-xs text-default-secondary\">\n {option.description}\n </span>\n </>\n )}\n />\n );\n}\n","import { useMemo } from 'react';\n\nimport { Combobox, type ComboboxOption, type ComboboxProps } from './combobox';\n\n/**\n * ISO 3166-1 alpha-2 codes for every officially assigned country and territory.\n *\n * `Intl` can name a region but cannot list them — there is no `supportedValuesOf('region')` —\n * so the codes are the one thing this component has to carry itself. Labels still come from\n * `Intl.DisplayNames`, which means they follow the locale instead of being frozen in English.\n */\nconst ISO_3166_ALPHA_2 =\n 'AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR ' +\n 'BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ ' +\n 'EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW ' +\n 'GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY ' +\n 'KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV ' +\n 'MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY ' +\n 'QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG ' +\n 'TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW';\n\nexport const COUNTRY_CODES: readonly string[] = ISO_3166_ALPHA_2.split(' ');\n\nexport interface CountrySelectProps\n extends Omit<ComboboxProps<string>, 'options' | 'filter' | 'renderOption'> {\n /** Restrict the list to these ISO 3166-1 alpha-2 codes. Default: every code. */\n countries?: readonly string[];\n /** Locale for the country names. Default: the browser's. */\n locale?: string;\n}\n\n/** Country names for `codes` in `locale`, sorted by name. Falls back to the code itself. */\nexport function countryOptions(\n codes: readonly string[] = COUNTRY_CODES,\n locale?: string,\n): ComboboxOption<string>[] {\n let names: Intl.DisplayNames | null = null;\n try {\n names = new Intl.DisplayNames(locale ? [locale] : undefined, { type: 'region' });\n } catch {\n // An unknown locale throws. Codes are still a usable list.\n }\n return codes\n .map((code) => ({ value: code, label: names?.of(code) ?? code, description: code }))\n .sort((a, b) => a.label.localeCompare(b.label, locale));\n}\n\n/**\n * Searchable country picker. The value is an ISO 3166-1 alpha-2 code (`\"LK\"`), never the\n * display name, so it survives a locale change and can be stored as-is.\n *\n * A thin layer over `Combobox` — same keyboard contract, same panel — that adds the list and\n * lets the query match the code as well as the name, so typing `GB` finds United Kingdom.\n * A value outside `countries` is still listed, so a saved country never renders as an empty\n * field.\n */\nexport function CountrySelect({\n countries,\n locale,\n placeholder = 'Select a country…',\n emptyMessage = 'No countries match',\n ...props\n}: CountrySelectProps) {\n const keep = [props.value, props.defaultValue].filter((v): v is string => !!v);\n const keepKey = keep.join('|');\n const options = useMemo(() => {\n const list = countryOptions(countries, locale);\n const missing = keep.filter((v) => !list.some((o) => o.value === v));\n return [...countryOptions(missing, locale), ...list];\n // `keep` is rebuilt every render; `keepKey` is its stable identity.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [countries, locale, keepKey]);\n\n return (\n <Combobox\n {...props}\n options={options}\n placeholder={placeholder}\n emptyMessage={emptyMessage}\n filter={(option, query) => {\n const q = query.trim().toLowerCase();\n return option.label.toLowerCase().includes(q) || option.value.toLowerCase() === q;\n }}\n />\n );\n}\n","import { useMemo } from 'react';\n\nimport { Combobox, type ComboboxOption, type ComboboxProps } from './combobox';\n\nexport interface TimeZoneSelectProps\n extends Omit<ComboboxProps<string>, 'options' | 'filter' | 'renderOption'> {\n /** Restrict the list to these IANA zone names. Default: every zone the runtime supports. */\n timeZones?: readonly string[];\n /**\n * The instant offsets are computed for. Default: now. Offsets move with daylight saving,\n * so a fixed date is mainly useful for tests and screenshots.\n */\n at?: Date;\n}\n\n/**\n * Renamed zones, old name → current IANA name. Chromium's ICU still lists the old names\n * (`Asia/Calcutta`, not `Asia/Kolkata`), so without this a search for Kolkata finds nothing\n * and a stored `Asia/Kolkata` matches no option.\n */\nconst RENAMED: Record<string, string> = {\n 'America/Godthab': 'America/Nuuk',\n 'Asia/Calcutta': 'Asia/Kolkata',\n 'Asia/Katmandu': 'Asia/Kathmandu',\n 'Asia/Rangoon': 'Asia/Yangon',\n 'Asia/Saigon': 'Asia/Ho_Chi_Minh',\n 'Atlantic/Faeroe': 'Atlantic/Faroe',\n 'Europe/Kiev': 'Europe/Kyiv',\n 'Pacific/Enderbury': 'Pacific/Kanton',\n 'Pacific/Ponape': 'Pacific/Pohnpei',\n 'Pacific/Truk': 'Pacific/Chuuk',\n};\n\n/** The current IANA name for a zone: `Asia/Kolkata` for `Asia/Calcutta`. */\nexport const currentZoneName = (zone: string): string => RENAMED[zone] ?? zone;\n\n/** `Intl.supportedValuesOf` is ES2022 and missing from older runtimes — read it defensively. */\nfunction supportedTimeZones(): string[] {\n const intl = Intl as typeof Intl & { supportedValuesOf?: (key: 'timeZone') => string[] };\n try {\n const zones = intl.supportedValuesOf?.('timeZone');\n if (zones && zones.length > 0) return zones;\n } catch {\n // Fall through.\n }\n return ['UTC'];\n}\n\n/** `\"+05:30\"` for Asia/Colombo. Minutes east of UTC are returned alongside for sorting. */\nexport function timeZoneOffset(timeZone: string, at: Date = new Date()): { label: string; minutes: number } {\n try {\n const part = new Intl.DateTimeFormat('en-US', { timeZone, timeZoneName: 'longOffset' })\n .formatToParts(at)\n .find((p) => p.type === 'timeZoneName')?.value;\n // \"GMT+05:30\", \"GMT-03:00\", or bare \"GMT\" for UTC itself.\n const match = part?.match(/GMT([+-])(\\d{2}):(\\d{2})/);\n if (!match) return { label: '+00:00', minutes: 0 };\n const [, sign, hh, mm] = match;\n const minutes = (Number(hh) * 60 + Number(mm)) * (sign === '-' ? -1 : 1);\n return { label: `${sign}${hh}:${mm}`, minutes };\n } catch {\n return { label: '+00:00', minutes: 0 };\n }\n}\n\n/**\n * One option per zone, labelled `(UTC+05:30) Asia/Colombo`, west to east then by name.\n * Renamed zones are listed under their current name, once.\n */\nexport function timeZoneOptions(\n zones: readonly string[] = supportedTimeZones(),\n at: Date = new Date(),\n): ComboboxOption<string>[] {\n return Array.from(new Set(zones.map(currentZoneName)))\n .map((zone) => ({ zone, minutes: timeZoneOffset(zone, at).minutes }))\n .sort((a, b) => a.minutes - b.minutes || a.zone.localeCompare(b.zone))\n .map(({ zone }) => zoneOption(zone, at));\n}\n\nconst zoneOption = (zone: string, at: Date): ComboboxOption<string> => ({\n value: zone,\n label: `(UTC${timeZoneOffset(zone, at).label}) ${zone.replace(/_/g, ' ')}`,\n});\n\n/**\n * Searchable IANA time-zone picker. The value is the zone name (`\"Asia/Colombo\"`), never an\n * offset: an offset changes with daylight saving and cannot be turned back into a zone.\n *\n * Labels show the current UTC offset, and the query matches the zone name with or without\n * underscores and the offset itself, so `colombo`, `new york` and `+05:30` all find a zone.\n * A value missing from the list — stored under another name, or outside `timeZones` — is\n * still listed, so a saved zone never renders as an empty field.\n */\nexport function TimeZoneSelect({\n timeZones,\n at,\n placeholder = 'Select a time zone…',\n emptyMessage = 'No time zones match',\n ...props\n}: TimeZoneSelectProps) {\n // `at` is a Date, so depend on its timestamp rather than its identity.\n const atTime = at?.getTime();\n const keep = [props.value, props.defaultValue].filter((v): v is string => !!v);\n const keepKey = keep.join('|');\n const options = useMemo(() => {\n const when = atTime === undefined ? new Date() : new Date(atTime);\n const list = timeZoneOptions(timeZones, when);\n const missing = keep.filter((v) => !list.some((o) => o.value === v));\n return [...missing.map((v) => zoneOption(v, when)), ...list];\n // `keep` is rebuilt every render; `keepKey` is its stable identity.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeZones, atTime, keepKey]);\n\n return (\n <Combobox\n {...props}\n options={options}\n placeholder={placeholder}\n emptyMessage={emptyMessage}\n filter={(option, query) => {\n const q = query.trim().toLowerCase();\n return option.label.toLowerCase().includes(q) || option.value.toLowerCase().includes(q);\n }}\n />\n );\n}\n","import { useEffect, useId, useMemo, useRef, useState, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { SearchIcon } from 'lucide-react';\n\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_ACTIVE,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n} from '../overlays/menu-styles';\n\nexport interface CommandItem {\n id: string;\n label: string;\n description?: string;\n /** Group heading. Items sharing a group render together, in the order given. */\n group?: string;\n icon?: ReactNode;\n /** Trailing hint — pass `<Kbd>` elements. */\n shortcut?: ReactNode;\n /** Extra words to match on that are not in the label — synonyms, the old name of a page. */\n keywords?: string[];\n disabled?: boolean;\n onSelect: () => void;\n}\n\nexport interface CommandProps {\n items: CommandItem[];\n /** Accessible name. Default `Command palette`. */\n label?: string;\n placeholder?: string;\n emptyMessage?: ReactNode;\n /** Called after any item is chosen — usually closes the containing dialog. */\n onAfterSelect?: () => void;\n autoFocus?: boolean;\n className?: string;\n}\n\n/**\n * A ⌘K command palette — filter over *actions* and run one.\n *\n * The same ARIA combobox pattern as `Combobox`, and for the same reasons: `role=\"combobox\"`\n * on the input, focus never leaving it, and `aria-activedescendant` carrying the highlight.\n * What differs is the intent, and it changes two behaviours:\n *\n * - Items are **commands, not values**. There is no selected state to display, no way to\n * clear, and choosing one runs a callback rather than setting anything.\n * - Matching includes `keywords`, so \"logout\" can find \"Sign out\" — a palette is useless if\n * you have to already know the wording.\n *\n * This is the palette body only. Put it in a `Modal` for the usual ⌘K overlay; keeping the\n * two separate means the palette can also be embedded in a page or a `Popover`, and the\n * dialog semantics stay with the component that owns them.\n *\n * A live region reports the result count, because otherwise a screen reader user typing into\n * the filter gets no feedback that the list changed underneath them.\n */\nexport function Command({\n items,\n label = 'Command palette',\n placeholder = 'Type a command or search…',\n emptyMessage = 'No results',\n onAfterSelect,\n autoFocus = true,\n className,\n}: CommandProps) {\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const listRef = useRef<HTMLDivElement>(null);\n\n const matches = useMemo(() => {\n if (!query) return items;\n const q = query.toLowerCase();\n return items.filter((item) => {\n if (item.label.toLowerCase().includes(q)) return true;\n if (item.group?.toLowerCase().includes(q)) return true;\n return item.keywords?.some((keyword) => keyword.toLowerCase().includes(q)) ?? false;\n });\n }, [items, query]);\n\n useEffect(() => {\n setActiveIndex(0);\n }, [query]);\n\n useEffect(() => {\n const node = listRef.current?.querySelector(`#${CSS.escape(optionId(activeIndex))}`);\n // Feature-detected — see the same note in `Combobox`. Absent in jsdom and some webviews.\n if (node instanceof Element && typeof node.scrollIntoView === 'function') {\n node.scrollIntoView({ block: 'nearest' });\n }\n });\n\n const run = (item: CommandItem) => {\n if (item.disabled) return;\n item.onSelect();\n onAfterSelect?.();\n };\n\n const move = (delta: number) => {\n if (matches.length === 0) return;\n setActiveIndex((current) => {\n let next = current;\n for (let i = 0; i < matches.length; i++) {\n next = (next + delta + matches.length) % matches.length;\n if (!matches[next]?.disabled) break;\n }\n return next;\n });\n };\n\n let renderedGroup: string | undefined;\n\n return (\n <div className={clsx('flex w-full flex-col', className)}>\n <div className=\"flex items-center gap-2 border-b border-default px-3.5 py-3\">\n <SearchIcon aria-hidden className=\"size-4 shrink-0 text-icon-default-secondary\" />\n <input\n role=\"combobox\"\n type=\"text\"\n autoComplete=\"off\"\n // A palette's list is always visible while it is open, so `aria-expanded` is\n // permanently true rather than tracking a collapsed state that never happens.\n aria-expanded\n aria-controls={listboxId}\n aria-autocomplete=\"list\"\n aria-activedescendant={matches.length > 0 ? optionId(activeIndex) : undefined}\n aria-label={label}\n // Autofocus is correct here specifically: a command palette is opened by an\n // explicit gesture (⌘K) whose entire purpose is to start typing, so *not* focusing\n // the input would strand the user. The rule guards against autofocus on ordinary\n // page load, which this is not. Caller can still opt out.\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n value={query}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n move(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n move(-1);\n break;\n case 'Home':\n event.preventDefault();\n setActiveIndex(0);\n break;\n case 'End':\n event.preventDefault();\n setActiveIndex(matches.length - 1);\n break;\n case 'Enter':\n if (matches[activeIndex]) {\n event.preventDefault();\n run(matches[activeIndex]);\n }\n break;\n default:\n break;\n }\n }}\n className=\"min-w-0 flex-1 bg-transparent text-body-sm text-default outline-none placeholder:text-default-tertiary\"\n />\n </div>\n\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label={label}\n // Focus stays in the filter input and `aria-activedescendant` carries the\n // highlight, so this must not become a tab stop of its own.\n className={clsx('max-h-80 overflow-y-auto p-1.5', SCROLLBAR_CLASSES)}\n >\n {matches.length === 0 && (\n <p className=\"px-2.5 py-6 text-center text-body-sm text-default-secondary\">\n {emptyMessage}\n </p>\n )}\n {matches.map((item, index) => {\n const isActive = index === activeIndex;\n const groupHeading = item.group !== renderedGroup ? item.group : undefined;\n renderedGroup = item.group;\n\n return (\n <div key={item.id}>\n {groupHeading && (\n <div\n role=\"presentation\"\n className={OVERLAY_HEADING}\n >\n {groupHeading}\n </div>\n )}\n {/* Not focusable by design — see the note in `Combobox`. Focus stays in the\n filter input and `aria-activedescendant` carries the highlight. */}\n {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus, jsx-a11y/click-events-have-key-events */}\n <div\n id={optionId(index)}\n role=\"option\"\n aria-selected={isActive}\n aria-disabled={item.disabled || undefined}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => run(item)}\n onPointerEnter={() => !item.disabled && setActiveIndex(index)}\n className={clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE.md,\n 'items-center',\n item.disabled\n ? 'cursor-not-allowed text-disabled'\n : isActive\n ? clsx(OVERLAY_ITEM_ACTIVE, 'text-default')\n : 'text-default',\n )}\n >\n {item.icon && (\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n {item.icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{item.label}</span>\n {item.description && (\n <span className=\"block truncate text-body-tiny text-default-secondary\">\n {item.description}\n </span>\n )}\n </span>\n {item.shortcut && (\n <span className=\"ml-auto flex shrink-0 items-center gap-1\">{item.shortcut}</span>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Typing filters the list silently otherwise — a sighted user sees it shrink, a\n screen reader user gets nothing. */}\n <span aria-live=\"polite\" className=\"sr-only\">\n {`${matches.length} ${matches.length === 1 ? 'result' : 'results'}`}\n </span>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\n/**\n * The six status tones from the Figma design system.\n * Values live in `src/app/styles/tokens/status.css`; see that file for why they do\n * not derive from the SDS semantic colour families.\n */\nexport type StatusTone =\n | 'neutral'\n | 'info'\n | 'warning'\n | 'caution'\n | 'accent'\n | 'positive'\n | 'danger';\n\nexport type StatusBadgeSize = 'sm' | 'md';\n\nconst TONE_STYLES: Record<StatusTone, string> = {\n neutral: 'bg-status-neutral text-status-neutral',\n info: 'bg-status-info text-status-info',\n warning: 'bg-status-warning text-status-warning',\n caution: 'bg-status-caution text-status-caution',\n accent: 'bg-status-accent text-status-accent',\n positive: 'bg-status-positive text-status-positive',\n danger: 'bg-status-danger text-status-danger',\n};\n\nconst DOT_STYLES: Record<StatusTone, string> = {\n neutral: 'bg-status-dot-neutral',\n info: 'bg-status-dot-info',\n warning: 'bg-status-dot-warning',\n caution: 'bg-status-dot-caution',\n accent: 'bg-status-dot-accent',\n positive: 'bg-status-dot-positive',\n danger: 'bg-status-dot-danger',\n};\n\nconst SIZE_STYLES: Record<StatusBadgeSize, string> = {\n sm: 'px-2 py-0.5 text-body-tiny',\n md: 'px-3 py-1 text-body-xs',\n};\n\nexport interface StatusBadgeProps {\n label: string;\n tone?: StatusTone;\n size?: StatusBadgeSize;\n /** Leading dot. On by default — the Figma status pills all carry one. */\n dot?: boolean;\n /**\n * Leading glyph, replacing the dot — e.g. `<CheckIcon className=\"size-3\" />`.\n * Use for states a colour alone under-states, like verified or rejected.\n */\n icon?: ReactNode;\n className?: string;\n}\n\n/**\n * The status pill.\n *\n * Replaces thirteen inline re-implementations of the same markup plus five\n * competing hardcoded hex palettes. Generalises `TableCellStatusPill`, which had\n * this exact markup but required callers to pass raw hex strings.\n *\n * Note this is NOT `StatusChip` — that one renders a label *and a count* and is a\n * different component.\n */\nexport function StatusBadge({\n label,\n tone = 'neutral',\n size = 'md',\n dot = true,\n icon,\n className,\n}: StatusBadgeProps) {\n return (\n <span\n data-tone={tone}\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded-full font-medium leading-tight whitespace-nowrap',\n SIZE_STYLES[size],\n TONE_STYLES[tone],\n className,\n )}\n >\n {icon ? (\n <span className=\"shrink-0\">{icon}</span>\n ) : (\n dot && <span className={clsx('size-1.5 shrink-0 rounded-full', DOT_STYLES[tone])} />\n )}\n {label}\n </span>\n );\n}\n","import clsx from 'clsx';\n\nexport type StatusDotTone = 'brand' | 'positive' | 'warning' | 'danger' | 'neutral' | 'default';\n\nexport interface StatusDotProps {\n tone?: StatusDotTone;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex color, overrides `tone` via inline style. Use when the exact source color doesn't match a design token. */\n color?: string;\n className?: string;\n}\n\nconst dotTones: Record<StatusDotTone, string> = {\n brand: 'bg-brand',\n positive:'bg-positive',\n warning: 'bg-warning',\n danger: 'bg-danger',\n neutral: 'bg-neutral',\n default: 'bg-default-tertiary',\n};\n\nexport function StatusDot({ tone = 'default', color, className }: StatusDotProps) {\n return (\n <span\n data-tone={tone}\n className={clsx('inline-block size-1.5 shrink-0 rounded-full', !color && dotTones[tone], className)}\n style={color ? { backgroundColor: color } : undefined}\n />\n );\n}\n","import clsx from 'clsx';\nimport { StatusDot } from './status-dot';\nimport type { StatusDotTone } from './status-dot';\n\nexport interface StatusChipProps {\n label: string;\n count: number | string;\n tone?: StatusDotTone;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex dot color, overrides `tone` via inline style. Use when the exact source color doesn't match a design token. */\n dotColor?: string;\n bg?: string;\n className?: string;\n}\n\nexport function StatusChip({ label, count, tone = 'default', dotColor, bg, className }: StatusChipProps) {\n return (\n <span\n data-tone={tone}\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded-full px-3 py-1',\n !bg && 'bg-default-secondary',\n className,\n )}\n style={bg ? { backgroundColor: bg } : undefined}\n >\n <StatusDot tone={tone} color={dotColor} />\n <span className=\"text-body-xs font-medium text-default\">{count}</span>\n <span className=\"text-body-xs text-default-secondary\">{label}</span>\n </span>\n );\n}\n","import clsx from 'clsx';\nimport { StatusDot } from './status-dot';\nimport type { StatusDotTone } from './status-dot';\n\nexport interface CountBadgeProps {\n count: number | string;\n label?: string;\n tone?: StatusDotTone;\n className?: string;\n}\n\nexport function CountBadge({ count, label, tone = 'positive', className }: CountBadgeProps) {\n return (\n <span\n data-tone={tone}\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded-full border border-default px-3 py-1 text-body-xs font-medium text-default',\n className,\n )}\n >\n <StatusDot tone={tone} />\n {count}\n {label && <span className=\"text-default-secondary\">{label}</span>}\n </span>\n );\n}\n","import clsx from 'clsx';\n\nexport type TagPillTone = 'default' | 'brand' | 'positive' | 'warning' | 'danger';\n\nexport interface TagPillProps {\n label: string;\n tone?: TagPillTone;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex bg/text pair, overrides `tone` via inline style. Use when the exact source colors don't match design tokens. */\n bg?: string;\n color?: string;\n className?: string;\n}\n\nconst toneStyles: Record<TagPillTone, string> = {\n default: 'bg-default-secondary text-default-secondary',\n brand: 'bg-brand-tertiary text-brand',\n positive:'bg-positive-tertiary text-positive',\n warning: 'bg-warning-tertiary text-warning',\n danger: 'bg-danger-tertiary text-danger',\n};\n\nexport function TagPill({ label, tone = 'default', bg, color, className }: TagPillProps) {\n return (\n <span\n data-tone={tone}\n className={clsx(\n 'inline-flex items-center rounded-full px-2 py-0.5 text-body-xs font-medium',\n !bg && !color && toneStyles[tone],\n className,\n )}\n style={{\n ...(bg ? { backgroundColor: bg } : undefined),\n ...(color ? { color } : undefined),\n }}\n >\n {label}\n </span>\n );\n}\n","import clsx from 'clsx';\n\nimport type { StatusTone } from './status-badge';\n\nconst DOT: Record<StatusTone, string> = {\n neutral: 'bg-status-dot-neutral',\n info: 'bg-status-dot-info',\n warning: 'bg-status-dot-warning',\n caution: 'bg-status-dot-caution',\n accent: 'bg-status-dot-accent',\n positive: 'bg-status-dot-positive',\n danger: 'bg-status-dot-danger',\n};\n\nexport interface TrailChipProps {\n label: string;\n value: string;\n tone?: StatusTone;\n /**\n * Data-driven dot colour, overriding `tone`. The investigations trail mirrors the\n * severity accent of whichever tree node is selected, and those accents come from\n * the row data rather than the status palette — this is the escape hatch Phase 10\n * classifies as \"genuinely data-driven colour\", not a token bypass.\n */\n dotColor?: string;\n className?: string;\n}\n\n/**\n * Dot + small uppercase label + value, used for the drill-down breadcrumb trail on\n * the investigations page.\n *\n * Promoted from `pages/investigations`, where the dot colour was passed as a raw hex.\n */\nexport function TrailChip({ label, value, tone = 'info', dotColor, className }: TrailChipProps) {\n return (\n <div\n data-tone={tone}\n className={clsx(\n 'flex items-center gap-2 rounded-full border border-default bg-default px-3 py-1.5',\n className,\n )}\n >\n <span\n className={clsx('size-1.5 shrink-0 rounded-full', !dotColor && DOT[tone])}\n style={dotColor ? { backgroundColor: dotColor } : undefined}\n />\n <span className=\"text-body-tiny font-semibold uppercase tracking-wide text-default-secondary\">\n {label}\n </span>\n <span className=\"text-body-xs font-medium text-default\">{value}</span>\n </div>\n );\n}\n","import { StatusBadge, type StatusTone } from './status-badge';\n\nexport type UserAccountStatus = 'active' | 'pending' | 'deactivated';\n\nconst STATUS_META: Record<UserAccountStatus, { label: string; tone: StatusTone }> = {\n active: { label: 'Active', tone: 'positive' },\n // `caution` (pale yellow), not `warning` (orange) — Pending is one step below a\n // warning on the severity ramp, and reads as waiting rather than at risk.\n pending: { label: 'Pending', tone: 'caution' },\n deactivated: { label: 'Deactivated', tone: 'danger' },\n};\n\nexport interface UserStatusPillProps {\n status: UserAccountStatus;\n}\n\n/** Account-status pill. A thin wrapper over `StatusBadge`. */\nexport function UserStatusPill({ status }: UserStatusPillProps) {\n const { label, tone } = STATUS_META[status];\n return <StatusBadge label={label} tone={tone} />;\n}\n","import clsx from 'clsx';\nimport { CheckIcon, CircleAlertIcon, LoaderCircleIcon, MinusIcon, XIcon } from 'lucide-react';\n\n/**\n * States of a compliance check.\n *\n * Union of the two previously-divergent local unions:\n * - `features/entity-detail` had passed | in_progress | pending | action_required\n * - `features/reviewer-detail` had passed | in-progress | failed | pending | waived\n *\n * Note `in_progress` (underscore) is canonical — entity-detail's spelling, which is\n * the one backed by the API. reviewer-detail used `in-progress` (hyphen) in mock data.\n */\nexport type CheckIndicatorStatus =\n | 'passed'\n | 'in_progress'\n | 'action_required'\n | 'failed'\n | 'pending'\n | 'waived';\n\n/**\n * `action_required` and `failed` share the Figma colours and differ only in glyph\n * (`!` vs `✕`); `waived` shares `pending`'s colours and adds a dash.\n */\nconst STATUS_STYLES: Record<CheckIndicatorStatus, string> = {\n passed: 'bg-status-check-passed border-status-check-passed text-status-check-passed',\n in_progress: 'bg-status-check-progress border-status-check-progress text-status-check-progress',\n action_required: 'bg-status-check-failed border-status-check-failed text-status-check-failed',\n failed: 'bg-status-check-failed border-status-check-failed text-status-check-failed',\n pending: 'bg-status-check-pending border-status-check-pending text-status-check-pending',\n waived: 'bg-status-check-pending border-status-check-pending text-status-check-pending',\n};\n\n/**\n * Glyphs — every one now comes from `lucide-react`, so the set is stroke-consistent.\n *\n * The two that used to be typographic: `◐` became `LoaderCircleIcon` (lucide has no\n * half-filled circle, but a partial ring reads as in-progress and is a real icon), and\n * `!` became `CircleAlertIcon`. Both are a small visual change from 0.2.0.\n */\nfunction StatusGlyph({ status }: { status: CheckIndicatorStatus }) {\n switch (status) {\n case 'passed':\n return <CheckIcon className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'failed':\n return <XIcon className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'waived':\n return <MinusIcon className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'in_progress':\n return <LoaderCircleIcon className=\"size-3\" strokeWidth={3} aria-hidden />;\n case 'action_required':\n return <CircleAlertIcon className=\"size-3.5\" strokeWidth={2.5} aria-hidden />;\n case 'pending':\n return null;\n }\n}\n\nexport interface CheckIndicatorProps {\n status: CheckIndicatorStatus;\n /** Accessible label. Without one the indicator is decorative, which is correct when an adjacent text label already names the state. */\n label?: string;\n className?: string;\n}\n\n/**\n * The 22px outlined circle used for compliance-check state in entity and reviewer\n * detail. Ring and glyph share one colour; see the check tokens in\n * `src/app/styles/tokens/status.css`.\n */\nexport function CheckIndicator({ status, label, className }: CheckIndicatorProps) {\n return (\n <div\n data-status={status}\n className={clsx(\n 'flex size-[22px] shrink-0 items-center justify-center rounded-full border-[1.5px]',\n STATUS_STYLES[status],\n className,\n )}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n >\n <StatusGlyph status={status} />\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type EntityIconBadgeSize = 'sm' | 'md';\nexport type EntityIconBadgeTone = 'default' | 'brand' | 'positive' | 'warning' | 'danger' | 'neutral';\nexport type EntityIconBadgeShape = 'square' | 'circle';\n\nexport interface EntityIconBadgeProps {\n size?: EntityIconBadgeSize;\n tone?: EntityIconBadgeTone;\n /**\n * `square` is the rounded-rect used on entity rows. `circle` is the tinted glyph\n * circle used in modal headers. A prop rather than a `className` override, so it\n * does not depend on Tailwind's stylesheet emit order.\n */\n shape?: EntityIconBadgeShape;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex background, overrides `tone` via inline style. Use when the exact source color doesn't match a design token. */\n bg?: string;\n iconColor?: string;\n children: ReactNode;\n className?: string;\n}\n\nconst sizeStyles: Record<EntityIconBadgeSize, string> = {\n sm: 'size-8',\n md: 'size-10',\n};\n\nconst shapeStyles: Record<EntityIconBadgeShape, Record<EntityIconBadgeSize, string>> = {\n square: { sm: 'rounded-lg', md: 'rounded-xl' },\n circle: { sm: 'rounded-full', md: 'rounded-full' },\n};\n\nconst toneStyles: Record<EntityIconBadgeTone, string> = {\n default: 'bg-default-secondary text-icon-default',\n brand: 'bg-brand-tertiary text-icon-brand',\n positive:'bg-positive-tertiary text-icon-positive',\n warning: 'bg-warning-tertiary text-icon-warning',\n danger: 'bg-danger-tertiary text-icon-danger',\n neutral: 'bg-neutral-tertiary text-icon-neutral',\n};\n\nexport function EntityIconBadge({ size = 'sm', tone = 'default', shape = 'square', bg, iconColor, children, className }: EntityIconBadgeProps) {\n return (\n <span\n data-tone={tone}\n className={clsx(\n 'inline-flex shrink-0 items-center justify-center',\n sizeStyles[size],\n shapeStyles[shape][size],\n !bg && !iconColor && toneStyles[tone],\n className,\n )}\n style={{\n ...(bg ? { backgroundColor: bg } : undefined),\n ...(iconColor ? { color: iconColor } : undefined),\n }}\n >\n {children}\n </span>\n );\n}\n","import { forwardRef, useEffect, useId, useRef, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { composeRefs } from '../../lib/slot';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { CheckControl, type CheckControlSize } from './check-control';\n\nexport type CheckboxSize = CheckControlSize;\n\nexport interface CheckboxProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'checked'> {\n /** Controlled. Omit and pass `defaultChecked` for uncontrolled. */\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n label?: ReactNode;\n /** Second line under the label. Matches Figma's `Supporting text` axis. */\n description?: ReactNode;\n /** Matches Figma's `Size` axis. Default `md`, which is 0.3.0's fixed 18px. */\n size?: CheckboxSize;\n indeterminate?: boolean;\n invalid?: boolean;\n className?: string;\n}\n\nconst LABEL_TEXT: Record<CheckboxSize, string> = {\n sm: 'text-body-tiny',\n md: 'text-body-xs',\n};\n\n/**\n * Checkbox built on a real `<input type=\"checkbox\">`.\n *\n * Widened in 0.4.0 to match Figma's `Checkbox` set, which has `Size: sm | md`,\n * `Text` and `Supporting text` axes — none of which existed in code, where the control was\n * a fixed 18px with an optional single-line label and no `id`, `name`, `value`, `required`\n * or ref. It also had no uncontrolled mode: `checked` and `onChange` were both required, so\n * the simplest possible use site needed a `useState` in the consumer.\n *\n * `onChange` became `onCheckedChange` and takes a boolean, matching the rest of 0.4.0.\n * The native `onChange` event shape is still reachable — the ref is forwarded to the real\n * input, so `react-hook-form`'s `register()` works.\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n {\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n label,\n description,\n size = 'md',\n indeterminate = false,\n invalid = false,\n disabled = false,\n id,\n className,\n ...props\n },\n ref,\n) {\n const [checked, setChecked] = useControllableState({\n value: checkedProp,\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n });\n\n const inputRef = useRef<HTMLInputElement>(null);\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n\n // `indeterminate` is a DOM property with no React attribute, so it has to be applied\n // imperatively.\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n return (\n <div className={clsx('flex flex-col', className)}>\n <label\n htmlFor={controlId}\n className={clsx(\n 'group inline-flex items-start gap-2.5',\n disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer',\n )}\n >\n <input\n ref={composeRefs<HTMLInputElement>(inputRef, ref)}\n id={controlId}\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={description ? descriptionId : undefined}\n onChange={(event) => setChecked(event.target.checked)}\n className=\"peer sr-only\"\n {...props}\n />\n <CheckControl\n type=\"checkbox\"\n checked={checked}\n indeterminate={indeterminate}\n disabled={disabled}\n invalid={invalid}\n size={size}\n />\n {label && <span className={clsx(LABEL_TEXT[size], 'text-default')}>{label}</span>}\n </label>\n {/* Outside the <label>, deliberately. Anything inside a label becomes part of the\n control's *accessible name*, so a nested description turns the name into\n \"Marketing We will not spam you\" — and `aria-describedby` then points at text that\n was already read as the name. Indented to line up under the label text. */}\n {description && (\n <span\n id={descriptionId}\n className={clsx(\n 'mt-0.5 pl-[26px]',\n LABEL_TEXT[size],\n disabled ? 'text-disabled' : 'text-default-secondary',\n )}\n >\n {description}\n </span>\n )}\n </div>\n );\n});\n","import clsx from 'clsx';\nimport { CheckIcon, MinusIcon } from 'lucide-react';\n\nexport type CheckControlSize = 'sm' | 'md';\n\n/**\n * The box/circle glyph shared by `Checkbox` and `RadioGroup`.\n *\n * Figma models both in a single `Checkbox` component set with a `Type: Checkbox | Radio`\n * axis and a `Size: sm | md` axis, because the geometry, border weight, states and\n * spacing are identical — only the corner radius and the checked mark differ. Splitting\n * them in code while Figma keeps them together is how the two drift, so this holds the\n * shared half.\n *\n * Always `aria-hidden`: the real `<input>` carries the state, and this is its picture.\n */\nexport const CHECK_SIZE: Record<CheckControlSize, { box: string; glyph: string; dot: string }> = {\n sm: { box: 'size-4', glyph: 'size-2.5', dot: 'size-1.5' },\n md: { box: 'size-[18px]', glyph: 'size-3', dot: 'size-2' },\n};\n\nexport interface CheckControlProps {\n type: 'checkbox' | 'radio';\n checked: boolean;\n indeterminate?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n size?: CheckControlSize;\n}\n\nexport function CheckControl({\n type,\n checked,\n indeterminate = false,\n disabled = false,\n invalid = false,\n size = 'md',\n}: CheckControlProps) {\n const s = CHECK_SIZE[size];\n const on = checked || indeterminate;\n\n return (\n <span\n aria-hidden\n className={clsx(\n 'mt-px flex shrink-0 items-center justify-center border-[1.5px] transition-colors',\n s.box,\n type === 'radio' ? 'rounded-full' : 'rounded-[4px]',\n // Ring is drawn from the peer input's focus state, so the visual box tracks real\n // focus rather than hover.\n 'peer-focus-visible:ring-2 peer-focus-visible:ring-brand peer-focus-visible:ring-offset-1 peer-focus-visible:ring-offset-default',\n disabled\n ? on\n ? 'border-disabled bg-disabled text-disabled-on-disabled'\n : 'border-disabled bg-disabled'\n : on\n ? 'border-brand-emphasis bg-brand text-brand-on-brand'\n : invalid\n ? 'border-danger bg-default'\n : 'border-default-secondary bg-default',\n )}\n >\n {type === 'checkbox' ? (\n indeterminate ? (\n <MinusIcon className={s.glyph} strokeWidth={3} />\n ) : checked ? (\n <CheckIcon className={s.glyph} strokeWidth={3} />\n ) : null\n ) : checked ? (\n <span className={clsx('rounded-full bg-current', s.dot)} />\n ) : null}\n </span>\n );\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { CheckControl, type CheckControlSize } from './check-control';\n\nexport type RadioGroupOrientation = 'vertical' | 'horizontal';\n\ninterface RadioGroupContextValue {\n name: string;\n value: string | undefined;\n setValue: (value: string) => void;\n size: CheckControlSize;\n disabled: boolean;\n invalid: boolean;\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextValue | null>(null);\n\nexport interface RadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n children: ReactNode;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Shared `name` for the underlying inputs. Generated when omitted. */\n name?: string;\n /** Names the group. Prefer wrapping in `FieldSet` + `FieldLegend` for a visible label. */\n label?: string;\n size?: CheckControlSize;\n orientation?: RadioGroupOrientation;\n disabled?: boolean;\n invalid?: boolean;\n required?: boolean;\n}\n\n/**\n * Radio group. Matches the `Type=Radio` half of Figma's `Checkbox` set, and shares its\n * geometry through `CheckControl`.\n *\n * Built on real `<input type=\"radio\">` elements sharing a `name`, which is what buys the\n * whole keyboard contract for free: arrow keys move *and* select, only the checked radio is\n * in the tab sequence, and the group is announced as \"2 of 4\". A `div`-based\n * `role=\"radiogroup\"` has to reimplement all of that, and the version of this pattern the\n * library already had — `SegmentedControl` before 0.4.0 — shipped with none of it.\n *\n * `role=\"radiogroup\"` is still set explicitly rather than relying on a `<fieldset>`, so the\n * group works with or without a visible legend.\n */\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(function RadioGroup(\n {\n children,\n value: valueProp,\n defaultValue,\n onValueChange,\n name,\n label,\n size = 'md',\n orientation = 'vertical',\n disabled = false,\n invalid = false,\n required = false,\n className,\n ...rest\n },\n ref,\n) {\n const generatedName = useId();\n const [value, setValue] = useControllableState<string | undefined>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: string | undefined) => void) | undefined,\n });\n\n return (\n <RadioGroupContext.Provider\n value={{\n name: name ?? generatedName,\n value,\n setValue: (next) => setValue(next),\n size,\n disabled,\n invalid,\n }}\n >\n <div\n ref={ref}\n role=\"radiogroup\"\n aria-label={label}\n aria-required={required || undefined}\n aria-invalid={invalid || undefined}\n aria-orientation={orientation}\n data-slot=\"radio-group\"\n className={clsx(\n 'flex',\n orientation === 'vertical' ? 'flex-col gap-2.5' : 'flex-row flex-wrap gap-4',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </RadioGroupContext.Provider>\n );\n});\n\nexport interface RadioProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'checked'> {\n value: string;\n label?: ReactNode;\n /** Second line under the label. Matches Figma's `Supporting text` axis. */\n description?: ReactNode;\n className?: string;\n}\n\nconst LABEL_TEXT: Record<CheckControlSize, string> = {\n sm: 'text-body-tiny',\n md: 'text-body-xs',\n};\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n { value, label, description, disabled, id, className, ...props },\n ref,\n) {\n const group = useContext(RadioGroupContext);\n if (!group) throw new Error('<Radio> must be used inside <RadioGroup>');\n\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n const isDisabled = disabled ?? group.disabled;\n const checked = group.value === value;\n\n return (\n <div className={clsx('flex flex-col', className)}>\n <label\n htmlFor={controlId}\n className={clsx(\n 'group inline-flex items-start gap-2.5',\n isDisabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer',\n )}\n >\n <input\n ref={ref}\n id={controlId}\n type=\"radio\"\n name={group.name}\n value={value}\n checked={checked}\n disabled={isDisabled}\n aria-describedby={description ? descriptionId : undefined}\n onChange={() => group.setValue(value)}\n className=\"peer sr-only\"\n {...props}\n />\n <CheckControl\n type=\"radio\"\n checked={checked}\n disabled={isDisabled}\n invalid={group.invalid}\n size={group.size}\n />\n {label && <span className={clsx(LABEL_TEXT[group.size], 'text-default')}>{label}</span>}\n </label>\n {/* Outside the <label> — see the note in `Checkbox`. Text nested in a label becomes\n part of the accessible *name*, so the description would be read twice: once as\n the name and again as the description. */}\n {description && (\n <span\n id={descriptionId}\n className={clsx(\n 'mt-0.5 pl-[26px]',\n LABEL_TEXT[group.size],\n isDisabled ? 'text-disabled' : 'text-default-secondary',\n )}\n >\n {description}\n </span>\n )}\n </div>\n );\n});\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\n/** Matches `MultiSelectCard`'s sizes, so the single- and multi-select cards line up. */\nexport type RadioCardsSize = 'default' | 'sm';\n\ninterface RadioCardsContextValue {\n name: string;\n value: string | undefined;\n setValue: (value: string) => void;\n size: RadioCardsSize;\n disabled: boolean;\n required: boolean;\n}\n\nconst RadioCardsContext = createContext<RadioCardsContextValue | null>(null);\n\nexport interface RadioCardsProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> {\n children: ReactNode;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Shared `name` for the underlying radios, which also submit with a form. Generated when omitted. */\n name?: string;\n /** Names the group. Prefer a visible `FieldLegend` in a `FieldSet` when there is one. */\n label?: string;\n size?: RadioCardsSize;\n disabled?: boolean;\n required?: boolean;\n}\n\n/**\n * Choose one of a few options shown as cards: a plan, a workspace type, an import source. The\n * single-select sibling of `MultiSelectCard`, new in 0.7.0 (Radix Themes' `Radio Cards`).\n *\n * Each card is a `<label>` around a real `<input type=\"radio\">`, for the same reason\n * `RadioGroup` uses native radios: arrows move *and* select, only the checked card is a tab\n * stop, and the group announces \"2 of 3\", with nothing reimplemented. The card's selected look\n * is styled from the input's own `:checked` state (`peer-checked:`), so the visual and the\n * semantics cannot disagree.\n *\n * The grid is the caller's: pass layout classes, e.g. `className=\"sm:grid-cols-3\"`.\n */\nexport const RadioCards = forwardRef<HTMLDivElement, RadioCardsProps>(function RadioCards(\n {\n children,\n value: valueProp,\n defaultValue,\n onValueChange,\n name,\n label,\n size = 'default',\n disabled = false,\n required = false,\n className,\n ...rest\n },\n ref,\n) {\n const generatedName = useId();\n const [value, setValue] = useControllableState<string | undefined>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange as ((next: string | undefined) => void) | undefined,\n });\n\n return (\n <RadioCardsContext.Provider\n value={{ name: name ?? generatedName, value, setValue, size, disabled, required }}\n >\n <div\n ref={ref}\n role=\"radiogroup\"\n aria-label={label}\n aria-required={required || undefined}\n data-slot=\"radio-cards\"\n className={cn('grid gap-3', className)}\n {...rest}\n >\n {children}\n </div>\n </RadioCardsContext.Provider>\n );\n});\n\nconst SIZE: Record<RadioCardsSize, { pad: string; iconBox: string; icon: string; mark: string; gap: string; title: string }> = {\n default: { pad: 'p-4', iconBox: 'size-10 rounded-xl', icon: 'size-5', mark: 'size-5', gap: 'mt-3', title: 'text-body-sm' },\n sm: { pad: 'p-3', iconBox: 'size-8 rounded-lg', icon: 'size-4', mark: 'size-4', gap: 'mt-2', title: 'text-body-xs' },\n};\n\nexport interface RadioCardsItemProps {\n value: string;\n title: ReactNode;\n description?: ReactNode;\n /** Leading glyph in a tinted box, as on `MultiSelectCard`. */\n icon?: ReactNode;\n disabled?: boolean;\n className?: string;\n}\n\nexport const RadioCardsItem = forwardRef<HTMLInputElement, RadioCardsItemProps>(function RadioCardsItem(\n { value, title, description, icon, disabled: itemDisabled = false, className },\n ref,\n) {\n const group = useContext(RadioCardsContext);\n if (!group) throw new Error('<RadioCardsItem> must be used inside <RadioCards>');\n const s = SIZE[group.size];\n const disabled = group.disabled || itemDisabled;\n const titleId = useId();\n const descriptionId = useId();\n\n return (\n <label\n data-slot=\"radio-cards-item\"\n className={cn(\n 'relative block cursor-pointer rounded-2xl border-2 border-default bg-default text-left transition-all',\n 'hover:border-default-secondary',\n // Selected and focus states come from the radio itself.\n 'has-[:checked]:border-brand has-[:checked]:bg-brand-tertiary',\n 'has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-brand has-[:focus-visible]:ring-offset-1 has-[:focus-visible]:ring-offset-default',\n 'has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60',\n s.pad,\n className,\n )}\n >\n <input\n ref={ref}\n type=\"radio\"\n name={group.name}\n value={value}\n checked={group.value === value}\n onChange={() => group.setValue(value)}\n disabled={disabled}\n required={group.required}\n // Named by the title alone. The wrapping <label> would otherwise fold the description\n // into the name (\"Team Up to 20 seats\"); it is wired as a description instead.\n aria-labelledby={titleId}\n aria-describedby={description ? descriptionId : undefined}\n className=\"sr-only\"\n />\n <div className=\"flex items-start justify-between gap-2\">\n {icon ? (\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center bg-brand-tertiary',\n '[label:has(:checked)_&]:bg-brand',\n s.iconBox,\n )}\n >\n <span className={clsx(s.icon, 'text-icon-brand [label:has(:checked)_&]:text-icon-brand-on-brand')}>\n {icon}\n </span>\n </span>\n ) : (\n <span />\n )}\n {/* The radio mark: a ring that fills with a dot when chosen. */}\n <span\n aria-hidden\n className={clsx(\n 'flex shrink-0 items-center justify-center rounded-full border-2 border-default',\n '[label:has(:checked)_&]:border-brand',\n s.mark,\n )}\n >\n <span className=\"size-2 scale-0 rounded-full bg-brand transition-transform [label:has(:checked)_&]:scale-100\" />\n </span>\n </div>\n <div className={s.gap}>\n <span id={titleId} className={clsx('block font-semibold text-default [label:has(:checked)_&]:text-brand', s.title)}>\n {title}\n </span>\n {description && (\n <span id={descriptionId} className=\"mt-0.5 block text-body-tiny text-default-secondary\">\n {description}\n </span>\n )}\n </div>\n </label>\n );\n});\n","import { createContext, forwardRef, useContext, useId, type ReactNode } from 'react';\nimport { cn } from '../../lib/cn';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { Checkbox, type CheckboxSize } from './checkbox';\nimport { FieldLegend, FieldSet } from './field';\n\ninterface CheckboxGroupContextValue {\n name: string;\n value: string[];\n toggle: (value: string, checked: boolean) => void;\n size: CheckboxSize;\n disabled: boolean;\n /** Whether a required group is still empty, so every item carries `required`. */\n required: boolean;\n}\n\nconst CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(null);\n\nexport interface CheckboxGroupProps {\n children: ReactNode;\n /** The group's visible name, rendered as the fieldset's `<legend>`. */\n legend: ReactNode;\n /** Checked values. Controlled; omit and pass `defaultValue` for uncontrolled. */\n value?: string[];\n defaultValue?: string[];\n onValueChange?: (value: string[]) => void;\n /** Shared `name`, so every checked value posts with a form. Generated when omitted. */\n name?: string;\n size?: CheckboxSize;\n orientation?: 'vertical' | 'horizontal';\n disabled?: boolean;\n /**\n * At least one option must be checked. While none is, every checkbox carries the native\n * `required`, so the form will not submit and the browser points at the first one. Checking\n * any of them lifts it from all. The legend gets\n * the same marker as a required field label.\n */\n required?: boolean;\n className?: string;\n}\n\n/**\n * A named set of checkboxes sharing one value array, new in 0.7.0 (Radix Themes'\n * `Checkbox Group`).\n *\n * A real `<fieldset>` and `<legend>`, which is the only markup that announces the group's name\n * before each option. Each item is the library's native `Checkbox`, so keyboard, form and\n * validation behaviour are the browser's.\n */\nexport const CheckboxGroup = forwardRef<HTMLFieldSetElement, CheckboxGroupProps>(function CheckboxGroup(\n {\n children,\n legend,\n value: valueProp,\n defaultValue = [],\n onValueChange,\n name,\n size = 'md',\n orientation = 'vertical',\n disabled = false,\n required = false,\n className,\n },\n ref,\n) {\n const generatedName = useId();\n const [value, setValue] = useControllableState<string[]>({\n value: valueProp,\n defaultValue,\n onChange: onValueChange,\n });\n\n const toggle = (item: string, checked: boolean) =>\n setValue(checked ? [...value.filter((v) => v !== item), item] : value.filter((v) => v !== item));\n\n const context = {\n name: name ?? generatedName,\n value,\n toggle,\n size,\n disabled,\n required: required && value.length === 0,\n };\n\n return (\n <CheckboxGroupContext.Provider value={context}>\n <FieldSet ref={ref} data-slot=\"checkbox-group\" data-required={required || undefined} className={className}>\n <FieldLegend\n variant=\"label\"\n className={required ? \"after:ml-0.5 after:text-danger after:content-['*']\" : undefined}\n >\n {legend}\n </FieldLegend>\n <div className={cn('flex', orientation === 'vertical' ? 'flex-col gap-2.5' : 'flex-row flex-wrap gap-4')}>\n {children}\n </div>\n </FieldSet>\n </CheckboxGroupContext.Provider>\n );\n});\n\nexport interface CheckboxGroupItemProps {\n value: string;\n label: ReactNode;\n description?: ReactNode;\n disabled?: boolean;\n}\n\nexport const CheckboxGroupItem = forwardRef<HTMLInputElement, CheckboxGroupItemProps>(\n function CheckboxGroupItem({ value, label, description, disabled }, ref) {\n const group = useContext(CheckboxGroupContext);\n if (!group) throw new Error('<CheckboxGroupItem> must be used inside <CheckboxGroup>');\n return (\n <Checkbox\n ref={ref}\n name={group.name}\n value={value}\n label={label}\n description={description}\n size={group.size}\n disabled={group.disabled || disabled}\n required={group.required}\n checked={group.value.includes(value)}\n onCheckedChange={(checked) => group.toggle(value, checked)}\n />\n );\n },\n);\n","import clsx from 'clsx';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport interface SegmentedControlOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps {\n options: SegmentedControlOption[];\n /** Controlled selection. Omit and pass `defaultValue` for uncontrolled. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Names the group. Required by the APG when the control has no visible label. */\n label?: string;\n className?: string;\n}\n\n/**\n * Single-select segmented toggle.\n *\n * Through 0.3.0 this had **no ARIA whatsoever** — the selected segment was distinguished\n * only by `bg-default shadow-panel`, so a screen reader user could not tell which of the\n * segments was active. It is single-select, so `radiogroup`/`radio` is the correct pattern\n * rather than a row of `aria-pressed` buttons: it announces \"2 of 3\" and lets the arrow\n * keys move between options, which a toggle-button group does not.\n *\n * `onChange` was also optional, so `<SegmentedControl options value />` rendered a control\n * that looked interactive and silently did nothing.\n */\nexport function SegmentedControl({\n options,\n value: valueProp,\n defaultValue,\n onValueChange,\n label,\n className,\n}: SegmentedControlProps) {\n const [value, setValue] = useControllableState({\n value: valueProp,\n defaultValue: defaultValue ?? options[0]?.value,\n onChange: onValueChange,\n });\n\n const selectedIndex = Math.max(\n 0,\n options.findIndex((option) => option.value === value),\n );\n\n const roving = useRovingFocus({\n orientation: 'horizontal',\n loop: true,\n defaultIndex: selectedIndex,\n });\n\n return (\n <div\n role=\"radiogroup\"\n aria-label={label}\n className={clsx(\n 'inline-flex items-center rounded-xl border border-default bg-default-secondary p-0.5',\n className,\n )}\n {...roving.containerProps}\n >\n {options.map((option, index) => {\n const selected = option.value === value;\n const itemProps = roving.itemProps(index, {\n disabled: option.disabled,\n label: option.label,\n });\n\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n disabled={option.disabled}\n {...itemProps}\n // The tab stop follows selection, not focus, so Tab lands on the active\n // segment rather than wherever the arrows were last used.\n tabIndex={selected ? 0 : -1}\n onFocus={() => {\n itemProps.onFocus();\n if (!option.disabled) setValue(option.value);\n }}\n onClick={() => !option.disabled && setValue(option.value)}\n className={clsx(\n 'rounded-lg px-3.5 py-1.5 text-body-xs font-medium transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default-secondary',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n selected\n ? 'bg-default text-default shadow-panel'\n : 'text-default-secondary hover:text-default',\n )}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { forwardRef, useId, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport interface SliderProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'onChange' | 'value'> {\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n /** Matches Figma's `Label` / `Has Label`. */\n label?: ReactNode;\n /** Matches Figma's `Description` / `Has Description`. */\n description?: ReactNode;\n /** Show the current value at the right of the label row. */\n showValue?: boolean;\n /** Formats the displayed and announced value — percentages, currency, durations. */\n formatValue?: (value: number) => string;\n className?: string;\n}\n\n/**\n * Range slider. Matches Figma's `Slider Field` (`State: Default | Disabled`, with label and\n * description slots).\n *\n * A native `<input type=\"range\">`, deliberately. It arrives with the entire APG slider\n * contract already implemented — arrow keys, Page Up/Down, Home/End, the correct\n * `aria-valuenow`/`valuemin`/`valuemax`, touch and pointer dragging, and RTL handling — and\n * a `div`-based slider has to rebuild all of it. The track and thumb are styled through the\n * vendor pseudo-elements instead, which is the one place raw `[&::-webkit-…]` selectors are\n * the right tool.\n *\n * `formatValue` feeds `aria-valuetext`, because \"70\" announced on a price slider is\n * meaningless where \"£70\" is not.\n */\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(\n {\n value,\n defaultValue,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n label,\n description,\n showValue = false,\n formatValue,\n disabled = false,\n id,\n className,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const controlId = id ?? generatedId;\n const descriptionId = `${controlId}-description`;\n\n const current = value ?? defaultValue ?? min;\n const display = formatValue ? formatValue(current) : String(current);\n\n return (\n <div className={clsx('flex w-full flex-col gap-1.5', className)}>\n {(label || showValue) && (\n <div className=\"flex items-baseline justify-between gap-2\">\n {label && (\n <label\n htmlFor={controlId}\n className={clsx('text-body-sm', disabled ? 'text-disabled' : 'text-default')}\n >\n {label}\n </label>\n )}\n {showValue && (\n <span className=\"text-body-sm font-medium tabular-nums text-default\">{display}</span>\n )}\n </div>\n )}\n {description && (\n <p\n id={descriptionId}\n className={clsx('text-body-xs', disabled ? 'text-disabled' : 'text-default-secondary')}\n >\n {description}\n </p>\n )}\n <input\n ref={ref}\n id={controlId}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={value}\n defaultValue={value === undefined ? defaultValue : undefined}\n disabled={disabled}\n aria-describedby={description ? descriptionId : undefined}\n // Only when a formatter is supplied — an aria-valuetext that merely repeats\n // aria-valuenow is noise.\n aria-valuetext={formatValue ? display : undefined}\n onChange={(event) => onValueChange?.(Number(event.target.value))}\n className={clsx(\n 'h-5 w-full cursor-pointer appearance-none bg-transparent',\n 'focus-visible:outline-none',\n disabled && 'cursor-not-allowed opacity-50',\n // Track\n '[&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-default-tertiary',\n '[&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-default-tertiary',\n '[&::-moz-range-progress]:h-1.5 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-brand',\n // Thumb. The negative margin centres it on the track, since the input box is\n // taller than the track to keep a comfortable pointer target.\n '[&::-webkit-slider-thumb]:-mt-[7px] [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-brand [&::-webkit-slider-thumb]:bg-default [&::-webkit-slider-thumb]:shadow-100',\n '[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-brand [&::-moz-range-thumb]:bg-default',\n // Focus ring on the thumb, not the whole 100%-wide input — a ring around the\n // full track reads as the row being focused rather than the handle.\n 'focus-visible:[&::-webkit-slider-thumb]:ring-2 focus-visible:[&::-webkit-slider-thumb]:ring-brand focus-visible:[&::-webkit-slider-thumb]:ring-offset-1',\n 'focus-visible:[&::-moz-range-thumb]:ring-2 focus-visible:[&::-moz-range-thumb]:ring-brand',\n )}\n {...props}\n />\n </div>\n );\n});\n","import { forwardRef, type LabelHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { useFieldContext } from './field';\nimport type { InputSize } from './input';\n\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n children: ReactNode;\n size?: InputSize;\n}\n\nconst SIZE: Record<InputSize, string> = {\n lg: 'text-body',\n md: 'text-body-sm',\n sm: 'text-body-tiny',\n};\n\n/**\n * A standalone `<label>`.\n *\n * `FieldLabel` is the one to reach for inside a `Field` — it picks up the generated id,\n * the size and the disabled state from context automatically. This is for the cases that\n * are not a field: naming a `SegmentedControl`, a group of buttons, or any control the\n * library does not wrap. It still reads `Field` context when it happens to be inside one,\n * so it degrades to `FieldLabel` behaviour rather than silently losing the association.\n */\nexport const Label = forwardRef<HTMLLabelElement, LabelProps>(function Label(\n { children, size, className, htmlFor, ...rest },\n ref,\n) {\n const field = useFieldContext();\n const resolvedSize = size ?? field?.size ?? 'md';\n\n return (\n <label\n ref={ref}\n htmlFor={htmlFor ?? field?.controlId}\n data-slot=\"label\"\n className={clsx(\n 'select-none',\n SIZE[resolvedSize],\n field?.disabled ? 'text-disabled' : 'text-default',\n className,\n )}\n {...rest}\n >\n {children}\n </label>\n );\n});\n","import {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n} from 'react';\nimport clsx from 'clsx';\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';\nimport { IconButton } from './icon-button';\n\nexport type CalendarMode = 'single' | 'range';\n\nexport interface DateRange {\n from: Date | null;\n to: Date | null;\n}\n\nexport interface CalendarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n mode?: CalendarMode;\n /** Selected date in `single` mode. */\n value?: Date | null;\n /** Selected range in `range` mode. */\n range?: DateRange;\n onSelect?: (value: Date) => void;\n onRangeChange?: (range: DateRange) => void;\n /** Month shown on mount. Defaults to the selection's month, else today. */\n defaultMonth?: Date;\n min?: Date;\n max?: Date;\n /** Return `true` to disable a day. Combined with `min`/`max`. */\n isDateDisabled?: (date: Date) => boolean;\n /** 0 = Sunday, 1 = Monday. Default `1`. */\n weekStartsOn?: 0 | 1;\n /** BCP 47 tag for month, weekday and announced day names. Default: the browser's. */\n locale?: string;\n /** Names the grid. Default `Calendar`. */\n label?: string;\n}\n\n// ── Date helpers ───────────────────────────────────────────────────────────────\n// Deliberately no date library. Everything below is calendar-grid arithmetic on local\n// dates, which is a few dozen lines; pulling in date-fns for it would be the largest\n// dependency in the package.\n\nconst startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());\nconst sameDay = (a: Date | null | undefined, b: Date | null | undefined) =>\n !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\nconst addDays = (d: Date, n: number) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);\nconst addMonths = (d: Date, n: number) => new Date(d.getFullYear(), d.getMonth() + n, 1);\nconst isBefore = (a: Date, b: Date) => startOfDay(a).getTime() < startOfDay(b).getTime();\nconst isAfter = (a: Date, b: Date) => startOfDay(a).getTime() > startOfDay(b).getTime();\nconst inRange = (d: Date, from: Date, to: Date) =>\n startOfDay(d).getTime() > startOfDay(from).getTime() &&\n startOfDay(d).getTime() < startOfDay(to).getTime();\n\n/** Six weeks of cells so the grid never changes height as the month changes. */\nfunction monthGrid(month: Date, weekStartsOn: 0 | 1): Date[] {\n const first = new Date(month.getFullYear(), month.getMonth(), 1);\n const offset = (first.getDay() - weekStartsOn + 7) % 7;\n const start = addDays(first, -offset);\n return Array.from({ length: 42 }, (_, i) => addDays(start, i));\n}\n\n/**\n * Month grid. Matches Figma's `Calendar`, `Calendar Button`\n * (`State: Default | Hover | Active | Disabled | Range | Range Disabled | Hidden`),\n * `Calendar Select Group` and `Calendar Month/Year Field`.\n *\n * The code had no calendar at all — `DatePicker` was a bare `<input type=\"date\">` with\n * Chromium-only indicator styling, so there was nothing to build a range picker on, no\n * locale control and no min/max navigation.\n *\n * The keyboard model is the APG date-grid pattern, and it is the whole reason this is not\n * just a table of buttons:\n *\n * - **One tab stop.** Tab enters the grid once and leaves it; arrows move within. A grid of\n * 42 individually tabbable buttons takes 42 presses to get past.\n * - **Arrows cross month boundaries.** Pressing Left on the 1st moves to the previous\n * month's last day and pages the view, rather than dead-ending.\n * - **PageUp/PageDown** move by month, **Home/End** to the start/end of the week.\n * - Each day's accessible name is the full date, not the number — \"14\" tells a screen\n * reader user nothing.\n */\nexport function Calendar({\n mode = 'single',\n value,\n range,\n onSelect,\n onRangeChange,\n defaultMonth,\n min,\n max,\n isDateDisabled,\n weekStartsOn = 1,\n locale,\n label = 'Calendar',\n className,\n ...rest\n}: CalendarProps) {\n const today = useMemo(() => startOfDay(new Date()), []);\n const gridId = useId();\n\n const [month, setMonth] = useState<Date>(\n () => defaultMonth ?? value ?? range?.from ?? today,\n );\n // The focused cell, which is what the roving tabindex follows. Distinct from the\n // selection: you can arrow around without selecting.\n const [focusedDate, setFocusedDate] = useState<Date>(\n () => value ?? range?.from ?? today,\n );\n const cellRefs = useRef(new Map<string, HTMLButtonElement>());\n\n const monthFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }),\n [locale],\n );\n const dayNameFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, { weekday: 'short' }),\n [locale],\n );\n const fullDateFormatter = useMemo(\n () => new Intl.DateTimeFormat(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }),\n [locale],\n );\n\n const disabled = useCallback(\n (date: Date) => {\n if (min && isBefore(date, min)) return true;\n if (max && isAfter(date, max)) return true;\n return isDateDisabled?.(date) ?? false;\n },\n [min, max, isDateDisabled],\n );\n\n const key = (d: Date) => `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;\n\n // Set by keyboard moves only. Focus must not be stolen on mount, or when a click has\n // already put focus on the cell the user pressed.\n const pendingFocus = useRef(false);\n\n const focusDate = useCallback((date: Date) => {\n pendingFocus.current = true;\n setFocusedDate(date);\n // A move across the month boundary pages the view; the target cell does not exist\n // until after that commit, which is why focus is applied in the effect below rather\n // than here.\n setMonth((current) =>\n current.getFullYear() === date.getFullYear() && current.getMonth() === date.getMonth()\n ? current\n : new Date(date.getFullYear(), date.getMonth(), 1),\n );\n }, []);\n\n useEffect(() => {\n if (!pendingFocus.current) return;\n const node = cellRefs.current.get(key(focusedDate));\n if (node) {\n node.focus();\n pendingFocus.current = false;\n }\n // If the node is still absent the month is mid-change; the next commit re-runs this.\n }, [focusedDate, month]);\n\n const select = (date: Date) => {\n if (disabled(date)) return;\n setFocusedDate(date);\n\n if (mode === 'single') {\n onSelect?.(date);\n return;\n }\n\n const current = range ?? { from: null, to: null };\n // Anchor a new range when there is none, when one is already complete, or when the\n // click lands before the anchor — the last case is what makes dragging backwards work\n // instead of producing an inverted range.\n if (!current.from || current.to || isBefore(date, current.from)) {\n onRangeChange?.({ from: date, to: null });\n } else {\n onRangeChange?.({ from: current.from, to: date });\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const moves: Record<string, () => Date> = {\n ArrowLeft: () => addDays(focusedDate, -1),\n ArrowRight: () => addDays(focusedDate, 1),\n ArrowUp: () => addDays(focusedDate, -7),\n ArrowDown: () => addDays(focusedDate, 7),\n Home: () => addDays(focusedDate, -((focusedDate.getDay() - weekStartsOn + 7) % 7)),\n End: () => addDays(focusedDate, 6 - ((focusedDate.getDay() - weekStartsOn + 7) % 7)),\n PageUp: () => addDays(focusedDate, 0) && new Date(focusedDate.getFullYear(), focusedDate.getMonth() - 1, focusedDate.getDate()),\n PageDown: () => new Date(focusedDate.getFullYear(), focusedDate.getMonth() + 1, focusedDate.getDate()),\n };\n\n const move = moves[event.key];\n if (move) {\n event.preventDefault();\n focusDate(move());\n }\n };\n\n const days = monthGrid(month, weekStartsOn);\n const weekdayNames = days.slice(0, 7).map((d) => dayNameFormatter.format(d));\n\n return (\n <div\n data-slot=\"calendar\"\n className={clsx('w-fit rounded-xl border border-default bg-default p-3', className)}\n {...rest}\n >\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Previous month\"\n disabled={!!min && isBefore(addMonths(month, -1), new Date(min.getFullYear(), min.getMonth(), 1))}\n onClick={() => setMonth(addMonths(month, -1))}\n >\n <ChevronLeftIcon aria-hidden size={16} />\n </IconButton>\n {/* aria-live so paging the month is announced — otherwise a screen reader user\n arrowing past the end of a month has no idea the view moved. */}\n <span aria-live=\"polite\" className=\"text-body-sm font-semibold text-default\">\n {monthFormatter.format(month)}\n </span>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Next month\"\n disabled={!!max && isAfter(addMonths(month, 1), new Date(max.getFullYear(), max.getMonth(), 1))}\n onClick={() => setMonth(addMonths(month, 1))}\n >\n <ChevronRightIcon aria-hidden size={16} />\n </IconButton>\n </div>\n\n {/* role=\"grid\" with an explicit row/cell structure, so a screen reader announces\n \"column 3, row 2\" and the day headers are tied to the columns. */}\n <div\n role=\"grid\"\n aria-label={label}\n id={gridId}\n // Programmatically focusable but out of the tab sequence: the roving day buttons\n // own the tab stop, and key handling is delegated here so it keeps working while\n // focus moves between cells.\n tabIndex={-1}\n onKeyDown={onKeyDown}\n >\n <div role=\"row\" className=\"mb-1 grid grid-cols-7\">\n {weekdayNames.map((name) => (\n <div\n key={name}\n role=\"columnheader\"\n // The short form is shown; the long form is not needed because each cell\n // announces its own full date.\n className=\"flex h-8 items-center justify-center text-body-tiny font-medium text-default-tertiary\"\n >\n {name}\n </div>\n ))}\n </div>\n\n {Array.from({ length: 6 }, (_, week) => (\n <div key={week} role=\"row\" className=\"grid grid-cols-7\">\n {days.slice(week * 7, week * 7 + 7).map((date) => {\n const outside = date.getMonth() !== month.getMonth();\n const isDisabled = disabled(date);\n const selected =\n mode === 'single'\n ? sameDay(date, value)\n : sameDay(date, range?.from) || sameDay(date, range?.to);\n const between =\n mode === 'range' && range?.from && range?.to\n ? inRange(date, range.from, range.to)\n : false;\n const isFocused = sameDay(date, focusedDate);\n\n return (\n <div role=\"gridcell\" key={key(date)} aria-selected={selected || undefined}>\n <button\n ref={(node) => {\n if (node) cellRefs.current.set(key(date), node);\n else cellRefs.current.delete(key(date));\n }}\n type=\"button\"\n // The roving tab stop: exactly one cell is reachable by Tab.\n tabIndex={isFocused ? 0 : -1}\n disabled={isDisabled}\n aria-label={fullDateFormatter.format(date)}\n aria-current={sameDay(date, today) ? 'date' : undefined}\n onClick={() => select(date)}\n onFocus={() => setFocusedDate(date)}\n className={clsx(\n 'flex size-9 items-center justify-center rounded-lg text-body-sm tabular-nums transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:text-disabled disabled:hover:bg-transparent',\n selected\n ? 'bg-brand font-semibold text-brand-on-brand'\n : between\n ? 'rounded-none bg-brand-tertiary text-default'\n : outside\n ? 'text-default-tertiary hover:bg-default-secondary'\n : 'text-default hover:bg-default-secondary',\n // Today is marked by a ring rather than a fill, so it stays legible\n // when it is also the selected day.\n sameDay(date, today) && !selected && 'ring-1 ring-inset ring-brand-tertiary',\n )}\n >\n {date.getDate()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { forwardRef, type HTMLAttributes, type InputHTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { SearchIcon, XIcon } from 'lucide-react';\nimport { useFieldControl } from './field';\nimport type { InputSize } from './input';\nimport { useControlSize } from './control-size';\n\nexport type InputGroupAlign = 'inline-start' | 'inline-end' | 'block-start' | 'block-end';\n\nconst HEIGHT: Record<InputSize, string> = {\n lg: 'h-12 text-body',\n md: 'h-9 text-body-sm',\n sm: 'h-6 text-body-tiny',\n};\n\nconst PAD: Record<InputSize, string> = {\n lg: 'px-4 gap-2',\n md: 'px-3 gap-1.5',\n sm: 'px-2 gap-1',\n};\n\nexport interface InputGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: InputSize;\n invalid?: boolean;\n disabled?: boolean;\n}\n\n/**\n * A bordered shell that holds an input alongside addons — a prefix, a unit suffix, a\n * search glyph, a clear button, a copy button.\n *\n * This generalises what `PasswordInput` did as a one-off. `Input` has `leadingIcon`,\n * `trailingIcon` and `trailingAction` props, which works for a single decoration but forces\n * absolute positioning and per-size padding maps to keep the text clear of it. Here the\n * addons are real flex siblings, so the input's text box simply ends where the addon\n * begins and nothing has to be measured.\n *\n * The border and focus ring live on the group, not the input — so focusing the input rings\n * the whole control, which is what a user perceives as \"the field\".\n */\nexport const InputGroup = forwardRef<HTMLDivElement, InputGroupProps>(function InputGroup(\n { children, size: sizeProp, invalid = false, disabled = false, className, ...rest },\n ref,\n) {\n const size = useControlSize(sizeProp);\n\n return (\n <div\n ref={ref}\n data-slot=\"input-group\"\n data-size={size}\n className={clsx(\n 'flex w-full items-center rounded-lg border transition-colors',\n 'bg-default text-default',\n HEIGHT[size],\n PAD[size],\n // `focus-within`, because the focused element is the nested input while the ring\n // belongs to the shell.\n 'focus-within:ring-2 focus-within:ring-offset-1 focus-within:ring-offset-default',\n disabled\n ? 'cursor-not-allowed border-disabled bg-disabled text-disabled'\n : invalid\n ? 'border-danger-secondary focus-within:border-danger focus-within:ring-danger'\n : 'border-default focus-within:border-brand focus-within:ring-brand',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n});\n\nexport interface InputGroupInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {}\n\n/**\n * The input inside an `InputGroup`. Carries no border, background or ring of its own —\n * the group owns all three.\n */\nexport const InputGroupInput = forwardRef<HTMLInputElement, InputGroupInputProps>(\n function InputGroupInput({ className, ...props }, ref) {\n const field = useFieldControl();\n return (\n <input\n ref={ref}\n {...field}\n className={clsx(\n 'min-w-0 flex-1 bg-transparent outline-none',\n 'placeholder:text-default-tertiary',\n 'disabled:cursor-not-allowed disabled:text-disabled disabled:placeholder:text-disabled',\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nexport interface InputGroupAddonProps extends HTMLAttributes<HTMLSpanElement> {\n children: ReactNode;\n align?: InputGroupAlign;\n /**\n * `true` when the addon is decoration — an icon, a unit. Decorative addons are\n * `aria-hidden` and ignore pointer events, so they never steal a click meant for the\n * text box. Default `true`; set `false` for an addon containing a control.\n */\n decorative?: boolean;\n}\n\nexport const InputGroupAddon = forwardRef<HTMLSpanElement, InputGroupAddonProps>(\n function InputGroupAddon(\n { children, align = 'inline-start', decorative = true, className, ...rest },\n ref,\n ) {\n return (\n <span\n ref={ref}\n aria-hidden={decorative || undefined}\n data-slot=\"input-group-addon\"\n data-align={align}\n className={clsx(\n 'flex shrink-0 items-center text-icon-default-secondary',\n decorative && 'pointer-events-none',\n align === 'inline-end' && 'order-last',\n className,\n )}\n {...rest}\n >\n {children}\n </span>\n );\n },\n);\n\nexport interface InputGroupTextProps extends HTMLAttributes<HTMLSpanElement> {\n children: ReactNode;\n}\n\n/** Static text inside the shell — a currency symbol, a domain suffix, a unit. */\nexport const InputGroupText = forwardRef<HTMLSpanElement, InputGroupTextProps>(\n function InputGroupText({ children, className, ...rest }, ref) {\n return (\n <span\n ref={ref}\n className={clsx('shrink-0 whitespace-nowrap text-default-secondary', className)}\n {...rest}\n >\n {children}\n </span>\n );\n },\n);\n\n// ── SearchInput ────────────────────────────────────────────────────────────────\n\nexport interface SearchInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n size?: InputSize;\n /** Renders a clear button once there is a value. */\n onClear?: () => void;\n /** Accessible name. Default `Search`. */\n label?: string;\n className?: string;\n}\n\n/**\n * Search field. Matches Figma's `Search` set — `Size: Large | Medium | Small`,\n * `State: Default | Disabled`, `Value Type: Filled | Placeholder`.\n *\n * `type=\"search\"` rather than `type=\"text\"`: it gets the platform's search affordances and\n * is announced as a search field. The clear button is a real button so it is keyboard\n * reachable, unlike the UA-provided cancel widget which is pointer-only in most browsers\n * and is therefore suppressed.\n */\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n { size: sizeProp, onClear, label = 'Search', disabled, value, className, ...props },\n ref,\n) {\n const size = useControlSize(sizeProp);\n const hasValue = value !== undefined && value !== '';\n\n return (\n <InputGroup size={size} disabled={disabled} className={className}>\n <InputGroupAddon>\n <SearchIcon className={size === 'sm' ? 'size-3' : 'size-4'} />\n </InputGroupAddon>\n <InputGroupInput\n ref={ref}\n type=\"search\"\n aria-label={label}\n disabled={disabled}\n value={value}\n // The UA cancel button cannot be focused or styled consistently, so it is hidden\n // in favour of the real button below.\n className=\"[&::-webkit-search-cancel-button]:appearance-none\"\n {...props}\n />\n {onClear && hasValue && (\n <InputGroupAddon align=\"inline-end\" decorative={false}>\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={onClear}\n disabled={disabled}\n className=\"flex items-center justify-center rounded transition-colors hover:text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n <XIcon aria-hidden className={size === 'sm' ? 'size-3' : 'size-4'} />\n </button>\n </InputGroupAddon>\n )}\n </InputGroup>\n );\n});\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { CircleCheckBigIcon, InfoIcon, OctagonAlertIcon, TriangleAlertIcon, XIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { EntityIconBadge, type EntityIconBadgeTone } from '../status/entity-icon-badge';\nimport { IconButton } from '../forms/icon-button';\nimport { OVERLAY_SCRIM } from './overlay';\nimport { deferEscapeToInnerPopup } from './overlay-stack';\nimport { PortalContainerProvider } from './portal';\nimport { isInsideToaster } from './toaster-guard';\nimport { composeRefs } from '../../lib/slot';\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'xl';\n/**\n * Note `positive`, not `success` — every other tone union in the library\n * (`InlineAlertTone`, `TagPillTone`, `EntityIconBadgeTone`) and the token layer say\n * `positive`, and one vocabulary beats a familiar synonym.\n */\nexport type ModalTone = 'default' | 'info' | 'positive' | 'warning' | 'danger';\nexport type ModalFooterAlign = 'start' | 'between' | 'end';\n\n/**\n * The `sm:` prefix is mandatory, not cosmetic. In 0.2.0 `max-w-[540px]` was applied\n * unprefixed, so between 540px and the `sm` breakpoint (640px) the \"bottom sheet\" was\n * a 540px card floating in the middle of the viewport.\n */\nconst SIZE: Record<ModalSize, string> = {\n sm: 'sm:max-w-[420px]',\n md: 'sm:max-w-[540px]',\n lg: 'sm:max-w-[640px]',\n xl: 'sm:max-w-[800px]',\n};\n\n/**\n * `info` / `positive` / `warning` reuse `InlineAlert`'s glyphs, so one semantic has one\n * mark across the system. `danger` deliberately differs from `warning`: a dialog that\n * is about to destroy something should not be glyph-identical to one merely cautioning.\n */\nconst TONE_ICON: Record<Exclude<ModalTone, 'default'>, ReactNode> = {\n info: <InfoIcon aria-hidden className=\"size-5\" />,\n positive: <CircleCheckBigIcon aria-hidden className=\"size-5\" />,\n warning: <TriangleAlertIcon aria-hidden className=\"size-5\" />,\n danger: <OctagonAlertIcon aria-hidden className=\"size-5\" />,\n};\n\n/** Reuses EntityIconBadge's tone map — one token map for tinted icon circles. */\nconst TONE_BADGE: Record<Exclude<ModalTone, 'default'>, EntityIconBadgeTone> = {\n info: 'brand',\n positive: 'positive',\n warning: 'warning',\n danger: 'danger',\n};\n\nconst FOOTER_ALIGN: Record<ModalFooterAlign, string> = {\n start: 'justify-start',\n between: 'justify-between',\n end: 'justify-end',\n};\n\n// ── Naming context ─────────────────────────────────────────────────────────────\n\n/**\n * Tells the panel which naming parts are actually rendered.\n *\n * Radix wires `aria-labelledby` / `aria-describedby` to its own Title and Description ids,\n * so the name still comes from the visible heading by reference (0.3.0 duplicated it into\n * `aria-label`, and the copy drifted). Two cases still need to know what is present:\n * - **No `ModalTitle`.** The `label` prop is rendered as a visually hidden Title, so the\n * dialog stays named without a heading anyone can see.\n * - **No `ModalDescription`.** Radix would otherwise point `aria-describedby` at an id\n * that is not in the document.\n *\n * Outside a Modal the parts render as plain elements, so a static layout (a docs preview,\n * a design-sync card) can still use them.\n */\ninterface ModalNamingContext {\n registerTitle: (present: boolean) => void;\n registerDescription: (present: boolean) => void;\n}\n\nconst ModalNaming = createContext<ModalNamingContext | null>(null);\n\n// ── Modal ──────────────────────────────────────────────────────────────────────\n\nexport interface ModalProps {\n /** Controlled open state. Omit it, with `ModalTrigger`, for an uncontrolled dialog. */\n open?: boolean;\n /** Initial state when uncontrolled. */\n defaultOpen?: boolean;\n /** Fired with `false` on Escape, an outside press, or the close button. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Accessible name. Only needed when the dialog renders no `ModalTitle` — with one, the\n * name comes from the heading itself via `aria-labelledby`, so it cannot drift.\n */\n label?: string;\n children: ReactNode;\n size?: ModalSize;\n /**\n * `alertdialog` for a dialog that interrupts to confirm or warn — it makes assistive\n * tech announce the body immediately rather than waiting to be browsed. `ConfirmDialog`\n * passes it; plain content dialogs should stay `dialog`.\n */\n role?: 'dialog' | 'alertdialog';\n /** Renders the top-right close button. */\n showClose?: boolean;\n /** Applied to the panel. With `cn`, `className=\"sm:max-w-[560px]\"` beats `size`. */\n className?: string;\n /** Call `preventDefault()` to keep the dialog open — e.g. unsaved input. */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** Call `preventDefault()` to keep the dialog open. */\n onInteractOutside?: (event: PointerEvent) => void;\n /** Focus this on open instead of the first tabbable element. */\n initialFocus?: React.RefObject<HTMLElement | null>;\n /**\n * Where to portal the dialog. Defaults to `document.body`. Pass the element the design\n * tokens are declared on when the app renders inside a shadow root or a scoped theme.\n */\n container?: HTMLElement | null;\n}\n\n/**\n * A centred dialog above `sm`, a bottom sheet below it.\n *\n * Composed from `ModalHeader` / `ModalBody` / `ModalFooter`, mirroring the `Card`\n * parts — so a modal can take any layout a card can, including headerless. Tone lives\n * on `ModalHeader` (the part that draws the glyph); `ConfirmDialog` and\n * `NoteConfirmModal` accept `tone` at their top level and forward it.\n *\n * Built on Radix Dialog from 0.7.0. Radix supplies the focus trap, focus return, Escape and\n * outside-press handling scoped to the topmost layer, scroll lock, and hiding the page behind\n * the dialog from assistive tech. The 0.6 overlay stack got the last of those wrong when\n * modals were stacked. Toasts stay reachable: their region is `aria-live`, which Radix leaves\n * exposed, and pressing one is not treated as an outside press.\n */\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(function Modal(\n { open, defaultOpen, onOpenChange, container, ...shell },\n ref,\n) {\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {/* The trigger, when there is one, is a direct child of the Root and outside the\n portal, so it renders in place. */}\n {extractTrigger(shell.children)}\n <DialogPrimitive.Portal container={container ?? undefined}>\n <ModalShell ref={ref} {...shell} />\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n});\n\nconst ModalShell = forwardRef<HTMLDivElement, Omit<ModalProps, 'open' | 'defaultOpen' | 'onOpenChange' | 'container'>>(\n function ModalShell(\n {\n label,\n children,\n size = 'md',\n role = 'dialog',\n showClose = true,\n className,\n onEscapeKeyDown,\n onInteractOutside,\n initialFocus,\n },\n ref,\n ) {\n const [hasTitle, setHasTitle] = useState(false);\n const [hasDescription, setHasDescription] = useState(false);\n // Floating panels that are not Radix parts portal in here (see PortalContainerProvider).\n const [contentNode, setContentNode] = useState<HTMLDivElement | null>(null);\n // Read during the first render, before Radix moves focus into the panel.\n const [returnFocusTo] = useState(() =>\n typeof document === 'undefined' ? null : (document.activeElement as HTMLElement | null),\n );\n\n return (\n <DialogPrimitive.Overlay\n className={cn(\n // The overlay wraps the content (a Radix-supported layout), so it also does the\n // centring: bottom sheet below `sm`, centred card above it.\n 'fixed inset-0 z-modal flex items-end justify-center sm:items-center',\n OVERLAY_SCRIM,\n )}\n >\n <DialogPrimitive.Content\n ref={composeRefs(ref, setContentNode)}\n role={role}\n // Only point at a description that exists. Passing `undefined` explicitly also\n // tells Radix the omission is deliberate.\n {...(hasDescription ? {} : { 'aria-describedby': undefined })}\n onOpenAutoFocus={(event) => {\n const target = initialFocus?.current;\n if (target) {\n event.preventDefault();\n target.focus();\n }\n }}\n onCloseAutoFocus={(event) => {\n // Radix's modal Dialog returns focus only to its own `Dialog.Trigger`. Most of\n // our modals are controlled and opened by an ordinary button, which Radix never\n // sees, so on close focus would drop to <body>. Return it to whatever held it on\n // open; that is the trigger whenever there is one.\n if (returnFocusTo?.isConnected && returnFocusTo !== document.body) {\n event.preventDefault();\n returnFocusTo.focus();\n }\n }}\n onEscapeKeyDown={(event) => {\n if (!deferEscapeToInnerPopup(event)) onEscapeKeyDown?.(event);\n }}\n onPointerDownOutside={(event) => {\n // A toast is not \"outside the dialog\" in any sense a user means. Pressing its\n // close button must not dismiss the modal underneath it.\n if (isInsideToaster(event.target)) {\n event.preventDefault();\n return;\n }\n const original = event.detail.originalEvent;\n onInteractOutside?.(original);\n if (original.defaultPrevented) event.preventDefault();\n }}\n className={cn(\n 'relative max-h-[92dvh] w-full overflow-y-auto bg-default shadow-400 focus:outline-none',\n // Not a `ScrollArea`: the panel is the dialog, so the scroll container has to stay\n // the element carrying `role`, `aria-modal` and the trap boundary. It is already\n // keyboard-scrollable because the trap focuses it on open.\n SCROLLBAR_CLASSES,\n 'rounded-t-2xl pb-[env(safe-area-inset-bottom)] sm:mx-4 sm:rounded-2xl sm:pb-0',\n SIZE[size],\n className,\n )}\n >\n {!hasTitle && label && (\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n )}\n {showClose && (\n <DialogPrimitive.Close asChild>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label=\"Close dialog\"\n // Floating rather than inside the header, so a headerless modal is still\n // dismissible. right-6/top-5 reproduces 0.2.0's position exactly.\n className=\"absolute right-6 top-5 z-raised\"\n >\n <XIcon size={16} aria-hidden />\n </IconButton>\n </DialogPrimitive.Close>\n )}\n <ModalNaming.Provider\n value={{ registerTitle: setHasTitle, registerDescription: setHasDescription }}\n >\n <PortalContainerProvider container={contentNode}>\n {withoutTrigger(children)}\n </PortalContainerProvider>\n </ModalNaming.Provider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Overlay>\n );\n },\n);\n\n// ── ModalTrigger / ModalClose ──────────────────────────────────────────────────\n\nexport interface ModalTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n /** Render onto the single child (e.g. a `Button`) instead of a bare `<button>`. */\n asChild?: boolean;\n}\n\n/**\n * Opens an uncontrolled `Modal`. Place it as a direct child of `Modal`; it renders in place,\n * not in the dialog. New in 0.7.0. Controlled modals (`open` + `onOpenChange`) do not need it.\n */\nexport const ModalTrigger = forwardRef<HTMLButtonElement, ModalTriggerProps>(\n function ModalTrigger(props, ref) {\n return <DialogPrimitive.Trigger ref={ref} {...props} />;\n },\n);\n// Marks the part so `Modal` can lift it out of the portalled content.\n(ModalTrigger as unknown as { __modalTrigger: true }).__modalTrigger = true;\n\nexport interface ModalCloseProps extends HTMLAttributes<HTMLButtonElement> {\n asChild?: boolean;\n}\n\n/** Closes the enclosing `Modal`, e.g. a footer \"Cancel\" button. New in 0.7.0. */\nexport const ModalClose = forwardRef<HTMLButtonElement, ModalCloseProps>(\n function ModalClose(props, ref) {\n return <DialogPrimitive.Close ref={ref} {...props} />;\n },\n);\n\nfunction isTrigger(node: ReactNode): boolean {\n return (\n typeof node === 'object' &&\n node !== null &&\n 'type' in node &&\n (node.type as { __modalTrigger?: boolean })?.__modalTrigger === true\n );\n}\n\nfunction extractTrigger(children: ReactNode): ReactNode {\n return Array.isArray(children) ? children.filter(isTrigger) : isTrigger(children) ? children : null;\n}\n\nfunction withoutTrigger(children: ReactNode): ReactNode {\n return Array.isArray(children)\n ? children.filter((child) => !isTrigger(child))\n : isTrigger(children)\n ? null\n : children;\n}\n\n// ── ModalHeader ────────────────────────────────────────────────────────────────\n\nexport interface ModalHeaderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Adds a tinted glyph circle. `default` renders none. */\n tone?: ModalTone;\n divider?: boolean;\n}\n\nexport const ModalHeader = forwardRef<HTMLDivElement, ModalHeaderProps>(function ModalHeader(\n { children, tone = 'default', divider = true, className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n data-tone={tone}\n className={cn(\n // pr-14 reserves the floating close button's column (24px gutter + 24px\n // button + gap), which the old flex-between header used to hold open.\n 'flex items-start gap-3 px-6 py-5 pr-14',\n divider && 'border-b border-default',\n className,\n )}\n {...rest}\n >\n {tone !== 'default' && (\n <EntityIconBadge size=\"md\" shape=\"circle\" tone={TONE_BADGE[tone]}>\n {TONE_ICON[tone]}\n </EntityIconBadge>\n )}\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n});\n\n// ── ModalTitle / ModalDescription / ModalBody / ModalFooter ────────────────────\n\nexport interface ModalTitleProps extends HTMLAttributes<HTMLHeadingElement> {\n children: ReactNode;\n}\n\nexport const ModalTitle = forwardRef<HTMLHeadingElement, ModalTitleProps>(function ModalTitle(\n { children, className, ...rest },\n ref,\n) {\n const naming = useContext(ModalNaming);\n\n useEffect(() => {\n naming?.registerTitle(true);\n return () => naming?.registerTitle(false);\n }, [naming]);\n\n const classes = cn('text-heading-sm font-semibold text-default', className);\n\n if (!naming) {\n return (\n <h2 ref={ref} className={classes} {...rest}>\n {children}\n </h2>\n );\n }\n\n return (\n <DialogPrimitive.Title ref={ref} className={classes} {...rest}>\n {children}\n </DialogPrimitive.Title>\n );\n});\n\nexport interface ModalDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {\n children: ReactNode;\n}\n\nexport const ModalDescription = forwardRef<HTMLParagraphElement, ModalDescriptionProps>(\n function ModalDescription({ children, className, ...rest }, ref) {\n const naming = useContext(ModalNaming);\n\n useEffect(() => {\n naming?.registerDescription(true);\n return () => naming?.registerDescription(false);\n }, [naming]);\n\n const classes = cn('mt-0.5 text-body-xs text-default-secondary', className);\n\n if (!naming) {\n return (\n <p ref={ref} className={classes} {...rest}>\n {children}\n </p>\n );\n }\n\n return (\n <DialogPrimitive.Description ref={ref} className={classes} {...rest}>\n {children}\n </DialogPrimitive.Description>\n );\n },\n);\n\nexport interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** Must not carry its own `overflow` — the panel is the scroll container. */\nexport const ModalBody = forwardRef<HTMLDivElement, ModalBodyProps>(function ModalBody(\n { children, className, ...rest },\n ref,\n) {\n return (\n <div ref={ref} className={cn('px-6 py-5', className)} {...rest}>\n {children}\n </div>\n );\n});\n\nexport interface ModalFooterProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n align?: ModalFooterAlign;\n divider?: boolean;\n}\n\nexport const ModalFooter = forwardRef<HTMLDivElement, ModalFooterProps>(function ModalFooter(\n { children, align = 'end', divider = true, className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={cn(\n 'flex items-center gap-2 px-6 py-4',\n FOOTER_ALIGN[align],\n divider && 'border-t border-default',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n});\n","/**\n * Marks the `Toaster` region so modal overlays can tell a press on a toast apart from a\n * press outside the dialog.\n *\n * A toast fired from inside a Modal (e.g. \"Saved\") renders in the toast region, which is a\n * sibling of the dialog in `document.body`. Radix dismisses a modal on any pointer-down outside\n * its content, so without this check, pressing the toast's close button would also close the\n * dialog the user was still working in.\n */\nexport const TOASTER_ATTRIBUTE = 'data-platned-toaster';\n\nexport function isInsideToaster(target: EventTarget | null): boolean {\n return target instanceof Element && target.closest(`[${TOASTER_ATTRIBUTE}]`) !== null;\n}\n","import { useId, type ReactElement, type ReactNode } from 'react';\nimport { Tooltip as TooltipPrimitive } from 'radix-ui';\nimport { cn } from '../../lib/cn';\nimport type { FloatingAlign, FloatingSide } from './floating';\nimport { usePortalContainer } from './portal';\n\nexport interface TooltipProps {\n /**\n * The trigger. Must be a single focusable element — a tooltip that can only be reached\n * with a pointer is invisible to keyboard and touch users, so this deliberately does not\n * wrap its child in a span to make it hoverable.\n */\n children: ReactElement;\n /** Bold first line. Matches Figma's `Title` property. */\n title?: ReactNode;\n /** Supporting line. Matches Figma's `Body` / `Has Body`. */\n body?: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n /** Delay before opening on hover, in ms. Default `150`. Keyboard focus opens at once. */\n openDelay?: number;\n /**\n * @deprecated Ignored from 0.7.0. The tooltip now stays open while the pointer travels\n * from the trigger onto it and while it is hovered, as WCAG 1.4.13 requires, which is what\n * a close delay used to approximate. Remove it from call sites; it will be dropped in 0.8.\n */\n closeDelay?: number;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * `describedby` — the trigger keeps its own name and the tooltip adds detail. This is\n * almost always what you want. `labelledby` makes the tooltip *be* the trigger's name,\n * for an icon-only button with no other text. Default `describedby`.\n *\n * Deliberately not called `as`: everywhere else in this library `as` chooses the rendered\n * element, and reusing it for something else here would be a trap (it also makes\n * `jsx-a11y`'s polymorphic-component checking treat the value as a tag name).\n */\n association?: 'describedby' | 'labelledby';\n className?: string;\n}\n\n/**\n * Tooltip. Matches Figma's `Tooltip` set — `Placement: Top | Left | Right | Bottom`, with\n * a title and an optional body.\n *\n * Built on Radix Tooltip from 0.7.0, which gets right what a naive tooltip does not:\n *\n * - **Keyboard and touch reachable.** Opens on keyboard focus as well as hover, and closes\n * on Escape. A hover-only tooltip is inaccessible to half the people using it.\n * - **Hoverable (WCAG 1.4.13).** It stays open while the pointer moves onto it, so a\n * magnifier user can read it. 0.6 closed it the moment the pointer left the trigger.\n * - **Escape closes only the tooltip.** It goes through the same layer stack as `Modal`, so\n * dismissing a tooltip inside a dialog no longer closes the dialog too.\n * - **Referenced, not floating text.** The trigger is `aria-describedby` the tooltip (or\n * `aria-labelledby` it), so it is announced *with* the control.\n * - **`role=\"tooltip\"` and no interactive content.** Use `Popover` for anything a user acts on.\n *\n * Each tooltip carries its own Radix provider, so there is nothing to mount at the app root.\n */\nexport function Tooltip({\n children,\n title,\n body,\n side = 'top',\n align = 'center',\n openDelay = 150,\n open,\n defaultOpen,\n onOpenChange,\n association = 'describedby',\n className,\n}: TooltipProps) {\n const container = usePortalContainer();\n const labelId = useId();\n const labelled = association === 'labelledby';\n\n const content = (\n <>\n {title && <p className=\"font-semibold\">{title}</p>}\n {body && <p className={cn(title && 'mt-0.5 opacity-80')}>{body}</p>}\n </>\n );\n\n return (\n <TooltipPrimitive.Provider delayDuration={openDelay}>\n <TooltipPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <TooltipPrimitive.Trigger\n asChild\n // As the trigger's *name*, the tooltip text has to exist while closed too, or the\n // control is unnamed; so it is rendered hidden, permanently, and Radix's own\n // description of it is switched off to avoid reading the name twice.\n {...(labelled ? { 'aria-labelledby': labelId, 'aria-describedby': undefined } : {})}\n >\n {children}\n </TooltipPrimitive.Trigger>\n {labelled && (\n <span id={labelId} hidden>\n {title}\n {body ? ' ' : null}\n {body}\n </span>\n )}\n <TooltipPrimitive.Portal container={container ?? undefined}>\n <TooltipPrimitive.Content\n side={side}\n align={align}\n sideOffset={6}\n collisionPadding={8}\n className={cn(\n 'z-tooltip max-w-[260px] rounded-lg bg-neutral px-3 py-2 shadow-300',\n 'text-body-xs text-neutral-on-neutral',\n className,\n )}\n >\n {content}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n </TooltipPrimitive.Provider>\n );\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n useMemo,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Popover as PopoverPrimitive } from 'radix-ui';\n\nimport { cn } from '../../lib/cn';\nimport { composeRefs } from '../../lib/slot';\nimport type { FloatingAlign, FloatingSide } from './floating';\nimport { deferEscapeToInnerPopup } from './overlay-stack';\nimport { usePortalContainer } from './portal';\n\n/** Shares the trigger's element, so the panel can be labelled by whatever id it really has. */\nconst PopoverTriggerNode = createContext<{\n node: HTMLElement | null;\n setNode: (node: HTMLElement | null) => void;\n modal: boolean;\n} | null>(null);\n\nexport interface PopoverProps {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Trap focus, lock scroll and hide the rest of the page from assistive tech. Default\n * `false`.\n *\n * A popover is normally non-modal: the page behind stays usable, and Tab moves out of the\n * panel and on through the document. Set `modal` when the panel is a small form whose\n * background must not be touched until it is dismissed.\n */\n modal?: boolean;\n}\n\n/**\n * A floating panel anchored to a trigger, for **interactive** content.\n *\n * The distinction from `Tooltip` is not visual and it matters: a tooltip cannot be hovered\n * into or focused, so anything interactive inside one is unreachable. If the panel holds a\n * link, a button or a field, it has to be a popover — which means a real trigger with\n * `aria-expanded`/`aria-controls`, focus moving into the panel on open, and focus returning\n * to the trigger on close.\n *\n * Built on Radix Popover from 0.7.0. Escape and outside press act on the topmost layer only,\n * so a popover inside a `Modal` closes without taking the modal with it, and focus leaving a\n * non-modal panel dismisses it rather than stranding it open.\n */\nexport function Popover({ children, open, defaultOpen, onOpenChange, modal = false }: PopoverProps) {\n const [node, setNode] = useState<HTMLElement | null>(null);\n const trigger = useMemo(() => ({ node, setNode, modal }), [node, modal]);\n\n return (\n <PopoverPrimitive.Root\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n modal={modal}\n >\n <PopoverTriggerNode.Provider value={trigger}>{children}</PopoverTriggerNode.Provider>\n </PopoverPrimitive.Root>\n );\n}\n\nexport interface PopoverTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n /** Render onto the single child (e.g. a `Button`) instead of a bare `<button>`. */\n asChild?: boolean;\n}\n\n/**\n * Toggles the popover. Radix sets `aria-haspopup=\"dialog\"`, `aria-expanded`,\n * `aria-controls` and `data-state`, and composes your handlers with its own rather than\n * replacing them (0.6's `onClick` overrode the toggle).\n */\nexport const PopoverTrigger = forwardRef<HTMLButtonElement, PopoverTriggerProps>(\n function PopoverTrigger(props, ref) {\n const trigger = useContext(PopoverTriggerNode);\n const fallbackId = useId();\n return (\n <PopoverPrimitive.Trigger\n ref={composeRefs(ref, trigger?.setNode)}\n // An id to label the panel by. An `asChild` child's own `id` wins, and the panel\n // reads the real one off the node, so either way the reference resolves.\n id={props.id ?? fallbackId}\n {...props}\n />\n );\n },\n);\n\nexport interface PopoverContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n sideOffset?: number;\n /** Accessible name for the panel. Falls back to being labelled by the trigger. */\n label?: string;\n /** Where to portal the panel. Defaults to the enclosing dialog, else `document.body`. */\n container?: HTMLElement | null;\n}\n\nexport const PopoverContent = forwardRef<HTMLDivElement, PopoverContentProps>(\n function PopoverContent(\n { children, side = 'bottom', align = 'center', sideOffset = 8, label, container, className, ...rest },\n ref,\n ) {\n const trigger = useContext(PopoverTriggerNode);\n const inherited = usePortalContainer();\n\n return (\n <PopoverPrimitive.Portal container={container ?? inherited ?? undefined}>\n <PopoverPrimitive.Content\n ref={ref}\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={8}\n onEscapeKeyDown={(event) => void deferEscapeToInnerPopup(event)}\n // Radix traps focus and hides the page for a modal popover but does not say so.\n aria-modal={trigger?.modal || undefined}\n aria-label={label}\n aria-labelledby={label ? undefined : trigger?.node?.id || undefined}\n className={cn(\n 'z-popover max-w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-default bg-default p-4 shadow-400',\n 'focus:outline-none',\n className,\n )}\n {...rest}\n >\n {children}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n );\n },\n);\n\n/** Closes the enclosing popover, e.g. an \"Apply\" or \"Cancel\" button. New in 0.7.0. */\nexport const PopoverClose = forwardRef<HTMLButtonElement, HTMLAttributes<HTMLButtonElement> & { asChild?: boolean }>(\n function PopoverClose(props, ref) {\n return <PopoverPrimitive.Close ref={ref} {...props} />;\n },\n);\n\n/** Positions the panel against an element other than the trigger. New in 0.7.0. */\nexport const PopoverAnchor = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement> & { asChild?: boolean }>(\n function PopoverAnchor(props, ref) {\n return <PopoverPrimitive.Anchor ref={ref} {...props} />;\n },\n);\n","import { useId, useState, type ReactElement, type ReactNode } from 'react';\nimport { HoverCard as HoverCardPrimitive } from 'radix-ui';\n\nimport { cn } from '../../lib/cn';\nimport type { FloatingAlign, FloatingSide } from './floating';\nimport { usePortalContainer } from './portal';\n\nexport interface HoverCardProps {\n /** The trigger. Must be a single focusable element — normally a link. */\n children: ReactElement;\n /** Panel content. May contain links and text; see the note on interactivity below. */\n content: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n /** Delay before opening, in ms. Default `400`. */\n openDelay?: number;\n /** Delay before closing, in ms. Default `200`. */\n closeDelay?: number;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n className?: string;\n}\n\n/**\n * A preview panel that appears on hover — a user card on an @mention, a page preview on a\n * link.\n *\n * Sits between `Tooltip` and `Popover`, and the difference is about intent rather than\n * looks:\n *\n * - `Tooltip` is a short label. It cannot be entered, so it must hold no controls.\n * - `HoverCard` is supplementary content that *can* be entered — the panel stays open while\n * the pointer is inside it, so a link in the preview is reachable. It is opened by hover\n * and focus, never by click.\n * - `Popover` is opened deliberately by click and is the only one of the three appropriate\n * for content the user must act on.\n *\n * **It is supplementary by contract.** Hover has no touch equivalent, so anything only\n * reachable here is unreachable on a phone. The panel is `aria-labelledby` the trigger and\n * exposed as a group; the trigger keeps its own name and destination.\n *\n * Built on Radix HoverCard from 0.7.0: the open and close delays, the pointer grace area\n * between trigger and panel, and Escape through the shared layer stack (so it closes only\n * the card, not a dialog behind it) come from Radix. The `group` role and the\n * `aria-describedby` wiring are ours; Radix gives the panel no role at all.\n */\nexport function HoverCard({\n children,\n content,\n side = 'bottom',\n align = 'center',\n openDelay = 400,\n closeDelay = 200,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n className,\n}: HoverCardProps) {\n const container = usePortalContainer();\n const baseId = useId();\n const contentId = `${baseId}-content`;\n const triggerId = `${baseId}-trigger`;\n // Tracked here as well as in Radix, because the trigger's description only points at the\n // panel while it exists.\n const [openState, setOpenState] = useState(defaultOpen);\n const open = openProp ?? openState;\n const handleOpenChange = (next: boolean) => {\n setOpenState(next);\n onOpenChange?.(next);\n };\n\n return (\n <HoverCardPrimitive.Root\n open={open}\n onOpenChange={handleOpenChange}\n openDelay={openDelay}\n closeDelay={closeDelay}\n >\n <HoverCardPrimitive.Trigger\n asChild\n id={triggerId}\n // Not `aria-haspopup`: nothing here is triggered by activation, and claiming a popup\n // on a plain link makes a screen reader promise an interaction that does not exist.\n aria-describedby={open ? contentId : undefined}\n >\n {children}\n </HoverCardPrimitive.Trigger>\n <HoverCardPrimitive.Portal container={container ?? undefined}>\n <HoverCardPrimitive.Content\n id={contentId}\n // `group`, not `dialog` — it was not opened deliberately and it traps nothing,\n // so announcing a dialog would be a lie.\n role=\"group\"\n aria-labelledby={triggerId}\n side={side}\n align={align}\n sideOffset={8}\n collisionPadding={8}\n className={cn(\n 'z-popover max-w-[min(20rem,calc(100vw-2rem))] rounded-xl border border-default bg-default p-4 shadow-400',\n className,\n )}\n >\n {content}\n </HoverCardPrimitive.Content>\n </HoverCardPrimitive.Portal>\n </HoverCardPrimitive.Root>\n );\n}\n","import {\n forwardRef,\n type HTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { ContextMenu as ContextMenuPrimitive } from 'radix-ui';\n\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/compose-event-handlers';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { MENU_PANEL_CLASSES, createMenuParts, focusMenuEdge, stopToAncestors } from './menu-core';\nimport { usePortalContainer } from './portal';\n\nexport interface ContextMenuProps {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * Right-click menu, built on Radix ContextMenu from 0.7.0.\n *\n * Shares every item and the whole keyboard contract with `DropdownMenu` (see `menu-core`);\n * the only difference is how it opens — at the pointer, with no trigger element to anchor\n * to.\n *\n * **A context menu must never be the only way to reach an action.** `contextmenu` fires on\n * right-click and on the Windows Menu / Shift+F10 keys, but not on touch, and plenty of\n * users never right-click at all. `ContextMenuTrigger` therefore also opens on Shift+F10 and\n * the ContextMenu key even where the browser would not, and anything in here should have a\n * visible equivalent elsewhere — usually a `DropdownMenu` on the same row.\n *\n * Radix ContextMenu has no `open` prop (it is opened by the pointer only), so a controlled\n * `open={false}` closes it, but `open={true}` cannot open it without a position.\n */\nexport function ContextMenu({ children, open: openProp, defaultOpen = false, onOpenChange }: ContextMenuProps) {\n const [, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n return (\n <ContextMenuPrimitive.Root onOpenChange={setOpen} modal={false}>\n {children}\n </ContextMenuPrimitive.Root>\n );\n}\n\nexport interface ContextMenuTriggerProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n disabled?: boolean;\n}\n\n/**\n * The area that responds to right-click. A wrapper with no tab stop of its own: the keyboard\n * path is Shift+F10 or the ContextMenu key from whatever inside it has focus.\n */\nexport const ContextMenuTrigger = forwardRef<HTMLDivElement, ContextMenuTriggerProps>(\n function ContextMenuTrigger({ children, disabled = false, className, onKeyDown, ...rest }, ref) {\n const openFromKeyboard = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (disabled || event.defaultPrevented) return;\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n // Cancelling the key also stops the browser's own `contextmenu`, so the menu opens\n // exactly once, at the focused element rather than wherever the pointer happens to be.\n event.preventDefault();\n const source = event.target instanceof HTMLElement ? event.target : event.currentTarget;\n const rect = source.getBoundingClientRect();\n source.dispatchEvent(\n new MouseEvent('contextmenu', {\n bubbles: true,\n cancelable: true,\n clientX: rect.left + rect.width / 2,\n clientY: rect.top + rect.height / 2,\n }),\n );\n }\n };\n\n return (\n <ContextMenuPrimitive.Trigger asChild disabled={disabled}>\n {/* The key handler only catches Shift+F10 / ContextMenu bubbling up from focusable\n content inside. The wrapper is deliberately not focusable and takes no role: its\n actions have a visible equivalent elsewhere, and a tab stop here would add an\n unexplained one in the middle of, say, a table row. */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div\n ref={ref}\n data-slot=\"context-menu-trigger\"\n className={className}\n onKeyDown={openFromKeyboard}\n {...rest}\n >\n {children}\n </div>\n </ContextMenuPrimitive.Trigger>\n );\n },\n);\n\nexport interface ContextMenuContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Minimum gap from the viewport edge, in px. Default `8`. */\n collisionPadding?: number;\n /** Where to portal the menu. Defaults to the enclosing dialog, else `document.body`. */\n container?: HTMLElement | null;\n}\n\nexport const ContextMenuContent = forwardRef<HTMLDivElement, ContextMenuContentProps>(\n function ContextMenuContent(\n { children, collisionPadding = 8, container, className, onClick, onKeyDown, onFocus, ...rest },\n ref,\n ) {\n const inherited = usePortalContainer();\n return (\n <ContextMenuPrimitive.Portal container={container ?? inherited ?? undefined}>\n <ContextMenuPrimitive.Content\n ref={ref}\n collisionPadding={collisionPadding}\n loop\n className={cn(MENU_PANEL_CLASSES, className)}\n onFocus={composeEventHandlers(onFocus, (event) => focusMenuEdge(event, 'start'))}\n onClick={(event) => {\n onClick?.(event);\n stopToAncestors(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n stopToAncestors(event);\n if (event.key === 'Tab') {\n // Tab leaves the menu, as in DropdownMenu. Radix has no imperative close for a\n // context menu, so Escape is replayed on the panel to dismiss it.\n event.currentTarget.dispatchEvent(\n new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }),\n );\n }\n }}\n {...rest}\n >\n {children}\n </ContextMenuPrimitive.Content>\n </ContextMenuPrimitive.Portal>\n );\n },\n);\n\nconst parts = createMenuParts(ContextMenuPrimitive);\n\nexport const ContextMenuItem = parts.Item;\nexport const ContextMenuCheckboxItem = parts.CheckboxItem;\nexport const ContextMenuRadioGroup = parts.RadioGroup;\nexport const ContextMenuRadioItem = parts.RadioItem;\nexport const ContextMenuGroup = parts.Group;\nexport const ContextMenuLabel = parts.Label;\nexport const ContextMenuSeparator = parts.Separator;\nexport const ContextMenuShortcut = parts.Shortcut;\nexport const ContextMenuSub = parts.Sub;\nexport const ContextMenuSubTrigger = parts.SubTrigger;\nexport const ContextMenuSubContent = parts.SubContent;\n","import {\n forwardRef,\n useId,\n type ComponentType,\n type ForwardRefExoticComponent,\n type HTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type RefAttributes,\n} from 'react';\nimport clsx from 'clsx';\nimport { CheckIcon, ChevronRightIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING_INSET } from '../../lib/focus-ring';\nimport {\n OVERLAY_HEADING,\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE,\n OVERLAY_PANEL_MENU,\n OVERLAY_SEPARATOR,\n type OverlayItemTone,\n} from './menu-styles';\nimport { usePortalContainer } from './portal';\n\n/**\n * The shared item set behind `DropdownMenu`, `ContextMenu` and `Menubar`.\n *\n * All three are the same WAI-ARIA menu: identical items, keyboard contract and ARIA. Only how\n * they *open* differs: a trigger button, a right-click at the pointer, or a bar of triggers.\n * From 0.7.0 that contract is Radix's (roving focus, typeahead, Home/End, submenus with a\n * safe pointer path, Escape through the shared layer stack), and this module only supplies\n * the look and our props.\n *\n * Radix scopes each item to its own root (`DropdownMenu.Item` will not work inside a\n * `ContextMenu`), so `createMenuParts` builds one identically styled set per primitive. That\n * keeps it one implementation, not three copies.\n */\n\n/** Panel chrome, shared so the three menus cannot drift apart visually. */\nexport const MENU_PANEL_CLASSES = cn('z-popover', OVERLAY_PANEL_MENU, 'focus:outline-none');\n\nconst ITEM_BASE = clsx(\n OVERLAY_ITEM_BASE,\n OVERLAY_ITEM_SIZE.md,\n // Highlight follows Radix's `data-highlighted`, which tracks pointer and keyboard alike.\n // The ring marks the keyboard position on top of it: the tint alone, shared with hover,\n // cannot tell a keyboard user which of two tinted items has focus.\n FOCUS_RING_INSET,\n 'data-[disabled]:cursor-not-allowed data-[disabled]:text-disabled',\n);\n\nexport type MenuItemTone = OverlayItemTone;\n\n/** Tone as a state attribute, styled here, so call sites never pass colour classes. */\nconst ITEM_TONE: Record<MenuItemTone, string> = {\n default: 'text-default data-[highlighted]:bg-default-secondary',\n danger: 'text-danger data-[highlighted]:bg-danger-tertiary',\n};\n\n/** Keeps a press inside a portalled menu from reaching a clickable ancestor, e.g. a table row. */\nexport function stopToAncestors(event: ReactMouseEvent | ReactKeyboardEvent) {\n event.stopPropagation();\n}\n\n/**\n * Lands on an item when a menu opens, whatever opened it.\n *\n * Radix focuses the panel on open and moves on to the first item only after a keyboard\n * open. The APG menu button (and 0.6) put focus on an item either way, and on the *last* one\n * after ArrowUp. Wire it to the content's `onFocus`. It is deferred a microtask so it runs\n * after Radix's own entry focus rather than being undone by it.\n */\nexport function focusMenuEdge(\n event: { target: EventTarget; currentTarget: HTMLElement },\n edge: 'start' | 'end',\n) {\n if (event.target !== event.currentTarget) return;\n const panel = event.currentTarget;\n queueMicrotask(() => {\n const items = panel.querySelectorAll<HTMLElement>('[role^=\"menuitem\"]:not([data-disabled])');\n if (edge === 'end') items[items.length - 1]?.focus();\n else if (document.activeElement === panel) items[0]?.focus();\n });\n}\n\n// ── Prop types (one set, shared by all three menus) ───────────────────────────\n\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n children: ReactNode;\n /** Called on activation. Call `event.preventDefault()` to keep the menu open. */\n onSelect?: (event: Event) => void;\n tone?: MenuItemTone;\n disabled?: boolean;\n /** Leading glyph. Marked decorative automatically. Matches Figma's `Icon` / `Has Icon`. */\n icon?: ReactNode;\n /** Second line. Matches Figma's `Description` / `Has Description`. */\n description?: ReactNode;\n /** Trailing shortcut hint. Matches Figma's `Shortcut` / `Has Shortcut`. */\n shortcut?: ReactNode;\n /** Typeahead match text, when `children` is not a plain string. */\n textValue?: string;\n}\n\nexport interface MenuCheckboxItemProps extends Omit<MenuItemProps, 'onSelect' | 'icon'> {\n checked: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nexport interface MenuRadioGroupProps {\n children: ReactNode;\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nexport interface MenuRadioItemProps extends Omit<MenuItemProps, 'onSelect' | 'icon'> {\n value: string;\n}\n\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Names the group. Rendered as a heading when set. */\n label?: string;\n}\n\nexport interface MenuLabelProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport interface MenuSeparatorProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport interface MenuShortcutProps extends HTMLAttributes<HTMLSpanElement> {\n children: ReactNode;\n}\n\nexport interface MenuSubProps {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport interface MenuSubTriggerProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n icon?: ReactNode;\n disabled?: boolean;\n textValue?: string;\n}\n\nexport interface MenuSubContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n// ── The primitive shape all three Radix menus share ────────────────────────────\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Part = ForwardRefExoticComponent<any & RefAttributes<HTMLDivElement>>;\n\nexport interface RadixMenuPrimitive {\n Item: Part;\n CheckboxItem: Part;\n RadioGroup: Part;\n RadioItem: Part;\n ItemIndicator: Part;\n Group: Part;\n Label: Part;\n Separator: Part;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Sub: ComponentType<any>;\n SubTrigger: Part;\n SubContent: Part;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Portal: ComponentType<any>;\n}\n\nexport function createMenuParts(P: RadixMenuPrimitive) {\n const Item = forwardRef<HTMLDivElement, MenuItemProps>(function MenuItem(\n { children, onSelect, tone = 'default', disabled = false, icon, description, shortcut, textValue, className, ...rest },\n ref,\n ) {\n const descriptionId = useId();\n return (\n <P.Item\n ref={ref}\n disabled={disabled}\n textValue={textValue}\n onSelect={onSelect}\n data-tone={tone}\n aria-describedby={description ? descriptionId : undefined}\n className={cn(ITEM_BASE, ITEM_TONE[tone], className)}\n {...rest}\n >\n {icon && (\n <span aria-hidden className=\"mt-0.5 flex size-4 shrink-0 items-center justify-center\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{children}</span>\n {description && (\n <span id={descriptionId} className=\"mt-0.5 block text-body-tiny text-default-secondary\">\n {description}\n </span>\n )}\n </span>\n {shortcut && (\n <span className=\"ml-auto shrink-0 pl-4 text-body-tiny text-default-tertiary\">{shortcut}</span>\n )}\n </P.Item>\n );\n });\n\n const CheckboxItem = forwardRef<HTMLDivElement, MenuCheckboxItemProps>(function MenuCheckboxItem(\n { children, checked, onCheckedChange, disabled = false, tone = 'default', shortcut, textValue, className, ...rest },\n ref,\n ) {\n return (\n <P.CheckboxItem\n ref={ref}\n checked={checked}\n onCheckedChange={(next: boolean | 'indeterminate') => onCheckedChange?.(next === true)}\n // Stays open: a checkbox item is for multi-select, and closing after each toggle\n // would make selecting three things take three round trips. Radix closes by default.\n onSelect={(event: Event) => event.preventDefault()}\n disabled={disabled}\n textValue={textValue}\n data-tone={tone}\n className={cn(ITEM_BASE, 'items-center', ITEM_TONE[tone], className)}\n {...rest}\n >\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n <P.ItemIndicator>\n <CheckIcon className=\"size-3.5\" strokeWidth={3} />\n </P.ItemIndicator>\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n {shortcut && (\n <span className=\"ml-auto shrink-0 pl-4 text-body-tiny text-default-tertiary\">{shortcut}</span>\n )}\n </P.CheckboxItem>\n );\n });\n\n function RadioGroup({ children, value, onValueChange }: MenuRadioGroupProps) {\n return (\n <P.RadioGroup value={value} onValueChange={onValueChange}>\n {children}\n </P.RadioGroup>\n );\n }\n\n const RadioItem = forwardRef<HTMLDivElement, MenuRadioItemProps>(function MenuRadioItem(\n { children, value, disabled = false, tone = 'default', textValue, className, ...rest },\n ref,\n ) {\n return (\n <P.RadioItem\n ref={ref}\n value={value}\n disabled={disabled}\n textValue={textValue}\n data-tone={tone}\n className={cn(ITEM_BASE, 'items-center', ITEM_TONE[tone], className)}\n {...rest}\n >\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n <P.ItemIndicator>\n <span className=\"block size-1.5 rounded-full bg-current\" />\n </P.ItemIndicator>\n </span>\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n </P.RadioItem>\n );\n });\n\n const Group = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { children, label, className, ...rest },\n ref,\n ) {\n const labelId = useId();\n return (\n <P.Group ref={ref} aria-labelledby={label ? labelId : undefined} className={className} {...rest}>\n {label && (\n <div id={labelId} className={OVERLAY_HEADING}>\n {label}\n </div>\n )}\n {children}\n </P.Group>\n );\n });\n\n /** A non-interactive heading inside the menu. Matches Figma's `Menu Heading`. */\n const Label = forwardRef<HTMLDivElement, MenuLabelProps>(function MenuLabel(\n { className, ...rest },\n ref,\n ) {\n return <P.Label ref={ref} className={cn(OVERLAY_HEADING, className)} {...rest} />;\n });\n\n /** Matches Figma's `Menu Separator`. */\n const Separator = forwardRef<HTMLDivElement, MenuSeparatorProps>(function MenuSeparator(\n { className, ...rest },\n ref,\n ) {\n return <P.Separator ref={ref} className={cn(OVERLAY_SEPARATOR, className)} {...rest} />;\n });\n\n /** Trailing keyboard hint, for use outside an item's `shortcut` prop. */\n const Shortcut = forwardRef<HTMLSpanElement, MenuShortcutProps>(function MenuShortcut(\n { className, ...rest },\n ref,\n ) {\n return (\n <span ref={ref} className={cn('ml-auto pl-4 text-body-tiny text-default-tertiary', className)} {...rest} />\n );\n });\n\n /** A nested menu. New in 0.7.0: Radix supplies the hover intent and safe pointer path. */\n function Sub({ children, open, defaultOpen, onOpenChange }: MenuSubProps) {\n return (\n <P.Sub open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {children}\n </P.Sub>\n );\n }\n\n /** The item that opens a `*Sub`. ArrowRight opens it, ArrowLeft closes it. */\n const SubTrigger = forwardRef<HTMLDivElement, MenuSubTriggerProps>(function MenuSubTrigger(\n { children, icon, disabled = false, textValue, className, ...rest },\n ref,\n ) {\n return (\n <P.SubTrigger\n ref={ref}\n disabled={disabled}\n textValue={textValue}\n className={cn(\n ITEM_BASE,\n 'items-center',\n ITEM_TONE.default,\n 'data-[state=open]:bg-default-secondary',\n className,\n )}\n {...rest}\n >\n {icon && (\n <span aria-hidden className=\"flex size-4 shrink-0 items-center justify-center\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n <ChevronRightIcon aria-hidden className=\"ml-auto size-4 shrink-0 text-default-tertiary\" />\n </P.SubTrigger>\n );\n });\n\n const SubContent = forwardRef<HTMLDivElement, MenuSubContentProps>(function MenuSubContent(\n { className, onClick, onKeyDown, ...rest },\n ref,\n ) {\n const container = usePortalContainer();\n return (\n <P.Portal container={container ?? undefined}>\n <P.SubContent\n ref={ref}\n sideOffset={4}\n collisionPadding={8}\n className={cn(MENU_PANEL_CLASSES, className)}\n onClick={(event: ReactMouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n stopToAncestors(event);\n }}\n onKeyDown={(event: ReactKeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n stopToAncestors(event);\n }}\n {...rest}\n />\n </P.Portal>\n );\n });\n\n return {\n Item,\n CheckboxItem,\n RadioGroup,\n RadioItem,\n Group,\n Label,\n Separator,\n Shortcut,\n Sub,\n SubTrigger,\n SubContent,\n };\n}\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { Menubar as MenubarPrimitive } from 'radix-ui';\n\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/compose-event-handlers';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { MENU_PANEL_CLASSES, createMenuParts, focusMenuEdge, stopToAncestors } from './menu-core';\nimport { usePortalContainer } from './portal';\n\nexport interface MenubarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'dir' | 'defaultValue'> {\n children: ReactNode;\n /** Reading direction, which flips Left/Right along the bar. */\n dir?: 'ltr' | 'rtl';\n /** Accessible name for the bar, e.g. \"Editor\". Required: a menubar is a landmark-like group. */\n label: string;\n /** The open menu's `value`, controlled. New in 0.7.0. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n}\n\n/**\n * A persistent horizontal bar of menus, as in a desktop application's File / Edit / View.\n *\n * Built on Radix Menubar from 0.7.0, which supplies the contract: one tab stop for the whole\n * bar, Left/Right along it, Down/Up into a menu, Left/Right from inside an open menu to its\n * sibling, and moving the pointer across the bar switching menus once one is open. Items are\n * the same parts as `DropdownMenu` (see `menu-core`).\n */\nexport const Menubar = forwardRef<HTMLDivElement, MenubarProps>(function Menubar(\n { children, label, value, defaultValue, onValueChange, className, ...rest },\n ref,\n) {\n return (\n <MenubarPrimitive.Root\n ref={ref}\n value={value}\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n loop\n aria-label={label}\n data-slot=\"menubar\"\n className={cn('flex items-center gap-0.5', className)}\n {...rest}\n >\n {children}\n </MenubarPrimitive.Root>\n );\n});\n\nexport interface MenubarMenuProps {\n children: ReactNode;\n /** Identifies the menu within the bar. */\n value: string;\n}\n\nexport function MenubarMenu({ children, value }: MenubarMenuProps) {\n return <MenubarPrimitive.Menu value={value}>{children}</MenubarPrimitive.Menu>;\n}\n\nexport interface MenubarTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n}\n\nexport const MenubarTrigger = forwardRef<HTMLButtonElement, MenubarTriggerProps>(\n function MenubarTrigger({ className, ...rest }, ref) {\n return (\n <MenubarPrimitive.Trigger\n ref={ref}\n className={cn(\n 'rounded-md px-2.5 py-1.5 text-body-sm text-default transition-colors',\n FOCUS_RING,\n 'hover:bg-default-secondary data-[state=open]:bg-default-secondary',\n className,\n )}\n {...rest}\n />\n );\n },\n);\n\nexport interface MenubarContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Where to portal the menu. Defaults to the enclosing dialog, else `document.body`. */\n container?: HTMLElement | null;\n}\n\nexport const MenubarContent = forwardRef<HTMLDivElement, MenubarContentProps>(\n function MenubarContent(\n { children, container, className, onClick, onKeyDown, onFocus, ...rest },\n ref,\n ) {\n const inherited = usePortalContainer();\n return (\n <MenubarPrimitive.Portal container={container ?? inherited ?? undefined}>\n <MenubarPrimitive.Content\n ref={ref}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n loop\n className={cn(MENU_PANEL_CLASSES, className)}\n onFocus={composeEventHandlers(onFocus, (event) => focusMenuEdge(event, 'start'))}\n onClick={(event) => {\n onClick?.(event);\n stopToAncestors(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n stopToAncestors(event);\n // Tab leaves the menu, as in DropdownMenu and ContextMenu. Radix keeps Tab inside an\n // open menu and has no imperative close here, so Escape is replayed on the panel.\n if (event.key === 'Tab') {\n event.currentTarget.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));\n }\n }}\n {...rest}\n >\n {children}\n </MenubarPrimitive.Content>\n </MenubarPrimitive.Portal>\n );\n },\n);\n\nconst parts = createMenuParts(MenubarPrimitive);\n\nexport const MenubarItem = parts.Item;\nexport const MenubarCheckboxItem = parts.CheckboxItem;\nexport const MenubarRadioGroup = parts.RadioGroup;\nexport const MenubarRadioItem = parts.RadioItem;\nexport const MenubarGroup = parts.Group;\nexport const MenubarLabel = parts.Label;\nexport const MenubarSeparator = parts.Separator;\nexport const MenubarShortcut = parts.Shortcut;\nexport const MenubarSub = parts.Sub;\nexport const MenubarSubTrigger = parts.SubTrigger;\nexport const MenubarSubContent = parts.SubContent;\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useState,\n type HTMLAttributes,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { XIcon } from 'lucide-react';\n\nimport { cn } from '../../lib/cn';\nimport { composeRefs } from '../../lib/slot';\nimport { ScrollArea } from '../cards/scroll-area';\nimport { IconButton } from '../forms/icon-button';\nimport { OVERLAY_SCRIM } from './overlay';\nimport { deferEscapeToInnerPopup } from './overlay-stack';\nimport { PortalContainerProvider } from './portal';\nimport { isInsideToaster } from './toaster-guard';\n\nexport type DrawerSide = 'right' | 'left';\nexport type DrawerFooterAlign = 'end' | 'between';\n\nexport interface DrawerProps {\n /** Controlled open state. Omit it, with `DrawerTrigger`, for an uncontrolled drawer. */\n open?: boolean;\n defaultOpen?: boolean;\n /** Fired with `false` on Escape, an outside press, or the close button. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Header content (left side). The copies this replaces differ only here — a status badge +\n * title in one, an avatar + title + category in another — so it is a slot, not props.\n *\n * Put a `DrawerTitle` in it and the drawer is named by that heading. Leave `header` out\n * altogether to compose the panel from `DrawerHeader` / `DrawerBody` / `DrawerFooter`.\n */\n header?: ReactNode;\n children: ReactNode;\n /** Footer content, with the `header` layout. Composed drawers use `DrawerFooter`. */\n footer?: ReactNode;\n /** `between` when the footer has a left-aligned secondary action. */\n footerAlign?: DrawerFooterAlign;\n /**\n * Panel width. Defaults to the `w-[440px] max-w-[90vw]` shared by every existing drawer.\n * `className` is merged with `cn` from 0.7.0, so a width there works too.\n */\n width?: string;\n /** Which edge the panel slides in from. Default `right`. */\n side?: DrawerSide;\n /**\n * Accessible name, for a drawer that renders no `DrawerTitle`.\n *\n * Required from 0.4.0 to 0.6, because a free `header` slot gave the name nowhere else\n * to come from. From 0.7.0 a `DrawerTitle` anywhere in the drawer names it by reference,\n * the way `ModalTitle` names a `Modal`, so `label` is only needed without one. With\n * neither, Radix warns in development.\n */\n label?: string;\n className?: string;\n /** Call `preventDefault()` to keep the drawer open — e.g. unsaved input. */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** Call `preventDefault()` to keep the drawer open. */\n onInteractOutside?: (event: PointerEvent) => void;\n /** Focus this on open instead of the first tabbable element. */\n initialFocus?: RefObject<HTMLElement | null>;\n /** Where to portal the drawer. Defaults to `document.body`. */\n container?: HTMLElement | null;\n}\n\ninterface DrawerNamingContext {\n registerTitle: (present: boolean) => void;\n registerDescription: (present: boolean) => void;\n}\n\nconst DrawerNaming = createContext<DrawerNamingContext | null>(null);\n\n/**\n * Side panel, built on Radix Dialog from 0.7.0. Radix handles Escape, the focus trap,\n * scroll lock, hiding the page from assistive tech, and returning focus on close.\n *\n * Two ways to fill it:\n *\n * // Slots: the layout every 0.6 drawer used.\n * <Drawer open={open} onOpenChange={setOpen}\n * header={<DrawerTitle>Supplier</DrawerTitle>} footer={<Button>Save</Button>}>\n * …body…\n * </Drawer>\n *\n * // Parts: for a header with a description, or a body that is not one scroll region.\n * <Drawer open={open} onOpenChange={setOpen}>\n * <DrawerHeader><DrawerTitle>Supplier</DrawerTitle><DrawerDescription>…</DrawerDescription></DrawerHeader>\n * <DrawerBody>…</DrawerBody>\n * <DrawerFooter><Button>Save</Button></DrawerFooter>\n * </Drawer>\n */\nexport const Drawer = forwardRef<HTMLDivElement, DrawerProps>(function Drawer(\n {\n open,\n defaultOpen,\n onOpenChange,\n header,\n children,\n footer,\n footerAlign = 'end',\n width = 'w-[440px] max-w-[90vw]',\n side = 'right',\n label,\n className,\n onEscapeKeyDown,\n onInteractOutside,\n initialFocus,\n container,\n },\n ref,\n) {\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {extractTrigger(children)}\n <DialogPrimitive.Portal container={container ?? undefined}>\n <DrawerPanel\n ref={ref}\n side={side}\n width={width}\n label={label}\n className={className}\n onEscapeKeyDown={onEscapeKeyDown}\n onInteractOutside={onInteractOutside}\n initialFocus={initialFocus}\n >\n {header !== undefined ? (\n <>\n <DrawerHeader>{header}</DrawerHeader>\n <DrawerBody label={label}>{withoutTrigger(children)}</DrawerBody>\n {footer && <DrawerFooter align={footerAlign}>{footer}</DrawerFooter>}\n </>\n ) : (\n withoutTrigger(children)\n )}\n </DrawerPanel>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n});\n\ninterface DrawerPanelProps\n extends Pick<\n DrawerProps,\n 'side' | 'width' | 'label' | 'className' | 'onEscapeKeyDown' | 'onInteractOutside' | 'initialFocus'\n > {\n children: ReactNode;\n}\n\nconst DrawerPanel = forwardRef<HTMLDivElement, DrawerPanelProps>(function DrawerPanel(\n { side = 'right', width, label, className, onEscapeKeyDown, onInteractOutside, initialFocus, children },\n ref,\n) {\n const [hasTitle, setHasTitle] = useState(false);\n const [hasDescription, setHasDescription] = useState(false);\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n // See Modal: Radix only returns focus to its own Trigger, and most drawers are opened by\n // an ordinary button. Captured before Radix moves focus into the panel.\n const [returnFocusTo] = useState(() =>\n typeof document === 'undefined' ? null : (document.activeElement as HTMLElement | null),\n );\n\n return (\n <DialogPrimitive.Overlay\n className={cn(\n 'fixed inset-0 z-modal flex',\n side === 'right' ? 'justify-end' : 'justify-start',\n OVERLAY_SCRIM,\n )}\n >\n <DialogPrimitive.Content\n asChild\n {...(hasDescription ? {} : { 'aria-describedby': undefined })}\n onOpenAutoFocus={(event) => {\n const target = initialFocus?.current;\n if (target) {\n event.preventDefault();\n target.focus();\n }\n }}\n onCloseAutoFocus={(event) => {\n if (returnFocusTo?.isConnected && returnFocusTo !== document.body) {\n event.preventDefault();\n returnFocusTo.focus();\n }\n }}\n onEscapeKeyDown={(event) => {\n if (!deferEscapeToInnerPopup(event)) onEscapeKeyDown?.(event);\n }}\n onPointerDownOutside={(event) => {\n if (isInsideToaster(event.target)) {\n event.preventDefault();\n return;\n }\n const original = event.detail.originalEvent;\n onInteractOutside?.(original);\n if (original.defaultPrevented) event.preventDefault();\n }}\n >\n {/* A `<div>`, not the `<aside>` of 0.6: `aside` is the complementary landmark, and\n `role=\"dialog\"` is not an allowed role on it (axe: aria-allowed-role). */}\n <div\n ref={composeRefs(ref, setPanelNode)}\n data-side={side}\n className={cn(\n 'relative flex h-full flex-col bg-default shadow-500 focus:outline-none',\n width,\n className,\n )}\n >\n {!hasTitle && label && (\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n )}\n <DrawerNaming.Provider\n value={{ registerTitle: setHasTitle, registerDescription: setHasDescription }}\n >\n <PortalContainerProvider container={panelNode}>{children}</PortalContainerProvider>\n </DrawerNaming.Provider>\n </div>\n </DialogPrimitive.Content>\n </DialogPrimitive.Overlay>\n );\n});\n\n// ── Trigger / Close ────────────────────────────────────────────────────────────\n\nexport interface DrawerTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n asChild?: boolean;\n}\n\n/** Opens an uncontrolled `Drawer`. A direct child of `Drawer`; it renders in place. */\nexport const DrawerTrigger = forwardRef<HTMLButtonElement, DrawerTriggerProps>(\n function DrawerTrigger(props, ref) {\n return <DialogPrimitive.Trigger ref={ref} {...props} />;\n },\n);\n(DrawerTrigger as unknown as { __drawerTrigger: true }).__drawerTrigger = true;\n\nexport interface DrawerCloseProps extends HTMLAttributes<HTMLButtonElement> {\n asChild?: boolean;\n}\n\n/** Closes the enclosing `Drawer`, e.g. a footer \"Cancel\" button. */\nexport const DrawerClose = forwardRef<HTMLButtonElement, DrawerCloseProps>(\n function DrawerClose(props, ref) {\n return <DialogPrimitive.Close ref={ref} {...props} />;\n },\n);\n\nfunction isTrigger(node: ReactNode): boolean {\n return (\n typeof node === 'object' &&\n node !== null &&\n 'type' in node &&\n (node.type as { __drawerTrigger?: boolean })?.__drawerTrigger === true\n );\n}\n\nfunction extractTrigger(children: ReactNode): ReactNode {\n return Array.isArray(children) ? children.filter(isTrigger) : isTrigger(children) ? children : null;\n}\n\nfunction withoutTrigger(children: ReactNode): ReactNode {\n return Array.isArray(children)\n ? children.filter((child) => !isTrigger(child))\n : isTrigger(children)\n ? null\n : children;\n}\n\n// ── Parts ──────────────────────────────────────────────────────────────────────\n\nexport interface DrawerHeaderProps extends HTMLAttributes<HTMLDivElement> {\n /** Renders the close button at the end of the header row. Default `true`. */\n showClose?: boolean;\n}\n\n/** The header row, with the close button. The `header` slot renders inside one of these. */\nexport const DrawerHeader = forwardRef<HTMLDivElement, DrawerHeaderProps>(function DrawerHeader(\n { children, showClose = true, className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={cn('flex items-start justify-between gap-3 border-b border-default p-6', className)}\n {...rest}\n >\n <div className=\"min-w-0\">{children}</div>\n {showClose && (\n <DialogPrimitive.Close asChild>\n <IconButton variant=\"subtle\" size=\"sm\" aria-label=\"Close\">\n <XIcon size={18} aria-hidden />\n </IconButton>\n </DialogPrimitive.Close>\n )}\n </div>\n );\n});\n\nexport interface DrawerTitleProps extends HTMLAttributes<HTMLHeadingElement> {}\n\n/** Names the drawer (`aria-labelledby`). Use it inside the `header` slot or `DrawerHeader`. */\nexport const DrawerTitle = forwardRef<HTMLHeadingElement, DrawerTitleProps>(function DrawerTitle(\n { className, children, ...rest },\n ref,\n) {\n const naming = useContext(DrawerNaming);\n useEffect(() => {\n naming?.registerTitle(true);\n return () => naming?.registerTitle(false);\n }, [naming]);\n\n const classes = cn('text-heading-sm font-semibold text-default', className);\n if (!naming) {\n return (\n <h2 ref={ref} className={classes} {...rest}>\n {children}\n </h2>\n );\n }\n return (\n <DialogPrimitive.Title ref={ref} className={classes} {...rest}>\n {children}\n </DialogPrimitive.Title>\n );\n});\n\nexport interface DrawerDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {}\n\n/** Describes the drawer (`aria-describedby`). */\nexport const DrawerDescription = forwardRef<HTMLParagraphElement, DrawerDescriptionProps>(\n function DrawerDescription({ className, ...rest }, ref) {\n const naming = useContext(DrawerNaming);\n useEffect(() => {\n naming?.registerDescription(true);\n return () => naming?.registerDescription(false);\n }, [naming]);\n\n const classes = cn('mt-0.5 text-body-xs text-default-secondary', className);\n if (!naming) return <p ref={ref} className={classes} {...rest} />;\n return <DialogPrimitive.Description ref={ref} className={classes} {...rest} />;\n },\n);\n\nexport interface DrawerBodyProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Accessible name for the scroll region, which becomes focusable when it overflows.\n * Defaults to \"Content\". It is not the drawer's own name, which would be announced twice.\n */\n label?: string;\n}\n\n/** The scrolling body. It fills the space between header and footer. */\nexport const DrawerBody = forwardRef<HTMLDivElement, DrawerBodyProps>(function DrawerBody(\n { children, label, className, ...rest },\n ref,\n) {\n return (\n <ScrollArea\n ref={ref}\n axis=\"vertical\"\n label={label ? `${label} content` : 'Content'}\n className=\"min-h-0 flex-1\"\n {...rest}\n >\n <div className={cn('space-y-6 p-6', className)}>{children}</div>\n </ScrollArea>\n );\n});\n\nexport interface DrawerFooterProps extends HTMLAttributes<HTMLDivElement> {\n align?: DrawerFooterAlign;\n}\n\nexport const DrawerFooter = forwardRef<HTMLDivElement, DrawerFooterProps>(function DrawerFooter(\n { align = 'end', className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n data-align={align}\n className={cn(\n 'flex items-center gap-2 border-t border-default px-6 py-4',\n align === 'between' ? 'justify-between' : 'justify-end',\n className,\n )}\n {...rest}\n />\n );\n});\n","import { forwardRef, useEffect, useRef, useState, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { composeRefs } from '../../lib/slot';\n\nexport type ScrollAreaAxis = 'vertical' | 'horizontal' | 'both';\n\nexport interface ScrollAreaProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n axis?: ScrollAreaAxis;\n /**\n * Accessible name for the scrollable region. Strongly recommended — a scroll container\n * that becomes focusable (see below) needs to announce what it is.\n */\n label?: string;\n}\n\nconst OVERFLOW: Record<ScrollAreaAxis, string> = {\n vertical: 'overflow-y-auto overflow-x-hidden',\n horizontal: 'overflow-x-auto overflow-y-hidden',\n both: 'overflow-auto',\n};\n\nexport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\n/**\n * A scrollable region with styled scrollbars.\n *\n * **Native scrolling, deliberately.** shadcn/Radix replaces the scrollbar with a rendered\n * one, which looks tidier and costs real accessibility: an overlay scrollbar has to\n * reimplement keyboard scrolling, momentum, trackpad and pen behaviour, and the OS\n * \"click the track to page\" convention — and it drops out entirely if the JS fails. Styling\n * `::-webkit-scrollbar` plus `scrollbar-width`/`scrollbar-color` gets most of the look with\n * none of that risk, and degrades to a normal scrollbar where unsupported.\n *\n * The one thing this *does* add is the piece browsers get wrong: a scroll container is not\n * keyboard focusable by default in Chrome or Safari, so a keyboard-only user cannot scroll\n * an overflowing `<div>` at all unless something inside it is focusable. This measures its\n * own content and sets `tabIndex={0}` only while it actually overflows, so the region is\n * scrollable with the arrow keys without adding a pointless tab stop when it does not.\n */\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(function ScrollArea(\n { children, axis = 'vertical', label, className, ...rest },\n ref,\n) {\n const localRef = useRef<HTMLDivElement>(null);\n const [overflows, setOverflows] = useState(false);\n\n useEffect(() => {\n const node = localRef.current;\n if (!node) return;\n\n const measure = () => {\n const vertical = node.scrollHeight > node.clientHeight + 1;\n const horizontal = node.scrollWidth > node.clientWidth + 1;\n setOverflows(\n axis === 'vertical' ? vertical : axis === 'horizontal' ? horizontal : vertical || horizontal,\n );\n };\n\n measure();\n\n // Feature-detected: `ResizeObserver` is absent in jsdom, in Safari before 13.1, and\n // during any server render, and an unguarded `new ResizeObserver` throws outright. The\n // measurement above has already run, so without the observer the tab stop is simply\n // decided once at mount rather than tracked — degraded, not broken.\n if (typeof ResizeObserver === 'undefined') return;\n\n // Content and box size both matter, so both are observed. On the element it catches the\n // box; on the first child it catches content growth.\n const observer = new ResizeObserver(measure);\n observer.observe(node);\n if (node.firstElementChild) observer.observe(node.firstElementChild);\n return () => observer.disconnect();\n }, [axis, children]);\n\n return (\n <div\n ref={composeRefs<HTMLDivElement>(localRef, ref)}\n // `role=\"region\"` only once it is focusable and named, so an ordinary non-overflowing\n // wrapper does not add a landmark to the page for nothing.\n role={overflows && label ? 'region' : undefined}\n aria-label={overflows ? label : undefined}\n tabIndex={overflows ? 0 : undefined}\n data-slot=\"scroll-area\"\n className={clsx(\n OVERFLOW[axis],\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n SCROLLBAR_CLASSES,\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n});\n","import { useRef, type ReactNode } from 'react';\n\nimport { Button } from '../forms/button';\nimport { Modal, ModalBody, ModalDescription, ModalFooter, ModalHeader, ModalTitle } from './modal';\nimport type { ModalSize, ModalTone } from './modal';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n title: string;\n subtitle?: string;\n /**\n * Adds a tinted glyph to the header. Defaults to `default` (no glyph) so existing\n * call sites look unchanged; opt in per dialog rather than deriving it from\n * `confirmVariant`, which would silently restyle every destructive confirm.\n */\n tone?: ModalTone;\n size?: ModalSize;\n confirmLabel?: string;\n cancelLabel?: string;\n confirmVariant?: 'primary' | 'danger';\n /**\n * The double-submit guard. While true, the confirm button shows a spinner and its\n * `confirmingLabel`, and ignores presses while keeping focus. The dialog also cannot be\n * dismissed (Escape, outside press, Cancel, the close button), so a request in flight\n * cannot lose the dialog that is waiting on it.\n */\n isConfirming?: boolean;\n /** Label shown on the confirm button while `isConfirming`. */\n confirmingLabel?: string;\n /** Optional body — a warning callout, a consequences list, or a failed-attempt error. */\n children?: ReactNode;\n className?: string;\n onConfirm: () => void;\n /** Fired with `false` on cancel, Escape, or an outside press. */\n onOpenChange: (open: boolean) => void;\n}\n\n/**\n * The in-app replacement for `window.confirm`: a title, an optional body, and a\n * cancel/confirm pair.\n *\n * Kept as a preset rather than folded into `Modal` because it carries *behaviour*, not\n * just layout — the `isConfirming` guard that disables the button and swaps its label\n * is the thing call sites get wrong when they hand-roll a confirm. For any other\n * shape, compose `Modal` and its parts directly.\n *\n * Focus opens on **Cancel**, the least destructive action, as the WAI-ARIA alert dialog\n * pattern recommends. Through 0.6 it opened on the close button, one Tab away from\n * \"Delete\".\n */\nexport function ConfirmDialog({\n open,\n title,\n subtitle,\n tone = 'default',\n size = 'md',\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n confirmVariant = 'primary',\n isConfirming = false,\n confirmingLabel = 'Working…',\n children,\n className,\n onConfirm,\n onOpenChange,\n}: ConfirmDialogProps) {\n const cancelRef = useRef<HTMLButtonElement>(null);\n // Every dismissal route (Escape, outside press, close button, Cancel) arrives here.\n const requestOpenChange = (next: boolean) => {\n if (!next && isConfirming) return;\n onOpenChange(next);\n };\n\n return (\n // `alertdialog`, not `dialog`: this interrupts to ask a yes/no question, so the body\n // should be announced on open rather than waiting to be browsed to. The name comes\n // from `ModalTitle` via `aria-labelledby`, so there is no `label` to keep in sync.\n <Modal\n open={open}\n onOpenChange={requestOpenChange}\n role=\"alertdialog\"\n size={size}\n className={className}\n initialFocus={cancelRef}\n >\n <ModalHeader tone={tone} divider={Boolean(children)}>\n <ModalTitle>{title}</ModalTitle>\n {subtitle && <ModalDescription>{subtitle}</ModalDescription>}\n </ModalHeader>\n {/* Guarded: 0.2.0 always rendered a body, so a childless confirm carried 40px of\n dead space plus a stray rule. */}\n {children && <ModalBody>{children}</ModalBody>}\n <ModalFooter>\n <Button\n ref={cancelRef}\n variant=\"neutral\"\n size=\"md\"\n disabled={isConfirming}\n onClick={() => requestOpenChange(false)}\n >\n {cancelLabel}\n </Button>\n <Button\n variant={confirmVariant}\n size=\"md\"\n loading={isConfirming}\n loadingLabel={confirmingLabel}\n onClick={onConfirm}\n >\n {isConfirming ? confirmingLabel : confirmLabel}\n </Button>\n </ModalFooter>\n </Modal>\n );\n}\n","import { useState } from 'react';\n\nimport { Button } from '../forms/button';\nimport { Textarea } from '../forms/textarea';\nimport { Modal, ModalBody, ModalDescription, ModalFooter, ModalHeader, ModalTitle } from './modal';\nimport type { ModalSize, ModalTone } from './modal';\n\nexport interface NoteConfirmModalProps {\n open: boolean;\n title: string;\n subtitle?: string;\n tone?: ModalTone;\n size?: ModalSize;\n confirmLabel: string;\n cancelLabel?: string;\n confirmVariant?: 'primary' | 'danger';\n /** Block confirmation until the note has content. */\n requireNote?: boolean;\n notePlaceholder?: string;\n /** Accessible name of the note field. The placeholder is not a label. Defaults to \"Note\". */\n noteLabel?: string;\n submittingLabel?: string;\n /** Shows a spinner on confirm and keeps the dialog from being dismissed mid-request. */\n isSubmitting?: boolean;\n className?: string;\n /** Fired with `false` on cancel, Escape, or an outside press. */\n onOpenChange: (open: boolean) => void;\n onConfirm: (note: string) => void;\n /**\n * Asked before an Escape or outside press throws away a note that has content.\n * Return `false` to keep the dialog open. Defaults to `window.confirm`.\n */\n onDiscardNote?: (note: string) => boolean;\n}\n\n/**\n * Confirm dialog that collects a free-text note — approvals, rejections, information\n * requests. The note is trimmed before it reaches `onConfirm`.\n *\n * Kept as a preset because it owns state, and a composition cannot.\n */\nexport function NoteConfirmModal({ open, ...rest }: NoteConfirmModalProps) {\n // The shell split is what resets the note. Before 0.3.0 this component had no `open`\n // prop and callers mounted it conditionally, so the typed note was discarded for free.\n // Now that it stays mounted, unmounting the shell is what clears it — otherwise a\n // rejection note would reappear the next time the dialog opened.\n if (!open) return null;\n return <NoteConfirmModalShell {...rest} />;\n}\n\nfunction NoteConfirmModalShell({\n title,\n subtitle,\n tone = 'default',\n size = 'md',\n confirmLabel,\n cancelLabel = 'Cancel',\n confirmVariant = 'primary',\n requireNote = false,\n notePlaceholder = 'Add a note…',\n noteLabel = 'Note',\n submittingLabel = 'Saving…',\n isSubmitting = false,\n className,\n onOpenChange,\n onConfirm,\n onDiscardNote,\n}: Omit<NoteConfirmModalProps, 'open'>) {\n const [note, setNote] = useState('');\n const noteMissing = requireNote && !note.trim();\n const requestOpenChange = (next: boolean) => {\n if (!next && isSubmitting) return;\n onOpenChange(next);\n };\n\n /**\n * Escape and an outside press both unmount the shell, which is what clears the note —\n * so before 0.4.0 either one silently destroyed whatever the user had typed, with no\n * warning and no undo. On a rejection-reason dialog that is real work lost.\n */\n const guardDiscard = (event: { preventDefault: () => void }) => {\n if (isSubmitting) {\n event.preventDefault();\n return;\n }\n if (!note.trim()) return;\n const confirmed = onDiscardNote\n ? onDiscardNote(note)\n : typeof window !== 'undefined' &&\n window.confirm('Discard your note? It will not be saved.');\n if (!confirmed) event.preventDefault();\n };\n\n return (\n <Modal\n open\n onOpenChange={requestOpenChange}\n size={size}\n className={className}\n onEscapeKeyDown={guardDiscard}\n onInteractOutside={guardDiscard}\n >\n <ModalHeader tone={tone}>\n <ModalTitle>{title}</ModalTitle>\n {subtitle && <ModalDescription>{subtitle}</ModalDescription>}\n </ModalHeader>\n <ModalBody>\n <Textarea\n value={note}\n onChange={(e) => setNote(e.target.value)}\n placeholder={notePlaceholder}\n aria-label={noteLabel}\n rows={4}\n />\n </ModalBody>\n <ModalFooter>\n <Button\n variant=\"neutral\"\n size=\"md\"\n disabled={isSubmitting}\n onClick={() => requestOpenChange(false)}\n >\n {cancelLabel}\n </Button>\n <Button\n variant={confirmVariant}\n size=\"md\"\n disabled={noteMissing}\n loading={isSubmitting}\n loadingLabel={submittingLabel}\n onClick={() => onConfirm(note.trim())}\n >\n {isSubmitting ? submittingLabel : confirmLabel}\n </Button>\n </ModalFooter>\n </Modal>\n );\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useMemo,\n useRef,\n type HTMLAttributes,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n} from 'react';\nimport { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';\nimport { EllipsisIcon } from 'lucide-react';\n\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/compose-event-handlers';\nimport { useControllableState } from '../../lib/use-controllable-state';\nimport { IconButton } from '../forms/icon-button';\nimport type { FloatingAlign, FloatingSide } from './floating';\nimport { MENU_PANEL_CLASSES, createMenuParts, focusMenuEdge, stopToAncestors } from './menu-core';\nimport { usePortalContainer } from './portal';\n\n/**\n * Overflow / row-actions menu.\n *\n * 0.4.0 rebuilt it to the WAI-ARIA menu contract after a version that declared the roles\n * and implemented none of the keys. 0.7.0 moves that contract onto Radix DropdownMenu, which\n * also brings submenus (`DropdownMenuSub`), the one thing 0.4.0 deliberately left out because\n * a half-built safe-travel path is worse than none.\n *\n * Kept from ours, on top of Radix:\n * - **ArrowUp on the trigger opens on the last item**, as the APG describes.\n * - **Tab closes the menu** so focus moves on through the page; Radix keeps Tab inside.\n * - **It works inside a clickable table row.** Presses on the trigger and in the panel stop\n * short of the row, the behaviour 0.2.0's `RowMenu` existed for.\n * - **Non-modal by default.** The page behind stays readable and interactive.\n */\n\nexport interface DropdownMenuProps {\n children: ReactNode;\n /** Controlled open state. Omit for uncontrolled. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Block the page while open (Radix's default). Default `false`, matching 0.6: a menu is\n * not a dialog, and the page behind it stays usable.\n */\n modal?: boolean;\n}\n\ninterface DropdownMenuState {\n setOpen: (open: boolean) => void;\n /** Which end to land on when the menu opens; ArrowUp on the trigger means \"last item\". */\n pendingEdge: { current: 'start' | 'end' };\n}\n\nconst DropdownMenuStateContext = createContext<DropdownMenuState | null>(null);\n\nfunction useDropdownMenuState(part: string): DropdownMenuState {\n const value = useContext(DropdownMenuStateContext);\n if (!value) throw new Error(`<${part}> must be used inside <DropdownMenu>`);\n return value;\n}\n\nexport function DropdownMenu({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n modal = false,\n}: DropdownMenuProps) {\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n const pendingEdge = useRef<'start' | 'end'>('start');\n const state = useMemo(() => ({ setOpen, pendingEdge }), [setOpen]);\n\n return (\n <DropdownMenuPrimitive.Root open={open} onOpenChange={setOpen} modal={modal}>\n <DropdownMenuStateContext.Provider value={state}>{children}</DropdownMenuStateContext.Provider>\n </DropdownMenuPrimitive.Root>\n );\n}\n\n// ── Trigger ────────────────────────────────────────────────────────────────────\n\nexport interface DropdownMenuTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children?: ReactNode;\n /** Render the child element instead of the default overflow button. */\n asChild?: boolean;\n /** Accessible name for the default `⋯` button. Ignored when `asChild` is set. */\n label?: string;\n}\n\nexport const DropdownMenuTrigger = forwardRef<HTMLButtonElement, DropdownMenuTriggerProps>(\n function DropdownMenuTrigger(\n { children, asChild = false, label = 'Open menu', onClick, onPointerDown, onMouseDown, onKeyDown, ...rest },\n ref,\n ) {\n const state = useDropdownMenuState('DropdownMenuTrigger');\n\n // Radix runs these first and then its own handler, so stopping propagation here keeps a\n // surrounding row from reacting without stopping the menu from opening.\n const handlers = {\n onClick: (event: ReactMouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n stopToAncestors(event);\n },\n onPointerDown: (event: ReactPointerEvent<HTMLButtonElement>) => {\n onPointerDown?.(event);\n event.stopPropagation();\n },\n onMouseDown: (event: ReactMouseEvent<HTMLButtonElement>) => {\n onMouseDown?.(event);\n stopToAncestors(event);\n },\n onKeyDown: (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (event.key === 'ArrowUp') {\n // Radix opens on ArrowDown only.\n event.preventDefault();\n state.pendingEdge.current = 'end';\n state.setOpen(true);\n }\n // Enter on the trigger must not also activate the row it sits in.\n if (event.key === 'Enter' || event.key === ' ') stopToAncestors(event);\n },\n };\n\n if (asChild) {\n return (\n <DropdownMenuPrimitive.Trigger ref={ref} asChild {...rest} {...handlers}>\n {children}\n </DropdownMenuPrimitive.Trigger>\n );\n }\n\n return (\n <DropdownMenuPrimitive.Trigger ref={ref} asChild {...rest} {...handlers}>\n <IconButton variant=\"neutral\" size=\"sm\" aria-label={label}>\n {children ?? <EllipsisIcon className=\"size-4\" aria-hidden />}\n </IconButton>\n </DropdownMenuPrimitive.Trigger>\n );\n },\n);\n\n// ── Content ────────────────────────────────────────────────────────────────────\n\nexport interface DropdownMenuContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n side?: FloatingSide;\n align?: FloatingAlign;\n sideOffset?: number;\n /** Where to portal the menu. Defaults to the enclosing dialog, else `document.body`. */\n container?: HTMLElement | null;\n /** Called when focus returns on close. Call `preventDefault()` to stop it moving to the trigger. */\n onCloseAutoFocus?: (event: Event) => void;\n}\n\nexport const DropdownMenuContent = forwardRef<HTMLDivElement, DropdownMenuContentProps>(\n function DropdownMenuContent(\n {\n children,\n side = 'bottom',\n align = 'end',\n sideOffset = 6,\n container,\n className,\n onClick,\n onKeyDown,\n onFocus,\n onCloseAutoFocus,\n ...rest\n },\n ref,\n ) {\n const state = useDropdownMenuState('DropdownMenuContent');\n const inherited = usePortalContainer();\n\n return (\n <DropdownMenuPrimitive.Portal container={container ?? inherited ?? undefined}>\n <DropdownMenuPrimitive.Content\n ref={ref}\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={8}\n // Arrow keys wrap from the last item to the first and back, as they did in 0.6.\n loop\n className={cn(MENU_PANEL_CLASSES, className)}\n onCloseAutoFocus={composeEventHandlers(onCloseAutoFocus, () => {\n state.pendingEdge.current = 'start';\n })}\n onFocus={composeEventHandlers(onFocus, (event) => {\n const edge = state.pendingEdge.current;\n state.pendingEdge.current = 'start';\n focusMenuEdge(event, edge);\n })}\n onClick={(event) => {\n onClick?.(event);\n stopToAncestors(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n stopToAncestors(event);\n // Tab leaves the menu rather than walking it: close, and Radix hands focus back\n // to the trigger, from where the browser carries on.\n if (event.key === 'Tab') state.setOpen(false);\n }}\n {...rest}\n >\n {children}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n );\n },\n);\n\n// ── Items ──────────────────────────────────────────────────────────────────────\n\nconst parts = createMenuParts(DropdownMenuPrimitive);\n\nexport const DropdownMenuItem = parts.Item;\nexport const DropdownMenuCheckboxItem = parts.CheckboxItem;\nexport const DropdownMenuRadioGroup = parts.RadioGroup;\nexport const DropdownMenuRadioItem = parts.RadioItem;\nexport const DropdownMenuGroup = parts.Group;\nexport const DropdownMenuLabel = parts.Label;\nexport const DropdownMenuSeparator = parts.Separator;\nexport const DropdownMenuShortcut = parts.Shortcut;\nexport const DropdownMenuSub = parts.Sub;\nexport const DropdownMenuSubTrigger = parts.SubTrigger;\nexport const DropdownMenuSubContent = parts.SubContent;\n\nexport type {\n MenuItemProps as DropdownMenuItemProps,\n MenuItemTone as DropdownMenuItemTone,\n MenuCheckboxItemProps as DropdownMenuCheckboxItemProps,\n MenuRadioGroupProps as DropdownMenuRadioGroupProps,\n MenuRadioItemProps as DropdownMenuRadioItemProps,\n MenuGroupProps as DropdownMenuGroupProps,\n MenuLabelProps as DropdownMenuLabelProps,\n MenuSeparatorProps as DropdownMenuSeparatorProps,\n MenuShortcutProps as DropdownMenuShortcutProps,\n MenuSubProps as DropdownMenuSubProps,\n MenuSubTriggerProps as DropdownMenuSubTriggerProps,\n MenuSubContentProps as DropdownMenuSubContentProps,\n} from './menu-core';\n","import { cn } from '../../lib/cn';\nimport { OVERLAY_SCRIM } from './overlay';\n\nexport interface ScrimProps {\n /** Dismiss the overlay this scrim sits behind. */\n onClose?: () => void;\n /**\n * Accessible name. With one, the scrim is a real `<button>`, which it must be when clicking it\n * is the *only* pointer route out. Without one it is `aria-hidden` decoration, and the overlay\n * must offer another exit (a close button, Escape).\n */\n label?: string;\n /** `absolute` when the scrim sits inside a wrapper that is already positioned. */\n position?: 'fixed' | 'absolute';\n /**\n * Fade instead of mounting and unmounting, for a panel that slides in and out. While closed\n * the scrim stops taking pointer events; an always-mounted scrim that kept them would silently\n * eat every click on the page. Set as `data-state`.\n */\n open?: boolean;\n /** Stacking and breakpoint gating, e.g. `z-overlay lg:hidden`. */\n className?: string;\n}\n\n/**\n * The dimming layer behind an overlay, for overlays `Modal` and `Drawer` do not cover (a\n * non-modal side panel, a mobile nav). New in 0.7.0, from SCIC. It exists so \"I need a scrim\"\n * never again means hand-writing `fixed inset-0 bg-black/40`, which is how SCIC ended up with\n * three scrim colours. The colour comes from `OVERLAY_SCRIM`.\n */\nexport function Scrim({ onClose, label, position = 'fixed', open, className }: ScrimProps) {\n const classes = cn(\n position === 'fixed' ? 'fixed inset-0' : 'absolute inset-0',\n OVERLAY_SCRIM,\n open !== undefined && 'transition-opacity duration-200 motion-reduce:transition-none',\n 'data-[state=closed]:pointer-events-none data-[state=closed]:opacity-0',\n className,\n );\n const state = open === undefined ? undefined : open ? 'open' : 'closed';\n\n if (label) {\n return <button type=\"button\" aria-label={label} data-state={state} onClick={onClose} className={classes} />;\n }\n // Decoration: the overlay offers another way out, so this needs no keyboard handler.\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions\n return <div aria-hidden data-state={state} onClick={onClose} className={classes} />;\n}\n","import { useState, type ReactNode } from 'react';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { XIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\nimport { Button } from '../forms/button';\nimport { deferEscapeToInnerPopup } from './overlay-stack';\nimport { PortalContainerProvider } from './portal';\n\n/**\n * `base` (the default) sits on the overlay layer, so a dialog opened from inside it appears above\n * it. `elevated` sits above another surface, e.g. a widget preview opened from a full-screen\n * dashboard. SCIC defaulted to `elevated`.\n */\nexport type FullscreenStacking = 'base' | 'elevated';\n\nconst STACKING: Record<FullscreenStacking, string> = {\n base: 'z-overlay',\n elevated: 'z-modal',\n};\n\nexport interface FullscreenSurfaceProps {\n /** Called on Escape and on the close button. The surface renders while mounted. */\n onClose: () => void;\n /** Accessible name of the surface, e.g. \"Supply risk dashboard\". */\n label: string;\n /** Text on the close button. Default \"Close\". */\n closeLabel?: string;\n stacking?: FullscreenStacking;\n children: ReactNode;\n className?: string;\n}\n\n/**\n * An opaque, scrollable surface that fills the viewport, with a close button: \"full screen\" and\n * \"expand this widget\". New in 0.7.0, from SCIC.\n *\n * No scrim, because nothing behind it is visible. But it *is* modal: SCIC's version left the page\n * underneath in the tab order, so Tab walked into content covered by the surface. Built on Radix\n * Dialog, it traps focus, hides the page from assistive tech, returns focus on close, and takes\n * Escape through the shared layer stack, so a dialog opened on top closes first.\n */\nexport function FullscreenSurface({\n onClose,\n label,\n closeLabel = 'Close',\n stacking = 'base',\n children,\n className,\n}: FullscreenSurfaceProps) {\n const [node, setNode] = useState<HTMLDivElement | null>(null);\n return (\n <DialogPrimitive.Root open onOpenChange={(open) => !open && onClose()}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Content\n ref={setNode}\n aria-describedby={undefined}\n onEscapeKeyDown={(event) => void deferEscapeToInnerPopup(event)}\n className={cn(\n 'fixed inset-0 overflow-auto bg-default-secondary p-4 focus:outline-none lg:p-6',\n STACKING[stacking],\n className,\n )}\n >\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <div className=\"mb-4 flex justify-end\">\n <DialogPrimitive.Close asChild>\n <Button variant=\"neutral\" size=\"md\" leadingIcon={<XIcon aria-hidden />}>\n {closeLabel}\n </Button>\n </DialogPrimitive.Close>\n </div>\n <PortalContainerProvider container={node}>{children}</PortalContainerProvider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport { VisuallyHidden as VisuallyHiddenPrimitive } from 'radix-ui';\n\nexport interface VisuallyHiddenProps extends HTMLAttributes<HTMLSpanElement> {\n /** Render the hiding styles onto the single child element instead of a `<span>`. */\n asChild?: boolean;\n}\n\n/**\n * Content that screen readers announce and nobody sees: a dialog title the design does\n * not show, a \"(opens in new tab)\" suffix, the label of an icon-only control.\n *\n * Tailwind's `sr-only` does the same job in markup the library owns, and nine components still\n * use it. This is for the call site, where a component is clearer than a utility class and\n * survives a `className` override that would otherwise drop `sr-only` along with the rest.\n */\nexport const VisuallyHidden = forwardRef<HTMLSpanElement, VisuallyHiddenProps>(\n function VisuallyHidden(props, ref) {\n return <VisuallyHiddenPrimitive.Root ref={ref} {...props} />;\n },\n);\n","import type { ReactElement } from 'react';\nimport { AccessibleIcon as AccessibleIconPrimitive } from 'radix-ui';\n\nexport interface AccessibleIconProps {\n /** The icon. A single element; it is hidden from assistive technology. */\n children: ReactElement;\n /** What the icon means. It is announced in place of the icon. */\n label: string;\n}\n\n/**\n * An icon that carries meaning on its own, with no visible text beside it: a \"verified\" tick\n * in a table cell, a warning glyph standing in for a status word.\n *\n * Icons are decorative by default (`lucide-react` hides them, and so does the library wherever\n * it renders one for you). That is right beside a label and wrong here, where the icon *is*\n * the information. This hides the SVG and adds the label as visually hidden text, which reads\n * reliably in every screen reader, unlike `aria-label` on an `<svg>`.\n *\n * Inside a button, use `IconButton` with `aria-label` instead: the name belongs to the control,\n * not to the glyph.\n *\n * <AccessibleIcon label=\"Verified\"><CircleCheckBigIcon className=\"size-4\" /></AccessibleIcon>\n */\nexport function AccessibleIcon({ children, label }: AccessibleIconProps) {\n return <AccessibleIconPrimitive.Root label={label}>{children}</AccessibleIconPrimitive.Root>;\n}\n","import { createContext, useContext, type HTMLAttributes, type ReactNode } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type CardSize = 'sm' | 'md' | 'lg';\nexport type CardRadius = 'lg' | 'xl' | '2xl';\nexport type CardTone = 'default' | 'brand' | 'positive' | 'warning' | 'danger';\nexport type CardFooterAlign = 'start' | 'between' | 'end';\n\nconst RADIUS: Record<CardRadius, string> = {\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n};\n\nconst TONE: Record<CardTone, string> = {\n default: 'border-default bg-default',\n brand: 'border-brand-tertiary bg-brand-tertiary',\n positive: 'border-positive-tertiary bg-positive-tertiary',\n warning: 'border-warning-tertiary bg-warning-tertiary',\n // The one asymmetry: danger keeps the strong `border-danger` rather than the\n // tertiary border, because it is the only tone that has to read as an alarm from\n // across a dashboard. Byte-identical to the deleted AlertCard's danger surface.\n danger: 'border-danger bg-danger-tertiary',\n};\n\n/**\n * Header and footer share one padding ladder, and it now matches `BODY_BOX` on both axes.\n *\n * It used to match horizontally and not vertically — `px-4 py-3` against the body's `p-4` —\n * so a header sat 4px tighter than the body it capped, and stacking a header on a body put\n * two different rhythms in one card. The horizontal inset was already the value that\n * mattered for aligning a title over its content; the vertical one was simply out of step.\n */\nconst BOX: Record<CardSize, string> = {\n sm: 'px-3 py-3',\n md: 'px-4 py-4',\n lg: 'px-5 py-5',\n};\n\nconst BODY_BOX: Record<CardSize, string> = {\n sm: 'gap-3 p-3',\n md: 'gap-4 p-4',\n lg: 'gap-5 p-5',\n};\n\nconst TITLE_SIZE: Record<CardSize, string> = {\n sm: 'text-body-xs',\n md: 'text-body-sm',\n lg: 'text-subheading-sm',\n};\n\n/**\n * One step below the title at every size.\n *\n * `CardDescription` was frozen at `text-body-tiny` while `CardTitle` scaled, so `size=\"lg\"`\n * put an 11px description under a 16px title and `size=\"sm\"` put 11px under 13px — the ratio\n * broke at both ends of the ladder. The size comes from the enclosing `CardHeader` through\n * context rather than a prop, because a description that has to be told its own size at every\n * call site is a size that will drift.\n */\nconst DESCRIPTION_SIZE: Record<CardSize, string> = {\n sm: 'text-body-tiny',\n md: 'text-body-tiny',\n lg: 'text-body-xs',\n};\n\nconst FOOTER_ALIGN: Record<CardFooterAlign, string> = {\n start: 'justify-start',\n between: 'justify-between',\n end: 'justify-end',\n};\n\n/**\n * Set by `CardHeader` so `CardDescription` tracks its sibling title's size.\n *\n * Deliberately only carries the size, and only from the header: the body has its own\n * ladder and nothing inside it reads this.\n */\nconst CardHeaderContext = createContext<CardSize>('md');\n\n// ── Card ───────────────────────────────────────────────────────────────────────\n\nexport interface CardProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** `2xl` suits detail pages, `xl` section panels, `lg` dense or nested cards. */\n radius?: CardRadius;\n /**\n * Surface tint. This is a prop rather than a `className` because a tone has to\n * un-set the base `border-default bg-default` pair, not add to it.\n */\n tone?: CardTone;\n}\n\n/**\n * The card shell. Composed from `CardHeader`, `CardBody` and `CardFooter` — or from\n * nothing at all, if you want content to bleed to the edges (drop `CardBody` and put\n * a `DataTable` straight inside).\n *\n * Replaces `SectionCard` and the two monolithic cards that shipped beside it,\n * `AlertCard` and `BenchmarkCard`. Both of those are now documented compositions; see\n * the Cards page. The vocabulary follows shadcn/ui so it is already familiar, with\n * `CardBody` in place of its `CardContent`.\n */\nexport function Card({ children, radius = '2xl', tone = 'default', className, ...rest }: CardProps) {\n return (\n <div\n data-tone={tone}\n data-slot=\"card\"\n // `overflow-hidden` is load-bearing: it clips a header's border-b to the\n // rounded corner. Removing it leaves the rule poking past the radius.\n className={cn('flex flex-col overflow-hidden border', RADIUS[radius], TONE[tone], className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n// ── CardHeader ─────────────────────────────────────────────────────────────────\n\nexport interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: CardSize;\n /** Bottom rule separating the header from the body. */\n divider?: boolean;\n}\n\n/**\n * Header row. Holds `CardTitle`, `CardDescription` and an optional `CardAction`.\n *\n * The `has-[…]` selector switches to a two-column grid only when a `CardAction` is\n * present, which is what lets title, description and action share a header with no\n * wrapper div and no stray gap when the action is absent.\n */\nexport function CardHeader({\n children,\n size = 'md',\n divider = true,\n className,\n ...rest\n}: CardHeaderProps) {\n return (\n <CardHeaderContext.Provider value={size}>\n <div\n data-slot=\"card-header\"\n className={cn(\n 'grid auto-rows-min items-center gap-x-3 gap-y-0.5',\n 'has-[[data-slot=card-action]]:grid-cols-[1fr_auto]',\n BOX[size],\n divider && 'border-b border-default',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </CardHeaderContext.Provider>\n );\n}\n\n// ── CardTitle / CardDescription / CardAction ───────────────────────────────────\n\nexport interface CardTitleProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n size?: CardSize;\n /** Heading level. Defaults to `p`; use h2/h3 where the page has a real hierarchy. */\n as?: 'h2' | 'h3' | 'h4' | 'p';\n}\n\nexport function CardTitle({ children, size = 'md', as: Tag = 'p', className, ...rest }: CardTitleProps) {\n return (\n <Tag\n data-slot=\"card-title\"\n // min-w-0 belongs here, not on the parent: a grid item defaults to\n // min-width:auto, so `truncate` on a title would not work without it.\n className={cn('min-w-0 font-semibold text-default', TITLE_SIZE[size], className)}\n {...rest}\n >\n {children}\n </Tag>\n );\n}\n\nexport interface CardDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {\n children: ReactNode;\n /** Overrides the size inherited from the enclosing `CardHeader`. */\n size?: CardSize;\n}\n\nexport function CardDescription({ children, size, className, ...rest }: CardDescriptionProps) {\n const inherited = useContext(CardHeaderContext);\n\n return (\n <p\n data-slot=\"card-description\"\n className={cn(\n 'min-w-0 text-default-secondary',\n DESCRIPTION_SIZE[size ?? inherited],\n className,\n )}\n {...rest}\n >\n {children}\n </p>\n );\n}\n\nexport interface CardActionProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/** Right-hand slot in a `CardHeader` — a button, a count, a status badge, a menu. */\nexport function CardAction({ children, className, ...rest }: CardActionProps) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn('col-start-2 row-span-2 row-start-1 shrink-0 self-center justify-self-end', className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n// ── CardBody ───────────────────────────────────────────────────────────────────\n\nexport interface CardBodyProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: CardSize;\n}\n\n/**\n * The content region. A vertical stack by default.\n *\n * Because this file uses `cn`, `className` genuinely overrides the base — so\n * `className=\"flex-row items-center\"` gives you a row, and\n * `className=\"grid grid-cols-3\"` a grid. That is what makes the `AlertCard` and\n * `BenchmarkCard` rebuilds possible without a `layout` prop.\n */\nexport function CardBody({ children, size = 'md', className, ...rest }: CardBodyProps) {\n return (\n <div data-slot=\"card-body\" className={cn('flex flex-col', BODY_BOX[size], className)} {...rest}>\n {children}\n </div>\n );\n}\n\n// ── CardFooter ─────────────────────────────────────────────────────────────────\n\nexport interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: CardSize;\n divider?: boolean;\n align?: CardFooterAlign;\n}\n\n/** Action row at the foot of a card. Mirrors `ModalFooter` and `Drawer`'s footer. */\nexport function CardFooter({\n children,\n size = 'md',\n divider = true,\n align = 'end',\n className,\n ...rest\n}: CardFooterProps) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n 'flex items-center gap-2',\n BOX[size],\n FOOTER_ALIGN[align],\n divider && 'border-t border-default',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","import { createContext, forwardRef, useContext, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Accordion as AccordionPrimitive } from 'radix-ui';\nimport { ChevronDownIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\n\nexport type AccordionType = 'single' | 'multiple';\n\nconst HeadingLevel = createContext<2 | 3 | 4>(3);\n\nexport interface AccordionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | 'dir'> {\n children: ReactNode;\n /** `single` closes the open item when another opens. Default `single`. */\n type?: AccordionType;\n /** Open item value(s) — a string for `single`, an array for `multiple`. */\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n /** Allow closing the open item in `single` mode. Default `true`. */\n collapsible?: boolean;\n /**\n * Heading level for each item's trigger. Default `3`.\n *\n * Each trigger is wrapped in a real heading, per the APG, so the accordion appears in\n * the document outline and a screen reader can jump between sections by heading. The\n * right level depends on what surrounds it, which only the caller knows.\n */\n headingLevel?: 2 | 3 | 4;\n disabled?: boolean;\n}\n\n/**\n * Accordion. Matches Figma's `Accordion` / `Accordion Item` (`State: Closed | Open`).\n *\n * Width is deliberately not set — Figma's own note on `Accordion Item` says the 640px in\n * the component set is a container artefact and the parent should own width, so this is\n * `w-full` and nothing more.\n *\n * Built on Radix Accordion from 0.7.0. The contract is unchanged: real headings, triggers with\n * `aria-expanded` / `aria-controls`, labelled `region` panels, Up/Down/Home/End between\n * triggers, and closed panels unmounted so they are not tabbable. New: your handlers on the\n * trigger compose with the toggle, every part forwards its ref, each part carries\n * `data-state`, and open content exposes `--radix-accordion-content-height` for animation.\n */\nexport const Accordion = forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n {\n children,\n type = 'single',\n value,\n defaultValue,\n onValueChange,\n collapsible = true,\n headingLevel = 3,\n disabled,\n className,\n ...rest\n },\n ref,\n) {\n const shared = {\n ref,\n disabled,\n 'data-slot': 'accordion',\n className: cn('w-full', className),\n ...rest,\n };\n\n const root =\n type === 'multiple' ? (\n <AccordionPrimitive.Root\n type=\"multiple\"\n value={value === undefined ? undefined : toArray(value)}\n defaultValue={defaultValue === undefined ? undefined : toArray(defaultValue)}\n onValueChange={onValueChange as ((value: string[]) => void) | undefined}\n {...shared}\n >\n {children}\n </AccordionPrimitive.Root>\n ) : (\n <AccordionPrimitive.Root\n type=\"single\"\n collapsible={collapsible}\n value={value === undefined ? undefined : toSingle(value)}\n defaultValue={defaultValue === undefined ? undefined : toSingle(defaultValue)}\n onValueChange={onValueChange as ((value: string) => void) | undefined}\n {...shared}\n >\n {children}\n </AccordionPrimitive.Root>\n );\n\n return <HeadingLevel.Provider value={headingLevel}>{root}</HeadingLevel.Provider>;\n});\n\nconst toArray = (value: string | string[]) => (Array.isArray(value) ? value : value ? [value] : []);\nconst toSingle = (value: string | string[]) => (Array.isArray(value) ? (value[0] ?? '') : value);\n\nexport interface AccordionItemProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n value: string;\n disabled?: boolean;\n}\n\nexport const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(function AccordionItem(\n { className, ...rest },\n ref,\n) {\n return (\n <AccordionPrimitive.Item\n ref={ref}\n data-slot=\"accordion-item\"\n className={cn('border-b border-default last:border-b-0', className)}\n {...rest}\n />\n );\n});\n\nexport interface AccordionTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n /** Hide the chevron — for a trigger that supplies its own affordance. */\n hideIndicator?: boolean;\n}\n\nexport const AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n function AccordionTrigger({ children, hideIndicator = false, className, ...rest }, ref) {\n const level = useContext(HeadingLevel);\n const Heading = `h${level}` as 'h3';\n\n return (\n // The heading carries no styling of its own — it exists so the accordion shows up in\n // the document outline, which is how screen reader users navigate between sections.\n <AccordionPrimitive.Header asChild>\n <Heading className=\"m-0\">\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cn(\n 'group flex w-full items-center justify-between gap-3 py-4 text-left',\n 'text-body-sm font-semibold text-default transition-colors',\n 'hover:text-brand',\n FOCUS_RING,\n 'disabled:cursor-not-allowed disabled:text-disabled',\n className,\n )}\n {...rest}\n >\n <span className=\"min-w-0 flex-1\">{children}</span>\n {!hideIndicator && (\n <ChevronDownIcon\n aria-hidden\n className={clsx(\n 'size-4 shrink-0 text-icon-default-secondary transition-transform',\n 'group-data-[state=open]:rotate-180',\n )}\n />\n )}\n </AccordionPrimitive.Trigger>\n </Heading>\n </AccordionPrimitive.Header>\n );\n },\n);\n\nexport interface AccordionContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\n/**\n * Unmounted while closed rather than height-collapsed: a `height: 0` panel keeps its content\n * focusable and announceable, so keyboard users would tab into a closed section.\n */\nexport const AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(\n function AccordionContent({ className, ...rest }, ref) {\n return (\n <AccordionPrimitive.Content\n ref={ref}\n data-slot=\"accordion-content\"\n className={cn('pb-4 text-body-sm text-default-secondary', className)}\n {...rest}\n />\n );\n },\n);\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Collapsible as CollapsiblePrimitive } from 'radix-ui';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\n/**\n * The trigger's id, so the panel can be a region labelled by it (Radix gives it no role), and\n * the open state, which `keepMounted` needs: Radix's own `forceMount` renders the content\n * visibly while closed, because it is meant for animation libraries that hide it themselves.\n */\nconst CollapsibleState = createContext<{ triggerId: string; open: boolean } | null>(null);\n\nexport interface CollapsibleProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n}\n\n/**\n * A show/hide region with a trigger. The single-item primitive behind `Accordion`.\n *\n * The whole point is the wiring, which is easy to get wrong by hand: the trigger needs\n * `aria-expanded` and `aria-controls`, the panel needs an id and a matching\n * `aria-labelledby`, and the panel must be genuinely removed from the accessibility tree\n * when closed — `height: 0` with `overflow: hidden` leaves its content focusable and\n * announceable, so a keyboard user tabs into a collapsed section.\n *\n * Built on Radix Collapsible from 0.7.0: your `onClick` on the trigger now runs alongside the\n * toggle instead of replacing it, every part forwards its ref, and the open content exposes\n * `--radix-collapsible-content-height` for a height animation. Each part carries\n * `data-state=\"open\" | \"closed\"`.\n */\nexport const Collapsible = forwardRef<HTMLDivElement, CollapsibleProps>(function Collapsible(\n { children, open: openProp, defaultOpen = false, onOpenChange, disabled, ...rest },\n ref,\n) {\n const triggerId = useId();\n const [open, setOpen] = useControllableState({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n return (\n <CollapsiblePrimitive.Root\n ref={ref}\n open={open}\n onOpenChange={setOpen}\n disabled={disabled}\n data-slot=\"collapsible\"\n {...rest}\n >\n <CollapsibleState.Provider value={{ triggerId, open }}>{children}</CollapsibleState.Provider>\n </CollapsiblePrimitive.Root>\n );\n});\n\nexport interface CollapsibleTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n children?: ReactNode;\n asChild?: boolean;\n}\n\nexport const CollapsibleTrigger = forwardRef<HTMLButtonElement, CollapsibleTriggerProps>(\n function CollapsibleTrigger(props, ref) {\n const state = useContext(CollapsibleState);\n return <CollapsiblePrimitive.Trigger ref={ref} id={state?.triggerId} {...props} />;\n },\n);\n\nexport interface CollapsibleContentProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /**\n * Keep the content mounted while closed, hidden with `hidden`. Default `false`.\n *\n * `hidden` — not `height: 0` — is what keeps hidden content out of the tab sequence and\n * the accessibility tree, so this stays safe. Use it to preserve form state or scroll\n * position across collapses.\n */\n keepMounted?: boolean;\n}\n\nexport const CollapsibleContent = forwardRef<HTMLDivElement, CollapsibleContentProps>(\n function CollapsibleContent({ keepMounted = false, ...rest }, ref) {\n const state = useContext(CollapsibleState);\n return (\n <CollapsiblePrimitive.Content\n ref={ref}\n forceMount={keepMounted || undefined}\n role=\"region\"\n aria-labelledby={state?.triggerId}\n {...(keepMounted ? { hidden: !state?.open } : {})}\n {...rest}\n />\n );\n },\n);\n","import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react';\nimport { cn } from '../../lib/cn';\nimport { Slot } from '../../lib/slot';\n\n/**\n * Layout primitives, new in 0.7.0: `Box`, `Flex`, `Grid`, `Container` and `Section`, the Radix\n * Themes layout set.\n *\n * Each is a thin, typed wrapper over the Tailwind utilities a page would otherwise hand-write.\n * Spacing props take the Figma spacing tokens by name (`gap=\"400\"` is 16px), so layout uses the\n * same scale as the components inside it and an arbitrary `gap-[13px]` has nowhere to go. All of\n * them take `asChild` to lay out an element of your own (a `<ul>`, a `<form>`, a `<main>`) and\n * merge `className` with `cn`, so a class you pass wins.\n *\n * The class maps below are written out literally on purpose: Tailwind only generates classes\n * that appear verbatim in source, so building them with template strings would emit no CSS.\n */\n\n/** A Figma spacing step, by name: `100` is 4px, `400` is 16px, `1600` is 64px. */\nexport type SpaceToken = '0' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '1000' | '1200' | '1600';\n\nconst GAP: Record<SpaceToken, string> = {\n '0': 'gap-0',\n '100': 'gap-100',\n '200': 'gap-200',\n '300': 'gap-300',\n '400': 'gap-400',\n '500': 'gap-500',\n '600': 'gap-600',\n '700': 'gap-700',\n '800': 'gap-800',\n '1000': 'gap-1000',\n '1200': 'gap-1200',\n '1600': 'gap-1600',\n};\nconst GAP_X: Record<SpaceToken, string> = {\n '0': 'gap-x-0',\n '100': 'gap-x-100',\n '200': 'gap-x-200',\n '300': 'gap-x-300',\n '400': 'gap-x-400',\n '500': 'gap-x-500',\n '600': 'gap-x-600',\n '700': 'gap-x-700',\n '800': 'gap-x-800',\n '1000': 'gap-x-1000',\n '1200': 'gap-x-1200',\n '1600': 'gap-x-1600',\n};\nconst GAP_Y: Record<SpaceToken, string> = {\n '0': 'gap-y-0',\n '100': 'gap-y-100',\n '200': 'gap-y-200',\n '300': 'gap-y-300',\n '400': 'gap-y-400',\n '500': 'gap-y-500',\n '600': 'gap-y-600',\n '700': 'gap-y-700',\n '800': 'gap-y-800',\n '1000': 'gap-y-1000',\n '1200': 'gap-y-1200',\n '1600': 'gap-y-1600',\n};\nconst PAD: Record<SpaceToken, string> = {\n '0': 'p-0',\n '100': 'p-100',\n '200': 'p-200',\n '300': 'p-300',\n '400': 'p-400',\n '500': 'p-500',\n '600': 'p-600',\n '700': 'p-700',\n '800': 'p-800',\n '1000': 'p-1000',\n '1200': 'p-1200',\n '1600': 'p-1600',\n};\nconst PAD_X: Record<SpaceToken, string> = {\n '0': 'px-0',\n '100': 'px-100',\n '200': 'px-200',\n '300': 'px-300',\n '400': 'px-400',\n '500': 'px-500',\n '600': 'px-600',\n '700': 'px-700',\n '800': 'px-800',\n '1000': 'px-1000',\n '1200': 'px-1200',\n '1600': 'px-1600',\n};\nconst PAD_Y: Record<SpaceToken, string> = {\n '0': 'py-0',\n '100': 'py-100',\n '200': 'py-200',\n '300': 'py-300',\n '400': 'py-400',\n '500': 'py-500',\n '600': 'py-600',\n '700': 'py-700',\n '800': 'py-800',\n '1000': 'py-1000',\n '1200': 'py-1200',\n '1600': 'py-1600',\n};\n\ninterface LayoutBaseProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n /** Lay out your own single child element instead of a `<div>`. */\n asChild?: boolean;\n /** Padding on every side, as a spacing token. */\n p?: SpaceToken;\n /** Horizontal padding, as a spacing token. */\n px?: SpaceToken;\n /** Vertical padding, as a spacing token. */\n py?: SpaceToken;\n}\n\nfunction padding({ p, px, py }: Pick<LayoutBaseProps, 'p' | 'px' | 'py'>) {\n return [p && PAD[p], px && PAD_X[px], py && PAD_Y[py]];\n}\n\nfunction rootElement(asChild: boolean | undefined, fallback: 'div' | 'section') {\n return (asChild ? Slot : fallback) as 'div';\n}\n\n// ── Box ────────────────────────────────────────────────────────────────────────\n\nexport type BoxProps = LayoutBaseProps;\n\n/** A plain block with token padding. The base the others build on. */\nexport const Box = forwardRef<HTMLDivElement, BoxProps>(function Box(\n { asChild, p, px, py, className, ...rest },\n ref,\n) {\n const Root = rootElement(asChild, 'div');\n return <Root ref={ref} className={cn(padding({ p, px, py }), className)} {...rest} />;\n});\n\n// ── Flex ───────────────────────────────────────────────────────────────────────\n\nexport type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';\nexport type FlexAlign = 'start' | 'center' | 'end' | 'baseline' | 'stretch';\nexport type FlexJustify = 'start' | 'center' | 'end' | 'between' | 'around';\n\nconst DIRECTION: Record<FlexDirection, string> = {\n row: 'flex-row',\n column: 'flex-col',\n 'row-reverse': 'flex-row-reverse',\n 'column-reverse': 'flex-col-reverse',\n};\n\nconst ALIGN: Record<FlexAlign, string> = {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n baseline: 'items-baseline',\n stretch: 'items-stretch',\n};\n\nconst JUSTIFY: Record<FlexJustify, string> = {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n around: 'justify-around',\n};\n\nexport interface FlexProps extends LayoutBaseProps {\n /** Default `row`. */\n direction?: FlexDirection;\n align?: FlexAlign;\n justify?: FlexJustify;\n gap?: SpaceToken;\n /** Let items wrap onto new lines. */\n wrap?: boolean;\n /** `inline-flex` instead of `flex`. */\n inline?: boolean;\n}\n\n/** A flex row or column with token gaps. */\nexport const Flex = forwardRef<HTMLDivElement, FlexProps>(function Flex(\n { asChild, direction = 'row', align, justify, gap, wrap, inline, p, px, py, className, ...rest },\n ref,\n) {\n const Root = rootElement(asChild, 'div');\n return (\n <Root\n ref={ref}\n className={cn(\n inline ? 'inline-flex' : 'flex',\n DIRECTION[direction],\n align && ALIGN[align],\n justify && JUSTIFY[justify],\n gap && GAP[gap],\n wrap && 'flex-wrap',\n padding({ p, px, py }),\n className,\n )}\n {...rest}\n />\n );\n});\n\n// ── Grid ───────────────────────────────────────────────────────────────────────\n\nexport type GridColumnCount = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;\nexport type GridBreakpoint = 'base' | 'sm' | 'md' | 'lg' | 'xl';\n\nconst COLUMNS: Record<GridBreakpoint, Record<GridColumnCount, string>> = {\n base: {\n 1: 'grid-cols-1',\n 2: 'grid-cols-2',\n 3: 'grid-cols-3',\n 4: 'grid-cols-4',\n 5: 'grid-cols-5',\n 6: 'grid-cols-6',\n 7: 'grid-cols-7',\n 8: 'grid-cols-8',\n 9: 'grid-cols-9',\n 10: 'grid-cols-10',\n 11: 'grid-cols-11',\n 12: 'grid-cols-12',\n },\n sm: {\n 1: 'sm:grid-cols-1',\n 2: 'sm:grid-cols-2',\n 3: 'sm:grid-cols-3',\n 4: 'sm:grid-cols-4',\n 5: 'sm:grid-cols-5',\n 6: 'sm:grid-cols-6',\n 7: 'sm:grid-cols-7',\n 8: 'sm:grid-cols-8',\n 9: 'sm:grid-cols-9',\n 10: 'sm:grid-cols-10',\n 11: 'sm:grid-cols-11',\n 12: 'sm:grid-cols-12',\n },\n md: {\n 1: 'md:grid-cols-1',\n 2: 'md:grid-cols-2',\n 3: 'md:grid-cols-3',\n 4: 'md:grid-cols-4',\n 5: 'md:grid-cols-5',\n 6: 'md:grid-cols-6',\n 7: 'md:grid-cols-7',\n 8: 'md:grid-cols-8',\n 9: 'md:grid-cols-9',\n 10: 'md:grid-cols-10',\n 11: 'md:grid-cols-11',\n 12: 'md:grid-cols-12',\n },\n lg: {\n 1: 'lg:grid-cols-1',\n 2: 'lg:grid-cols-2',\n 3: 'lg:grid-cols-3',\n 4: 'lg:grid-cols-4',\n 5: 'lg:grid-cols-5',\n 6: 'lg:grid-cols-6',\n 7: 'lg:grid-cols-7',\n 8: 'lg:grid-cols-8',\n 9: 'lg:grid-cols-9',\n 10: 'lg:grid-cols-10',\n 11: 'lg:grid-cols-11',\n 12: 'lg:grid-cols-12',\n },\n xl: {\n 1: 'xl:grid-cols-1',\n 2: 'xl:grid-cols-2',\n 3: 'xl:grid-cols-3',\n 4: 'xl:grid-cols-4',\n 5: 'xl:grid-cols-5',\n 6: 'xl:grid-cols-6',\n 7: 'xl:grid-cols-7',\n 8: 'xl:grid-cols-8',\n 9: 'xl:grid-cols-9',\n 10: 'xl:grid-cols-10',\n 11: 'xl:grid-cols-11',\n 12: 'xl:grid-cols-12',\n },\n};\n\nexport interface GridProps extends LayoutBaseProps {\n /**\n * Column count, fixed or per breakpoint: `columns={3}` or\n * `columns={{ base: 1, md: 2, lg: 4 }}`.\n */\n columns?: GridColumnCount | Partial<Record<GridBreakpoint, GridColumnCount>>;\n /**\n * As many columns as fit, each at least this wide, e.g. `\"16rem\"`. Responds to the grid's own\n * width, not the viewport's, so it suits form fields and card lists inside panels of any size\n * (what SCIC's `FormGrid` did). Ignored when `columns` is set.\n */\n minColumnWidth?: string;\n gap?: SpaceToken;\n gapX?: SpaceToken;\n gapY?: SpaceToken;\n align?: FlexAlign;\n}\n\n/** A CSS grid with token gaps: fixed, responsive or auto-fitting columns. */\nexport const Grid = forwardRef<HTMLDivElement, GridProps>(function Grid(\n { asChild, columns, minColumnWidth, gap, gapX, gapY, align, p, px, py, className, style, ...rest },\n ref,\n) {\n const Root = rootElement(asChild, 'div');\n const columnClasses =\n columns === undefined\n ? []\n : typeof columns === 'number'\n ? [COLUMNS.base[columns]]\n : (Object.entries(columns) as [GridBreakpoint, GridColumnCount][]).map(\n ([breakpoint, count]) => COLUMNS[breakpoint][count],\n );\n // `min(100%, …)` keeps a single column from overflowing a container narrower than the minimum.\n const autoFit: CSSProperties | undefined =\n columns === undefined && minColumnWidth\n ? { gridTemplateColumns: `repeat(auto-fit, minmax(min(100%, ${minColumnWidth}), 1fr))` }\n : undefined;\n\n return (\n <Root\n ref={ref}\n className={cn(\n 'grid',\n columnClasses,\n gap && GAP[gap],\n gapX && GAP_X[gapX],\n gapY && GAP_Y[gapY],\n align && ALIGN[align],\n padding({ p, px, py }),\n className,\n )}\n style={autoFit ? { ...autoFit, ...style } : style}\n {...rest}\n />\n );\n});\n\n// ── Container ──────────────────────────────────────────────────────────────────\n\nexport type ContainerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\nconst CONTAINER: Record<ContainerSize, string> = {\n sm: 'max-w-[640px]',\n md: 'max-w-[880px]',\n lg: 'max-w-[1136px]',\n xl: 'max-w-[1440px]',\n full: 'max-w-none',\n};\n\nexport interface ContainerProps extends LayoutBaseProps {\n /** Maximum content width. Default `lg` (1136px). */\n size?: ContainerSize;\n}\n\n/** Centres content at a maximum width, with a 16px side gutter by default. */\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container(\n { asChild, size = 'lg', p, px = '400', py, className, ...rest },\n ref,\n) {\n const Root = rootElement(asChild, 'div');\n return (\n <Root\n ref={ref}\n className={cn('mx-auto w-full', CONTAINER[size], padding({ p, px, py }), className)}\n {...rest}\n />\n );\n});\n\n// ── Section ────────────────────────────────────────────────────────────────────\n\nexport type SectionSize = 'sm' | 'md' | 'lg';\n\nconst SECTION: Record<SectionSize, string> = {\n sm: 'py-600',\n md: 'py-1000',\n lg: 'py-1600',\n};\n\nexport interface SectionProps extends LayoutBaseProps {\n /** Vertical rhythm: 24, 40 or 64px above and below. Default `md`. */\n size?: SectionSize;\n}\n\n/**\n * A page band with vertical rhythm, rendered as a `<section>`. Give it a heading (or an\n * `aria-label`) when it should be a landmark; an unnamed `<section>` is announced as nothing at\n * all, which is the right default for a purely visual band.\n */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n { asChild, size = 'md', p, px, py, className, ...rest },\n ref,\n) {\n const Root = rootElement(asChild, 'section');\n return (\n <Root\n ref={ref as never}\n className={cn(SECTION[size], padding({ p, px, py }), className)}\n {...rest}\n />\n );\n});\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport interface AspectRatioProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Width ÷ height. `16 / 9` for video, `1` for a square, `4 / 3` for a photo. Default `1`. */\n ratio?: number;\n}\n\n/**\n * Holds a fixed width-to-height ratio for its content.\n *\n * Uses the CSS `aspect-ratio` property rather than the old padding-top percentage hack, so\n * the child is a normal in-flow element instead of being absolutely positioned inside a\n * zero-height box. The ratio is an inline style because it is a per-instance numeric value —\n * a Tailwind class cannot express `16 / 9` without an arbitrary-value escape at every call\n * site.\n */\nexport const AspectRatio = forwardRef<HTMLDivElement, AspectRatioProps>(function AspectRatio(\n { children, ratio = 1, className, style, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n data-slot=\"aspect-ratio\"\n style={{ aspectRatio: ratio, ...style }}\n className={clsx('w-full overflow-hidden [&>*]:size-full [&>img]:object-cover', className)}\n {...rest}\n >\n {children}\n </div>\n );\n});\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { composeEventHandlers } from '../../lib/compose-event-handlers';\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';\nimport { IconButton } from '../forms/icon-button';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\ninterface CarouselContextValue {\n index: number;\n setIndex: (index: number) => void;\n count: number;\n registerSlide: () => number;\n resetSlides: () => void;\n baseId: string;\n loop: boolean;\n paused: boolean;\n setPaused: (paused: boolean) => void;\n hasAutoplay: boolean;\n}\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nfunction useCarousel(part: string): CarouselContextValue {\n const value = useContext(CarouselContext);\n if (!value) throw new Error(`<${part}> must be used inside <Carousel>`);\n return value;\n}\n\nexport interface CarouselProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** Names the carousel region. Required — a nameless region is not navigable. */\n label: string;\n index?: number;\n defaultIndex?: number;\n onIndexChange?: (index: number) => void;\n /** Number of slides. Needed up front for the controls; `CarouselSlide` count is checked against it. */\n count: number;\n loop?: boolean;\n /** Advance every N ms. Omit for a manual carousel. */\n autoplayInterval?: number;\n}\n\n/**\n * A slide carousel.\n *\n * Carousels are one of the most reliably inaccessible patterns on the web, so the parts that\n * look like polish here are the requirements:\n *\n * - **`aria-roledescription=\"carousel\"`** on a named region, so it is announced as a carousel\n * rather than as an anonymous group of divs.\n * - **Slides are `role=\"group\"` with `aria-roledescription=\"slide\"` and an\n * \"N of M\" label** — position is otherwise invisible to anyone not seeing the dots.\n * - **Off-screen slides are `hidden`**, not merely translated out of view. A slide moved with\n * `transform` keeps its links in the tab order, so keyboard users tab into content they\n * cannot see. This is the single most common carousel bug.\n * - **Autoplay stops on hover, on focus, and permanently once the user takes control**, and\n * there is a visible pause button whenever autoplay is on — required by WCAG 2.2.2 for any\n * motion lasting more than five seconds.\n * - **`prefers-reduced-motion` disables autoplay entirely**, rather than just shortening the\n * transition.\n */\nexport function Carousel({\n children,\n label,\n index: indexProp,\n defaultIndex = 0,\n onIndexChange,\n count,\n loop = false,\n autoplayInterval,\n className,\n ...rest\n}: CarouselProps) {\n const [index, setIndex] = useControllableState({\n value: indexProp,\n defaultValue: defaultIndex,\n onChange: onIndexChange,\n });\n\n const baseId = useId();\n const cursor = useRef(0);\n const [paused, setPaused] = useState(false);\n const [userTookControl, setUserTookControl] = useState(false);\n\n const hasAutoplay = autoplayInterval !== undefined && autoplayInterval > 0;\n\n const context = useMemo<CarouselContextValue>(\n () => ({\n index,\n setIndex: (next) => {\n // Any deliberate move stops autoplay for good. Resuming after a user has navigated\n // yanks the content out from under them.\n setUserTookControl(true);\n setIndex(next);\n },\n count,\n registerSlide: () => cursor.current++,\n resetSlides: () => {\n cursor.current = 0;\n },\n baseId,\n loop,\n paused,\n setPaused,\n hasAutoplay,\n }),\n [index, setIndex, count, baseId, loop, paused, hasAutoplay],\n );\n\n context.resetSlides();\n\n useEffect(() => {\n if (!hasAutoplay || paused || userTookControl) return;\n // Autoplay is motion the user did not ask for, so it does not start at all when they\n // have asked for less of it.\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\n\n const timer = setInterval(() => {\n setIndex(index === count - 1 ? (loop ? 0 : index) : index + 1);\n }, autoplayInterval);\n return () => clearInterval(timer);\n }, [hasAutoplay, paused, userTookControl, autoplayInterval, index, count, loop, setIndex]);\n\n return (\n <CarouselContext.Provider value={context}>\n {/* The APG carousel pattern puts Left/Right on the region itself, so slides can be\n paged from anywhere inside without first tabbing to the controls. The region is not\n focusable and does not need to be — the keys arrive by bubbling from whatever inside\n it has focus. */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <div\n // `region` + roledescription is what makes this announce as a carousel.\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label={label}\n data-slot=\"carousel\"\n className={clsx('relative', className)}\n {...rest}\n onPointerEnter={composeEventHandlers(rest.onPointerEnter, () => hasAutoplay && setPaused(true))}\n onPointerLeave={composeEventHandlers(rest.onPointerLeave, () => hasAutoplay && setPaused(false))}\n onFocus={composeEventHandlers(rest.onFocus, () => hasAutoplay && setPaused(true))}\n onBlur={composeEventHandlers(rest.onBlur, (event) => {\n if (hasAutoplay && !event.currentTarget.contains(event.relatedTarget as Node)) {\n setPaused(false);\n }\n })}\n onKeyDown={composeEventHandlers(rest.onKeyDown, (event) => {\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n context.setIndex(index === 0 ? (loop ? count - 1 : 0) : index - 1);\n }\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n context.setIndex(index === count - 1 ? (loop ? 0 : index) : index + 1);\n }\n })}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\nexport interface CarouselViewportProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function CarouselViewport({ children, className, ...rest }: CarouselViewportProps) {\n const carousel = useCarousel('CarouselViewport');\n return (\n <div\n id={`${carousel.baseId}-viewport`}\n data-slot=\"carousel-viewport\"\n className={clsx('overflow-hidden', className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport interface CarouselSlideProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function CarouselSlide({ children, className, ...rest }: CarouselSlideProps) {\n const carousel = useCarousel('CarouselSlide');\n const slideIndex = carousel.registerSlide();\n const active = slideIndex === carousel.index;\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n // Position stated explicitly — without it, only the dots convey where you are.\n aria-label={`${slideIndex + 1} of ${carousel.count}`}\n // `hidden`, not a transform. An off-screen slide that is merely translated keeps its\n // links focusable, so Tab walks into invisible content.\n hidden={!active}\n data-slot=\"carousel-slide\"\n className={className}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport interface CarouselControlsProps extends HTMLAttributes<HTMLDivElement> {\n /** Show the dot indicators. Default `true`. */\n showDots?: boolean;\n}\n\nexport function CarouselControls({ showDots = true, className, ...rest }: CarouselControlsProps) {\n const carousel = useCarousel('CarouselControls');\n const { index, count, loop } = carousel;\n\n const go = useCallback(\n (next: number) => {\n const wrapped = ((next % count) + count) % count;\n carousel.setIndex(loop ? wrapped : Math.min(Math.max(next, 0), count - 1));\n },\n [carousel, count, loop],\n );\n\n return (\n <div\n className={clsx('mt-3 flex items-center justify-between gap-3', className)}\n {...rest}\n >\n <IconButton\n variant=\"neutral\"\n size=\"sm\"\n aria-label=\"Previous slide\"\n aria-controls={`${carousel.baseId}-viewport`}\n disabled={!loop && index === 0}\n onClick={() => go(index - 1)}\n >\n <ChevronLeftIcon aria-hidden size={16} />\n </IconButton>\n\n {showDots && (\n <div role=\"group\" aria-label={`Slide ${index + 1} of ${count}`} className=\"flex items-center gap-2\">\n {Array.from({ length: count }, (_, i) => (\n <button\n key={i}\n type=\"button\"\n aria-label={`Go to slide ${i + 1}`}\n aria-current={i === index ? 'true' : undefined}\n onClick={() => go(i)}\n className={clsx(\n 'size-2 rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 focus-visible:ring-offset-default',\n i === index ? 'bg-brand' : 'bg-default-tertiary hover:bg-neutral-secondary',\n )}\n />\n ))}\n </div>\n )}\n\n <div className=\"flex items-center gap-1.5\">\n {/* Required by WCAG 2.2.2 whenever autoplay is on: any motion lasting more than five\n seconds needs a visible, keyboard-reachable way to stop it. */}\n {carousel.hasAutoplay && (\n <IconButton\n variant=\"neutral\"\n size=\"sm\"\n aria-label={carousel.paused ? 'Start automatic slide show' : 'Stop automatic slide show'}\n onClick={() => carousel.setPaused(!carousel.paused)}\n >\n <span aria-hidden className=\"text-body-tiny font-semibold\">\n {carousel.paused ? '▶' : '❚❚'}\n </span>\n </IconButton>\n )}\n <IconButton\n variant=\"neutral\"\n size=\"sm\"\n aria-label=\"Next slide\"\n aria-controls={`${carousel.baseId}-viewport`}\n disabled={!loop && index === count - 1}\n onClick={() => go(index + 1)}\n >\n <ChevronRightIcon aria-hidden size={16} />\n </IconButton>\n </div>\n </div>\n );\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { ScrollArea } from './scroll-area';\nimport clsx from 'clsx';\nimport { composeEventHandlers } from '../../lib/compose-event-handlers';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type ResizableDirection = 'horizontal' | 'vertical';\n\ninterface ResizableContextValue {\n direction: ResizableDirection;\n /** First pane's size, as a percentage of the container. */\n size: number;\n setSize: (size: number) => void;\n min: number;\n max: number;\n containerRef: React.RefObject<HTMLDivElement | null>;\n baseId: string;\n dragging: boolean;\n setDragging: (dragging: boolean) => void;\n}\n\nconst ResizableContext = createContext<ResizableContextValue | null>(null);\n\nfunction useResizable(part: string): ResizableContextValue {\n const value = useContext(ResizableContext);\n if (!value) throw new Error(`<${part}> must be used inside <Resizable>`);\n return value;\n}\n\nexport interface ResizableProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n direction?: ResizableDirection;\n /** First pane's size as a percentage. Controlled. */\n size?: number;\n defaultSize?: number;\n onSizeChange?: (size: number) => void;\n /** Percentage bounds. Defaults `10` and `90`. */\n min?: number;\n max?: number;\n}\n\n/**\n * Two resizable panes with a draggable divider.\n *\n * This is the APG **window splitter** pattern, and the handle is the whole component as far\n * as accessibility goes. A `<div>` with pointer listeners — the usual implementation — is\n * completely unusable without a mouse. `ResizableHandle` is therefore a real focusable\n * control with:\n *\n * - `role=\"separator\"` plus `aria-valuenow`/`valuemin`/`valuemax`, so the current split is\n * announced as a percentage rather than being invisible;\n * - `tabIndex={0}` and arrow keys to move it in 1% steps, Shift+arrow in 10%, Home/End to\n * the bounds, and Enter to collapse and restore;\n * - `aria-controls` pointing at the pane it resizes.\n *\n * Sizes are percentages, not pixels, so the split survives a container resize — a pixel\n * split silently becomes wrong the moment the window changes.\n */\nexport function Resizable({\n children,\n direction = 'horizontal',\n size: sizeProp,\n defaultSize = 50,\n onSizeChange,\n min = 10,\n max = 90,\n className,\n ...rest\n}: ResizableProps) {\n const [size, setSize] = useControllableState({\n value: sizeProp,\n defaultValue: defaultSize,\n onChange: onSizeChange,\n });\n\n const containerRef = useRef<HTMLDivElement>(null);\n const baseId = useId();\n const [dragging, setDragging] = useState(false);\n\n const context = useMemo<ResizableContextValue>(\n () => ({\n direction,\n size,\n setSize: (next) => setSize(Math.min(Math.max(next, min), max)),\n min,\n max,\n containerRef,\n baseId,\n dragging,\n setDragging,\n }),\n [direction, size, setSize, min, max, baseId, dragging],\n );\n\n return (\n <ResizableContext.Provider value={context}>\n <div\n ref={containerRef}\n data-slot=\"resizable\"\n className={clsx(\n 'flex w-full',\n direction === 'horizontal' ? 'flex-row' : 'flex-col',\n // While dragging, suppress selection and pointer events inside the panes so the\n // gesture cannot start selecting text or hovering things it passes over.\n dragging && 'select-none [&_*]:pointer-events-none',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n </ResizableContext.Provider>\n );\n}\n\nexport interface ResizablePanelProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** `first` is the pane the handle sizes; `second` fills the remainder. */\n which: 'first' | 'second';\n}\n\nexport function ResizablePanel({ children, which, className, ...rest }: ResizablePanelProps) {\n const ctx = useResizable('ResizablePanel');\n const axis = ctx.direction === 'horizontal' ? 'width' : 'height';\n\n return (\n // A panel holds arbitrary content, which may be entirely static — so it needs the tab\n // stop `ScrollArea` adds while overflowing, not just the scrollbar styling.\n <ScrollArea\n axis=\"both\"\n id={which === 'first' ? `${ctx.baseId}-first` : `${ctx.baseId}-second`}\n data-slot=\"resizable-panel\"\n style={which === 'first' ? { [axis]: `${ctx.size}%` } : { flex: '1 1 0%' }}\n className={clsx('min-h-0 min-w-0', className)}\n {...rest}\n >\n {children}\n </ScrollArea>\n );\n}\n\nexport interface ResizableHandleProps extends HTMLAttributes<HTMLDivElement> {\n /** Names the splitter. Default `Resize panels`. */\n label?: string;\n /** Show the grip dots. Default `true`. */\n withGrip?: boolean;\n}\n\nexport function ResizableHandle({\n label = 'Resize panels',\n withGrip = true,\n className,\n ...rest\n}: ResizableHandleProps) {\n const ctx = useResizable('ResizableHandle');\n const horizontal = ctx.direction === 'horizontal';\n const collapsedFrom = useRef<number | null>(null);\n\n const fromPointer = useCallback(\n (clientX: number, clientY: number) => {\n const container = ctx.containerRef.current;\n if (!container) return;\n const rect = container.getBoundingClientRect();\n const ratio = horizontal\n ? (clientX - rect.left) / rect.width\n : (clientY - rect.top) / rect.height;\n ctx.setSize(ratio * 100);\n },\n [ctx, horizontal],\n );\n\n useEffect(() => {\n if (!ctx.dragging) return;\n\n const onMove = (event: PointerEvent) => fromPointer(event.clientX, event.clientY);\n const onUp = () => ctx.setDragging(false);\n\n // Listeners on the window, not the handle: the pointer routinely leaves the 8px handle\n // mid-drag, and a handle-scoped listener would drop the gesture.\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n window.addEventListener('pointercancel', onUp);\n return () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n window.removeEventListener('pointercancel', onUp);\n };\n }, [ctx, fromPointer]);\n\n return (\n // A *focusable* separator is the APG window-splitter pattern, and the whole point of this\n // component: without the tab stop and the arrow keys below, a split view can only be\n // resized with a mouse. ARIA explicitly allows a focusable separator, which is what\n // carries `aria-valuenow`; jsx-a11y models `separator` as always non-interactive.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex, jsx-a11y/no-noninteractive-element-interactions\n <div\n role=\"separator\"\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n aria-label={label}\n aria-orientation={horizontal ? 'vertical' : 'horizontal'}\n aria-valuenow={Math.round(ctx.size)}\n aria-valuemin={ctx.min}\n aria-valuemax={ctx.max}\n aria-controls={`${ctx.baseId}-first`}\n data-slot=\"resizable-handle\"\n {...rest}\n onPointerDown={composeEventHandlers(rest.onPointerDown, (event) => {\n event.preventDefault();\n ctx.setDragging(true);\n })}\n onKeyDown={composeEventHandlers(rest.onKeyDown, (event) => {\n const step = event.shiftKey ? 10 : 1;\n const decrease = horizontal ? 'ArrowLeft' : 'ArrowUp';\n const increase = horizontal ? 'ArrowRight' : 'ArrowDown';\n\n if (event.key === decrease) {\n event.preventDefault();\n ctx.setSize(ctx.size - step);\n } else if (event.key === increase) {\n event.preventDefault();\n ctx.setSize(ctx.size + step);\n } else if (event.key === 'Home') {\n event.preventDefault();\n ctx.setSize(ctx.min);\n } else if (event.key === 'End') {\n event.preventDefault();\n ctx.setSize(ctx.max);\n } else if (event.key === 'Enter') {\n // Collapse/restore, so the splitter is useful without dragging at all.\n event.preventDefault();\n if (collapsedFrom.current === null) {\n collapsedFrom.current = ctx.size;\n ctx.setSize(ctx.min);\n } else {\n ctx.setSize(collapsedFrom.current);\n collapsedFrom.current = null;\n }\n }\n })}\n className={clsx(\n 'group relative flex shrink-0 items-center justify-center bg-divider transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand',\n 'hover:bg-brand-tertiary',\n horizontal ? 'w-px cursor-col-resize' : 'h-px cursor-row-resize',\n className,\n )}\n \n >\n {/* An invisible padded hit area, so the 1px rule is grabbable without being 8px of\n visible chrome. */}\n <span\n aria-hidden\n className={clsx('absolute', horizontal ? 'inset-y-0 -inset-x-1.5' : '-inset-y-1.5 inset-x-0')}\n />\n {withGrip && (\n <span\n aria-hidden\n className={clsx(\n 'relative z-raised flex items-center justify-center rounded-full border border-default bg-default',\n 'opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100',\n horizontal ? 'h-6 w-2.5' : 'h-2.5 w-6',\n )}\n >\n <span className={clsx('rounded-full bg-default-tertiary', horizontal ? 'h-2.5 w-px' : 'h-px w-2.5')} />\n </span>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\n/**\n * Two genuinely different heading contexts, which the source markup distinguished:\n *\n * `page` 24px title / 14px subtitle — an in-body page heading (settings, users,\n * alerts), i.e. the old `text-2xl` + `mt-1 text-body-sm` block.\n * `toolbar` 20px title / 13px subtitle — inside a `PageToolbar`, where the bar is\n * only 72px tall. Flattening these into one size would have grown ten\n * toolbar titles by 4px.\n * `section` 18px — a panel or card heading.\n */\nexport type PageHeadingSize = 'page' | 'toolbar' | 'section';\n\nconst TITLE: Record<PageHeadingSize, string> = {\n // `text-2xl` was stock Tailwind rather than the design tokens. Same 24px, now on-token.\n page: 'text-heading font-semibold text-default',\n toolbar: 'text-heading-sm font-semibold leading-snug text-default',\n // Was `text-lg` — stock Tailwind's 18px, off the type scale. Snapped DOWN to 16 rather\n // than up to 20, because 20 is already `toolbar`: rounding up would have made two of the\n // three sizes identical and collapsed the ramp to page 24 / toolbar 20 / section 20.\n section: 'text-subheading-sm font-semibold text-default',\n};\n\nconst SUBTITLE: Record<PageHeadingSize, string> = {\n page: 'mt-1 text-body-sm text-default-secondary',\n toolbar: 'text-body-xs text-default-secondary',\n section: 'mt-1 text-body-sm text-default-secondary',\n};\n\nexport interface PageHeadingProps {\n title: ReactNode;\n subtitle?: ReactNode;\n size?: PageHeadingSize;\n /** Heading level. Defaults to `h1` for page/toolbar and `h2` for section. */\n as?: 'h1' | 'h2' | 'h3';\n /** Right-aligned action cluster. When set, the heading becomes a flex row. */\n actions?: ReactNode;\n /** Clamp a long title to one line — needed when the title is user data, e.g. an article headline. */\n truncateTitle?: boolean;\n className?: string;\n}\n\n/**\n * Page or section title with an optional subtitle underneath.\n *\n * Replaces nine copies of the `<h1>` + `<p className=\"mt-1 …\">` block, plus the\n * heading halves of `SettingsTabs` and `my-account/tabs`.\n *\n * Emitting a real heading element matters: `reviewer-detail`,\n * `settings-audit-log`'s table area and `widget-gallery` render their titles as\n * `<p>`/`<div>` today, so `getByRole('heading')` finds nothing there — an\n * accessibility gap the e2e specs currently work around.\n */\nexport function PageHeading({\n title,\n subtitle,\n size = 'page',\n as,\n actions,\n truncateTitle,\n className,\n}: PageHeadingProps) {\n const Tag = as ?? (size === 'section' ? 'h2' : 'h1');\n\n const heading = (\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <Tag className={clsx(TITLE[size], truncateTitle && 'truncate')}>{title}</Tag>\n {subtitle && <p className={SUBTITLE[size]}>{subtitle}</p>}\n </div>\n );\n\n if (!actions) return className ? <div className={className}>{heading}</div> : heading;\n\n return (\n <div className={clsx('flex items-start justify-between gap-4', className)}>\n {heading}\n <div className=\"flex shrink-0 items-center gap-2\">{actions}</div>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { ArrowLeftIcon } from 'lucide-react';\nimport { IconButton } from '../forms/icon-button';\n\nexport type PageToolbarSize = 'sm' | 'md';\n\nexport interface PageToolbarProps {\n children: ReactNode;\n /**\n * Renders an icon-only back control at the far left, ahead of the heading: the Page Header's\n * `backButton` in Figma (node 3473:16837). New in 0.7.0, from SCIC. Omit for no back control.\n */\n onBack?: () => void;\n /** Accessible name for the back control. Default \"Go back\". */\n backLabel?: string;\n /** Allow the row to wrap when the action cluster is wide (entity-detail has seven buttons). */\n wrap?: boolean;\n /**\n * The bar's **own** height and padding. `sm` suits a secondary bar under the main toolbar.\n *\n * Not to be confused with `FilterBar.size`, which sets the density of the controls\n * *inside* the row. Same literals, different subject: a bar sizes itself, a row of\n * controls sizes its children. `PageToolbar` passes nothing down.\n */\n size?: PageToolbarSize;\n className?: string;\n}\n\nconst SIZE: Record<PageToolbarSize, string> = {\n sm: 'min-h-[56px] px-4 py-3 md:px-7',\n md: 'min-h-[72px] px-4 py-4 md:px-7',\n};\n\n/**\n * The sticky top bar on a full-bleed detail or list screen: title block on the\n * left, actions on the right.\n *\n * Replaces ten copies of this class string. Three of those copies used the\n * responsive `px-4 py-4 md:px-7` and seven used a fixed `px-7 py-4`; the responsive\n * variant is adopted here, which is a deliberate improvement below `md` where the\n * fixed 28px padding was cramped.\n */\nexport function PageToolbar({\n children,\n onBack,\n backLabel = 'Go back',\n wrap,\n size = 'md',\n className,\n}: PageToolbarProps) {\n return (\n <div\n className={clsx(\n 'flex shrink-0 items-center gap-4 border-b border-default bg-default',\n SIZE[size],\n !onBack && 'justify-between',\n !onBack && wrap && 'flex-wrap gap-2',\n className,\n )}\n >\n {onBack && (\n <IconButton variant=\"neutral\" size=\"md\" aria-label={backLabel} onClick={onBack}>\n <ArrowLeftIcon aria-hidden />\n </IconButton>\n )}\n {/* With a back control the heading and actions keep their split inside a flex-1\n wrapper, so the back control stays pinned left rather than spaced out with them. */}\n {onBack ? (\n <div className={clsx('flex min-w-0 flex-1 items-center justify-between gap-4', wrap && 'flex-wrap gap-2')}>\n {children}\n </div>\n ) : (\n children\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { ControlSizeProvider } from '../forms/control-size';\n\nexport type FilterBarSize = 'sm' | 'md';\n\nexport interface FilterBarProps {\n children: ReactNode;\n /** Right-aligned slot for a result count or a secondary action. */\n trailing?: ReactNode;\n /**\n * Row density. Sets the gap between controls **and** the default `size` of the controls\n * inside — an Input, Select, Combobox, DatePicker or Button that is not given its own\n * `size` inherits this one. Pass `size` on a child to opt it out.\n *\n * `sm` is for a filter row inside a card or drawer: 8px gaps and 24px controls.\n */\n size?: FilterBarSize;\n className?: string;\n}\n\nconst GAP: Record<FilterBarSize, string> = {\n sm: 'gap-2',\n md: 'gap-3',\n};\n\n/**\n * Row of search inputs and filter selects above a table.\n *\n * Replaces nine copies of `flex flex-wrap items-center gap-3`.\n *\n * Through 0.4.0 `size` set only the gap, so every caller had to repeat it on each control\n * and the page documenting this component got it wrong: its `size=\"sm\"` example put a 24px\n * Input beside a 36px Select. A container with a size prop should mean it, so the size now\n * reaches the controls through `ControlSizeProvider`.\n */\nexport function FilterBar({ children, trailing, size = 'md', className }: FilterBarProps) {\n return (\n <ControlSizeProvider size={size}>\n <div className={clsx('flex flex-wrap items-center', GAP[size], className)}>\n {children}\n {/* Was a fixed `gap-2`, which disagreed with the row itself at `md`. */}\n {trailing && <div className={clsx('ml-auto flex items-center', GAP[size])}>{trailing}</div>}\n </div>\n </ControlSizeProvider>\n );\n}\n","import {\n createContext,\n forwardRef,\n useContext,\n useId,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { useRovingFocus } from '../../lib/use-roving-focus';\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type TabsVariant = 'underline' | 'pill';\nexport type TabsSize = 'sm' | 'md';\nexport type TabsOrientation = 'horizontal' | 'vertical';\n/**\n * `automatic` selects as focus moves, which is the APG default and right when panels are\n * cheap. `manual` requires Enter/Space — use it when switching tab triggers a fetch, so\n * arrowing across five tabs does not fire five requests.\n */\nexport type TabsActivation = 'automatic' | 'manual';\n\nexport interface TabItem<K extends string = string> {\n key: K;\n label: string;\n /** Renders a count chip after the label. */\n count?: number;\n disabled?: boolean;\n}\n\n/** The `items` form: a tab strip only, with `TabsPanel`s placed wherever the page needs them. */\nexport interface TabsProps<K extends string = string> {\n items: TabItem<K>[];\n /** Controlled selection. Omit and pass `defaultValue` for uncontrolled. */\n value?: K;\n defaultValue?: K;\n onValueChange?: (key: K) => void;\n /**\n * `underline` is the detail-page form (entity detail, reviewer detail, role detail).\n * `pill` is the filter-style form used by the reviewer queue.\n */\n variant?: TabsVariant;\n /** `md` is the page-level strip; `sm` suits a tab strip inside a card or drawer. */\n size?: TabsSize;\n orientation?: TabsOrientation;\n activation?: TabsActivation;\n /**\n * Shared prefix for the tab and panel ids. Pass the same value to each `TabsPanel` and the\n * tabs point `aria-controls` at their panels. Without it, `aria-controls` is left off: a\n * generated prefix would point it at ids no panel has. The composable form needs neither.\n */\n idPrefix?: string;\n /** Names the tab strip. Required by the APG when there is more than one on a page. */\n label?: string;\n className?: string;\n}\n\n/**\n * The composable form, new in 0.7.0 and built on Radix Tabs: `Tabs` wraps a `TabsList` of\n * `TabsTrigger`s and the `TabsContent` panels, and wires every id itself.\n */\nexport interface TabsRootProps {\n children: ReactNode;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n variant?: TabsVariant;\n size?: TabsSize;\n orientation?: TabsOrientation;\n activation?: TabsActivation;\n /** Reading direction, which flips Left/Right in a horizontal strip. */\n dir?: 'ltr' | 'rtl';\n className?: string;\n}\n\n/**\n * Per-variant sizing. The two variants have genuinely different geometry — a pill has\n * a background to pad against, an underline only has a baseline — so this is a nested\n * map rather than one shared scale.\n */\nconst SIZE: Record<TabsVariant, Record<TabsSize, { strip: string; tab: string }>> = {\n underline: {\n sm: { strip: 'gap-4', tab: 'px-0.5 py-1.5 text-body-xs' },\n md: { strip: 'gap-6', tab: 'px-0.5 py-2.5 text-body-sm' },\n },\n pill: {\n sm: { strip: 'gap-1', tab: 'rounded-md px-2.5 py-1.5 text-body-tiny' },\n md: { strip: 'gap-1.5', tab: 'rounded-lg px-3.5 py-2 text-body-xs' },\n },\n};\n\n/**\n * One look for both forms, keyed on `aria-selected`, which our strip and Radix's triggers\n * both set. The selected state lives in the attribute, not in a conditional class.\n *\n * The `underline` selected colour is `background-brand` (#0C2D58), which is what Figma\n * specifies.\n */\nconst TAB_VARIANT: Record<TabsVariant, string> = {\n pill: clsx(\n 'font-medium text-default-secondary hover:bg-default-secondary',\n 'aria-selected:bg-brand aria-selected:text-brand-on-brand aria-selected:hover:bg-brand',\n ),\n underline: clsx(\n 'leading-snug font-normal text-default-secondary hover:text-default',\n 'border-b-2 border-transparent',\n 'aria-selected:border-brand-emphasis aria-selected:font-semibold aria-selected:text-brand-emphasis',\n ),\n};\n\nconst tabClasses = (variant: TabsVariant, size: TabsSize) =>\n clsx(\n 'group flex shrink-0 items-center gap-1.5 whitespace-nowrap transition-colors',\n FOCUS_RING,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n SIZE[variant][size].tab,\n TAB_VARIANT[variant],\n );\n\nconst stripClasses = (variant: TabsVariant, size: TabsSize, orientation: TabsOrientation) =>\n clsx(\n 'flex shrink-0',\n // The strip's own children are the tab stops, so it needs no tab stop of its own.\n orientation === 'vertical' ? 'flex-col' : clsx('overflow-x-auto', SCROLLBAR_CLASSES),\n SIZE[variant][size].strip,\n variant === 'underline' &&\n (orientation === 'vertical' ? 'border-r border-default' : 'border-b border-default'),\n );\n\n/** The count chip. Inverts with its tab in the pill variant, styled from the tab's state. */\nfunction TabCount({ count, variant }: { count: number; variant: TabsVariant }) {\n return (\n <span\n className={clsx(\n 'rounded-md bg-default-secondary px-1.5 py-px text-body-tiny font-medium leading-snug text-default-secondary',\n variant === 'pill' &&\n 'group-aria-selected:bg-brand-hover group-aria-selected:text-brand-on-brand',\n )}\n >\n {count}\n </span>\n );\n}\n\nexport const tabId = (prefix: string, key: string) => `${prefix}-tab-${key}`;\nexport const tabPanelId = (prefix: string, key: string) => `${prefix}-panel-${key}`;\n\n/**\n * Tabs, in two forms.\n *\n * // items: a strip; panels live anywhere, linked by idPrefix.\n * <Tabs items={items} value={tab} onValueChange={setTab} idPrefix=\"entity\" />\n * <TabsPanel tabKey=\"overview\" idPrefix=\"entity\" active={tab === 'overview'}>…</TabsPanel>\n *\n * // composable (0.7.0, Radix): strip and panels in one tree, ids wired for you.\n * <Tabs defaultValue=\"overview\">\n * <TabsList label=\"Sections\"><TabsTrigger value=\"overview\">Overview</TabsTrigger></TabsList>\n * <TabsContent value=\"overview\">…</TabsContent>\n * </Tabs>\n *\n * Both implement the WAI-ARIA tabs pattern: one tab stop on the selected tab, arrows along the\n * strip (wrapping), Home/End, disabled tabs skipped, automatic or manual activation, and\n * `role=\"tabpanel\"` regions labelled by their tabs. 0.3.0 had the roles and none of the keys.\n */\n// Overloads, not a union of the two prop types: with a union, `onValueChange={(key) => …}`\n// loses its contextual type and `key` becomes an implicit `any` at every strict call site.\nexport function Tabs<K extends string = string>(props: TabsProps<K>): ReactElement;\nexport function Tabs(props: TabsRootProps): ReactElement;\nexport function Tabs<K extends string = string>(props: TabsProps<K> | TabsRootProps): ReactElement {\n if ('items' in props && props.items) return <ItemsTabs {...(props as TabsProps<K>)} />;\n return <TabsRoot {...(props as TabsRootProps)} />;\n}\n\nfunction ItemsTabs<K extends string = string>({\n items,\n value: valueProp,\n defaultValue,\n onValueChange,\n variant = 'underline',\n size = 'md',\n orientation = 'horizontal',\n activation = 'automatic',\n idPrefix,\n label,\n className,\n}: TabsProps<K>) {\n const generatedPrefix = useId();\n const prefix = idPrefix ?? generatedPrefix;\n\n const [value, setValue] = useControllableState<K>({\n value: valueProp,\n defaultValue: defaultValue ?? items[0]?.key,\n onChange: onValueChange as ((next: K) => void) | undefined,\n });\n\n const selectedIndex = Math.max(\n 0,\n items.findIndex((item) => item.key === value),\n );\n\n const roving = useRovingFocus({\n orientation: orientation === 'vertical' ? 'vertical' : 'horizontal',\n loop: true,\n defaultIndex: selectedIndex,\n });\n\n return (\n <div\n role=\"tablist\"\n aria-label={label}\n aria-orientation={orientation}\n data-variant={variant}\n className={cn(stripClasses(variant, size, orientation), className)}\n {...roving.containerProps}\n >\n {items.map((tab, index) => {\n const active = tab.key === value;\n const itemProps = roving.itemProps(index, { disabled: tab.disabled, label: tab.label });\n\n return (\n <button\n key={tab.key}\n type=\"button\"\n role=\"tab\"\n id={tabId(prefix, tab.key)}\n aria-selected={active}\n aria-controls={idPrefix ? tabPanelId(prefix, tab.key) : undefined}\n data-state={active ? 'active' : 'inactive'}\n disabled={tab.disabled}\n {...itemProps}\n // Selection, not focus, owns the tab stop: Tab must land on the *selected*\n // tab, which is not necessarily the one the arrow keys last visited.\n tabIndex={active ? 0 : -1}\n onFocus={() => {\n itemProps.onFocus();\n // Automatic activation: focus and selection move together.\n if (activation === 'automatic' && !tab.disabled) setValue(tab.key);\n }}\n onClick={() => !tab.disabled && setValue(tab.key)}\n onKeyDown={(event) => {\n if (activation === 'manual' && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n setValue(tab.key);\n }\n }}\n className={tabClasses(variant, size)}\n >\n {tab.label}\n {tab.count !== undefined && <TabCount count={tab.count} variant={variant} />}\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Panels get a visible focus ring: they are tab stops when they hold nothing focusable. */\nconst PANEL_CLASSES = clsx(FOCUS_RING, 'rounded-sm');\n\nexport interface TabsPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** The `key` of the tab this panel belongs to. */\n tabKey: string;\n /** Must match the `idPrefix` given to `Tabs`. */\n idPrefix: string;\n /** Whether this panel's tab is the selected one. */\n active: boolean;\n children: ReactNode;\n /**\n * Keep the panel mounted while hidden. Default `false`. Mounting all panels preserves\n * scroll position and form state across tab switches at the cost of rendering them all.\n */\n keepMounted?: boolean;\n}\n\n/**\n * The `role=\"tabpanel\"` half of the `items` form.\n *\n * `tabIndex={0}` is deliberate and required: when a panel contains no focusable element,\n * it must be reachable itself, otherwise Tab from the selected tab skips the content\n * entirely. So it also needs a visible focus ring, which 0.6 suppressed (WCAG 2.4.7).\n */\nexport function TabsPanel({\n tabKey,\n idPrefix,\n active,\n children,\n keepMounted = false,\n className,\n ...rest\n}: TabsPanelProps) {\n if (!active && !keepMounted) return null;\n\n return (\n <div\n role=\"tabpanel\"\n id={tabPanelId(idPrefix, tabKey)}\n aria-labelledby={tabId(idPrefix, tabKey)}\n hidden={!active}\n tabIndex={0}\n data-state={active ? 'active' : 'inactive'}\n className={cn(PANEL_CLASSES, className)}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n// ── Composable form (Radix) ────────────────────────────────────────────────────\n\nconst TabsStyle = createContext<{ variant: TabsVariant; size: TabsSize; orientation: TabsOrientation }>({\n variant: 'underline',\n size: 'md',\n orientation: 'horizontal',\n});\n\nfunction TabsRoot({\n children,\n value,\n defaultValue,\n onValueChange,\n variant = 'underline',\n size = 'md',\n orientation = 'horizontal',\n activation = 'automatic',\n dir,\n className,\n}: TabsRootProps) {\n return (\n <TabsPrimitive.Root\n value={value}\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n orientation={orientation}\n activationMode={activation}\n dir={dir}\n className={cn(orientation === 'vertical' ? 'flex gap-6' : 'flex flex-col gap-4', className)}\n >\n <TabsStyle.Provider value={{ variant, size, orientation }}>{children}</TabsStyle.Provider>\n </TabsPrimitive.Root>\n );\n}\n\nexport interface TabsListProps extends HTMLAttributes<HTMLDivElement> {\n /** Names the tab strip. Required by the APG when there is more than one on a page. */\n label?: string;\n}\n\nexport const TabsList = forwardRef<HTMLDivElement, TabsListProps>(function TabsList(\n { label, className, ...rest },\n ref,\n) {\n const style = useContext(TabsStyle);\n return (\n <TabsPrimitive.List\n ref={ref}\n aria-label={label}\n loop\n data-variant={style.variant}\n className={cn(stripClasses(style.variant, style.size, style.orientation), className)}\n {...rest}\n />\n );\n});\n\nexport interface TabsTriggerProps extends HTMLAttributes<HTMLButtonElement> {\n value: string;\n disabled?: boolean;\n /** Renders a count chip after the label. */\n count?: number;\n}\n\nexport const TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(function TabsTrigger(\n { value, disabled, count, className, children, ...rest },\n ref,\n) {\n const style = useContext(TabsStyle);\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n value={value}\n disabled={disabled}\n className={cn(tabClasses(style.variant, style.size), className)}\n {...rest}\n >\n {children}\n {count !== undefined && <TabCount count={count} variant={style.variant} />}\n </TabsPrimitive.Trigger>\n );\n});\n\nexport interface TabsContentProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n /** Keep the panel mounted while hidden, preserving its state. Default `false`. */\n keepMounted?: boolean;\n}\n\nexport const TabsContent = forwardRef<HTMLDivElement, TabsContentProps>(function TabsContent(\n { value, keepMounted = false, className, ...rest },\n ref,\n) {\n return (\n <TabsPrimitive.Content\n ref={ref}\n value={value}\n forceMount={keepMounted || undefined}\n className={cn(PANEL_CLASSES, 'data-[state=inactive]:hidden', className)}\n {...rest}\n />\n );\n});\n","import { type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\n\nexport type NavItemSize = 'sm' | 'md';\nexport type NavItemVariant = 'card' | 'plain';\n\nexport interface NavItemProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * Leading glyph. Optional, but when `collapsed` it is the only thing left to look at, so\n * a row without one falls back to a monogram taken from the label.\n */\n icon?: ReactNode;\n label: string;\n /**\n * A destination that exists but cannot be opened right now (no permission, coming soon).\n * Dimmed, out of the tab order and inert under `asChild`, with `aria-disabled` so it is\n * still announced. New in 0.7.0; replaces `pointer-events-none opacity-40` at the call site.\n */\n disabled?: boolean;\n /**\n * The row you are on — the current route. Paints the brand fill and, under `asChild`, sets\n * `aria-current=\"page\"`; it also reflects to `data-state=\"active\"`.\n *\n * Not the same thing as focus, though Figma's `MenuButton` names this variant\n * `state=focussed`. That is a misnomer to fix on the design side: keyboard focus is the\n * ring below, it is transient and can land on any row, and if it painted the brand fill\n * too there would be no way to see which row is the current one while tabbing past it.\n */\n isActive?: boolean;\n /** Red indicator dot at top-right corner (e.g. unread count) */\n indicator?: boolean;\n /** Collapsed mode — label is visually hidden but stays in the accessibility tree. */\n collapsed?: boolean;\n /** Row height. `sm` suits a dense secondary nav or a nested group. */\n size?: NavItemSize;\n /**\n * Row weight.\n *\n * `card` gives every inactive row its own border and surface — right for a short primary\n * rail of eight or ten destinations, where each row is a target in its own right.\n * `plain` drops both, so an inactive row is just text: right for a long grouped nav,\n * where thirty bordered pills read as thirty cards rather than a list.\n *\n * A variant decides what a row looks like **at rest, and nothing else**. Hover and the\n * current-row fill are one vocabulary shared by both — see `STATE`. Through 0.5.0 each\n * variant defined its own, and `plain`'s was invisible against the rail it was written for.\n */\n variant?: NavItemVariant;\n /**\n * Render the single child element as the row, so the row itself is the link or button.\n *\n * `NavItem` is presentational by default — a `<span>` with hover styling. That is fine\n * inside a router `NavLink`, which is how `src/sidebar/` uses it, but on its own it is a\n * nav row that looks interactive and cannot be focused or activated. `asChild` is the\n * fix for anyone using it outside that wrapper:\n *\n * <NavItem asChild icon={<HouseIcon />} label=\"Home\">\n * <NavLink to=\"/\" />\n * </NavItem>\n */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * `md` is Figma's `MenuButton` in every dimension: 44px tall, 12px radius, 12px gap, 14px\n * padding-x. `square` is the collapsed footprint — the design does not stretch a collapsed row\n * to the rail width, it centres a 44×44 button, which is exactly `px-3.5` either side of a\n * 16px icon.\n *\n * The label is the one deliberate departure. Figma specifies Body Base (16px); this is\n * `text-body-sm` (14px), because 16px rows read as oversized against everything else in a\n * product shell. The design file is the authority on the box and the colours, not on this.\n *\n * `sm` has no counterpart in the design file; it is a code-only density for long navs.\n */\nconst SIZE: Record<NavItemSize, { box: string; label: string; square: string }> = {\n sm: { box: 'h-9 gap-2 rounded-lg px-3 py-1.5', label: 'text-body-xs', square: 'w-9' },\n md: { box: 'h-11 gap-3 rounded-xl px-3.5 py-2.5', label: 'text-body-sm', square: 'w-11' },\n};\n\n/**\n * Up to two characters standing in for a missing icon in the collapsed rail.\n *\n * Two rather than one because any nav long enough to be worth collapsing collides on first\n * letters — the docs' own sidebar has Button beside Badges and Input beside Icons. Multiple\n * words give one initial each (\"Color Tokens\" → \"CT\"); a single word gives its first two\n * (\"Button\" → \"Bu\"), which stays readable rather than shouting. Words that open with\n * punctuation are skipped, so \"Cards & Containers\" is \"CC\" and not \"C&\".\n */\nfunction monogram(label: string): string {\n const words = label.split(/\\s+/).filter((word) => /^[\\p{L}\\p{N}]/u.test(word));\n const [first, second] = words;\n // A label of nothing but symbols has no initials to take; show its first character.\n if (!first) return Array.from(label.trim())[0]?.toUpperCase() ?? '';\n if (second) return (Array.from(first)[0] + Array.from(second)[0]).toUpperCase();\n const [a, b] = Array.from(first);\n return a.toUpperCase() + (b ?? '').toLowerCase();\n}\n\n/**\n * What a row looks like when you are on it, and when you hover one you are not — shared by\n * both variants and declared nowhere else. Selection means one thing in this library.\n *\n * Through 0.5.0 each variant carried its own pair, and `plain`'s hover was\n * `hover:bg-default-hover` — a generic app-surface token resolving to `--prim-gray-100`,\n * which is the same #F5F5F5 as the `bg-default-secondary` rail a sidebar row sits on. Plain\n * rows therefore had **no visible hover at all** in light mode, and `plain`'s active\n * `bg-brand-tertiary` (#F1F7FD) was a 1.02:1 step against that same rail. The bug survived\n * because the docs demo every variant on `bg-default` — white — where the collision does\n * not occur.\n */\nconst STATE = {\n // Figma MenuButton `state=hover`. No border change: Figma holds it at #D9D9D9 through\n // hover and moves only the fill and the text.\n hover: 'hover:bg-brand-tertiary-hover hover:text-brand',\n // Figma MenuButton `state=focussed`, which is that file's name for selected — see the\n // `isActive` doc comment. Hovering the current row darkens it rather than reverting it to\n // the pale hover tint, which would read as the row losing its selection under the cursor.\n active: 'bg-brand text-brand-on-brand hover:bg-brand-hover',\n} as const;\n\n/** The resting appearance — the whole of the difference between the two variants. */\nconst VARIANT: Record<NavItemVariant, { active: string; inactive: string }> = {\n card: {\n // `border-transparent` holds the 1px so the icon and label do not shift outward when a\n // row becomes the current one — the same trick, for the same reason, as `button.tsx`.\n // `bg-brand` still paints edge to edge, since backgrounds clip to the border box.\n active: clsx('border border-transparent', STATE.active),\n inactive: clsx('border border-default bg-default text-default-secondary', STATE.hover),\n },\n plain: {\n active: STATE.active,\n inactive: clsx('text-default-secondary', STATE.hover),\n },\n};\n\nexport function NavItem({\n icon,\n label,\n isActive = false,\n indicator = false,\n collapsed = false,\n size = 'md',\n variant = 'card',\n asChild = false,\n disabled = false,\n children,\n className,\n onClick,\n ...rest\n}: NavItemProps) {\n const s = SIZE[size];\n const v = VARIANT[variant];\n\n const rootProps = {\n // Only meaningful when `asChild` renders a real link — a decorative span with\n // aria-current would be a lie.\n 'aria-current': asChild && isActive ? ('page' as const) : undefined,\n // Same attribute the disclosure components and `TableRow` use, so the state is\n // addressable from a consumer's CSS. `active` rather than `selected`: a nav row is where\n // you *are* (`aria-current=\"page\"`), which is a different thing from a row you have\n // *picked* (`aria-selected`) — `TableRow` is the latter and says `selected`.\n 'data-state': isActive ? ('active' as const) : undefined,\n 'data-disabled': disabled || undefined,\n 'aria-disabled': disabled || undefined,\n className: clsx(\n 'relative flex items-center transition-colors',\n // Unconditional: a row can also become focusable by the caller putting it inside a\n // link, which is how `src/sidebar/` uses it. A ring that only appears under `asChild`\n // leaves that case with no visible focus at all.\n // The offset is `default-secondary`, not `default`: a nav row's home is the sidebar\n // rail, and `ring-offset-default` is #FFFFFF, so a focused `plain` row drew a 1px white\n // halo on the #F5F5F5 rail. The offset itself is load-bearing — in dark mode\n // `ring-brand` and `bg-brand` are both #F1F7FD, so without it a focused *active* row\n // would have no visible ring at its inner edge.\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default-secondary',\n s.box,\n // Expanded rows fill the nav; a collapsed one is a centred square, not a stretched row.\n collapsed ? clsx('justify-center', s.square) : 'w-full',\n isActive ? v.active : v.inactive,\n 'data-[disabled]:cursor-not-allowed data-[disabled]:opacity-40 data-[disabled]:hover:bg-transparent data-[disabled]:hover:text-default-secondary',\n className,\n ),\n ...rest,\n // After the spread: a disabled row refuses the press (a router Link skips navigation when\n // the event is prevented) and leaves the tab order, as a disabled control does.\n ...(disabled ? { tabIndex: -1 } : {}),\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n onClick?.(event);\n },\n };\n\n const content = (\n <>\n {icon != null ? (\n <span aria-hidden className=\"shrink-0 [&_svg]:size-4\">\n {icon}\n </span>\n ) : (\n // Icons are optional, but the collapsed rail hides the label — so a row with neither\n // renders as an empty box. Through 0.5.0 that is exactly what a nav without icons\n // collapsed to, the docs site's own 36-row sidebar included. The monogram is\n // decorative in the same way the icon is: the `sr-only` label below still names the\n // row.\n collapsed && (\n <span\n aria-hidden\n // `min-w-4` rather than `size-4`: the box matches the 16px an icon would take,\n // but a wide pair like \"MW\" is allowed to outgrow it rather than be clipped.\n className=\"flex h-4 min-w-4 shrink-0 items-center justify-center text-body-tiny font-semibold leading-none tracking-tight\"\n >\n {monogram(label)}\n </span>\n )\n )}\n {/* `collapsed` hides the label visually but keeps it in the accessibility tree.\n Through 0.3.0 the span was not rendered at all and no `aria-label` replaced it,\n so a collapsed sidebar was nine unlabelled icon links — the icon itself carries\n no name, being decorative. */}\n <span\n className={clsx(\n 'min-w-0 truncate font-regular leading-snug',\n s.label,\n collapsed ? 'sr-only' : 'flex-1',\n )}\n >\n {label}\n </span>\n {indicator && (\n <span\n // The dot is the only carrier of \"there is something new here\", so it needs a\n // name of its own rather than being purely decorative.\n role=\"status\"\n aria-label=\"Unread\"\n className=\"absolute -right-px -top-px size-2 rounded-full bg-danger\"\n />\n )}\n </>\n );\n\n if (asChild) {\n // The child element becomes the row itself, so the icon/label/indicator go inside it\n // and its own children (usually nothing, since the label comes from `label`) are\n // discarded in favour of the composed content.\n return (\n <Slot wrapChildren={() => content} {...rootProps}>\n {children}\n </Slot>\n );\n }\n\n return <span {...rootProps}>{content}</span>;\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type EyebrowLabelVariant = 'uppercase' | 'plain';\n\nexport interface EyebrowLabelProps {\n children: ReactNode;\n /**\n * `uppercase` is the dominant form (nine of twelve source copies).\n * `plain` covers the entity-detail / reviewer-detail variant, whose label text is\n * already capitalised in the source string.\n */\n variant?: EyebrowLabelVariant;\n className?: string;\n}\n\n/**\n * Small semibold label above a group of fields.\n *\n * Replaces twelve copies across three variants:\n * `mb-2 text-body-tiny font-semibold uppercase tracking-wide …` (×9)\n * `text-[11px] font-semibold … tracking-wide` (×5, entity/reviewer detail)\n * `text-body-tiny font-semibold uppercase tracking-wider` (×2, entity onboarding)\n *\n * `text-body-tiny` is 11px, so the `text-[11px]` variant collapses into it exactly.\n * The `tracking-wider` copies become `tracking-wide` — a 0.0125em difference at 11px,\n * i.e. sub-pixel.\n */\nexport function EyebrowLabel({ children, variant = 'uppercase', className }: EyebrowLabelProps) {\n return (\n <p\n data-variant={variant}\n className={clsx(\n 'text-body-tiny font-semibold tracking-wide text-default-secondary',\n variant === 'uppercase' && 'uppercase',\n className,\n )}\n >\n {children}\n </p>\n );\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\n\nexport type SeparatorOrientation = 'horizontal' | 'vertical';\n\nexport interface SeparatorProps extends HTMLAttributes<HTMLDivElement> {\n orientation?: SeparatorOrientation;\n /**\n * `true` when the rule is purely visual, which is the common case. A decorative\n * separator is `role=\"none\"` and stays out of the accessibility tree; a semantic one\n * is `role=\"separator\"` and announces a break between groups.\n */\n decorative?: boolean;\n}\n\n/**\n * A hairline rule. Matches Figma's `Menu Separator`, generalised to both orientations.\n *\n * Drawn as a filled element rather than a border, because a 1px border on a flex child\n * collapses to nothing at some zoom levels while a `1px` height does not — which is why\n * the preset carries a `divider` background token separate from `border-default`.\n */\nexport const Separator = forwardRef<HTMLDivElement, SeparatorProps>(function Separator(\n { orientation = 'horizontal', decorative = true, className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n role={decorative ? 'none' : 'separator'}\n aria-orientation={decorative ? undefined : orientation}\n data-slot=\"separator\"\n className={clsx(\n 'shrink-0 bg-divider',\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px',\n className,\n )}\n {...rest}\n />\n );\n});\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport type KbdSize = 'sm' | 'md';\n\nexport interface KbdProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n size?: KbdSize;\n}\n\nconst SIZE: Record<KbdSize, string> = {\n sm: 'h-4 min-w-4 px-1 text-body-tiny',\n md: 'h-5 min-w-5 px-1.5 text-body-xs',\n};\n\n/**\n * A keyboard key. Matches Figma's `Menu Shortcut`.\n *\n * Renders a real `<kbd>` so assistive tech announces it as key input rather than as a\n * stray glyph — `⌘K` read as plain text is \"place of interest sign K\".\n *\n * Pass one key per element and let the caller supply the joiner, so a shortcut reads as\n * separate keys instead of one run-together string:\n *\n * <Kbd>⌘</Kbd><Kbd>K</Kbd>\n */\nexport const Kbd = forwardRef<HTMLElement, KbdProps>(function Kbd(\n { children, size = 'md', className, ...rest },\n ref,\n) {\n return (\n <kbd\n ref={ref}\n data-slot=\"kbd\"\n className={clsx(\n 'inline-flex items-center justify-center rounded border border-default bg-default-secondary',\n 'font-medium tabular-nums text-default-secondary',\n SIZE[size],\n className,\n )}\n {...rest}\n >\n {children}\n </kbd>\n );\n});\n","import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { ChevronRightIcon } from 'lucide-react';\nimport { Slot } from '../../lib/slot';\n\nexport interface BreadcrumbProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n /** Names the landmark. Default `Breadcrumb`. */\n label?: string;\n}\n\n/**\n * Breadcrumb trail.\n *\n * A `<nav>` wrapping an ordered list, which is the whole semantic point: the order *is* the\n * hierarchy, so `<ol>` says something `<div>` cannot, and the landmark lets a screen reader\n * user jump to the trail without walking the header.\n *\n * The separators are `aria-hidden` and generated by the list, not passed in — a chevron\n * announced between every crumb is noise, and the `/` characters people usually hand-type\n * get read out one by one.\n */\nexport const Breadcrumb = forwardRef<HTMLElement, BreadcrumbProps>(function Breadcrumb(\n { children, label = 'Breadcrumb', className, ...rest },\n ref,\n) {\n return (\n <nav ref={ref} aria-label={label} data-slot=\"breadcrumb\" {...rest}>\n <ol className={clsx('flex flex-wrap items-center gap-1.5 p-0 text-body-xs', className)}>\n {children}\n </ol>\n </nav>\n );\n});\n\nexport interface BreadcrumbItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n children: ReactNode;\n /**\n * The page you are on. Renders as plain text with `aria-current=\"page\"` rather than a\n * link — a link to the current page is a dead control, and the APG says the last crumb\n * should not be one.\n */\n current?: boolean;\n /** Render a router `Link` instead of an `<a>`. */\n asChild?: boolean;\n /** Suppress the leading separator. Set automatically on the first item you render. */\n first?: boolean;\n}\n\nexport const BreadcrumbItem = forwardRef<HTMLAnchorElement, BreadcrumbItemProps>(\n function BreadcrumbItem({ children, current = false, asChild = false, first = false, className, ...rest }, ref) {\n return (\n <li className=\"flex items-center gap-1.5\">\n {!first && (\n <ChevronRightIcon aria-hidden className=\"size-3.5 shrink-0 text-icon-default-tertiary\" />\n )}\n {current ? (\n <span aria-current=\"page\" className={clsx('font-medium text-default', className)}>\n {children}\n </span>\n ) : asChild ? (\n <Slot\n className={clsx(\n 'rounded text-default-secondary transition-colors hover:text-brand',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n className,\n )}\n {...rest}\n >\n {children}\n </Slot>\n ) : (\n <a\n ref={ref}\n className={clsx(\n 'rounded text-default-secondary transition-colors hover:text-brand',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n className,\n )}\n {...rest}\n >\n {children}\n </a>\n )}\n </li>\n );\n },\n);\n\nexport interface BreadcrumbEllipsisProps extends HTMLAttributes<HTMLSpanElement> {}\n\n/**\n * Stands in for collapsed middle crumbs on a deep trail.\n *\n * A `<span>`, not a button: it is a truncation marker, and making it a disabled control\n * puts an unusable stop in the tab order. If the hidden crumbs need to be reachable, wrap\n * this in a `DropdownMenuTrigger` and list them.\n */\nexport const BreadcrumbEllipsis = forwardRef<HTMLSpanElement, BreadcrumbEllipsisProps>(\n function BreadcrumbEllipsis({ className, ...rest }, ref) {\n return (\n <li className=\"flex items-center gap-1.5\">\n <ChevronRightIcon aria-hidden className=\"size-3.5 shrink-0 text-icon-default-tertiary\" />\n <span\n ref={ref}\n aria-label=\"Collapsed items\"\n className={clsx('px-0.5 text-default-tertiary', className)}\n {...rest}\n >\n …\n </span>\n </li>\n );\n },\n);\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';\nimport { SelectControl } from '../forms/select';\n\nexport type PaginationType = 'default' | 'dots';\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** 1-based. */\n page: number;\n /** Total number of pages. Values below 1 render nothing. */\n pageCount: number;\n onPageChange: (page: number) => void;\n /** Matches Figma's `Type` axis. `dots` is the compact carousel form. */\n type?: PaginationType;\n /** How many numbered pages to show either side of the current one. Default `1`. */\n siblingCount?: number;\n /** Names the nav landmark. Default `Pagination`. */\n label?: string;\n}\n\nconst GAP = '…';\n\n/**\n * Builds the visible page list with ellipses.\n *\n * Always returns first and last, the current page, and `siblingCount` either side. The\n * window is widened rather than allowed to shrink near the ends, so the control does not\n * change width as the user pages through — a row of buttons that reflows under the cursor\n * is how you mis-click.\n */\nexport function paginationRange(\n page: number,\n pageCount: number,\n siblingCount = 1,\n): (number | typeof GAP)[] {\n // first + last + current + 2 siblings + 2 possible gaps\n const totalSlots = siblingCount * 2 + 5;\n if (pageCount <= totalSlots) {\n return Array.from({ length: pageCount }, (_, i) => i + 1);\n }\n\n const left = Math.max(page - siblingCount, 1);\n const right = Math.min(page + siblingCount, pageCount);\n\n const showLeftGap = left > 3;\n const showRightGap = right < pageCount - 2;\n\n if (!showLeftGap && showRightGap) {\n const count = siblingCount * 2 + 3;\n return [...Array.from({ length: count }, (_, i) => i + 1), GAP, pageCount];\n }\n\n if (showLeftGap && !showRightGap) {\n const count = siblingCount * 2 + 3;\n return [1, GAP, ...Array.from({ length: count }, (_, i) => pageCount - count + 1 + i)];\n }\n\n return [\n 1,\n GAP,\n ...Array.from({ length: right - left + 1 }, (_, i) => left + i),\n GAP,\n pageCount,\n ];\n}\n\nconst ARROW_BASE = clsx(\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-lg border transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n 'disabled:cursor-not-allowed disabled:border-disabled disabled:bg-disabled disabled:text-disabled',\n 'border-default bg-default text-default hover:bg-default-secondary hover:text-brand',\n);\n\n/**\n * Pagination. Matches Figma's `Pagination` (`Type: Default | Dots`), `Pagination Page`\n * (`State: Default | Hover | Current | Current Hover`), `Pagination Next` / `Previous`\n * (`Default | Hover | Disabled`) and `Pagination dots` (`Active | Inactive`).\n *\n * `DataTable` had no pager at all, so every consumer built one. Notes on the semantics:\n *\n * - A `<nav>` landmark with a name, so it is reachable by landmark navigation.\n * - `aria-current=\"page\"` on the active page. It is the only non-visual signal of which\n * page you are on; the filled background is not announced.\n * - Each page button is named \"Page 3\", not \"3\" — a bare number read out of context tells\n * a screen reader user nothing about what activating it does.\n * - The ellipsis is inert text, not a disabled button, so it is skipped rather than\n * announced as an unavailable control.\n */\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n pageCount,\n onPageChange,\n type = 'default',\n siblingCount = 1,\n label = 'Pagination',\n className,\n ...rest\n },\n ref,\n) {\n if (pageCount < 1) return null;\n\n const go = (next: number) => {\n const clamped = Math.min(Math.max(next, 1), pageCount);\n if (clamped !== page) onPageChange(clamped);\n };\n\n return (\n <nav\n ref={ref}\n aria-label={label}\n data-slot=\"pagination\"\n className={clsx('flex items-center gap-1.5', className)}\n {...rest}\n >\n <button\n type=\"button\"\n aria-label=\"Previous page\"\n disabled={page <= 1}\n onClick={() => go(page - 1)}\n className={ARROW_BASE}\n >\n <ChevronLeftIcon aria-hidden className=\"size-4\" />\n </button>\n\n {type === 'dots' ? (\n // The dots form has no room for numbers, so the list itself is the only place the\n // position can be stated — hence the live-region-free but explicitly named group.\n <span\n role=\"group\"\n aria-label={`Page ${page} of ${pageCount}`}\n className=\"flex items-center gap-2 px-2\"\n >\n {Array.from({ length: pageCount }, (_, i) => i + 1).map((n) => (\n <button\n key={n}\n type=\"button\"\n aria-label={`Page ${n}`}\n aria-current={n === page ? 'page' : undefined}\n onClick={() => go(n)}\n className={clsx(\n 'size-2 rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 focus-visible:ring-offset-default',\n n === page ? 'bg-brand' : 'bg-default-tertiary hover:bg-neutral-secondary',\n )}\n />\n ))}\n </span>\n ) : (\n paginationRange(page, pageCount, siblingCount).map((entry, index) =>\n entry === GAP ? (\n <span\n key={`gap-${index}`}\n aria-hidden\n className=\"inline-flex size-9 items-center justify-center text-body-sm text-default-tertiary\"\n >\n {GAP}\n </span>\n ) : (\n <button\n key={entry}\n type=\"button\"\n aria-label={`Page ${entry}`}\n aria-current={entry === page ? 'page' : undefined}\n onClick={() => go(entry)}\n className={clsx(\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-lg border text-body-sm tabular-nums transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n entry === page\n ? 'border-brand bg-brand font-semibold text-brand-on-brand'\n : 'border-default bg-default text-default hover:bg-default-secondary hover:text-brand',\n )}\n >\n {entry}\n </button>\n ),\n )\n )}\n\n <button\n type=\"button\"\n aria-label=\"Next page\"\n disabled={page >= pageCount}\n onClick={() => go(page + 1)}\n className={ARROW_BASE}\n >\n <ChevronRightIcon aria-hidden className=\"size-4\" />\n </button>\n </nav>\n );\n});\n\n// ── PaginationBar ──────────────────────────────────────────────────────────────\n\nexport interface PaginationBarProps {\n /** 1-based. */\n page: number;\n /** Rows per page. */\n pageSize: number;\n /** Total rows across every page. */\n total: number;\n onPageChange: (page: number) => void;\n /** Offer a page-size selector. Omit it, or pass `[]` as `pageSizeOptions`, to hide one. */\n onPageSizeChange?: (pageSize: number) => void;\n /** Page sizes on offer. Default `[10, 20, 50]`. */\n pageSizeOptions?: number[];\n /** Replaces the \"Showing 1–10 of 57\" summary. */\n summary?: ReactNode;\n /** Names the page-button landmark. Default \"Pages\". */\n label?: string;\n className?: string;\n}\n\n/**\n * A full pager row: a range summary, an optional page-size selector, and the page buttons.\n * New in 0.7.0, from SCIC's `Pagination` (whose `limit` is `pageSize` here). `DataTable` renders\n * one; use it directly for a list that pages without a table.\n *\n * Only the page buttons are the `<nav>` landmark. The summary and the size selector sit beside\n * it, because a landmark should hold navigation and nothing else.\n */\nexport function PaginationBar({\n page,\n pageSize,\n total,\n onPageChange,\n onPageSizeChange,\n pageSizeOptions = [10, 20, 50],\n summary,\n label = 'Pages',\n className,\n}: PaginationBarProps) {\n const pageCount = Math.max(1, Math.ceil(total / pageSize));\n const from = total === 0 ? 0 : (page - 1) * pageSize + 1;\n const to = Math.min(total, page * pageSize);\n const showSize = Boolean(onPageSizeChange) && pageSizeOptions.length > 0;\n const options = pageSizeOptions.includes(pageSize)\n ? pageSizeOptions\n : [...pageSizeOptions, pageSize].sort((a, b) => a - b);\n\n return (\n <div\n data-slot=\"pagination-bar\"\n className={clsx('flex flex-wrap items-center justify-between gap-x-4 gap-y-3', className)}\n >\n <p className=\"text-body-xs text-default-secondary\">\n {summary ?? (\n <>\n Showing {from}–{to} of {total}\n </>\n )}\n </p>\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-3\">\n {showSize && (\n <div className=\"flex items-center gap-2\">\n <span aria-hidden className=\"text-body-xs text-default-secondary\">\n Rows per page\n </span>\n <SelectControl\n aria-label=\"Rows per page\"\n size=\"sm\"\n className=\"w-[72px]\"\n value={String(pageSize)}\n options={options.map((size) => ({ value: String(size), label: String(size) }))}\n onValueChange={(value) => onPageSizeChange?.(Number(value))}\n />\n </div>\n )}\n <Pagination page={page} pageCount={pageCount} onPageChange={onPageChange} label={label} />\n </div>\n </div>\n );\n}\n","import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { Slot } from '../../lib/slot';\n\nexport type NavigationMenuOrientation = 'horizontal' | 'vertical';\nexport type NavigationMenuVariant = 'pill' | 'link';\n\nexport interface NavigationMenuProps extends HTMLAttributes<HTMLElement> {\n children: ReactNode;\n orientation?: NavigationMenuOrientation;\n /** Names the nav landmark. Required when a page has more than one `<nav>`. */\n label: string;\n}\n\n/**\n * A navigation landmark wrapping a list of links. Matches Figma's `Navigation Pill List`\n * and `Navigation Button List`.\n *\n * Why the `<nav>` + `<ul>` + `<li>` nesting rather than a flat row of anchors: the list is\n * what makes a screen reader announce \"list, 5 items\" and lets the user jump the whole\n * block. A bare row of links is announced one at a time with no sense of how many there\n * are or where the set ends. The `label` is required for the same reason — an unnamed\n * landmark in a page with a sidebar *and* a top bar is not navigable.\n */\nexport const NavigationMenu = forwardRef<HTMLElement, NavigationMenuProps>(\n function NavigationMenu({ children, orientation = 'horizontal', label, className, ...rest }, ref) {\n return (\n <nav ref={ref} aria-label={label} data-slot=\"navigation-menu\" {...rest}>\n <ul\n className={clsx(\n 'flex list-none p-0',\n orientation === 'vertical' ? 'flex-col gap-1' : 'flex-row items-center gap-1',\n className,\n )}\n >\n {children}\n </ul>\n </nav>\n );\n },\n);\n\nexport interface NavigationMenuItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n children: ReactNode;\n /** Matches Figma's `State: Active`. Sets `aria-current=\"page\"`. */\n active?: boolean;\n variant?: NavigationMenuVariant;\n /** Render a router `Link` instead of an `<a>`. */\n asChild?: boolean;\n /** Leading glyph. Marked decorative automatically. */\n icon?: ReactNode;\n}\n\n/**\n * A single navigation link. Matches Figma's `Navigation Pill` and `Navigation Button`\n * (`State: Default | Active | Hover`).\n *\n * `aria-current=\"page\"` is the point: the filled pill is not announced, so without it a\n * screen reader user cannot tell which page they are on.\n */\nexport const NavigationMenuItem = forwardRef<HTMLAnchorElement, NavigationMenuItemProps>(\n function NavigationMenuItem(\n { children, active = false, variant = 'pill', asChild = false, icon, className, ...rest },\n ref,\n ) {\n const content = (\n <>\n {icon && (\n <span aria-hidden className=\"shrink-0 [&_svg]:size-4\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 truncate\">{children}</span>\n </>\n );\n\n const linkProps = {\n 'aria-current': active ? ('page' as const) : undefined,\n className: clsx(\n 'inline-flex items-center gap-2 whitespace-nowrap transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n variant === 'pill'\n ? clsx(\n 'rounded-lg px-3 py-1.5 text-body-xs font-medium',\n active\n ? 'bg-brand text-brand-on-brand'\n : 'text-default-secondary hover:bg-default-secondary hover:text-default',\n )\n : clsx(\n 'rounded px-1 py-0.5 text-body-sm',\n active\n ? 'font-semibold text-brand'\n : 'text-default-secondary hover:text-default',\n ),\n className,\n ),\n ...rest,\n };\n\n return (\n <li>\n {asChild ? (\n <Slot wrapChildren={() => content} {...linkProps}>\n {children}\n </Slot>\n ) : (\n <a ref={ref} {...linkProps}>\n {content}\n </a>\n )}\n </li>\n );\n },\n);\n","import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\nimport { Slot } from '../../lib/slot';\n\n/**\n * The type ramp as components, mirroring Figma's `Text*` primitives one-for-one:\n * `Text`, `Text Strong`, `Text Emphasis`, `Text Small`, `Text Code`, `Text Link`,\n * `Text Heading`, `Text Subheading`, `Text Subtitle`, `Text Title Page`,\n * `Text Title Hero`, `Text List`, `Text List Item`, `Text Link List`.\n *\n * These existed in Figma with settled styles and had no code counterpart, so every\n * consumer reached for a raw `text-body-sm text-default` triplet and the ramp drifted.\n * Each component pins the size/weight/colour combination and nothing else, so layout\n * stays the caller's job.\n *\n * All of them take `asChild`, because the right element is contextual — a `Heading` is an\n * `<h2>` on a page and an `<h3>` inside a card, and only the caller knows the outline.\n */\n\n/**\n * The text colour as a meaning, new in 0.7.0. `muted` and `subtle` are the secondary and\n * tertiary steps; the rest are the status tones. It replaces the\n * `className={denied ? 'text-danger' : 'text-positive'}` that consumers were writing, so state\n * is a prop and the colour stays a token. Omit it to keep each component's own colour.\n */\nexport type TextTone = 'default' | 'muted' | 'subtle' | 'brand' | 'positive' | 'warning' | 'danger';\n\nconst TONE: Record<TextTone, string> = {\n default: 'text-default',\n muted: 'text-default-secondary',\n subtle: 'text-default-tertiary',\n brand: 'text-brand',\n positive: 'text-positive',\n warning: 'text-warning',\n danger: 'text-danger',\n};\n\ntype BaseProps = HTMLAttributes<HTMLElement> & {\n children?: ReactNode;\n asChild?: boolean;\n /** Text colour as a meaning. See `TextTone`. */\n tone?: TextTone;\n};\n\n/** Factory for the plain ramp entries — identical except for element and classes. */\nfunction textComponent(\n displayName: string,\n defaultElement: 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'strong' | 'em' | 'code' | 'q',\n classes: string,\n) {\n const Component = forwardRef<HTMLElement, BaseProps>(function TextComponent(\n { children, asChild = false, tone, className, ...rest },\n ref,\n ) {\n const Root = (asChild ? Slot : defaultElement) as 'p';\n return (\n <Root\n ref={ref as never}\n data-tone={tone}\n // `cn`, so the tone's colour (and then the caller's class) beats the ramp's own.\n className={cn(classes, tone && TONE[tone], className)}\n {...rest}\n >\n {children}\n </Root>\n );\n });\n Component.displayName = displayName;\n return Component;\n}\n\n// ── Body ───────────────────────────────────────────────────────────────────────\n\nexport type TextProps = BaseProps;\n\n/** `Text` — the default body paragraph. */\nexport const Text = textComponent('Text', 'p', 'text-body text-default');\n\n/** `Text Small` — secondary body copy. */\nexport const TextSmall = textComponent('TextSmall', 'p', 'text-body-sm text-default-secondary');\n\n/** `Text Tiny` — the smallest readable step; captions and table meta. */\nexport const TextTiny = textComponent('TextTiny', 'p', 'text-body-tiny text-default-secondary');\n\n/** `Text Strong` — emphasis by weight, in a real `<strong>`. */\nexport const TextStrong = textComponent('TextStrong', 'strong', 'font-semibold text-default');\n\n/** `Text Emphasis` — emphasis by slant, in a real `<em>`. */\nexport const TextEmphasis = textComponent('TextEmphasis', 'em', 'italic text-default');\n\n/** An inline quotation, in a real `<q>` so the browser adds locale-correct quote marks. New in 0.7.0. */\nexport const Quote = textComponent('Quote', 'q', 'italic text-default');\n\n/** `Text Code` — inline monospace. */\nexport const TextCode = textComponent(\n 'TextCode',\n 'code',\n 'rounded border border-default bg-default-secondary px-1 py-0.5 font-mono text-body-xs text-default',\n);\n\n// ── Headings ───────────────────────────────────────────────────────────────────\n\n/** `Text Title Hero` — the largest step, one per page at most. */\nexport const TitleHero = textComponent('TitleHero', 'h1', 'text-title-hero font-bold text-default');\n\n/** `Text Title Page` — page title. */\nexport const TitlePage = textComponent('TitlePage', 'h1', 'text-title font-bold text-default');\n\n/** `Text Subtitle` — a lead paragraph under a title; regular weight by design. */\nexport const Subtitle = textComponent('Subtitle', 'p', 'text-subtitle text-default-secondary');\n\n/** `Text Heading` — section heading. */\nexport const Heading = textComponent('Heading', 'h2', 'text-heading font-semibold text-default');\n\n/** `Text Subheading` — subsection heading; regular weight, matching Figma. */\nexport const Subheading = textComponent('Subheading', 'h3', 'text-subheading text-default');\n\n// ── Blockquote ─────────────────────────────────────────────────────────────────\n\nexport interface BlockquoteProps extends HTMLAttributes<HTMLQuoteElement> {\n children?: ReactNode;\n /** URL of the source, set as the `cite` attribute. Not shown; pair with a visible credit. */\n cite?: string;\n tone?: TextTone;\n}\n\n/**\n * A block quotation, new in 0.7.0, matching Radix Themes' `Blockquote`. A real\n * `<blockquote>`, so assistive tech announces where the quotation starts and ends.\n */\nexport const Blockquote = forwardRef<HTMLQuoteElement, BlockquoteProps>(function Blockquote(\n { children, cite, tone, className, ...rest },\n ref,\n) {\n return (\n <blockquote\n ref={ref}\n cite={cite}\n data-tone={tone}\n className={cn(\n 'border-l-4 border-default pl-4 text-body italic text-default-secondary',\n tone && TONE[tone],\n className,\n )}\n {...rest}\n >\n {children}\n </blockquote>\n );\n});\n\n// ── Link ───────────────────────────────────────────────────────────────────────\n\nexport interface TextLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n children?: ReactNode;\n asChild?: boolean;\n}\n\n/**\n * `Text Link`. Underlined rather than colour-only: colour alone is not a sufficient\n * distinction for a link inside a run of text (WCAG 1.4.1).\n */\nexport const TextLink = forwardRef<HTMLAnchorElement, TextLinkProps>(function TextLink(\n { children, asChild = false, className, ...rest },\n ref,\n) {\n const Root = (asChild ? Slot : 'a') as 'a';\n return (\n <Root\n ref={ref}\n className={clsx(\n 'rounded text-brand underline decoration-1 underline-offset-2 transition-colors',\n 'hover:text-brand-secondary',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n className,\n )}\n {...rest}\n >\n {children}\n </Root>\n );\n});\n\n// ── Lists ──────────────────────────────────────────────────────────────────────\n\nexport type TextListVariant = 'bulleted' | 'numbered' | 'plain';\nexport type TextListDensity = 'default' | 'compact';\n\nexport interface TextListProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n variant?: TextListVariant;\n /** Matches Figma's `Density` axis on `Text List` / `Text Link List`. */\n density?: TextListDensity;\n}\n\nconst LIST_MARKER: Record<TextListVariant, string> = {\n bulleted: 'list-disc pl-5',\n numbered: 'list-decimal pl-5',\n plain: 'list-none pl-0',\n};\n\n/** `Text List` — a real `<ul>`/`<ol>`, so item count is announced. */\nexport const TextList = forwardRef<HTMLElement, TextListProps>(function TextList(\n { children, variant = 'bulleted', density = 'default', className, ...rest },\n ref,\n) {\n const Root = (variant === 'numbered' ? 'ol' : 'ul') as 'ul';\n return (\n <Root\n ref={ref as never}\n className={clsx(\n 'text-body text-default',\n LIST_MARKER[variant],\n density === 'compact' ? 'space-y-0.5' : 'space-y-1.5',\n className,\n )}\n {...rest}\n >\n {children}\n </Root>\n );\n});\n\nexport type TextListItemProps = HTMLAttributes<HTMLLIElement> & { children?: ReactNode };\n\n/** `Text List Item`. */\nexport const TextListItem = forwardRef<HTMLLIElement, TextListItemProps>(function TextListItem(\n { children, className, ...rest },\n ref,\n) {\n return (\n <li ref={ref} className={clsx('text-body text-default', className)} {...rest}>\n {children}\n </li>\n );\n});\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { WidgetTitle } from './widget-title';\nimport type { WidgetTitleSize } from './widget-title';\n\nexport type WidgetHeaderEyebrowVariant = 'uppercase' | 'plain';\n\nexport interface WidgetHeaderProps {\n eyebrow?: string;\n eyebrowVariant?: WidgetHeaderEyebrowVariant;\n title: string;\n titleSize?: WidgetTitleSize;\n subtitle?: string;\n badge?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\n// uppercase: 11px/medium/tracked, matches Variation 2 mockups · plain: 13px/regular, matches Variation 1's small label line\nconst eyebrowStyles: Record<WidgetHeaderEyebrowVariant, string> = {\n uppercase: 'text-body-tiny font-medium uppercase tracking-[0.66px] text-default-secondary',\n plain: 'text-body-xs leading-[1.4] text-default-secondary',\n};\n\nexport function WidgetHeader({\n eyebrow,\n eyebrowVariant = 'uppercase',\n title,\n titleSize,\n subtitle,\n badge,\n action,\n className,\n}: WidgetHeaderProps) {\n return (\n <div className={clsx('flex items-start justify-between gap-2', className)}>\n <div className=\"min-w-0 flex-1\">\n {eyebrow && <p className={eyebrowStyles[eyebrowVariant]}>{eyebrow}</p>}\n <WidgetTitle size={titleSize}>{title}</WidgetTitle>\n {subtitle && (\n <p className=\"mt-1 text-body-xs text-default-secondary leading-snug\">{subtitle}</p>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {badge}\n {action}\n </div>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport type WidgetTitleSize = 'sm' | 'md' | 'lg';\n\nexport interface WidgetTitleProps {\n children: ReactNode;\n size?: WidgetTitleSize;\n className?: string;\n}\n\n// sm: 16px/semibold (default) · md: 18px/bold (Variation 2 mockups) · lg: 20px/semibold (Variation 1 mockups)\nconst sizeStyles: Record<WidgetTitleSize, string> = {\n sm: 'text-subheading-sm font-semibold leading-none',\n // Was `text-[18px]`, which had no step on the type scale (Scale 04 = 16, Scale 05 = 20).\n // Now 20px, so `md` and `lg` are the same size and separate on weight alone — bold vs\n // semibold. That is the intended trade for getting off an off-scale literal.\n md: 'text-subheading font-bold leading-normal',\n lg: 'text-subheading font-semibold leading-[1.2]',\n};\n\nexport function WidgetTitle({ children, size = 'sm', className }: WidgetTitleProps) {\n return (\n <h3 className={clsx(sizeStyles[size], 'text-default', className)}>\n {children}\n </h3>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\n\nexport interface WidgetFooterProps {\n caption?: string;\n subcaption?: string;\n action?: ReactNode;\n className?: string;\n}\n\nexport function WidgetFooter({ caption, subcaption, action, className }: WidgetFooterProps) {\n return (\n <div className={clsx('flex items-center gap-3', className)}>\n {caption && (\n <div className=\"flex items-stretch gap-3 flex-1 min-w-0\">\n <div className=\"w-0.5 shrink-0 self-stretch rounded-full bg-brand\" />\n <div className=\"min-w-0\">\n <p className=\"text-body-sm font-medium text-default leading-snug\">\n {caption}\n </p>\n {subcaption && (\n <p className=\"mt-0.5 text-body-xs text-default-secondary\">{subcaption}</p>\n )}\n </div>\n </div>\n )}\n {action && <div className=\"ml-auto shrink-0\">{action}</div>}\n </div>\n );\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { cn } from '../../lib/cn';\n\n/**\n * The dashboard grid vocabulary, ported from SCIC in 0.7.0: a 12-column row, five widget widths\n * and three canonical card heights. The heights are modular (364 = 170·2 + 24, 752 = 170·4 +\n * 24·3), so two stacked `medium` cards bottom-align with one `large`.\n *\n * Not included: SCIC's drag-and-drop masonry dashboard, which needs `@dnd-kit` and stays in the\n * app until it earns a subpath of its own.\n */\n\n/** Column span within the 12-column grid. */\nexport type ColSize = 'tiny' | 'small' | 'medium' | 'large' | 'full';\n\n/** Canonical widget card heights. */\nexport type WidgetHeight = 'small' | 'medium' | 'large';\n\n/**\n * Viewport-driven spans: everything stacks (tiny tiles pair up 2×2) below `lg`, then the\n * 12-column spans apply. Right when the grid gets the whole viewport. For a grid that shares\n * its row with a rail or drawer, size by its own width: see `useWidthTier` and\n * `COL_SPAN_BY_TIER`.\n */\nexport const COL_SPAN: Record<ColSize, string> = {\n tiny: 'col-span-6 lg:col-span-3',\n small: 'col-span-12 lg:col-span-4',\n medium: 'col-span-12 lg:col-span-6',\n large: 'col-span-12 lg:col-span-8',\n full: 'col-span-12',\n};\n\nexport const HEIGHT_CLASS: Record<WidgetHeight, string> = {\n small: 'h-[170px]',\n medium: 'h-[364px]',\n large: 'h-[752px]',\n};\n\n/** The same heights in px, for layout maths. Keep in step with `HEIGHT_CLASS`. */\nexport const HEIGHT_PX: Record<WidgetHeight, number> = {\n small: 170,\n medium: 364,\n large: 752,\n};\n\nexport interface WidgetGridProps {\n children: ReactNode;\n className?: string;\n}\n\n/** A vertical stack of `WidgetGridRow`s with the dashboard gutters. */\nexport function WidgetGrid({ children, className }: WidgetGridProps) {\n return <div className={cn('flex w-full flex-col gap-3 lg:gap-6', className)}>{children}</div>;\n}\n\nexport interface WidgetGridRowProps {\n children: ReactNode;\n className?: string;\n}\n\n/** A 12-column row. Place `WidgetGridItem`s in it. */\nexport function WidgetGridRow({ children, className }: WidgetGridRowProps) {\n return <div className={cn('grid grid-cols-12 items-start gap-3 lg:gap-6', className)}>{children}</div>;\n}\n\nexport interface WidgetGridItemProps extends HTMLAttributes<HTMLDivElement> {\n /** How many columns the widget claims. */\n size: ColSize;\n /** Fixes the card height to the canonical scale. Omit for content height. */\n height?: WidgetHeight;\n}\n\n/**\n * One widget's cell. Takes `size` and `height` as props, so a dashboard never composes span\n * classes itself. They are also set as `data-size` / `data-height`.\n */\nexport function WidgetGridItem({ size, height, className, ...rest }: WidgetGridItemProps) {\n return (\n <div\n data-size={size}\n data-height={height}\n className={cn(COL_SPAN[size], height && clsx(HEIGHT_CLASS[height], 'min-h-0'), className)}\n {...rest}\n />\n );\n}\n","import type { ColSize } from '../components/widgets/widget-grid';\n\n/**\n * Container-width tiers for grids that cannot use viewport breakpoints, because they share their\n * row with a nav rail or a docked drawer. Pure functions, ported from SCIC in 0.7.0. The hook that\n * measures and debounces is `useWidthTier`.\n */\nexport type GridTier = 'stacked' | 'narrow' | 'standard' | 'wide';\n\nexport const GRID_TIERS: readonly GridTier[] = ['stacked', 'narrow', 'standard', 'wide'];\n\n/** The narrowest width, in px, at which each tier applies. */\nexport const TIER_MIN_PX: Record<GridTier, number> = {\n stacked: 0,\n narrow: 560,\n standard: 760,\n wide: 960,\n};\n\n/**\n * How far past a threshold the width must go before the tier follows. A tier change reflows the\n * grid, which can add or remove the page scrollbar and so change the measured width: a margin\n * narrower than a scrollbar oscillates.\n */\nexport const TIER_HYSTERESIS_PX = 24;\n\n/** Widths are rounded down to this step, so sub-pixel jitter does not re-render. */\nexport const WIDTH_QUANTUM_PX = 8;\n\nexport function quantizeWidth(px: number): number {\n if (!Number.isFinite(px) || px <= 0) return 0;\n return Math.floor(px / WIDTH_QUANTUM_PX) * WIDTH_QUANTUM_PX;\n}\n\n/** The tier for a width, with no hysteresis. */\nexport function tierForWidth(px: number): GridTier {\n if (px >= TIER_MIN_PX.wide) return 'wide';\n if (px >= TIER_MIN_PX.standard) return 'standard';\n if (px >= TIER_MIN_PX.narrow) return 'narrow';\n return 'stacked';\n}\n\n/** The next tier from `current`, holding still inside the hysteresis band. */\nexport function nextTier(current: GridTier, px: number): GridTier {\n let tier = current;\n for (let i = 0; i < GRID_TIERS.length; i += 1) {\n const index = GRID_TIERS.indexOf(tier);\n const up = GRID_TIERS[index + 1];\n if (up && px >= TIER_MIN_PX[up] + TIER_HYSTERESIS_PX) {\n tier = up;\n continue;\n }\n if (index > 0 && px < TIER_MIN_PX[tier] - TIER_HYSTERESIS_PX) {\n tier = GRID_TIERS[index - 1];\n continue;\n }\n break;\n }\n return tier;\n}\n\n/** Columns (of 12) each widget width claims, per tier. */\nexport const TIER_COLS: Record<GridTier, Record<ColSize, number>> = {\n stacked: { tiny: 6, small: 12, medium: 12, large: 12, full: 12 },\n narrow: { tiny: 6, small: 6, medium: 12, large: 12, full: 12 },\n standard: { tiny: 3, small: 6, medium: 6, large: 12, full: 12 },\n wide: { tiny: 3, small: 4, medium: 6, large: 8, full: 12 },\n};\n\n/** `TIER_COLS` as literal classes (Tailwind only emits classes it finds verbatim). */\nexport const COL_SPAN_BY_TIER: Record<GridTier, Record<ColSize, string>> = {\n stacked: { tiny: 'col-span-6', small: 'col-span-12', medium: 'col-span-12', large: 'col-span-12', full: 'col-span-12' },\n narrow: { tiny: 'col-span-6', small: 'col-span-6', medium: 'col-span-12', large: 'col-span-12', full: 'col-span-12' },\n standard: { tiny: 'col-span-3', small: 'col-span-6', medium: 'col-span-6', large: 'col-span-12', full: 'col-span-12' },\n wide: { tiny: 'col-span-3', small: 'col-span-4', medium: 'col-span-6', large: 'col-span-8', full: 'col-span-12' },\n};\n\nexport function colsFor(tier: GridTier, size: ColSize): number {\n return TIER_COLS[tier][size];\n}\n\n/** The pixel width of a cell spanning `cols` of 12, given the grid width and column gap. */\nexport function slotWidthPx(gridWidthPx: number, columnGapPx: number, cols: number): number {\n return (cols * (gridWidthPx + columnGapPx)) / 12 - columnGapPx;\n}\n","import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { nextTier, quantizeWidth, type GridTier } from './width-tier';\n\nconst useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\n/** How long the width must hold still before a new tier commits, so an animating panel commits once. */\nexport const TIER_SETTLE_MS = 200;\n\nexport interface UseWidthTierOptions {\n /** Stop committing new widths, e.g. while a drawer animates. Unfreezing flushes the latest. */\n frozen?: boolean;\n}\n\nexport interface UseWidthTierResult {\n ref: (node: HTMLElement | null) => void;\n /** The quantised width, or `null` before the first measurement. */\n widthPx: number | null;\n tier: GridTier;\n}\n\n/**\n * Measures an element and reports its `GridTier`, debounced and with hysteresis. Ported from\n * SCIC in 0.7.0. Without `ResizeObserver` (jsdom, very old browsers) it measures once on mount\n * rather than throwing.\n */\nexport function useWidthTier({ frozen = false }: UseWidthTierOptions = {}): UseWidthTierResult {\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [{ widthPx, tier }, setMeasured] = useState<{ widthPx: number | null; tier: GridTier }>({\n widthPx: null,\n tier: 'wide',\n });\n\n // The latest observed width, read by a pending commit, so it always lands on the current\n // width rather than a stale one.\n const observed = useRef<number | null>(null);\n const frozenRef = useRef(frozen);\n frozenRef.current = frozen;\n const tierRef = useRef<GridTier>(tier);\n tierRef.current = tier;\n const widthRef = useRef<number | null>(widthPx);\n widthRef.current = widthPx;\n\n const commit = useCallback(() => {\n const raw = observed.current;\n // A hidden subtree measures 0: keep the last value rather than collapsing and snapping back.\n if (raw === null || raw <= 0 || frozenRef.current) return;\n const next = quantizeWidth(raw);\n const nextT = nextTier(tierRef.current, next);\n if (next === widthRef.current && nextT === tierRef.current) return;\n setMeasured({ widthPx: next, tier: nextT });\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n if (!node) return;\n let frame = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n // Read and commit synchronously: an observer's first callback lands after paint, and the\n // settle delay would hold it longer, so the grid would show frames at a guessed tier.\n observed.current = node.getBoundingClientRect().width;\n commit();\n\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) observed.current = entry.contentRect.width;\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n frame = 0;\n if (timer) clearTimeout(timer);\n timer = setTimeout(commit, TIER_SETTLE_MS);\n });\n });\n observer.observe(node);\n return () => {\n observer.disconnect();\n if (frame) cancelAnimationFrame(frame);\n if (timer) clearTimeout(timer);\n };\n }, [node, commit]);\n\n // Unfreezing flushes the width that changed while frozen: nothing else would pick it up.\n useEffect(() => {\n if (!frozen) commit();\n }, [frozen, commit]);\n\n return { ref: setNode, widthPx, tier };\n}\n","import clsx from 'clsx';\nimport type { ReactElement, ReactNode } from 'react';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { Slot } from '../../lib/slot';\nimport type { StatusTone } from '../status/status-badge';\n\nconst DOT_TONE: Record<StatusTone, string> = {\n neutral: 'bg-status-dot-neutral',\n info: 'bg-status-dot-info',\n warning: 'bg-status-dot-warning',\n caution: 'bg-status-dot-caution',\n accent: 'bg-status-dot-accent',\n positive: 'bg-status-dot-positive',\n danger: 'bg-status-dot-danger',\n};\n\nexport interface StatTileProps {\n label: string;\n value: string | number;\n /** Status tone for the leading dot. Prefer this over `dotColor`. */\n tone?: StatusTone;\n /**\n * @deprecated Pass `tone` instead. A raw colour here bypasses the token layer,\n * which is how competing status palettes drift apart.\n */\n dotColor?: string;\n /** A muted line under the value: a comparison, a unit, \"of 240\". New in 0.7.0, from SCIC. */\n hint?: ReactNode;\n /**\n * Makes the tile a toggle button, for a row of tiles that filter a list below. New in 0.7.0.\n * Pair with `selected`.\n */\n onClick?: () => void;\n /**\n * The tile's filter is the active one. Sets `aria-pressed` (with `onClick`) or `aria-current`\n * (with `asChild`), and `data-state=\"selected\"`, which the tile styles: no conditional border\n * classes needed.\n */\n selected?: boolean;\n /** Render onto the single child instead, e.g. a router `<Link>` to a filtered page. */\n asChild?: boolean;\n /** The element to render onto, with `asChild`. Its own children are replaced by the tile. */\n children?: ReactElement;\n className?: string;\n}\n\n/**\n * A labelled figure: \"Open cases 42\".\n *\n * From 0.7.0 a tile can also be the filter for the list beneath it, which is what Cleo's\n * Companies, Employees and Users screens hand-built with\n * `className={filter === t.f ? 'border-brand …' : ''}`. Give it `onClick` and `selected` and it\n * is a real toggle button (`aria-pressed`), styled from its own state.\n */\nexport function StatTile({\n label,\n value,\n tone,\n dotColor,\n hint,\n onClick,\n selected,\n asChild = false,\n children,\n className,\n}: StatTileProps) {\n const showDot = Boolean(tone || dotColor);\n const interactive = Boolean(onClick) || asChild;\n\n const content = (\n <>\n <span className=\"flex items-center gap-1.5\">\n {showDot && (\n <span\n aria-hidden\n className={clsx('size-2 shrink-0 rounded-full', tone && DOT_TONE[tone])}\n style={tone ? undefined : { backgroundColor: dotColor }}\n />\n )}\n <span className=\"text-body-xs font-medium text-default-secondary whitespace-nowrap\">\n {label}\n </span>\n </span>\n <span className=\"text-heading font-semibold text-default leading-none\">{value}</span>\n {hint && <span className=\"text-body-tiny text-default-secondary\">{hint}</span>}\n </>\n );\n\n const rootProps = {\n 'data-state': selected ? 'selected' : undefined,\n className: cn(\n 'flex flex-col gap-2 rounded-xl border border-default bg-default p-4 text-left',\n interactive && ['cursor-pointer transition-colors hover:border-default-secondary', FOCUS_RING],\n 'data-[state=selected]:border-brand data-[state=selected]:bg-brand-tertiary',\n className,\n ),\n };\n\n if (asChild) {\n return (\n // A link to a filtered view is the current one, not a pressed toggle: `aria-pressed` is\n // only valid on a button.\n <Slot {...rootProps} aria-current={selected ? 'true' : undefined} wrapChildren={() => content}>\n {children}\n </Slot>\n );\n }\n\n if (onClick) {\n return (\n <button type=\"button\" aria-pressed={selected ?? false} onClick={onClick} {...rootProps}>\n {content}\n </button>\n );\n }\n\n return <div {...rootProps}>{content}</div>;\n}\n","import clsx from 'clsx';\n\nexport type StatNumberSize = 'sm' | 'md' | 'lg';\n\nexport type StatNumberWeight = 'medium' | 'bold';\n\nexport interface StatNumberProps {\n value: string | number;\n unit?: string;\n size?: StatNumberSize;\n weight?: StatNumberWeight;\n /** @deprecated Bypasses the design tokens — pass `tone` instead. Raw hex color, overrides the default text color via inline style. Use when the exact source color doesn't match a design token. */\n color?: string;\n className?: string;\n}\n\n// 32 / 40 / 48px — the --typo-scale-07/08/09 steps. These read `text-scale-0*` until\n// 0.3.0, which the preset never defined, so every size emitted no font-size at all.\nconst sizeStyles: Record<StatNumberSize, string> = {\n sm: 'text-subtitle',\n md: 'text-subtitle-lg',\n lg: 'text-title',\n};\n\nconst weightStyles: Record<StatNumberWeight, string> = {\n medium: 'font-medium',\n bold: 'font-bold',\n};\n\nexport function StatNumber({ value, unit, size = 'md', weight = 'bold', color, className }: StatNumberProps) {\n return (\n <p\n className={clsx(sizeStyles[size], weightStyles[weight], 'leading-none', !color && 'text-default', className)}\n style={color ? { color } : undefined}\n >\n {value}\n {unit && (\n <span className=\"ml-1 text-subheading font-medium text-default-secondary\">{unit}</span>\n )}\n </p>\n );\n}\n","import clsx from 'clsx';\n\nexport type ScoreValueSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl';\nexport type ScoreValueWeight = 'normal' | 'semibold' | 'bold';\nexport type ScoreTone = 'brand' | 'positive' | 'warning' | 'danger' | 'neutral' | 'default';\nexport type ScoreValueTone = ScoreTone | 'auto';\n\n/**\n * The four tones the automatic ramp can produce.\n *\n * Narrower than `ScoreTone` on purpose: a ramp position is always one of these, so the\n * result is directly assignable to `ProgressBarTone` too — which is what lets a caller\n * tone a bar and its score from one `getScoreTone` call.\n */\nexport type ScoreRampTone = 'positive' | 'neutral' | 'warning' | 'danger';\n\n/** Which end of the scale is the bad end. */\nexport type ScoreDirection = 'higher-is-worse' | 'higher-is-better';\n\nexport interface ScoreThresholds {\n /** At or above this, the score is `danger`. */\n danger: number;\n /** At or above this, `warning`. */\n warning: number;\n /** At or above this, `neutral`. Below it, `positive`. */\n neutral: number;\n}\n\n/**\n * Default ramp, on a 0–100 scale read as \"higher is worse\" — the risk case.\n *\n * 0.2.0's ramp had only four stops and resolved 65–79 to `brand` (the blue brand\n * colour), which left `warning` and `positive` unreachable without passing `tone`\n * by hand. This is a real five-stop ramp.\n */\nexport const DEFAULT_SCORE_THRESHOLDS: ScoreThresholds = { danger: 80, warning: 65, neutral: 50 };\n\n/**\n * Resolve a numeric score to a tone.\n *\n * Was `getRiskTone` in 0.2.0, with the thresholds and the direction both hardcoded.\n */\nexport function getScoreTone(\n score: number,\n {\n direction = 'higher-is-worse',\n thresholds = DEFAULT_SCORE_THRESHOLDS,\n }: { direction?: ScoreDirection; thresholds?: ScoreThresholds } = {},\n): ScoreRampTone {\n // Flip the score, not the comparisons — one ramp, read from either end.\n const v = direction === 'higher-is-better' ? 100 - score : score;\n if (v >= thresholds.danger) return 'danger';\n if (v >= thresholds.warning) return 'warning';\n if (v >= thresholds.neutral) return 'neutral';\n return 'positive';\n}\n\n// 13 / 14 / 16 / 20 / 32px\nconst SIZE: Record<ScoreValueSize, string> = {\n sm: 'text-body-xs',\n md: 'text-body-sm',\n lg: 'text-subheading-sm',\n xl: 'text-subheading',\n '2xl': 'text-subtitle',\n};\n\nconst WEIGHT: Record<ScoreValueWeight, string> = {\n normal: 'font-normal',\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nconst TONE: Record<ScoreTone, string> = {\n brand: 'text-brand',\n positive: 'text-positive',\n warning: 'text-warning',\n danger: 'text-danger',\n neutral: 'text-default-secondary',\n default: 'text-default',\n};\n\nexport interface ScoreValueProps {\n value: string | number;\n /** Trailing caption — `/100`, `High`, `of target`. */\n label?: string;\n size?: ScoreValueSize;\n weight?: ScoreValueWeight;\n /** `auto` derives the tone from `value` via {@link getScoreTone}. */\n tone?: ScoreValueTone;\n direction?: ScoreDirection;\n thresholds?: ScoreThresholds;\n className?: string;\n}\n\n/**\n * A scored number with an optional caption and a tone that can track its value.\n *\n * Was `RiskScore`. Nothing about it was ever risk-specific except the name and the\n * direction of its ramp, so both are now parameters: use it for a risk score, a\n * compliance score, a match confidence, a utilisation percentage.\n *\n * Not to be confused with `StatNumber`, which is the *large display* number with a\n * unit (32–48px, for tiles and widget headlines). `ScoreValue` is the inline one with\n * a label and a tone ramp.\n */\nexport function ScoreValue({\n value,\n label,\n size = 'md',\n weight = 'bold',\n tone = 'auto',\n direction = 'higher-is-worse',\n thresholds = DEFAULT_SCORE_THRESHOLDS,\n className,\n}: ScoreValueProps) {\n // A numeric-looking string still resolves. In 0.2.0 `tone=\"auto\"` fell back to\n // `default` for any string, so callers passing `score=\"82\"` silently got no tone.\n const numeric = typeof value === 'number' ? value : Number(value);\n const resolved: ScoreTone =\n tone === 'auto'\n ? Number.isFinite(numeric)\n ? getScoreTone(numeric, { direction, thresholds })\n : 'default'\n : tone;\n\n return (\n <span data-tone={resolved} className={clsx('inline-flex items-baseline gap-1', className)}>\n <span className={clsx(SIZE[size], WEIGHT[weight], TONE[resolved])}>{value}</span>\n {label && <span className=\"text-body-xs text-default-secondary whitespace-nowrap\">{label}</span>}\n </span>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type TileGridColumns = 2 | 3 | 4 | 5 | 6;\n\n/**\n * Responsive column counts. Every source copy started two-up on mobile and stepped\n * to its full count at one breakpoint.\n *\n * The twelve source grids disagreed on which: seven used `lg:`, three used `md:`.\n * Standardising on `lg:` matches eight of them byte-for-byte and is the safer choice\n * — five tiles at `md` (768px) was cramped. `alerts`, `settings-users` and\n * `settings-organization` therefore stay two-up slightly longer on tablets than\n * before; that is the one deliberate layout change here.\n *\n * Six keeps its intermediate `sm:grid-cols-3` step, matching entities-listing —\n * without it, six tiles would stack 2×3 on tablet instead of 3×2.\n */\nexport type TileGridBreakpoint = 'sm' | 'md' | 'lg';\n\nconst COLUMNS: Record<TileGridBreakpoint, Record<TileGridColumns, string>> = {\n sm: {\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 sm:grid-cols-3',\n 4: 'grid-cols-2 sm:grid-cols-4',\n 5: 'grid-cols-2 sm:grid-cols-5',\n 6: 'grid-cols-2 sm:grid-cols-6',\n },\n md: {\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 md:grid-cols-3',\n 4: 'grid-cols-2 md:grid-cols-4',\n 5: 'grid-cols-2 md:grid-cols-5',\n 6: 'grid-cols-2 sm:grid-cols-3 md:grid-cols-6',\n },\n lg: {\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-2 lg:grid-cols-4',\n 5: 'grid-cols-2 lg:grid-cols-5',\n 6: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-6',\n },\n};\n\nexport interface TileGridProps {\n children: ReactNode;\n columns?: TileGridColumns;\n /**\n * Breakpoint at which the grid reaches its full column count. `lg` is the default\n * and correct for a full-width page. Narrow contexts — a stat row inside a panel,\n * as on the article detail page — legitimately need `sm`.\n */\n at?: TileGridBreakpoint;\n className?: string;\n}\n\n/**\n * A responsive grid of equal-width tiles.\n *\n * Was `StatTileGrid`, which read as a `StatTile`-specific component. It has never been\n * coupled to one: no context, no cloning, no constraint on `children`. It takes any\n * nodes — `StatTile`s, `Card`s, chart tiles — and only owns the column counts and the\n * `gap-3`. The rename says so.\n */\nexport function TileGrid({\n children,\n columns = 4,\n at = 'lg',\n className,\n}: TileGridProps) {\n return <div className={clsx('grid gap-3', COLUMNS[at][columns], className)}>{children}</div>;\n}\n","/**\n * Chart colour.\n *\n * SVG paints via the `stroke` / `fill` *attributes*, which cannot take a Tailwind\n * class — so charts resolve a `tone` to a CSS variable reference instead of a utility.\n * That keeps them on the token layer; 0.2.0's charts defaulted to raw hex (`#0c2d58`,\n * `rgba(140,155,176,0.5)`) and drifted from it.\n *\n * Every chart still accepts an explicit `color` string for genuinely data-driven\n * colour — a series whose colour comes from the data, not from semantics.\n */\nexport type ChartTone = 'brand' | 'info' | 'positive' | 'warning' | 'danger' | 'neutral';\n\nexport const CHART_TONE: Record<ChartTone, string> = {\n brand: 'var(--color-background-brand-default)',\n info: 'var(--status-info-dot)',\n positive: 'var(--color-background-positive-default)',\n warning: 'var(--color-background-warning-default)',\n danger: 'var(--color-background-danger-default)',\n neutral: 'var(--color-background-neutral-default)',\n};\n\n/** The muted track/rest colour behind a highlighted series. */\nexport const CHART_TRACK = 'var(--color-background-default-tertiary)';\n\n/**\n * Ordered sequence for multi-series charts, so two donuts in the same product never\n * assign different colours to the same first category. Semantic tones come first\n * because a chart with two or three series is usually still saying something.\n */\nexport const CHART_SEQUENCE: ChartTone[] = ['brand', 'info', 'positive', 'warning', 'danger', 'neutral'];\n\n/** Resolve an explicit colour, else a tone, else the sequence position. */\nexport function resolveChartColor(color: string | undefined, tone: ChartTone | undefined, index = 0): string {\n if (color) return color;\n if (tone) return CHART_TONE[tone];\n return CHART_TONE[CHART_SEQUENCE[index % CHART_SEQUENCE.length]];\n}\n","import clsx from 'clsx';\nimport { resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type BarChartOrientation = 'vertical' | 'horizontal';\nexport type BarChartSize = 'sm' | 'md' | 'lg';\n\n/** Thickness of one bar / one group slot, and the label type step. */\nconst SIZE: Record<BarChartSize, { band: number; gap: number; label: string }> = {\n sm: { band: 14, gap: 6, label: 'text-body-tiny' },\n md: { band: 20, gap: 8, label: 'text-body-xs' },\n lg: { band: 28, gap: 10, label: 'text-body-xs' },\n};\n\nexport interface BarChartSeries {\n label: string;\n /** One value per category. */\n values: number[];\n tone?: ChartTone;\n color?: string;\n}\n\nexport interface BarChartProps {\n /** Category names — the axis labels. */\n categories: string[];\n series: BarChartSeries[];\n orientation?: BarChartOrientation;\n /** Stack series on top of each other instead of placing them side by side. */\n stacked?: boolean;\n size?: BarChartSize;\n /** Overall length of the value axis, in px. */\n length?: number;\n /** Show the category labels along the axis. */\n showLabels?: boolean;\n /** Print each bar's value at the end of the bar. Horizontal orientation only. */\n showValues?: boolean;\n radius?: number;\n label?: string;\n className?: string;\n}\n\n/**\n * Grouped or stacked bars, in either orientation.\n *\n * Horizontal is the orientation the library was missing and the one that actually suits\n * category data, because long category names get a full line of width rather than being\n * rotated or truncated under a vertical bar.\n *\n * Deliberately axis-light: one baseline, no gridlines, no ticks. For anything needing\n * real axes or interaction, this is the wrong component.\n */\nexport function BarChart({\n categories,\n series,\n orientation = 'horizontal',\n stacked = false,\n size = 'md',\n length = 240,\n showLabels = true,\n showValues = false,\n radius = 3,\n label,\n className,\n}: BarChartProps) {\n const { band, gap, label: labelClass } = SIZE[size];\n if (categories.length === 0 || series.length === 0) return null;\n\n // Stacked bars share one band per category; grouped bars split it between series.\n const perCategory = stacked ? band : band * series.length + gap * (series.length - 1);\n\n const categoryTotals = categories.map((_, ci) =>\n stacked\n ? series.reduce((sum, s) => sum + Math.max(0, s.values[ci] ?? 0), 0)\n : Math.max(...series.map((s) => Math.max(0, s.values[ci] ?? 0))),\n );\n const max = Math.max(...categoryTotals, 1);\n\n const horizontal = orientation === 'horizontal';\n\n return (\n <div\n className={clsx('flex w-full min-w-0', horizontal ? 'flex-col gap-2' : 'flex-row items-end gap-3', className)}\n role={label ? 'img' : undefined}\n aria-label={label}\n // Without a label the chart is decoration and its bars are noise in the a11y tree.\n // Every other chart in the family had this fallback; BarChart was the one that did\n // not, so an unlabelled one announced each bar's markup.\n aria-hidden={label ? undefined : true}\n >\n {categories.map((category, ci) => {\n const bars = series.map((s, si) => ({\n key: s.label,\n value: Math.max(0, s.values[ci] ?? 0),\n color: resolveChartColor(s.color, s.tone, si),\n }));\n\n return (\n <div\n key={category}\n className={clsx('flex min-w-0', horizontal ? 'flex-col gap-1' : 'h-full flex-col justify-end gap-1.5')}\n style={horizontal ? undefined : { width: perCategory }}\n >\n {showLabels && horizontal && (\n <span className={clsx('truncate text-default-secondary', labelClass)}>{category}</span>\n )}\n\n <div\n className={clsx('flex', horizontal ? 'items-center gap-2' : 'w-full flex-1 items-end justify-center')}\n style={horizontal ? undefined : { height: length }}\n >\n <div\n className={clsx('flex min-w-0', stacked ? 'gap-0' : '')}\n style={\n horizontal\n ? { width: length, flexDirection: stacked ? 'row' : 'column', gap: stacked ? 0 : gap }\n : {\n height: '100%',\n width: perCategory,\n flexDirection: stacked ? 'column-reverse' : 'row',\n alignItems: 'flex-end',\n gap: stacked ? 0 : gap,\n }\n }\n >\n {bars.map((bar) => {\n const extent = `${(bar.value / max) * 100}%`;\n return (\n <div\n key={bar.key}\n title={`${category} · ${bar.key}: ${bar.value}`}\n className=\"transition-all\"\n style={{\n backgroundColor: bar.color,\n borderRadius: radius,\n ...(horizontal\n ? { width: extent, height: stacked ? band : band }\n : { height: extent, width: stacked ? perCategory : band }),\n }}\n />\n );\n })}\n </div>\n {showValues && horizontal && (\n <span className={clsx('shrink-0 tabular-nums text-default-secondary', labelClass)}>\n {categoryTotals[ci]}\n </span>\n )}\n </div>\n\n {showLabels && !horizontal && (\n <span className={clsx('truncate text-center text-default-secondary', labelClass)}>{category}</span>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { CHART_TRACK, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type DonutChartSize = 'sm' | 'md' | 'lg';\n\n/** Diameter and default ring thickness, in px. */\nconst SIZE: Record<DonutChartSize, { box: number; thickness: number }> = {\n sm: { box: 88, thickness: 10 },\n md: { box: 128, thickness: 14 },\n lg: { box: 180, thickness: 20 },\n};\n\nexport interface DonutSegment {\n label: string;\n value: number;\n /** Token-backed colour. Falls back to the segment's position in the chart sequence. */\n tone?: ChartTone;\n /** Explicit colour, for data-driven series. */\n color?: string;\n}\n\nexport interface DonutChartProps {\n segments: DonutSegment[];\n size?: DonutChartSize;\n /** Ring thickness in px. Overrides the `size` preset. */\n thickness?: number;\n /** Large text at the centre — a total, a percentage. */\n centerValue?: ReactNode;\n /** Caption beneath `centerValue`. */\n centerLabel?: ReactNode;\n /** Gap between segments, in degrees. */\n gap?: number;\n /** Accessible description. */\n label?: string;\n className?: string;\n}\n\n/**\n * A proportional ring.\n *\n * Drawn with `stroke-dasharray` on circles rather than arc paths: one element per\n * segment, no trigonometry, and the segments stay crisp at any thickness.\n */\nexport function DonutChart({\n segments,\n size = 'md',\n thickness,\n centerValue,\n centerLabel,\n gap = 2,\n label,\n className,\n}: DonutChartProps) {\n const { box, thickness: presetThickness } = SIZE[size];\n const ring = thickness ?? presetThickness;\n const radius = (box - ring) / 2;\n const circumference = 2 * Math.PI * radius;\n const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0);\n\n // A gap is only meaningful between two or more visible segments.\n const visible = segments.filter((s) => s.value > 0);\n const gapLength = visible.length > 1 ? (gap / 360) * circumference : 0;\n\n let offset = 0;\n\n return (\n <div className={clsx('relative inline-flex shrink-0 items-center justify-center', className)}>\n <svg\n width={box}\n height={box}\n viewBox={`0 0 ${box} ${box}`}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n // -90° so the first segment starts at twelve o'clock rather than three.\n className=\"block -rotate-90\"\n >\n <circle cx={box / 2} cy={box / 2} r={radius} fill=\"none\" stroke={CHART_TRACK} strokeWidth={ring} />\n {total > 0 &&\n segments.map((segment, i) => {\n const fraction = Math.max(0, segment.value) / total;\n const length = Math.max(0, fraction * circumference - gapLength);\n const dash = `${length} ${circumference - length}`;\n const thisOffset = offset;\n offset += fraction * circumference;\n if (segment.value <= 0) return null;\n return (\n <circle\n key={segment.label}\n cx={box / 2}\n cy={box / 2}\n r={radius}\n fill=\"none\"\n stroke={resolveChartColor(segment.color, segment.tone, i)}\n strokeWidth={ring}\n strokeDasharray={dash}\n strokeDashoffset={-thisOffset}\n strokeLinecap=\"butt\"\n />\n );\n })}\n </svg>\n {(centerValue != null || centerLabel != null) && (\n <div className=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n {centerValue != null && (\n <span className=\"text-subheading-sm font-bold leading-none text-default\">{centerValue}</span>\n )}\n {centerLabel != null && (\n <span className=\"mt-0.5 text-body-tiny text-default-secondary\">{centerLabel}</span>\n )}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { CHART_TRACK, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type RadialGaugeSize = 'sm' | 'md' | 'lg';\n\nconst SIZE: Record<RadialGaugeSize, { box: number; thickness: number; value: string }> = {\n sm: { box: 72, thickness: 8, value: 'text-body-sm' },\n md: { box: 104, thickness: 11, value: 'text-subheading-sm' },\n lg: { box: 148, thickness: 15, value: 'text-subheading' },\n};\n\nexport interface RadialGaugeProps {\n value: number;\n /** Top of the scale. */\n max?: number;\n size?: RadialGaugeSize;\n tone?: ChartTone;\n color?: string;\n /** Ring thickness in px. Overrides the `size` preset. */\n thickness?: number;\n /**\n * Sweep in degrees. 360 is a full ring; 270 leaves a gap at the bottom, which reads\n * more like a dial than a pie.\n */\n sweep?: number;\n /** Centre content. Defaults to the value; pass `null` for an empty ring. */\n children?: ReactNode;\n /** Caption beneath the centre value. */\n centerLabel?: ReactNode;\n label?: string;\n className?: string;\n}\n\n/**\n * A single-value arc — a score ring, a utilisation dial, a completion meter.\n *\n * The shape the library had no form for: `ProgressBar` covers linear progress and\n * `DonutChart` compares parts of a whole, but neither draws \"one number against its\n * ceiling\" in a round frame.\n */\nexport function RadialGauge({\n value,\n max = 100,\n size = 'md',\n tone = 'brand',\n color,\n thickness,\n sweep = 270,\n children,\n centerLabel,\n label,\n className,\n}: RadialGaugeProps) {\n const preset = SIZE[size];\n const box = preset.box;\n const ring = thickness ?? preset.thickness;\n const radius = (box - ring) / 2;\n const circumference = 2 * Math.PI * radius;\n\n const clampedSweep = Math.min(360, Math.max(1, sweep));\n const arc = (clampedSweep / 360) * circumference;\n const fraction = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;\n const stroke = resolveChartColor(color, tone);\n\n // Rotate so the arc is centred on twelve o'clock: -90° puts the start at the top,\n // then half the unswept remainder brings it back round.\n const rotation = -90 + (360 - clampedSweep) / 2;\n\n return (\n <div className={clsx('relative inline-flex shrink-0 items-center justify-center', className)}>\n <svg\n width={box}\n height={box}\n viewBox={`0 0 ${box} ${box}`}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className=\"block\"\n style={{ transform: `rotate(${rotation}deg)` }}\n >\n <circle\n cx={box / 2}\n cy={box / 2}\n r={radius}\n fill=\"none\"\n stroke={CHART_TRACK}\n strokeWidth={ring}\n strokeDasharray={`${arc} ${circumference - arc}`}\n strokeLinecap=\"round\"\n />\n <circle\n cx={box / 2}\n cy={box / 2}\n r={radius}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={ring}\n strokeDasharray={`${arc * fraction} ${circumference - arc * fraction}`}\n strokeLinecap=\"round\"\n className=\"transition-all\"\n />\n </svg>\n <div className=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n {children === undefined ? (\n <span className={clsx('font-bold leading-none text-default', preset.value)}>{value}</span>\n ) : (\n children\n )}\n {centerLabel != null && (\n <span className=\"mt-0.5 text-body-tiny text-default-secondary\">{centerLabel}</span>\n )}\n </div>\n </div>\n );\n}\n","import { useId } from 'react';\nimport clsx from 'clsx';\nimport { CHART_TONE, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type SparklineVariant = 'line' | 'area';\nexport type SparklineSize = 'sm' | 'md' | 'lg';\n\n/** Size presets, so callers stop passing bare pixel pairs. */\nconst SIZE: Record<SparklineSize, { width: number; height: number }> = {\n sm: { width: 80, height: 24 },\n md: { width: 120, height: 36 },\n lg: { width: 200, height: 56 },\n};\n\nexport interface SparklineProps {\n data: number[];\n variant?: SparklineVariant;\n /** Token-backed colour. Ignored when `color` is set. */\n tone?: ChartTone;\n /** Explicit colour, for series whose colour comes from the data. */\n color?: string;\n size?: SparklineSize;\n /** Overrides the `size` preset. */\n width?: number;\n height?: number;\n strokeWidth?: number;\n /** Dot on the final point — useful when the line is the \"current value\". */\n showEndDot?: boolean;\n /**\n * Stretch to fill the container instead of drawing at a fixed pixel size.\n *\n * The `size` preset still sets the viewBox, so it decides the sampling density; the SVG then\n * scales to the box it is given. Stroke width is held constant with `non-scaling-stroke`,\n * without which a non-uniform stretch would thin the line on one axis and thicken it on the\n * other.\n */\n fill?: boolean;\n /** Accessible description. Omit to keep the chart decorative. */\n label?: string;\n className?: string;\n}\n\n/**\n * A compact trend line, with no axes and no interaction.\n *\n * `variant=\"area\"` adds the gradient fill beneath the line that 0.2.0 had no way to\n * draw, which is what makes a sparkline readable at `lg` where a bare 1.5px stroke\n * looks thin.\n */\nexport function Sparkline({\n data,\n variant = 'line',\n tone = 'brand',\n color,\n size = 'md',\n width,\n height,\n strokeWidth = 1.5,\n showEndDot = false,\n fill: stretch = false,\n label,\n className,\n}: SparklineProps) {\n const gradientId = useId();\n if (data.length < 2) return null;\n\n const w = width ?? SIZE[size].width;\n const h = height ?? SIZE[size].height;\n const stroke = resolveChartColor(color, tone);\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n const pad = strokeWidth;\n const innerH = h - pad * 2;\n const innerW = w - pad * 2;\n\n const coords = data.map((v, i) => ({\n x: pad + (i / (data.length - 1)) * innerW,\n y: pad + innerH - ((v - min) / range) * innerH,\n }));\n const points = coords.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(' ');\n // Close the path down to the baseline so the fill has something to fill.\n const areaPath = `M ${points.split(' ').join(' L ')} L ${coords[coords.length - 1].x.toFixed(2)},${h} L ${coords[0].x.toFixed(2)},${h} Z`;\n const last = coords[coords.length - 1];\n\n return (\n <svg\n width={stretch ? undefined : w}\n height={stretch ? undefined : h}\n viewBox={`0 0 ${w} ${h}`}\n preserveAspectRatio={stretch ? 'none' : undefined}\n fill=\"none\"\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={clsx('block', stretch ? 'h-full w-full' : 'shrink-0', className)}\n >\n {variant === 'area' && (\n <>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={stroke} stopOpacity={0.24} />\n <stop offset=\"100%\" stopColor={stroke} stopOpacity={0} />\n </linearGradient>\n </defs>\n <path d={areaPath} fill={`url(#${gradientId})`} />\n </>\n )}\n <polyline\n points={points}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n // Holds the line at `strokeWidth` under a non-uniform stretch. Harmless when not\n // stretching, since the scale is 1:1 there.\n vectorEffect={stretch ? 'non-scaling-stroke' : undefined}\n fill=\"none\"\n />\n {showEndDot && (\n <circle\n cx={last.x}\n cy={last.y}\n // A stretched circle would become an ellipse, so the dot is drawn in viewBox units\n // and sized from the smaller axis to stay visually round enough at either extreme.\n r={strokeWidth * 1.6}\n fill={stroke}\n stroke={CHART_TONE.neutral}\n strokeWidth={0}\n />\n )}\n </svg>\n );\n}\n","import clsx from 'clsx';\nimport { CHART_TRACK, resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type MiniBarChartSize = 'sm' | 'md' | 'lg';\nexport type MiniBarChartOrientation = 'vertical' | 'horizontal';\n\nconst SIZE: Record<MiniBarChartSize, { width: number; height: number; gap: number }> = {\n sm: { width: 80, height: 32, gap: 2 },\n md: { width: 120, height: 48, gap: 3 },\n lg: { width: 200, height: 72, gap: 4 },\n};\n\nexport interface MiniBarChartProps {\n bars: number[];\n /** Colour of the highlighted bars. */\n tone?: ChartTone;\n color?: string;\n /** Colour of the un-highlighted bars. Defaults to the muted track token. */\n restColor?: string;\n /**\n * Which bars are highlighted. A number or list of indices; negatives count from the\n * end, so `-1` is the last bar. Pass `[]` to highlight none.\n *\n * Replaces 0.2.0's `highlightLastBar` boolean, which could only ever mean `-1`.\n */\n highlight?: number | number[];\n size?: MiniBarChartSize;\n /** Overrides the `size` preset. */\n width?: number;\n height?: number;\n gap?: number;\n orientation?: MiniBarChartOrientation;\n radius?: number;\n /**\n * Stretch to fill the container instead of drawing at a fixed pixel size.\n *\n * The `size` preset still sets the viewBox, so it decides the bar-to-gap proportions; the\n * SVG then scales to whatever box it is given. Without this a widget body could only hold a\n * chart at a hardcoded width, which stops being the right width as soon as the widget\n * reflows.\n */\n fill?: boolean;\n label?: string;\n className?: string;\n}\n\n/** A compact bar series with no axes — a distribution or a per-period count. */\nexport function MiniBarChart({\n bars,\n tone = 'brand',\n color,\n restColor = CHART_TRACK,\n highlight = -1,\n size = 'md',\n width,\n height,\n gap,\n orientation = 'vertical',\n radius = 2,\n fill: stretch = false,\n label,\n className,\n}: MiniBarChartProps) {\n if (bars.length === 0) return null;\n\n const preset = SIZE[size];\n const w = width ?? preset.width;\n const h = height ?? preset.height;\n const g = gap ?? preset.gap;\n const fill = resolveChartColor(color, tone);\n\n const highlighted = new Set(\n (Array.isArray(highlight) ? highlight : [highlight]).map((i) => (i < 0 ? bars.length + i : i)),\n );\n\n const max = Math.max(...bars) || 1;\n const vertical = orientation === 'vertical';\n // The cross-axis is divided between bars; the value axis carries the magnitude.\n const span = vertical ? w : h;\n const extent = vertical ? h : w;\n const barThickness = (span - g * (bars.length - 1)) / bars.length;\n\n return (\n <svg\n width={stretch ? undefined : w}\n height={stretch ? undefined : h}\n viewBox={`0 0 ${w} ${h}`}\n // `none` so the bars fill the box on both axes rather than letterboxing inside it —\n // there is no geometry here whose aspect ratio has to be preserved, only rectangles.\n preserveAspectRatio={stretch ? 'none' : undefined}\n fill=\"none\"\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={clsx('block', stretch ? 'h-full w-full' : 'shrink-0', className)}\n >\n {bars.map((v, i) => {\n const magnitude = Math.max(2, (v / max) * extent);\n const offset = i * (barThickness + g);\n return (\n <rect\n key={i}\n x={(vertical ? offset : 0).toFixed(2)}\n // Vertical bars grow up from the baseline; horizontal ones out from the left.\n y={(vertical ? extent - magnitude : offset).toFixed(2)}\n width={(vertical ? barThickness : magnitude).toFixed(2)}\n height={(vertical ? magnitude : barThickness).toFixed(2)}\n fill={highlighted.has(i) ? fill : restColor}\n rx={radius}\n />\n );\n })}\n </svg>\n );\n}\n","import clsx from 'clsx';\nimport { LegendDot, type LegendDotShape, type LegendDotSize } from './legend-dot';\nimport { resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type ChartLegendOrientation = 'vertical' | 'horizontal';\n\nexport interface ChartLegendItem {\n label: string;\n /** Trailing value. Omit for a legend that only names the series. */\n count?: number | string;\n /** Token-backed colour. Falls back to the item's position in the chart sequence. */\n tone?: ChartTone;\n /** Explicit colour, for data-driven series. */\n color?: string;\n}\n\nexport interface ChartLegendProps {\n items: ChartLegendItem[];\n /**\n * `vertical` spreads each row to fill its container, so the counts align in a column\n * beside a donut. `horizontal` wraps inline, for a legend under a bar chart.\n */\n orientation?: ChartLegendOrientation;\n size?: LegendDotSize;\n shape?: LegendDotShape;\n className?: string;\n}\n\n/** Series names, swatches and optional values. */\nexport function ChartLegend({\n items,\n orientation = 'vertical',\n size = 'md',\n shape = 'dot',\n className,\n}: ChartLegendProps) {\n const horizontal = orientation === 'horizontal';\n\n return (\n <div\n className={clsx(\n horizontal ? 'flex flex-wrap items-center gap-x-4 gap-y-2' : 'flex flex-col gap-3',\n className,\n )}\n >\n {items.map((item, i) => (\n <div\n key={item.label}\n className={clsx('flex items-center gap-2', horizontal ? 'min-w-0' : 'justify-between')}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n {/* Resolved here, not in LegendDot, so the sequence fallback can use the\n item's position — matching how DonutChart colours its segments. */}\n <LegendDot color={resolveChartColor(item.color, item.tone, i)} size={size} shape={shape} />\n <span className=\"truncate text-body-xs text-default-secondary\">{item.label}</span>\n </div>\n {item.count != null && (\n <span className=\"shrink-0 text-body-xs font-semibold tabular-nums text-default\">{item.count}</span>\n )}\n </div>\n ))}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { resolveChartColor, type ChartTone } from './chart-tone';\n\nexport type LegendDotSize = 'sm' | 'md';\n/** `line` is the swatch for a line series; `dot` and `square` for areas and bars. */\nexport type LegendDotShape = 'dot' | 'square' | 'line';\n\nconst SHAPE: Record<LegendDotShape, Record<LegendDotSize, string>> = {\n dot: { sm: 'size-1.5 rounded-full', md: 'size-2 rounded-full' },\n square: { sm: 'size-1.5 rounded-[2px]', md: 'size-2 rounded-[3px]' },\n line: { sm: 'h-0.5 w-3 rounded-full', md: 'h-0.5 w-4 rounded-full' },\n};\n\nexport interface LegendDotProps {\n /** Token-backed colour. Ignored when `color` is set. */\n tone?: ChartTone;\n /** Explicit colour, for data-driven series. */\n color?: string;\n size?: LegendDotSize;\n shape?: LegendDotShape;\n className?: string;\n}\n\n/** The colour swatch beside a series name. */\nexport function LegendDot({ tone, color, size = 'md', shape = 'dot', className }: LegendDotProps) {\n return (\n <span\n className={clsx('inline-block shrink-0', SHAPE[shape][size], className)}\n style={{ backgroundColor: resolveChartColor(color, tone) }}\n aria-hidden\n />\n );\n}\n","import clsx from 'clsx';\nimport { TrendingDownIcon, TrendingUpIcon } from 'lucide-react';\n\nexport type TrendLabelWeight = 'semibold' | 'bold';\nexport type TrendLabelSize = 'sm' | 'md' | 'lg';\n/**\n * Which direction is the good one.\n *\n * A delta component cannot infer this: +4% on-time delivery is good, +4% unit cost is\n * not. 0.2.0 had no such prop, so the only way to render a \"rising is bad\" delta was to\n * pass a raw hex — which is exactly what the deleted `BenchmarkCard` did, inverting its\n * own `positiveColor` default to red to compensate.\n */\nexport type TrendDirection = 'up-is-good' | 'up-is-bad';\n\nconst SIZE: Record<TrendLabelSize, string> = {\n sm: 'text-body-xs',\n md: 'text-body-sm',\n lg: 'text-subheading-sm',\n};\n\nconst ICON_SIZE: Record<TrendLabelSize, string> = {\n sm: 'size-3',\n md: 'size-3.5',\n lg: 'size-4',\n};\n\nconst weightBySize: Record<TrendLabelSize, TrendLabelWeight> = {\n sm: 'semibold',\n md: 'semibold',\n lg: 'bold',\n};\n\nconst WEIGHT: Record<TrendLabelWeight, string> = {\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nexport interface TrendLabelProps {\n value: number;\n suffix?: string;\n size?: TrendLabelSize;\n weight?: TrendLabelWeight;\n direction?: TrendDirection;\n /** Trend arrow. On by default — the docs described one long before there was one. */\n showArrow?: boolean;\n /** Explicit colour, for the rare data-driven case. Overrides the direction logic. */\n color?: string;\n className?: string;\n}\n\n/** A signed delta with a direction arrow, toned by whether the movement is good news. */\nexport function TrendLabel({\n value,\n suffix = '%',\n size = 'md',\n weight,\n direction = 'up-is-good',\n showArrow = true,\n color,\n className,\n}: TrendLabelProps) {\n const rising = value > 0;\n // Zero is neither good nor bad. 0.2.0 rendered it as a green \"+0%\".\n const flat = value === 0;\n const good = direction === 'up-is-good' ? rising : !rising;\n const Arrow = rising ? TrendingUpIcon : TrendingDownIcon;\n\n return (\n <span\n className={clsx(\n 'inline-flex items-center gap-1 whitespace-nowrap',\n SIZE[size],\n WEIGHT[weight ?? weightBySize[size]],\n !color && (flat ? 'text-default-secondary' : good ? 'text-positive' : 'text-danger'),\n className,\n )}\n style={color ? { color } : undefined}\n >\n {showArrow && !flat && <Arrow className={clsx('shrink-0', ICON_SIZE[size])} aria-hidden />}\n {rising ? '+' : ''}\n {value}\n {suffix}\n </span>\n );\n}\n","import clsx from 'clsx';\nimport type { MouseEvent, ReactElement, ReactNode } from 'react';\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { Slot } from '../../lib/slot';\n\nexport type ListRowDensity = 'default' | 'compact';\nexport type ListRowDivider = 'none' | 'top' | 'bottom';\n\nconst DENSITY: Record<ListRowDensity, { pad: string; gap: string; title: string; description: string }> = {\n default: {\n pad: 'py-4',\n gap: 'gap-3',\n title: 'text-body-sm font-semibold text-default',\n description: 'text-body-xs text-default-secondary',\n },\n compact: {\n pad: 'py-2.5',\n gap: 'gap-2',\n title: 'text-body-xs font-semibold text-default',\n description: 'text-body-tiny text-default-secondary',\n },\n};\n\nconst DIVIDER: Record<ListRowDivider, string> = {\n none: '',\n top: 'border-t border-default',\n bottom: 'border-b border-default',\n};\n\nexport interface ListRowProps {\n /** Left of the title, on the title line — an icon badge, avatar, checkbox, file chip. */\n leading?: ReactNode;\n title?: ReactNode;\n /** Inline after the title — a Required/Optional chip, a count, a tag. */\n titleMeta?: ReactNode;\n /** Muted line under the title. */\n description?: ReactNode;\n /** Right end of the title line — a `StatusBadge`, a score, a timestamp. */\n meta?: ReactNode;\n /** Right-hand column spanning the whole row, vertically centred — actions, a `Toggle`. */\n trailing?: ReactNode;\n /** Full-width block below the title line — a `FileRow`, a `FileDropZone`, an alert, a nested list. */\n footer?: ReactNode;\n density?: ListRowDensity;\n divider?: ListRowDivider;\n /** Render an `<li>` instead of a `<div>` — use inside a `<ul>`/`<ol>`. */\n as?: 'div' | 'li';\n onClick?: () => void;\n /**\n * Render onto the single child instead, e.g. a router `<Link>` for a row that navigates.\n * The child is the interactive element and the slots render inside it. New in 0.7.0.\n *\n * <ListRow asChild title=\"Acme\" description=\"Supplier\"><Link to=\"/acme\" /></ListRow>\n */\n asChild?: boolean;\n /** The element to render onto, with `asChild`. Its own children are replaced by the slots. */\n children?: ReactElement;\n /**\n * The row is chosen, in a set where rows toggle on and off (a picker, a multi-select list).\n * Sets `aria-pressed` on a clickable row and `data-state=\"selected\"`, which the row styles.\n * New in 0.7.0; it replaces conditional `bg-brand-tertiary` classes at the call site.\n */\n selected?: boolean;\n /**\n * The row is the current one in a navigation-like list (the open section, this page). Sets\n * `aria-current` and is styled like `selected`. New in 0.7.0.\n */\n current?: boolean | 'page' | 'step' | 'location';\n /** A clickable row that cannot be activated right now. Sets `aria-disabled`. New in 0.7.0. */\n disabled?: boolean;\n /**\n * Accessible name for a clickable row. Strongly recommended whenever `onClick` is set:\n * without it the name is the concatenation of every slot's text.\n */\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * The generic list row: six slots and no opinion about what goes in them.\n *\n * Replaces `DocumentRow` and `DocumentChecklistRow`, which baked one product's\n * document-upload flow — its status vocabulary, its five raw-hex pills and its\n * unicode-glyph labels — into the library. Every feature of those rows is reachable by\n * composing this with `FileRow`, `FileDropZone` and `StatusBadge`; see the docs.\n *\n * State is a prop, not a class: `selected`, `current` and `disabled` set the attributes that\n * announce them (`aria-pressed`, `aria-current`, `aria-disabled`, `data-state`) and the row\n * styles itself from those.\n */\nexport function ListRow({\n leading,\n title,\n titleMeta,\n description,\n meta,\n trailing,\n footer,\n density = 'default',\n divider = 'none',\n as: Tag = 'div',\n onClick,\n asChild = false,\n children,\n selected,\n current,\n disabled = false,\n 'aria-label': ariaLabel,\n className,\n}: ListRowProps) {\n const d = DENSITY[density];\n const hasTitleLine = Boolean(leading || title != null || titleMeta || meta);\n const clickable = Boolean(onClick) && !asChild;\n const interactive = clickable || asChild;\n\n const activate = () => {\n if (!disabled) onClick?.();\n };\n\n const rootProps = {\n 'data-state': selected ? 'selected' : undefined,\n 'aria-current': current === true ? ('true' as const) : current || undefined,\n className: cn(\n 'flex w-full items-start',\n d.pad,\n DIVIDER[divider],\n interactive && ['cursor-pointer rounded-lg transition-colors hover:bg-default-secondary/50', FOCUS_RING],\n // State styled from the attributes that announce it.\n 'data-[state=selected]:bg-brand-tertiary aria-[current]:bg-brand-tertiary',\n disabled && 'cursor-not-allowed opacity-60 hover:bg-transparent',\n className,\n ),\n };\n\n const body = (\n <>\n <div className={clsx('flex min-w-0 flex-1 flex-col', d.gap)}>\n {hasTitleLine && (\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n {leading}\n {title != null && <span className={clsx('truncate', d.title)}>{title}</span>}\n {titleMeta && <span className=\"shrink-0\">{titleMeta}</span>}\n </div>\n {meta && <span className=\"shrink-0\">{meta}</span>}\n </div>\n )}\n {description && <p className={d.description}>{description}</p>}\n {/* Both slots stop click and key propagation when the row itself is clickable.\n The JSDoc on `trailing` and `footer` advertises putting a `Toggle` or a\n `Button` in them, and through 0.3.0 activating that control fired the nested\n handler *and* the row's `onClick` — so toggling a switch also navigated. */}\n {footer && (\n // These two wrappers are propagation barriers, not controls — they add no\n // behaviour of their own and must not be focusable or take a role.\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div onClick={stopIfInteractive} onKeyDown={stopIfInteractive}>\n {footer}\n </div>\n )}\n </div>\n {trailing && (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n className=\"ml-3 flex shrink-0 items-center self-center\"\n onClick={stopIfInteractive}\n onKeyDown={stopIfInteractive}\n >\n {trailing}\n </div>\n )}\n </>\n );\n\n if (asChild) {\n return (\n <Slot\n {...rootProps}\n aria-disabled={disabled || undefined}\n aria-label={ariaLabel}\n // A disabled link must refuse the press, as Button's does: preventing it also stops a\n // router `<Link>`, and leaving the tab order matches a disabled `<button>`.\n tabIndex={disabled ? -1 : undefined}\n onClick={disabled ? refusePress : undefined}\n wrapChildren={() => body}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <Tag\n {...rootProps}\n onClick={clickable ? activate : undefined}\n // Unlike a <tr>, a div/li has no conflicting implicit role, so button is correct here.\n role={clickable ? 'button' : undefined}\n aria-pressed={clickable && selected !== undefined ? selected : undefined}\n aria-disabled={clickable && disabled ? true : undefined}\n // Without this the row's accessible name is the concatenation of everything inside\n // it — title, meta, description, footer and the label of any nested control.\n aria-label={clickable ? ariaLabel : undefined}\n tabIndex={clickable ? 0 : undefined}\n onKeyDown={\n clickable\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n activate();\n }\n }\n : undefined\n }\n >\n {body}\n </Tag>\n );\n}\n\n/**\n * Keeps an interaction with a nested control from also triggering the row.\n *\n * Note the remaining limitation: a focusable descendant inside `role=\"button\"` is invalid\n * ARIA regardless of propagation, so a row that is *itself* clickable and *also* contains\n * controls is a compromise. Prefer either a clickable row with static content, or a static\n * row whose title is its own button.\n */\nfunction stopIfInteractive(event: { stopPropagation: () => void }) {\n event.stopPropagation();\n}\n\nfunction refusePress(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface FileRowProps {\n name: string;\n /** Muted second line — size, upload date, uploader. */\n detail?: ReactNode;\n /** Leading chip showing the file extension, e.g. `\"PDF\"`. Ignored when `leading` is set. */\n fileType?: string;\n /** Custom leading node — overrides `fileType`. */\n leading?: ReactNode;\n /** The canonical action. Renders a text link before `actions`. */\n onDownload?: () => void;\n downloadLabel?: string;\n /** Everything else on the right — `Button`s, a `DropdownMenu`. */\n actions?: ReactNode;\n className?: string;\n}\n\n/** The extension chip. Lifted unchanged from the deleted `DocumentRow`. */\nfunction FileTypeBadge({ type }: { type: string }) {\n return (\n <span className=\"flex size-[34px] shrink-0 items-center justify-center rounded-md bg-brand-tertiary text-body-tiny font-semibold text-brand\">\n {type}\n </span>\n );\n}\n\n/**\n * One attached file: name, optional detail line, and actions.\n *\n * This strip was hardcoded inline inside both `DocumentRow` and\n * `DocumentChecklistRow`. Nothing about it is document-specific — it is the same row\n * for a generated export, an invoice or an evidence attachment.\n */\nexport function FileRow({\n name,\n detail,\n fileType,\n leading,\n onDownload,\n downloadLabel = 'Download',\n actions,\n className,\n}: FileRowProps) {\n const lead = leading ?? (fileType ? <FileTypeBadge type={fileType} /> : null);\n\n return (\n <div\n className={clsx(\n 'flex items-center gap-3 rounded-lg border border-default bg-default px-3 py-2.5',\n className,\n )}\n >\n {lead}\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"truncate text-body-sm font-medium text-default\">{name}</span>\n {detail && <span className=\"text-body-xs text-default-secondary\">{detail}</span>}\n </div>\n {(onDownload || actions) && (\n <div className=\"flex shrink-0 items-center gap-3\">\n {onDownload && (\n <button\n type=\"button\"\n onClick={onDownload}\n className=\"text-body-xs font-medium text-brand hover:underline\"\n >\n {downloadLabel}\n </button>\n )}\n {actions}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type ScoredRowAlign = 'center' | 'end';\n/** 8 / 12 / 20 / 48px — the four gaps the source mockups actually used. */\nexport type ScoredRowGap = 'sm' | 'md' | 'lg' | 'xl';\n\nconst GAP: Record<ScoredRowGap, string> = {\n sm: 'gap-2',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-12',\n};\n\nconst ALIGN: Record<ScoredRowAlign, string> = {\n center: 'items-center',\n end: 'items-end',\n};\n\nexport interface ScoredRowProps {\n /** Leading visual — an `EntityIconBadge`, an `Avatar`, a rank number, or nothing. */\n leading?: ReactNode;\n title: ReactNode;\n subtitle?: ReactNode;\n /** Fixed-width column between the title block and the meter. */\n aside?: ReactNode;\n /** The bar. Put a `<ProgressBar>` here — the row does not choose one for you. */\n meter?: ReactNode;\n /** Right-hand value — a `<ScoreValue>`, a `<TrendLabel>`, a `<Badge>`, a button. */\n trailing?: ReactNode;\n /** CSS width values. Omit one and that slot flexes instead. */\n titleWidth?: string;\n asideWidth?: string;\n meterWidth?: string;\n trailingWidth?: string;\n gap?: ScoredRowGap;\n /** Gap between `leading` and the title block. Defaults to `gap`. */\n leadingGap?: ScoredRowGap;\n align?: ScoredRowAlign;\n className?: string;\n}\n\n/**\n * A row with a title block, an optional bar and a right-hand value.\n *\n * Was `EntityRow`. The rename is the smaller half of the change: the old component\n * hardcoded `RiskScore`, `WidgetProgressBar`, `TrendLabel` and `getRiskTone`, which\n * locked it to one scoring domain and forced 32 props — including four raw\n * `CSSProperties` escape hatches and a magic `nameWidth = '133px'` — to make it fit\n * anything else. The score and the bar are now slots, so the caller decides.\n */\nexport function ScoredRow({\n leading,\n title,\n subtitle,\n aside,\n meter,\n trailing,\n titleWidth,\n asideWidth,\n meterWidth,\n trailingWidth,\n gap = 'md',\n leadingGap,\n align = 'center',\n className,\n}: ScoredRowProps) {\n return (\n <div className={clsx('flex w-full', ALIGN[align], GAP[gap], className)}>\n <div\n className={clsx(\n 'flex min-w-0',\n ALIGN[align],\n GAP[leadingGap ?? gap],\n titleWidth ? 'shrink-0' : 'flex-1',\n )}\n style={titleWidth ? { width: titleWidth } : undefined}\n >\n {leading}\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-body-sm font-medium leading-none text-default\">{title}</p>\n {subtitle && <p className=\"mt-0.5 truncate text-body-xs text-default-secondary\">{subtitle}</p>}\n </div>\n </div>\n\n {aside && (\n <div\n className={clsx('min-w-0', asideWidth ? 'shrink-0' : 'flex-1')}\n style={asideWidth ? { width: asideWidth } : undefined}\n >\n {aside}\n </div>\n )}\n\n {meter && (\n <div\n className={clsx('min-w-0', meterWidth ? 'shrink-0' : 'flex-1')}\n style={meterWidth ? { width: meterWidth } : undefined}\n >\n {meter}\n </div>\n )}\n\n {trailing && (\n <div className=\"shrink-0 text-right\" style={trailingWidth ? { width: trailingWidth } : undefined}>\n {trailing}\n </div>\n )}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { ProgressBar } from '../feedback/progress-bar';\nimport type { ProgressBarTone } from '../feedback/progress-bar';\nimport { ScoreValue, getScoreTone } from '../stats/score-value';\nimport type { ScoreDirection, ScoreValueSize, ScoreValueWeight } from '../stats/score-value';\n\nexport interface NumberedListItem {\n title: string;\n /** Second line under the title — a region, a category, an id. */\n subtitle?: string;\n score: number;\n /** Bar and value colour for this row. `auto` derives it from `score`. */\n tone?: ProgressBarTone | 'auto';\n}\n\nexport type NumberedListGap = 'sm' | 'md';\n\nexport interface NumberedListProps {\n items: NumberedListItem[];\n /** Which end of the scale is bad, for rows resolving `tone` automatically. */\n direction?: ScoreDirection;\n scoreSize?: ScoreValueSize;\n scoreWeight?: ScoreValueWeight;\n /** First ordinal. Set it to continue a list across a page boundary. */\n startAt?: number;\n gap?: NumberedListGap;\n className?: string;\n}\n\nconst GAP: Record<NumberedListGap, string> = {\n sm: 'gap-2',\n md: 'gap-3',\n};\n\n/**\n * A ranked leaderboard: ordinal, title, score, and a full-width bar under each row.\n *\n * Was `RankedRow`, which was one row and made the caller supply both the `<ol>` and every\n * `rank` by hand — so a filtered or re-sorted list silently kept stale numbers. Owning the\n * list means the ordinal is derived from position and cannot disagree with the order on\n * screen. It also puts it at the same granularity as `StepsList`, its neighbour.\n *\n * It still hardcodes `ProgressBar` and `ScoreValue`, and that is the point: a leaderboard\n * row *is* those three things. Where the pieces need to vary, reach for `ScoredRow`, whose\n * slots take arbitrary content.\n */\nexport function NumberedList({\n items,\n direction = 'higher-is-worse',\n scoreSize = 'md',\n scoreWeight = 'bold',\n startAt = 1,\n gap = 'md',\n className,\n}: NumberedListProps) {\n return (\n <ol className={clsx('flex list-none flex-col p-0', GAP[gap], className)}>\n {items.map((item, index) => {\n const tone =\n !item.tone || item.tone === 'auto'\n ? getScoreTone(item.score, { direction })\n : item.tone;\n\n return (\n <li key={`${item.title}-${index}`} className=\"flex w-full shrink-0 flex-col gap-1.5\">\n <div className=\"flex w-full items-center justify-between\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n {/* Fixed width so the titles align whether the ordinal is 1 or 10. */}\n <span className=\"w-[14px] shrink-0 text-body-xs font-bold text-default-secondary\">\n {startAt + index}\n </span>\n <div className=\"flex min-w-0 flex-col gap-px\">\n <span className=\"truncate text-body-sm font-medium leading-none text-default\">\n {item.title}\n </span>\n {item.subtitle && (\n <span className=\"text-body-tiny text-default-tertiary\">{item.subtitle}</span>\n )}\n </div>\n </div>\n <ScoreValue\n value={item.score}\n size={scoreSize}\n weight={scoreWeight}\n tone={tone}\n className=\"ml-2 shrink-0\"\n />\n </div>\n <ProgressBar value={item.score} tone={tone} aria-label={`${item.title} score`} />\n </li>\n );\n })}\n </ol>\n );\n}\n","import { useId } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type ProgressBarTone = 'brand' | 'positive' | 'warning' | 'danger' | 'neutral';\nexport type ProgressBarSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/** 4 / 6 / 8 / 12px. `sm` is 0.2.0's only height, and stays the default. */\nconst SIZE: Record<ProgressBarSize, string> = {\n xs: 'h-1',\n sm: 'h-1.5',\n md: 'h-2',\n lg: 'h-3',\n};\n\nconst FILL: Record<ProgressBarTone, string> = {\n brand: 'bg-brand',\n positive: 'bg-positive',\n warning: 'bg-warning',\n danger: 'bg-danger',\n neutral: 'bg-neutral',\n};\n\nexport interface ProgressBarProps {\n /** 0–100. Values outside the range are clamped. */\n value: number;\n tone?: ProgressBarTone;\n size?: ProgressBarSize;\n /** Caption above the bar. Also becomes the accessible name. */\n label?: string;\n /** Show the percentage at the right of the label row. */\n showValue?: boolean;\n /** CSS radius override, e.g. `'1px'` for a square-ended bar. Defaults to fully round. */\n radius?: string;\n /** Accessible name when there is no visible `label`. */\n 'aria-label'?: string;\n /**\n * Draw the bar as this many equal steps, filled in whole steps, e.g. a password-strength\n * meter. New in 0.7.0; replaces hand-built rows of tinted bars.\n */\n segments?: number;\n /**\n * What the value means, announced instead of the number (`aria-valuetext`), e.g. \"Strong\".\n * A strength meter at 75 means nothing as \"75 percent\".\n */\n valueText?: string;\n /**\n * Applied to the track. This is how you set a fixed width — `className=\"w-16\"`.\n * It genuinely overrides the base `w-full` because this file uses `cn`.\n */\n className?: string;\n}\n\n/**\n * A horizontal progress / proportion bar.\n *\n * Was `WidgetProgressBar` in 0.2.0, which fixed the height at 6px and lived under\n * `widgets/` despite being a general-purpose primitive — so `TableCellProgress`\n * hand-rolled a second copy rather than reuse it. It also had no ARIA at all.\n */\nexport function ProgressBar({\n value,\n tone = 'brand',\n size = 'sm',\n label,\n showValue = false,\n radius,\n 'aria-label': ariaLabel,\n segments,\n valueText,\n className,\n}: ProgressBarProps) {\n const clamped = Math.min(100, Math.max(0, value));\n const rounded = radius ? undefined : 'rounded-full';\n const labelId = useId();\n\n const filledSegments = segments ? Math.round((clamped / 100) * segments) : 0;\n\n const track = segments ? (\n <div\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuetext={valueText}\n aria-labelledby={label ? labelId : undefined}\n aria-label={label ? undefined : ariaLabel}\n data-tone={tone}\n className={cn('flex w-full gap-1', className)}\n >\n {Array.from({ length: segments }, (_, index) => (\n <span\n key={index}\n data-filled={index < filledSegments || undefined}\n className={cn('flex-1 bg-default-tertiary transition-colors', SIZE[size], rounded, index < filledSegments && FILL[tone])}\n style={radius ? { borderRadius: radius } : undefined}\n />\n ))}\n </div>\n ) : (\n <div\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuetext={valueText}\n data-tone={tone}\n // The doc comment on `label` promised it \"also becomes the accessible name\", and\n // through 0.3.0 it did the opposite: setting `label` *suppressed* `aria-label` while\n // the caption rendered as an unlabelled sibling `<span>` with no id, so\n // `<ProgressBar label=\"Risk score\" />` produced a progressbar with no name at all.\n aria-labelledby={label ? labelId : undefined}\n aria-label={label ? undefined : ariaLabel}\n className={cn('w-full overflow-hidden bg-default-tertiary', SIZE[size], rounded, className)}\n style={radius ? { borderRadius: radius } : undefined}\n >\n <div\n className={cn('h-full transition-all', rounded, FILL[tone])}\n style={{ width: `${clamped}%`, ...(radius ? { borderRadius: radius } : undefined) }}\n />\n </div>\n );\n\n // No caption row means no wrapper — the bar must stay a direct child of whatever\n // laid it out, so a parent's `flex-1` or grid placement still applies to it.\n if (!label && !showValue) return track;\n\n return (\n <div>\n <div className=\"mb-1.5 flex items-center justify-between gap-2\">\n {label && (\n <span id={labelId} className=\"text-body-xs text-default-secondary\">\n {label}\n </span>\n )}\n {showValue && (\n <span className=\"ml-auto text-body-xs font-medium tabular-nums text-default\">\n {Math.round(clamped)}%\n </span>\n )}\n </div>\n {track}\n </div>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface IconTextRowProps {\n icon: ReactNode;\n title: string;\n detail: string;\n className?: string;\n}\n\n/**\n * A circular icon badge, a title, and one line of detail.\n *\n * Feature lists, empty-state explanations, onboarding intros, \"what happens next\"\n * steps. Was `FeatureRow`, which named it after the one screen it was extracted from.\n */\nexport function IconTextRow({ icon, title, detail, className }: IconTextRowProps) {\n return (\n <div className={clsx('flex items-start gap-3', className)}>\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-brand\">\n {icon}\n </span>\n <div className=\"min-w-0\">\n <p className=\"text-body-sm font-semibold text-default\">{title}</p>\n <p className=\"mt-0.5 text-body-xs text-default-secondary\">{detail}</p>\n </div>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { CheckIcon } from 'lucide-react';\n\nexport type ChecklistRowState = 'done' | 'active' | 'pending';\n\nexport interface ChecklistRowProps {\n label: string;\n state: ChecklistRowState;\n className?: string;\n}\n\n/**\n * One step in a progress checklist: a done tick, a spinning active ring, or an empty\n * pending ring.\n *\n * Shared by the event-onboarding \"building your dashboard\" screen and the\n * intelligence page's processing checklist. Both drove the same three states; only\n * the onboarding copy had the animated ring, which is the better treatment and is\n * adopted for both.\n *\n * Renders an `<li>` — callers must wrap it in a list, which is what both sources did.\n */\nexport function ChecklistRow({ label, state, className }: ChecklistRowProps) {\n return (\n <li data-state={state} className={clsx('flex items-center gap-3', className)}>\n <span className=\"flex size-5 shrink-0 items-center justify-center\">\n {state === 'done' ? (\n <CheckIcon className=\"size-4 text-positive\" strokeWidth={2.5} aria-hidden />\n ) : (\n <span\n className={clsx(\n 'size-3.5 rounded-full border-2',\n state === 'active'\n ? 'animate-pulse border-brand-emphasis border-t-transparent'\n : 'border-disabled',\n )}\n />\n )}\n </span>\n <span\n className={clsx(\n 'text-body-sm',\n state === 'pending' ? 'text-default-tertiary' : 'font-semibold text-default',\n )}\n >\n {label}\n </span>\n </li>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport interface StepsListProps {\n steps: ReactNode[];\n className?: string;\n}\n\n/**\n * Ordered list of instructions with small filled number bullets.\n *\n * Was `NumberedStepsList`. Renamed in 0.5.0 because `NumberedList` — the ranked\n * leaderboard — also numbers its rows, and two components whose names both led with\n * \"Numbered\" gave no hint which was which. The distinction is what the numbers *mean*:\n * here they are sequence (\"do this, then this\"), there they are rank.\n *\n * The bullet was `bg-[#e7edfb] text-[#1d4ed8]` — a pale blue pair that is not in the\n * token set. It now uses the brand-tertiary background and brand text, which is the\n * documented treatment for a subtle brand-tinted chip.\n */\nexport function StepsList({ steps, className }: StepsListProps) {\n return (\n <ol className={clsx('flex flex-col gap-1.5', className)}>\n {steps.map((step, i) => (\n // `text-[12px]` was off the type scale; 12 sits midway between Scale 01 (11) and\n // Scale 02 (13), so it rounds up to 13 like every other snap in this pass.\n <li key={i} className=\"flex items-start gap-2 text-body-xs text-default\">\n <span className=\"mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-[9px] font-bold text-brand\">\n {i + 1}\n </span>\n {step}\n </li>\n ))}\n </ol>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type DetailItemLayout = 'stacked' | 'inline';\nexport type DetailItemSpan = 1 | 2 | 'full';\n\nexport interface DetailItemProps {\n label: string;\n value: ReactNode;\n /** Optional second line under the value. */\n detail?: ReactNode;\n /**\n * `stacked` puts the label above the value (detail pages, review summaries).\n * `inline` puts a fixed-width label beside it (drawer detail rows).\n */\n layout?: DetailItemLayout;\n /**\n * Columns to occupy inside a `DetailGrid`. `full` spans the row — for a long value\n * such as an alias list or a legal name that would otherwise truncate.\n */\n span?: DetailItemSpan;\n /**\n * Label column width for the `inline` layout. A `min-w`/`max-w` pair rather than a\n * fixed `w-`, so a long label wraps instead of colliding with the value.\n */\n labelWidth?: string;\n className?: string;\n}\n\nconst SPAN: Record<DetailItemSpan, string> = {\n 1: '',\n 2: 'sm:col-span-2',\n full: 'col-span-full',\n};\n\n/**\n * A label/value pair.\n *\n * Was `MetaField` — an internal codename that said nothing about the shape. Consolidates\n * the same pair from six places: an entity-detail overview grid, a reviewer-detail metric\n * column, three `DetailRow` copies in drawers, and `ReviewMeta` in two onboarding wizards.\n *\n * An empty value renders an em dash, which is what every source copy did by hand. Note\n * that the check is for `null`/`undefined`/`''` only — `0` and `false` are real values and\n * render as themselves.\n */\nexport function DetailItem({\n label,\n value,\n detail,\n layout = 'stacked',\n span = 1,\n labelWidth = 'min-w-[96px] max-w-[140px]',\n className,\n}: DetailItemProps) {\n const shown = value === null || value === undefined || value === '' ? '—' : value;\n\n if (layout === 'inline') {\n return (\n <div className={clsx('flex gap-3 text-body-xs', SPAN[span], className)}>\n <span className={clsx('shrink-0 text-default-secondary', labelWidth)}>{label}</span>\n {/* `detail` used to be dropped silently in this branch. */}\n <span className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"text-default\">{shown}</span>\n {detail && <span className=\"text-default-secondary\">{detail}</span>}\n </span>\n </div>\n );\n }\n\n return (\n <div className={clsx('flex min-w-0 flex-col gap-0.5', SPAN[span], className)}>\n <p className=\"text-body-tiny font-medium text-default-secondary\">{label}</p>\n <p className=\"text-body-sm font-medium text-default\">{shown}</p>\n {detail && <p className=\"text-body-xs text-default-secondary\">{detail}</p>}\n </div>\n );\n}\n\nexport type DetailGridColumns = 2 | 3 | 4 | 'auto';\n\nexport interface DetailGridProps {\n children: ReactNode;\n columns?: DetailGridColumns;\n className?: string;\n}\n\nconst COLUMNS: Record<DetailGridColumns, string> = {\n // Fills the row whatever its width, and reflows to fewer columns as it narrows.\n auto: 'grid-cols-[repeat(auto-fit,minmax(180px,1fr))]',\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-4',\n};\n\n/**\n * Wrapper for a set of `DetailItem`s.\n *\n * A real grid, not the `flex flex-wrap` it was as `MetaFieldGrid`. Under flex-wrap every\n * item had to carry its own width (`sm:w-[262px]` was the documented idiom) and whatever\n * space was left over at the end of a row stayed empty — so a three-item row in a wide\n * card had a ragged gap on the right. `1fr` tracks divide the row exactly, and an item\n * that genuinely needs more room asks for it with `span` instead of a magic width.\n */\nexport function DetailGrid({ children, columns = 'auto', className }: DetailGridProps) {\n return (\n <div className={clsx('grid gap-x-4 gap-y-4', COLUMNS[columns], className)}>{children}</div>\n );\n}\n","import { useEffect, useState, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { CheckIcon, CopyIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\nimport { IconButton } from '../forms/icon-button';\n\n/**\n * Label/value rows for a detail page, as a real `<dl>`. New in 0.7.0, from SCIC.\n *\n * Use it for a profile or account summary read top to bottom. `DetailGrid` / `DetailItem`\n * are for a multi-column summary card. The rows here are width-aware without a breakpoint: the\n * label has a fixed basis and the value a minimum one, and the row wraps, so in a narrow panel\n * (a one-third column, a 320px phone, 200% zoom) the value drops below its label instead of\n * being squeezed into a sliver beside it.\n */\nexport interface DescriptionListProps {\n children: ReactNode;\n className?: string;\n}\n\nexport function DescriptionList({ children, className }: DescriptionListProps) {\n return <dl className={cn('flex flex-col gap-3', className)}>{children}</dl>;\n}\n\nexport interface DescriptionItemProps {\n label: string;\n /** An empty value renders an em dash. */\n value: ReactNode;\n /**\n * Adds a copy-to-clipboard button. Pass the plain string to copy: emails and ids are long,\n * unbroken and commonly pasted elsewhere.\n */\n copyValue?: string;\n className?: string;\n}\n\nexport function DescriptionItem({ label, value, copyValue, className }: DescriptionItemProps) {\n const shown = value === null || value === undefined || value === '' ? '—' : value;\n return (\n <div className={cn('flex flex-wrap items-start gap-x-4 gap-y-0.5 text-body-xs', className)}>\n <dt className=\"shrink-0 grow-0 basis-28 text-default-secondary\">{label}</dt>\n {/* `min-w-0` lets the value shrink below its content; `overflow-wrap:anywhere` lets an\n unbroken token (an email, a URL, an id) break rather than overflow. */}\n <dd className=\"flex min-w-0 flex-[1_1_10rem] items-start gap-1.5 text-default\">\n <span className=\"min-w-0 [overflow-wrap:anywhere]\">{shown}</span>\n {copyValue && <CopyButton value={copyValue} label={`Copy ${label.toLowerCase()}`} />}\n </dd>\n </div>\n );\n}\n\nexport interface CopyButtonProps {\n /** The text to copy. */\n value: string;\n /** The button's accessible name, e.g. \"Copy email\". */\n label: string;\n /** Announced after a copy. Default \"Copied\". */\n copiedLabel?: string;\n className?: string;\n}\n\n/**\n * An icon button that copies `value` to the clipboard, shows a tick for two seconds, and\n * announces the copy in a polite live region. Exported for ids and codes outside a\n * `DescriptionList`.\n */\nexport function CopyButton({ value, label, copiedLabel = 'Copied', className }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n\n useEffect(() => {\n if (!copied) return;\n const timer = window.setTimeout(() => setCopied(false), 2000);\n return () => window.clearTimeout(timer);\n }, [copied]);\n\n return (\n <>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label={label}\n data-state={copied ? 'copied' : undefined}\n className={cn('-my-0.5 touch-hit', className)}\n onClick={() => {\n void navigator.clipboard?.writeText(value).then(\n () => setCopied(true),\n () => undefined,\n );\n }}\n >\n {copied ? <CheckIcon aria-hidden /> : <CopyIcon aria-hidden />}\n </IconButton>\n <span role=\"status\" className=\"sr-only\">\n {copied ? copiedLabel : ''}\n </span>\n </>\n );\n}\n\n/**\n * A one-line email that truncates the local part and keeps the domain:\n * `alexandra.konstan…@example.com`. The full address stays in the DOM (screen readers and copy\n * get all of it) and in `title`. Pair it with `copyValue`, so touch users, who cannot hover, can\n * still get the address.\n */\nexport function EmailText({ email, className }: { email: string; className?: string }) {\n const at = email.lastIndexOf('@');\n const local = at > 0 ? email.slice(0, at) : email;\n const domain = at > 0 ? email.slice(at) : '';\n return (\n <span title={email} className={clsx('flex min-w-0 max-w-full', className)}>\n <span className=\"min-w-0 truncate\">{local}</span>\n {/* Near-zero shrink: the local part gives up its width first. */}\n {domain && <span className=\"min-w-0 truncate [flex-shrink:0.001]\">{domain}</span>}\n </span>\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { CheckIcon } from 'lucide-react';\n\nexport type CheckedGroupListColumns = 1 | 2 | 3;\n\n/** One labelled group of ticked items. */\nexport interface CheckedGroup {\n label: string;\n items: string[];\n}\n\nexport interface CheckedGroupListProps {\n groups: CheckedGroup[];\n columns?: CheckedGroupListColumns;\n /** Leading glyph for every item. Defaults to a check; pass `null` for none. */\n icon?: ReactNode | null;\n emptyLabel?: string;\n className?: string;\n}\n\nconst COLUMNS: Record<CheckedGroupListColumns, string> = {\n 1: 'columns-1',\n 2: 'columns-2',\n 3: 'columns-3',\n};\n\n/**\n * A read-only, grouped list of ticked items in a balanced multi-column flow.\n *\n * Was `PermissionGrid` — RBAC-specific naming for a generic shape, and not a grid\n * either: groups pack tightly down each column rather than aligning to shared row\n * heights, so a tall group beside a short one leaves no ragged gap.\n * `break-inside-avoid` keeps each group whole within a column.\n *\n * Granted permissions, included plan features, completed requirements, matched\n * criteria — anything that is \"these labels, grouped, all ticked\".\n */\nexport function CheckedGroupList({\n groups,\n columns = 2,\n icon,\n emptyLabel = 'None.',\n className,\n}: CheckedGroupListProps) {\n if (groups.length === 0) {\n return <p className={clsx('text-body-xs text-default-secondary', className)}>{emptyLabel}</p>;\n }\n\n // `undefined` means \"not passed\" → default check. `null` means \"explicitly none\".\n const glyph = icon === undefined ? <CheckIcon className=\"size-3.5\" strokeWidth={2.5} aria-hidden /> : icon;\n\n return (\n <div className={clsx(COLUMNS[columns], 'gap-x-6', className)}>\n {groups.map((group) => (\n <div key={group.label} className=\"mb-5 break-inside-avoid last:mb-0\">\n <p className=\"mb-2 text-body-tiny font-semibold uppercase tracking-wide text-default-secondary\">\n {group.label}\n </p>\n <ul className=\"space-y-1.5\">\n {group.items.map((item) => (\n <li key={item} className=\"flex items-center gap-2 text-body-xs text-default\">\n {glyph && <span className=\"shrink-0\">{glyph}</span>}\n {item}\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n}\n","import { useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { ChevronRightIcon } from 'lucide-react';\n\nimport { useControllableState } from '../../lib/use-controllable-state';\n\nexport type TreeViewSize = 'sm' | 'md';\n\nexport interface TreeItemState {\n /** 1 for a root item. */\n level: number;\n hasChildren: boolean;\n expanded: boolean;\n selected: boolean;\n}\n\nexport interface TreeViewProps<T> {\n /** Root items. */\n items: readonly T[];\n getId: (item: T) => string;\n /** Children of an item. Omit (or return nothing) for a flat list. */\n getChildren?: (item: T) => readonly T[] | undefined;\n /**\n * The row content — a slot rather than props, so the caller decides what a node shows\n * (an avatar, a code, a status badge). The chevron, indentation and selection highlight\n * are drawn by the tree.\n */\n renderItem: (item: T, state: TreeItemState) => ReactNode;\n /** Accessible name of the tree. */\n label: string;\n /** Ids of expanded items. Controlled. */\n expanded?: string[];\n defaultExpanded?: string[];\n onExpandedChange?: (expanded: string[]) => void;\n /** Id of the selected item. Controlled. */\n selected?: string | null;\n defaultSelected?: string | null;\n /** Fired on click, Enter or Space. */\n onSelect?: (id: string, item: T) => void;\n size?: TreeViewSize;\n className?: string;\n}\n\ninterface FlatNode<T> {\n id: string;\n item: T;\n level: number;\n parentId: string | null;\n hasChildren: boolean;\n expanded: boolean;\n}\n\nconst ROW: Record<TreeViewSize, string> = {\n sm: 'min-h-8 py-1 text-body-xs',\n md: 'min-h-10 py-2 text-body-sm',\n};\n\n/** Indentation per level, in px. Data-driven, so it is an inline style rather than a class. */\nconst INDENT = 18;\n\n/**\n * An expandable tree — the ARIA tree pattern, with one tab stop.\n *\n * Focus is a roving tabindex over the *visible* rows, kept here rather than in\n * `useRovingFocus` because a tree gives Left and Right their own meaning: Right expands a\n * closed node or steps into an open one, Left collapses an open node or steps out to its\n * parent. Selection is separate from focus — arrowing does not select — so browsing a\n * controlled tree fires no `onSelect`.\n *\n * Children render inside a real `role=\"group\"`, which is what lets a screen reader announce\n * level and position without `aria-level` being guessed from indentation.\n */\nexport function TreeView<T>({\n items,\n getId,\n getChildren,\n renderItem,\n label,\n expanded: expandedProp,\n defaultExpanded = [],\n onExpandedChange,\n selected: selectedProp,\n defaultSelected = null,\n onSelect,\n size = 'md',\n className,\n}: TreeViewProps<T>) {\n const [expanded, setExpanded] = useControllableState<string[]>({\n value: expandedProp,\n defaultValue: defaultExpanded,\n onChange: onExpandedChange,\n });\n const [selected, setSelected] = useControllableState<string | null>({\n value: selectedProp,\n defaultValue: defaultSelected,\n });\n const [focusedId, setFocusedId] = useState<string | null>(null);\n const rowRefs = useRef(new Map<string, HTMLElement>());\n\n const expandedSet = useMemo(() => new Set(expanded), [expanded]);\n\n // Visible rows in document order — what the arrow keys walk.\n const visible = useMemo(() => {\n const out: FlatNode<T>[] = [];\n const walk = (nodes: readonly T[], level: number, parentId: string | null) => {\n for (const item of nodes) {\n const id = getId(item);\n const children = getChildren?.(item) ?? [];\n const isOpen = children.length > 0 && expandedSet.has(id);\n out.push({ id, item, level, parentId, hasChildren: children.length > 0, expanded: isOpen });\n if (isOpen) walk(children, level + 1, id);\n }\n };\n walk(items, 1, null);\n return out;\n }, [items, getId, getChildren, expandedSet]);\n\n // The single tab stop: the focused row if still visible, else the selection, else the first.\n const tabStop =\n visible.find((n) => n.id === focusedId)?.id ??\n visible.find((n) => n.id === selected)?.id ??\n visible[0]?.id;\n\n const focus = (id: string | undefined) => {\n if (!id) return;\n setFocusedId(id);\n rowRefs.current.get(id)?.focus();\n };\n\n const toggle = (id: string, open: boolean) => {\n setExpanded((prev) => (open ? [...prev.filter((x) => x !== id), id] : prev.filter((x) => x !== id)));\n };\n\n const choose = (node: FlatNode<T>) => {\n setSelected(node.id);\n onSelect?.(node.id, node.item);\n };\n\n const onKeyDown = (event: KeyboardEvent, node: FlatNode<T>) => {\n const index = visible.findIndex((n) => n.id === node.id);\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focus(visible[index + 1]?.id);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focus(visible[index - 1]?.id);\n break;\n case 'ArrowRight':\n event.preventDefault();\n if (node.hasChildren && !node.expanded) toggle(node.id, true);\n else if (node.expanded) focus(visible[index + 1]?.id);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n if (node.expanded) toggle(node.id, false);\n else if (node.parentId) focus(node.parentId);\n break;\n case 'Home':\n event.preventDefault();\n focus(visible[0]?.id);\n break;\n case 'End':\n event.preventDefault();\n focus(visible[visible.length - 1]?.id);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n choose(node);\n break;\n default:\n break;\n }\n };\n\n const renderLevel = (nodes: readonly T[], level: number): ReactNode =>\n nodes.map((item, i) => {\n const id = getId(item);\n const node = visible.find((n) => n.id === id);\n // Not visible means an ancestor is collapsed — but then this level is not rendered at all.\n if (!node) return null;\n const children = getChildren?.(item) ?? [];\n const isSelected = selected === id;\n\n return (\n <li\n key={id}\n role=\"treeitem\"\n aria-level={level}\n aria-setsize={nodes.length}\n aria-posinset={i + 1}\n aria-expanded={node.hasChildren ? node.expanded : undefined}\n aria-selected={isSelected}\n tabIndex={tabStop === id ? 0 : -1}\n ref={(el) => {\n if (el) rowRefs.current.set(id, el);\n else rowRefs.current.delete(id);\n }}\n onFocus={(event) => {\n // Only the row itself — focus bubbling up from a nested row must not steal it.\n if (event.target === event.currentTarget) setFocusedId(id);\n }}\n onKeyDown={(event) => {\n if (event.target === event.currentTarget) onKeyDown(event, node);\n }}\n className=\"outline-none [&:focus-visible>div]:ring-2 [&:focus-visible>div]:ring-inset [&:focus-visible>div]:ring-brand\"\n >\n {/* The row is a click target, but the keyboard contract lives on the treeitem above,\n which owns focus — the same split Combobox makes with its options. */}\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}\n <div\n onClick={() => {\n focus(id);\n choose(node);\n }}\n style={{ paddingLeft: 8 + (level - 1) * INDENT }}\n className={clsx(\n 'flex w-full cursor-pointer items-center gap-1.5 rounded-md pr-2 transition-colors',\n ROW[size],\n isSelected ? 'bg-brand-secondary text-default' : 'text-default hover:bg-default-secondary',\n )}\n >\n {node.hasChildren ? (\n // Not a button: the treeitem is the one tab stop, and Left/Right already toggle.\n // A pointer user still needs a target that toggles without selecting.\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions\n <span\n aria-hidden\n data-tree-toggle=\"\"\n onClick={(event) => {\n event.stopPropagation();\n toggle(id, !node.expanded);\n focus(id);\n }}\n className=\"flex size-5 shrink-0 items-center justify-center rounded text-icon-default-secondary hover:bg-default-tertiary\"\n >\n <ChevronRightIcon className={clsx('size-3.5 transition-transform', node.expanded && 'rotate-90')} />\n </span>\n ) : (\n <span aria-hidden className=\"size-5 shrink-0\" />\n )}\n <div className=\"min-w-0 flex-1\">\n {renderItem(item, {\n level,\n hasChildren: node.hasChildren,\n expanded: node.expanded,\n selected: isSelected,\n })}\n </div>\n </div>\n {node.expanded && (\n <ul role=\"group\" className=\"m-0 list-none p-0\">\n {renderLevel(children, level + 1)}\n </ul>\n )}\n </li>\n );\n });\n\n return (\n <ul role=\"tree\" aria-label={label} className={clsx('m-0 flex list-none flex-col p-0', className)}>\n {renderLevel(items, 1)}\n </ul>\n );\n}\n","import { forwardRef, type HTMLAttributes, type TdHTMLAttributes, type ThHTMLAttributes } from 'react';\nimport clsx from 'clsx';\nimport { ChevronDownIcon, ChevronsUpDownIcon, ChevronUpIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\n\nexport type TableDensity = 'default' | 'compact';\nexport type TableSortDirection = 'ascending' | 'descending';\n\n/**\n * The composable table primitive, matching Figma's `Table` and `Table cell`.\n *\n * `DataTable` is the config-driven form — you give it `columns` and `rows` and it renders\n * everything. It is the right tool most of the time, and it is not going away. But it\n * cannot express a grouped header, a footer row, a colspan, or a cell layout outside its\n * `render` signature, so anything unusual meant abandoning it for a hand-rolled `<table>`\n * with none of the semantics. These parts are that escape hatch with the semantics kept.\n *\n * Figma's `Table cell` has a 32-value `Style` axis (lead checkbox, lead avatar, badges\n * multiple, trend positive/negative, action icons, star ratings, payment method…). Those\n * are *compositions*, not variants of one component — each is an existing library\n * component dropped into a cell — so they are expressed here as `TableCell` plus whatever\n * goes inside it, rather than 32 props.\n */\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Names the table. Required unless you render a `TableCaption`. */\n label?: string;\n density?: TableDensity;\n /** Equal-width columns driven by `<colgroup>`, matching `DataTable`. Default `false`. */\n fixed?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(function Table(\n { label, density = 'default', fixed = false, className, children, ...rest },\n ref,\n) {\n return (\n // The scroll container is separate from the table so the header stays inside the\n // scrolling region — a table that is its own scroll container cannot have a sticky\n // header.\n // The scroll wrapper is required for a <table>, which cannot itself scroll, so this\n // takes the scrollbar styling rather than ScrollArea.\n <div className={clsx('w-full overflow-x-auto', SCROLLBAR_CLASSES)}>\n <table\n ref={ref}\n aria-label={label}\n data-slot=\"table\"\n data-density={density}\n className={cn('w-full border-collapse', fixed && 'table-fixed', className)}\n {...rest}\n >\n {children}\n </table>\n </div>\n );\n});\n\nexport interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {}\n\n/**\n * A visible table title that also names the table. Prefer this over `label` when the\n * heading is on screen anyway — `DataTable` could not be named at all before 0.4.0.\n */\nexport const TableCaption = forwardRef<HTMLTableCaptionElement, TableCaptionProps>(\n function TableCaption({ className, ...rest }, ref) {\n return (\n <caption\n ref={ref}\n className={cn('px-4 py-3 text-left text-body-sm text-default-secondary', className)}\n {...rest}\n />\n );\n },\n);\n\nexport const TableHeader = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(\n function TableHeader({ className, ...rest }, ref) {\n return <thead ref={ref} className={cn('border-b border-default', className)} {...rest} />;\n },\n);\n\nexport const TableBody = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(\n function TableBody({ className, ...rest }, ref) {\n return <tbody ref={ref} className={className} {...rest} />;\n },\n);\n\nexport const TableFooter = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(\n function TableFooter({ className, ...rest }, ref) {\n return (\n <tfoot\n ref={ref}\n className={cn('border-t border-default bg-default-secondary font-medium', className)}\n {...rest}\n />\n );\n },\n);\n\n/**\n * A row's state tint. Each is a meaning, not a colour: `muted` for an inactive or ended\n * record, `danger` for a denied or failed one, and so on. New in 0.7.0, to replace the\n * `className={active ? '' : 'bg-default-secondary'}` consumers were writing on every row.\n */\nexport type TableRowTone = 'default' | 'muted' | 'brand' | 'positive' | 'warning' | 'danger';\n\n/** Styled from `data-tone`, so the state lives in one attribute rather than in call sites. */\nconst ROW_TONE = clsx(\n 'data-[tone=muted]:bg-default-secondary',\n 'data-[tone=brand]:bg-brand-tertiary',\n 'data-[tone=positive]:bg-positive-tertiary',\n 'data-[tone=warning]:bg-warning-tertiary',\n 'data-[tone=danger]:bg-danger-tertiary',\n);\n\nexport interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n selected?: boolean;\n /** State tint; see `TableRowTone`. Selection wins over tone. */\n tone?: TableRowTone;\n /** De-emphasises the row (an expired or archived record) without hiding it. */\n dimmed?: boolean;\n}\n\nexport const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(function TableRow(\n { selected, tone = 'default', dimmed = false, className, ...rest },\n ref,\n) {\n return (\n <tr\n ref={ref}\n // `aria-selected` only when selection is actually in play — on a row that is not\n // part of a selectable set it is meaningless noise.\n aria-selected={selected}\n data-state={selected ? 'selected' : undefined}\n data-tone={tone === 'default' ? undefined : tone}\n data-dimmed={dimmed || undefined}\n className={cn(\n 'border-b border-default last:border-b-0 transition-colors',\n 'hover:bg-default-secondary/50',\n ROW_TONE,\n 'data-[dimmed]:opacity-60',\n 'data-[state=selected]:bg-brand-tertiary',\n className,\n )}\n {...rest}\n />\n );\n});\n\nexport interface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /**\n * Makes the header a sort control. `false` means sortable but not currently sorted.\n *\n * `aria-sort` goes on the `<th>` and must be present on exactly one column at a time —\n * it is the only non-visual signal of sort state, and `DataTable` had none.\n */\n sort?: TableSortDirection | false;\n onSort?: () => void;\n align?: 'left' | 'center' | 'right';\n /** Keeps the header visible while the body scrolls. */\n sticky?: boolean;\n}\n\nconst ALIGN = { left: 'text-left', center: 'text-center', right: 'text-right' } as const;\n\nexport const TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(function TableHead(\n { sort, onSort, align = 'left', sticky = false, className, children, ...rest },\n ref,\n) {\n const sortable = sort !== undefined && onSort !== undefined;\n\n return (\n <th\n ref={ref}\n // `scope=\"col\"` is what ties every cell beneath to this header when a screen reader\n // reads a cell out of context.\n scope=\"col\"\n aria-sort={sort === undefined ? undefined : sort === false ? 'none' : sort}\n className={cn(\n 'px-4 py-3 text-body-xs font-semibold text-default-secondary',\n ALIGN[align],\n sticky && 'sticky top-0 z-raised bg-default',\n className,\n )}\n {...rest}\n >\n {sortable ? (\n <button\n type=\"button\"\n onClick={onSort}\n className={clsx(\n 'inline-flex items-center gap-1.5 rounded transition-colors hover:text-default',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default',\n )}\n >\n {children}\n {sort === false ? (\n <ChevronsUpDownIcon aria-hidden className=\"size-3.5 opacity-50\" />\n ) : sort === 'ascending' ? (\n <ChevronUpIcon aria-hidden className=\"size-3.5\" />\n ) : (\n <ChevronDownIcon aria-hidden className=\"size-3.5\" />\n )}\n </button>\n ) : (\n children\n )}\n </th>\n );\n});\n\nexport interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {\n align?: 'left' | 'center' | 'right';\n /** Vertical rhythm. Matches `DataTable`'s `density`. */\n density?: TableDensity;\n /** Makes this the row's header cell — `scope=\"row\"`, for a table with row headers. */\n header?: boolean;\n}\n\nexport const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(function TableCell(\n { align = 'left', density = 'default', header = false, className, ...rest },\n ref,\n) {\n const Tag = header ? 'th' : 'td';\n return (\n <Tag\n ref={ref as never}\n scope={header ? 'row' : undefined}\n className={cn(\n density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n 'text-body-sm text-default',\n header && 'font-medium',\n ALIGN[align],\n className,\n )}\n {...rest}\n />\n );\n});\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport {\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n type Cell,\n type Column,\n type ColumnDef,\n type ColumnFiltersState,\n type OnChangeFn,\n type PaginationState,\n type Row,\n type RowData,\n type RowSelectionState,\n type SortingState,\n type Table as TanstackTable,\n type TableOptions,\n type Updater,\n type VisibilityState,\n} from '@tanstack/react-table';\n\nimport { cn } from '../../lib/cn';\nimport { devWarn } from '../../lib/dev-warn';\nimport { FOCUS_RING_INSET } from '../../lib/focus-ring';\nimport { SCROLLBAR_CLASSES } from '../../lib/scrollbar';\nimport { useElementWidth } from '../../lib/use-element-width';\nimport { EmptyState } from '../feedback/empty-state';\nimport { Skeleton } from '../feedback/skeleton';\nimport { Button } from '../forms/button';\nimport { SearchInput } from '../forms/input-group';\nimport {\n DEFAULT_CARD_BREAKPOINT_PX,\n cardSlots,\n nextLayoutMode,\n widthToPx,\n type ColumnMobileRole,\n type TableLayoutMode,\n} from './data-table-layout';\nimport {\n DataTableColumnHeader,\n DataTablePagination,\n DataTableViewOptions,\n SELECT_COLUMN_ID,\n columnLabel,\n createSelectColumn,\n} from './data-table-parts';\nimport { TableRow, type TableRowTone } from './table';\n\n// ── Column meta ────────────────────────────────────────────────────────────────\n\nexport type DataTableColumnAlign = 'start' | 'center' | 'end';\n\n/**\n * Per-column layout options, carried on TanStack's `meta`. Declared by augmenting TanStack's\n * own `ColumnMeta`, so `meta` on your `ColumnDef` is typed with no extra import:\n *\n * const columns: ColumnDef<Supplier>[] = [\n * { accessorKey: 'name', header: 'Supplier', meta: { width: '280px', grow: true, mobile: 'title' } },\n * ];\n */\ndeclare module '@tanstack/react-table' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface ColumnMeta<TData extends RowData, TValue> {\n /**\n * CSS width for the column's `<col>`, e.g. `\"320px\"` or `\"10rem\"`. A column is never\n * narrower than its header text. With `grow`, this is the floor instead.\n */\n width?: string;\n /** Absorbs the table's remaining width, with `width` as its floor. Usually one column. */\n grow?: boolean;\n /** Horizontal alignment of the header and cells. Default `start`. */\n align?: DataTableColumnAlign;\n /**\n * The cell renders its own controls (a button, a toggle, a menu). Presses inside it stop\n * before reaching the row's `onRowClick`, and the cell stops clipping its overflow, so\n * focus rings are not cut off.\n */\n interactive?: boolean;\n /** Keep the header for screen readers but hide it visually, e.g. an actions column. */\n hideHeader?: boolean;\n /** The column's part in card mode. See `ColumnMobileRole`. Default `field`. */\n mobile?: ColumnMobileRole;\n /** Pin the first (`start`) or last (`end`) visible column while the table scrolls sideways. */\n sticky?: 'start' | 'end';\n /** The column's name where its header cannot be shown as text: menus, card labels. */\n label?: string;\n /** Extra classes on the header cell. An escape hatch; prefer `align`. */\n headerClassName?: string;\n /** Extra classes on each body cell. An escape hatch; prefer `align`. */\n cellClassName?: string;\n }\n}\n\n// ── Props ──────────────────────────────────────────────────────────────────────\n\nexport type DataTableDensity = 'default' | 'compact';\nexport type DataTableAlign = 'center' | 'top';\n\n/** The table state you can control. Every key is optional and independently controlled. */\nexport interface DataTableState {\n sorting: SortingState;\n globalFilter: string;\n columnFilters: ColumnFiltersState;\n pagination: PaginationState;\n columnVisibility: VisibilityState;\n rowSelection: RowSelectionState;\n}\n\n/** Hand an operation to the server. The table then shows `data` as given for that operation. */\nexport interface DataTableManual {\n sorting?: boolean;\n filtering?: boolean;\n pagination?: boolean;\n /** Total rows on the server. Needed with `pagination`, so the pager knows the page count. */\n rowCount?: number;\n}\n\nexport interface DataTableSearchOptions {\n /** Filter one column instead of every column. */\n columnId?: string;\n placeholder?: string;\n /** Accessible name. Default \"Search\". */\n label?: string;\n}\n\nexport interface DataTableRowLinkProps {\n href: string;\n className: string;\n children: ReactNode;\n 'data-row-link': '';\n}\n\nexport interface DataTableProps<TData, TValue = unknown> {\n /** TanStack column definitions. Layout options go in each column's `meta`. */\n columns: ColumnDef<TData, TValue>[];\n data: TData[];\n /** A stable id per row. Defaults to the row index, which breaks selection across re-sorts. */\n getRowId?: (row: TData, index: number) => string;\n\n /**\n * Accessible name, rendered as a visually hidden `<caption>`. Give the table either this or\n * `caption`: an unnamed table is announced as just \"table\".\n */\n label?: string;\n /** A visible caption above the table, which also names it. */\n caption?: ReactNode;\n\n // ── Built-in tools ──────────────────────────────────────────────────────────\n /** A search box. `true` filters across every column; pass options to filter one column. */\n searchable?: boolean | DataTableSearchOptions;\n /** A \"Columns\" menu to show and hide columns. */\n columnVisibility?: boolean;\n /** Page the rows. Default `true`. */\n pagination?: boolean;\n /** Rows per page to start with. Default `10`. */\n pageSize?: number;\n /** Page sizes to offer. Default `[10, 20, 50]`; `[]` hides the selector. */\n pageSizeOptions?: number[];\n /**\n * Adds a leading checkbox column (unless the columns already include `createSelectColumn()`).\n * Pass a function to make only some rows selectable.\n */\n enableRowSelection?: boolean | ((row: TData) => boolean);\n /** The selected rows, every time the selection changes. */\n onSelectionChange?: (rows: TData[]) => void;\n /** Names a row for its selection checkbox and its card, e.g. `(s) => s.name`. */\n getRowLabel?: (row: TData) => string;\n\n // ── Row behaviour ───────────────────────────────────────────────────────────\n /**\n * Whole-row activation for rows that open something in place (a drawer, a modal). Keyboard\n * users focus the row and press Enter or Space. Rows that navigate should use `getRowHref`.\n */\n onRowClick?: (row: TData) => void;\n /**\n * The row's destination. The title cell renders as a real link (so middle-click, open in a\n * new tab and screen-reader link lists all work) and a click anywhere else on the row follows\n * it. Takes precedence over `onRowClick`.\n */\n getRowHref?: (row: TData) => string;\n /** Renders the row link, e.g. through your router's `Link`. Default: a plain `<a>`. */\n renderRowLink?: (props: DataTableRowLinkProps) => ReactElement;\n /** A state tint per row, e.g. `(u) => (u.active ? undefined : 'muted')`. */\n getRowTone?: (row: TData) => TableRowTone | undefined;\n /** De-emphasise some rows, e.g. expired ones. */\n getRowDimmed?: (row: TData) => boolean;\n\n // ── States ──────────────────────────────────────────────────────────────────\n /** Shows skeleton rows in place of `data`. */\n loading?: boolean;\n /** How many skeleton rows. Default `5`. */\n loadingRows?: number;\n /** A load failure, shown in place of the rows. Takes precedence over loading and empty. */\n error?: ReactNode;\n /** Adds a Retry button to the error state. */\n onRetry?: () => void;\n /** Shown when there are no rows. A string, or your own node. Default \"No results found.\" */\n empty?: ReactNode;\n\n // ── Slots ───────────────────────────────────────────────────────────────────\n /** Extra toolbar content beside the search box: filters, a primary action. */\n toolbar?: ReactNode;\n /** Extra content below the pager, e.g. a \"refreshed 2 min ago\" note. */\n footer?: ReactNode;\n\n // ── Layout ──────────────────────────────────────────────────────────────────\n density?: DataTableDensity;\n /** Vertical alignment of body cells. Use `top` for multi-line or ragged cells. */\n align?: DataTableAlign;\n /**\n * Render rows as cards when the table's own width is below the breakpoint. Default `true`\n * at 560px. `false` always renders a table.\n */\n responsive?: boolean | { breakpoint?: number };\n\n // ── Server-side and controlled state ────────────────────────────────────────\n manual?: DataTableManual;\n /** Controlled state. Any key you pass is controlled; the rest stay internal. */\n state?: Partial<DataTableState>;\n onSortingChange?: (sorting: SortingState) => void;\n onGlobalFilterChange?: (value: string) => void;\n onColumnFiltersChange?: (filters: ColumnFiltersState) => void;\n onPaginationChange?: (pagination: PaginationState) => void;\n onColumnVisibilityChange?: (visibility: VisibilityState) => void;\n onRowSelectionChange?: (selection: RowSelectionState) => void;\n /** Passed to `useReactTable` last, for anything this API does not cover. */\n tableOptions?: Partial<TableOptions<TData>>;\n\n /** Classes on the bordered wrapper. Layout only, e.g. margins. */\n className?: string;\n}\n\n// ── Styles ─────────────────────────────────────────────────────────────────────\n\n/**\n * `default` is 0.2.0's spacing verbatim. `compact` is the audit / AI-widget density: an 11px\n * semibold uppercase header over 13px cells.\n */\nconst DENSITY: Record<DataTableDensity, { headerCell: string; headerText: string; bodyCell: string }> = {\n default: {\n headerCell: 'px-4 py-3',\n headerText: 'text-body-xs font-medium text-default-secondary',\n bodyCell: 'px-4 py-[14px]',\n },\n compact: {\n headerCell: 'px-3 py-2',\n headerText: 'text-body-tiny font-semibold uppercase tracking-[0.4px] text-default-secondary',\n bodyCell: 'px-3 py-2 text-body-xs text-default',\n },\n};\n\nconst VERTICAL: Record<DataTableAlign, string> = {\n center: 'align-middle',\n top: 'align-top',\n};\n\nconst TEXT_ALIGN: Record<DataTableColumnAlign, string> = {\n start: 'text-left',\n center: 'text-center',\n end: 'text-right',\n};\n\n/** Marks the row's primary link, so a click elsewhere on the row can follow it. */\nconst ROW_LINK_ATTR = 'data-row-link';\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nfunction resolve<T>(updater: Updater<T>, previous: T): T {\n return typeof updater === 'function' ? (updater as (old: T) => T)(previous) : updater;\n}\n\n/** One piece of table state, controlled when `controlled` is defined. */\nfunction useTableState<T>(\n controlled: T | undefined,\n initial: T,\n onChange: ((value: T) => void) | undefined,\n): [T, OnChangeFn<T>] {\n const [inner, setInner] = useState(initial);\n const value = controlled ?? inner;\n const latest = useRef(value);\n latest.current = value;\n const isControlled = controlled !== undefined;\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const set = useCallback<OnChangeFn<T>>(\n (updater) => {\n const next = resolve(updater, latest.current);\n if (!isControlled) setInner(next);\n onChangeRef.current?.(next);\n },\n [isControlled],\n );\n return [value, set];\n}\n\n/**\n * Stops a cell's own controls from also activating the row.\n *\n * `display: contents`, so it adds no box. `mousedown` is deliberately not stopped: that would\n * also stop the outside-press listener of an open menu in another row, which would then not\n * close.\n */\nfunction CellInteractionGuard({ children }: { children: ReactNode }) {\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions\n <div\n className=\"contents\"\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => event.stopPropagation()}\n onKeyUp={(event) => event.stopPropagation()}\n >\n {children}\n </div>\n );\n}\n\nconst HEADER_PADDING_PX: Record<DataTableDensity, number> = { default: 32, compact: 24 };\n\n/**\n * Each header's natural one-line width (content plus cell padding), keyed by column id.\n *\n * Headers are never truncated: a column narrower than its header is widened to this width,\n * and the table's minimum width grows with it, so a tight container scrolls sideways rather\n * than cutting \"Risk score\" down to \"Risk …\". The content is `w-max`, so its width does not\n * depend on the column's: no feedback loop. Re-measured once web fonts load.\n */\nfunction useHeaderWidths(padding: number, deps: unknown) {\n const nodes = useRef(new Map<string, HTMLElement>());\n const [widths, setWidths] = useState<Record<string, number>>({});\n\n const measure = useCallback(() => {\n const next: Record<string, number> = {};\n nodes.current.forEach((node, id) => {\n next[id] = Math.ceil(node.getBoundingClientRect().width) + padding;\n });\n setWidths((previous) => {\n const keys = Object.keys(next);\n const same =\n keys.length === Object.keys(previous).length && keys.every((key) => previous[key] === next[key]);\n return same ? previous : next;\n });\n }, [padding]);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(measure, [measure, deps]);\n useLayoutEffect(() => {\n let live = true;\n void document.fonts?.ready.then(() => live && measure());\n return () => {\n live = false;\n };\n }, [measure]);\n\n const register = useCallback(\n (id: string) => (node: HTMLElement | null) => {\n if (node) nodes.current.set(id, node);\n else nodes.current.delete(id);\n },\n [],\n );\n\n return { widths, register };\n}\n\n/**\n * Whether the horizontal scroller has content hidden off either edge. Drives the scroller\n * becoming a focusable, named region only when it really scrolls (WCAG 2.1.1), the edge\n * shadows, and sticky columns.\n */\nfunction useScrollEdges() {\n const [node, setNode] = useState<HTMLDivElement | null>(null);\n const [edges, setEdges] = useState({ overflowing: false, atStart: true, atEnd: true });\n\n const measure = useCallback(() => {\n if (!node) return;\n const { scrollLeft, scrollWidth, clientWidth } = node;\n const next = {\n overflowing: scrollWidth > clientWidth + 1,\n atStart: scrollLeft <= 1,\n atEnd: scrollLeft + clientWidth >= scrollWidth - 1,\n };\n setEdges((previous) =>\n previous.overflowing === next.overflowing &&\n previous.atStart === next.atStart &&\n previous.atEnd === next.atEnd\n ? previous\n : next,\n );\n }, [node]);\n\n useLayoutEffect(() => {\n if (!node) return;\n measure();\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(measure);\n observer.observe(node);\n if (node.firstElementChild) observer.observe(node.firstElementChild);\n return () => observer.disconnect();\n }, [node, measure]);\n\n return { ref: setNode, onScroll: measure, ...edges };\n}\n\nfunction defaultRowLink({ children, ...props }: DataTableRowLinkProps) {\n return <a {...props}>{children}</a>;\n}\n\n// ── DataTable ──────────────────────────────────────────────────────────────────\n\n/**\n * A data table on TanStack Table: sorting, search, pagination, column visibility and row\n * selection built in, client-side by default and server-driven through `manual`.\n *\n * <DataTable label=\"Suppliers\" columns={columns} data={suppliers} searchable columnVisibility />\n *\n * `TData` and `TValue` are inferred from `columns`, so `cell: ({ row }) => row.original.name`\n * is typed. Layout options (width, alignment, card-mode role, sticky) go in each column's `meta`.\n *\n * Layout, from SCIC's table:\n * - `table-fixed` plus one `<colgroup>`, so one set of widths governs every row and cells can\n * ellipsise. A column is never narrower than its header.\n * - Whatever does not fit scrolls inside a focusable, named region with edge shadows and\n * optional sticky first or last columns.\n * - Below 560px of its own width (not the viewport's) each row becomes a card: the title column\n * leads, `status` and `actions` sit at the top, the rest become labelled values.\n *\n * Accessibility: a real `<table>` with a caption, `aria-sort` on sortable headers, `aria-busy`\n * while loading, a polite announcement of the result count after a search, keyboard row\n * activation, and named selection checkboxes.\n */\nexport function DataTable<TData, TValue = unknown>({\n columns,\n data,\n getRowId,\n label,\n caption,\n searchable = false,\n columnVisibility: showColumnMenu = false,\n pagination: paginated = true,\n pageSize = 10,\n pageSizeOptions = [10, 20, 50],\n enableRowSelection,\n onSelectionChange,\n getRowLabel,\n onRowClick,\n getRowHref,\n renderRowLink = defaultRowLink,\n getRowTone,\n getRowDimmed,\n loading = false,\n loadingRows = 5,\n error,\n onRetry,\n empty = 'No results found.',\n toolbar,\n footer,\n density = 'default',\n align = 'center',\n responsive = true,\n manual = {},\n state = {},\n onSortingChange,\n onGlobalFilterChange,\n onColumnFiltersChange,\n onPaginationChange,\n onColumnVisibilityChange,\n onRowSelectionChange,\n tableOptions,\n className,\n}: DataTableProps<TData, TValue>) {\n if (!label && !caption) {\n devWarn('DataTable needs `label` or `caption`: an unnamed table is announced as just \"table\".');\n }\n if (manual.pagination && manual.rowCount === undefined) {\n devWarn('DataTable `manual.pagination` needs `manual.rowCount` to know how many pages there are.');\n }\n\n const [sorting, setSorting] = useTableState(state.sorting, [], onSortingChange);\n const [globalFilter, setGlobalFilter] = useTableState(state.globalFilter, '', onGlobalFilterChange);\n const [columnFilters, setColumnFilters] = useTableState(state.columnFilters, [], onColumnFiltersChange);\n const [pagination, setPagination] = useTableState(\n state.pagination,\n { pageIndex: 0, pageSize },\n onPaginationChange,\n );\n const [columnVisibility, setColumnVisibility] = useTableState(\n state.columnVisibility,\n {},\n onColumnVisibilityChange,\n );\n const [rowSelection, setRowSelection] = useTableState(state.rowSelection, {}, onRowSelectionChange);\n\n const allColumns = useMemo(() => {\n const cols = columns as ColumnDef<TData, unknown>[];\n if (!enableRowSelection || cols.some((column) => column.id === SELECT_COLUMN_ID)) return cols;\n return [createSelectColumn<TData>({ getRowLabel: getRowLabel && ((row) => `Select ${getRowLabel(row)}`) }), ...cols];\n }, [columns, enableRowSelection, getRowLabel]);\n\n const table = useReactTable<TData>({\n data,\n columns: allColumns,\n getRowId,\n state: { sorting, globalFilter, columnFilters, pagination, columnVisibility, rowSelection },\n onSortingChange: setSorting,\n onGlobalFilterChange: setGlobalFilter,\n onColumnFiltersChange: setColumnFilters,\n onPaginationChange: setPagination,\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: setRowSelection,\n enableRowSelection:\n typeof enableRowSelection === 'function'\n ? (row: Row<TData>) => enableRowSelection(row.original)\n : Boolean(enableRowSelection),\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: manual.sorting ? undefined : getSortedRowModel(),\n getFilteredRowModel: manual.filtering ? undefined : getFilteredRowModel(),\n getPaginationRowModel: paginated && !manual.pagination ? getPaginationRowModel() : undefined,\n manualSorting: manual.sorting,\n manualFiltering: manual.filtering,\n manualPagination: !paginated || manual.pagination,\n rowCount: manual.rowCount,\n ...tableOptions,\n });\n\n // Reported as rows rather than TanStack's id map, which is what a caller wants to act on.\n const selectionReported = useRef(false);\n useEffect(() => {\n if (!onSelectionChange) return;\n if (!selectionReported.current) {\n selectionReported.current = true;\n return;\n }\n onSelectionChange(table.getSelectedRowModel().rows.map((row) => row.original));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rowSelection]);\n\n // ── Layout mode ──────────────────────────────────────────────────────────────\n const [wrapRef, containerWidth] = useElementWidth<HTMLDivElement>();\n const breakpoint =\n responsive === false\n ? 0\n : typeof responsive === 'object'\n ? (responsive.breakpoint ?? DEFAULT_CARD_BREAKPOINT_PX)\n : DEFAULT_CARD_BREAKPOINT_PX;\n // The card switch carries hysteresis, so it reads the previous value. `nextLayoutMode` is a\n // fixed point, which is what makes computing it during render (and twice in StrictMode) safe.\n const modeRef = useRef<TableLayoutMode>('table');\n const mode = nextLayoutMode(modeRef.current, containerWidth, breakpoint);\n modeRef.current = mode;\n\n // ── Search ───────────────────────────────────────────────────────────────────\n const search = searchable === true ? {} : searchable || undefined;\n const searchColumn = search?.columnId ? table.getColumn(search.columnId) : undefined;\n const searchValue = searchColumn ? String(searchColumn.getFilterValue() ?? '') : globalFilter;\n const setSearchValue = (value: string) => {\n if (searchColumn) searchColumn.setFilterValue(value || undefined);\n else table.setGlobalFilter(value);\n };\n const filtering = Boolean(globalFilter) || columnFilters.length > 0;\n\n // ── Placeholder states ───────────────────────────────────────────────────────\n const rows = table.getRowModel().rows;\n const isEmpty = !loading && !error && rows.length === 0;\n const placeholder = error ? (\n <EmptyState\n message={typeof error === 'string' ? error : 'Something went wrong loading this data.'}\n variant=\"error\"\n size=\"md\"\n action={\n onRetry ? (\n <Button variant=\"neutral\" size=\"sm\" onClick={onRetry}>\n Retry\n </Button>\n ) : undefined\n }\n className=\"mx-auto max-w-[520px]\"\n />\n ) : isEmpty ? (\n typeof empty === 'string' ? (\n <EmptyState message={empty} size=\"md\" className=\"mx-auto max-w-[520px]\" />\n ) : (\n empty\n )\n ) : null;\n\n const resultCount = manual.filtering ? table.getRowCount() : table.getFilteredRowModel().rows.length;\n const showToolbar = Boolean(search || toolbar || showColumnMenu);\n const showPager = paginated && !error && table.getRowCount() > 0;\n\n const view = {\n table,\n label,\n caption,\n density,\n align,\n loading,\n loadingRows,\n placeholder,\n onRowClick,\n getRowHref,\n renderRowLink,\n getRowTone,\n getRowDimmed,\n getRowLabel,\n };\n\n return (\n <div data-slot=\"data-table\" className={cn('flex flex-col gap-3', className)}>\n {showToolbar && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {search && (\n <SearchInput\n size=\"sm\"\n label={search.label ?? 'Search'}\n placeholder={search.placeholder ?? 'Search…'}\n value={searchValue}\n onChange={(event) => setSearchValue(event.target.value)}\n onClear={() => setSearchValue('')}\n className=\"w-full max-w-[280px]\"\n />\n )}\n {toolbar}\n {showColumnMenu && (\n <div className=\"ml-auto\">\n <DataTableViewOptions table={table} />\n </div>\n )}\n </div>\n )}\n\n {/* Announced after a search, so a screen-reader user learns the effect of what they typed. */}\n <p role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {filtering && !loading ? `${resultCount} ${resultCount === 1 ? 'result' : 'results'}` : ''}\n </p>\n\n {/* Border, radius and corner clipping, and the measured node: its width is set by the\n parent, never by which layout renders inside, so measuring it cannot loop. */}\n <div ref={wrapRef} className=\"overflow-hidden rounded-xl border border-default bg-default\">\n {mode === 'cards' ? <CardList {...view} /> : <TableView {...view} />}\n\n {showPager && (\n <div className=\"border-t border-default px-4 py-3\">\n <DataTablePagination table={table} pageSizeOptions={pageSizeOptions} />\n </div>\n )}\n {footer && <div className=\"border-t border-default px-4 py-3\">{footer}</div>}\n </div>\n </div>\n );\n}\n\n// ── Views ──────────────────────────────────────────────────────────────────────\n\ninterface ViewProps<TData> {\n table: TanstackTable<TData>;\n label?: string;\n caption?: ReactNode;\n density: DataTableDensity;\n align: DataTableAlign;\n loading: boolean;\n loadingRows: number;\n /** Error or empty content; null when rows should render. */\n placeholder: ReactNode;\n onRowClick?: (row: TData) => void;\n getRowHref?: (row: TData) => string;\n renderRowLink: (props: DataTableRowLinkProps) => ReactElement;\n getRowTone?: (row: TData) => TableRowTone | undefined;\n getRowDimmed?: (row: TData) => boolean;\n getRowLabel?: (row: TData) => string;\n}\n\n/** The column the row link (or card title) belongs to: `mobile: 'title'`, else the first. */\nfunction titleColumnId<TData>(columns: Column<TData, unknown>[]): string | undefined {\n const content = columns.filter((column) => column.id !== SELECT_COLUMN_ID);\n return (content.find((column) => column.columnDef.meta?.mobile === 'title') ?? content[0])?.id;\n}\n\nfunction TableView<TData>({\n table,\n label,\n caption,\n density,\n align,\n loading,\n loadingRows,\n placeholder,\n onRowClick,\n getRowHref,\n renderRowLink,\n getRowTone,\n getRowDimmed,\n}: ViewProps<TData>) {\n const d = DENSITY[density];\n const columns = table.getVisibleLeafColumns();\n const scroll = useScrollEdges();\n const headers = useHeaderWidths(HEADER_PADDING_PX[density], columns.map((column) => column.id).join());\n\n // A column is never narrower than its header (see useHeaderWidths).\n const columnPx = (column: Column<TData, unknown>) =>\n Math.max(widthToPx(column.columnDef.meta?.width), headers.widths[column.id] ?? 0);\n const minWidth = columns.reduce((sum, column) => sum + columnPx(column), 0);\n const showPlaceholder = loading || placeholder !== null;\n\n // Sticky only matters while something is actually scrolled out of view.\n const first = columns[0];\n const last = columns[columns.length - 1];\n const stickyStart = scroll.overflowing && first?.columnDef.meta?.sticky === 'start' ? first.id : undefined;\n const stickyEnd =\n scroll.overflowing && last?.columnDef.meta?.sticky === 'end' && last !== first ? last.id : undefined;\n const hasSticky = Boolean(stickyStart || stickyEnd);\n const titleId = titleColumnId(columns);\n const rowAction = getRowHref ? 'link' : onRowClick ? 'click' : null;\n\n const stickyClass = (id: string, header: boolean) =>\n clsx(\n id === stickyStart && [\n 'sticky left-0 z-raised',\n // A hairline where content slides under the pinned column, once it has scrolled.\n !scroll.atStart && 'shadow-[inset_-1px_0_0_var(--color-border-default-default)]',\n ],\n id === stickyEnd && [\n 'sticky right-0 z-raised',\n !scroll.atEnd && 'shadow-[inset_1px_0_0_var(--color-border-default-default)]',\n ],\n (id === stickyStart || id === stickyEnd) &&\n (header ? 'bg-default-secondary' : ['bg-default', rowAction && 'group-hover:bg-default-secondary']),\n );\n\n const regionLabel = label ? `${label} (scrolls horizontally)` : 'Table (scrolls horizontally)';\n\n return (\n <div className=\"relative\">\n {/* The one scroll container. It cannot clip a row's action menu: menus portal out. */}\n <div\n ref={scroll.ref}\n onScroll={scroll.onScroll}\n className={cn('overflow-x-auto overscroll-x-contain', SCROLLBAR_CLASSES, scroll.overflowing && FOCUS_RING_INSET)}\n {...(scroll.overflowing ? { role: 'region', tabIndex: 0, 'aria-label': regionLabel } : {})}\n >\n <table\n className=\"w-full table-fixed border-collapse text-left\"\n // Dropped in the placeholder states: with a minimum width, a colSpan message centres\n // in the scrolled coordinate space and can sit off-screen.\n style={showPlaceholder ? undefined : { minWidth }}\n aria-busy={loading || undefined}\n >\n {/* Must precede <colgroup> per the HTML content model. */}\n {caption ? (\n <caption className=\"px-4 pt-3 text-left text-body-sm text-default-secondary\">{caption}</caption>\n ) : (\n label && <caption className=\"sr-only\">{label}</caption>\n )}\n\n <colgroup>\n {columns.map((column) => {\n const meta = column.columnDef.meta;\n const floor = headers.widths[column.id] ?? 0;\n return (\n <col\n key={column.id}\n style={\n meta?.grow || !meta?.width\n ? undefined\n : { width: floor > widthToPx(meta.width) ? floor : meta.width }\n }\n />\n );\n })}\n </colgroup>\n\n <thead>\n {table.getHeaderGroups().map((group) => (\n <tr key={group.id} className=\"bg-default-secondary\">\n {group.headers.map((header) => {\n const meta = header.column.columnDef.meta;\n const sortable = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n const definition = header.column.columnDef.header;\n return (\n <th\n key={header.id}\n scope=\"col\"\n colSpan={header.colSpan}\n // Omitted when the column cannot sort: aria-sort=\"none\" would tell a\n // screen-reader user the column IS sortable and is simply unsorted.\n aria-sort={\n sortable ? (sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : 'none') : undefined\n }\n className={cn(\n d.headerCell,\n d.headerText,\n TEXT_ALIGN[meta?.align ?? 'start'],\n !meta?.interactive && 'overflow-hidden',\n stickyClass(header.column.id, true),\n meta?.headerClassName,\n )}\n >\n {header.isPlaceholder ? null : typeof definition === 'string' || definition === undefined ? (\n <span ref={meta?.hideHeader ? undefined : headers.register(header.column.id)} className=\"inline-block\">\n <DataTableColumnHeader column={header.column} />\n </span>\n ) : (\n flexRender(definition, header.getContext())\n )}\n </th>\n );\n })}\n </tr>\n ))}\n </thead>\n\n <tbody>\n {loading && !placeholder ? (\n Array.from({ length: loadingRows }, (_, index) => (\n <tr key={`skeleton-${index}`} className={clsx(index > 0 && 'border-t border-default')}>\n {columns.map((column) => (\n <td key={column.id} className={clsx(d.bodyCell, 'align-middle')}>\n <Skeleton className={column.columnDef.meta?.grow ? 'w-[70%]' : 'w-[55%]'} />\n </td>\n ))}\n </tr>\n ))\n ) : placeholder ? (\n <tr>\n <td colSpan={columns.length} className=\"px-4\">\n {placeholder}\n </td>\n </tr>\n ) : (\n table.getRowModel().rows.map((row) => (\n <BodyRow\n key={row.id}\n row={row}\n density={density}\n align={align}\n titleId={titleId}\n rowAction={rowAction}\n hasSticky={hasSticky}\n stickyClass={stickyClass}\n onRowClick={onRowClick}\n getRowHref={getRowHref}\n renderRowLink={renderRowLink}\n getRowTone={getRowTone}\n getRowDimmed={getRowDimmed}\n />\n ))\n )}\n </tbody>\n </table>\n </div>\n\n {/* Edge shadows: the scroll affordance a thin (or overlay) scrollbar does not give. */}\n {scroll.overflowing && !scroll.atStart && !stickyStart && (\n <span aria-hidden className=\"pointer-events-none absolute inset-y-0 left-0 w-6 bg-gradient-to-r from-default-secondary to-transparent\" />\n )}\n {scroll.overflowing && !scroll.atEnd && !stickyEnd && (\n <span aria-hidden className=\"pointer-events-none absolute inset-y-0 right-0 w-6 bg-gradient-to-l from-default-secondary to-transparent\" />\n )}\n </div>\n );\n}\n\ninterface BodyRowProps<TData>\n extends Pick<ViewProps<TData>, 'density' | 'align' | 'onRowClick' | 'getRowHref' | 'renderRowLink' | 'getRowTone' | 'getRowDimmed'> {\n row: Row<TData>;\n titleId: string | undefined;\n rowAction: 'link' | 'click' | null;\n hasSticky: boolean;\n stickyClass: (id: string, header: boolean) => string;\n}\n\nfunction BodyRow<TData>({\n row,\n density,\n align,\n titleId,\n rowAction,\n hasSticky,\n stickyClass,\n onRowClick,\n getRowHref,\n renderRowLink,\n getRowTone,\n getRowDimmed,\n}: BodyRowProps<TData>) {\n const d = DENSITY[density];\n const href = getRowHref?.(row.original);\n\n return (\n <TableRow\n selected={row.getIsSelected() || undefined}\n tone={getRowTone?.(row.original)}\n dimmed={getRowDimmed?.(row.original)}\n className={cn(\n 'group',\n rowAction && ['cursor-pointer', hasSticky && 'hover:bg-default-secondary'],\n // outline, not ring: `ring-*` is box-shadow, which browsers do not paint on a <tr>\n // under border-collapse.\n rowAction === 'click' &&\n 'outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-brand',\n )}\n // Navigation rows are reached through their title link, so the row is not a second tab\n // stop. Click-to-open rows have no link, so the row is one. No role=\"button\": it would\n // replace the row role and detach the row from the table.\n tabIndex={rowAction === 'click' ? 0 : undefined}\n onClick={\n rowAction === 'link'\n ? (event) => {\n // The link handles its own clicks, including modifier-clicks.\n if ((event.target as HTMLElement).closest('a')) return;\n event.currentTarget.querySelector<HTMLAnchorElement>(`[${ROW_LINK_ATTR}]`)?.click();\n }\n : rowAction === 'click'\n ? () => onRowClick!(row.original)\n : undefined\n }\n onKeyDown={\n rowAction === 'click'\n ? (event) => {\n // A keystroke that started inside a cell control is not a row activation.\n if (event.target !== event.currentTarget) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onRowClick!(row.original);\n }\n }\n : undefined\n }\n >\n {row.getVisibleCells().map((cell) => (\n <BodyCell\n key={cell.id}\n cell={cell}\n className={cn(d.bodyCell, VERTICAL[align], stickyClass(cell.column.id, false))}\n link={href && cell.column.id === titleId ? href : undefined}\n renderRowLink={renderRowLink}\n />\n ))}\n </TableRow>\n );\n}\n\nfunction BodyCell<TData>({\n cell,\n className,\n link,\n renderRowLink,\n}: {\n cell: Cell<TData, unknown>;\n className: string;\n link?: string;\n renderRowLink: (props: DataTableRowLinkProps) => ReactElement;\n}) {\n const meta = cell.column.columnDef.meta;\n let content: ReactNode = flexRender(cell.column.columnDef.cell, cell.getContext());\n if (link) {\n content = renderRowLink({\n href: link,\n [ROW_LINK_ATTR]: '',\n className: cn('block min-w-0 rounded-sm', FOCUS_RING_INSET),\n children: content,\n });\n }\n\n return (\n <td\n className={cn(\n className,\n TEXT_ALIGN[meta?.align ?? 'start'],\n // Guards against a bespoke cell bleeding into the next column. Interactive cells opt\n // out so focus rings are not clipped.\n !meta?.interactive && 'overflow-hidden',\n meta?.cellClassName,\n )}\n >\n {meta?.interactive ? <CellInteractionGuard>{content}</CellInteractionGuard> : content}\n </td>\n );\n}\n\n// ── Card mode ──────────────────────────────────────────────────────────────────\n\n/**\n * Rows as a list of cards, for containers too narrow for a table.\n *\n * The title is the row's one link or button, stretched over the card with `::after` so the\n * whole card is a hit target while its accessible name stays the title text. Actions, the\n * selection checkbox and interactive fields sit above the stretch (`relative z-raised`) so they\n * stay operable. Values are a `<dl>` whose terms are the column labels, so each value keeps the\n * label a table header would otherwise give it.\n */\nfunction CardList<TData>({\n table,\n label,\n loading,\n loadingRows,\n placeholder,\n onRowClick,\n getRowHref,\n renderRowLink,\n getRowTone,\n getRowDimmed,\n getRowLabel,\n}: ViewProps<TData>) {\n if (placeholder) return <div className=\"px-4\">{placeholder}</div>;\n\n if (loading) {\n return (\n <ul aria-label={label} aria-busy=\"true\" className=\"divide-y divide-default\">\n {Array.from({ length: loadingRows }, (_, index) => (\n <li key={index} className=\"flex flex-col gap-3 p-4\">\n <Skeleton className=\"w-2/3\" />\n <Skeleton className=\"w-1/2\" />\n <Skeleton className=\"w-5/6\" />\n </li>\n ))}\n </ul>\n );\n }\n\n const columns = table.getVisibleLeafColumns();\n const selectable = columns.some((column) => column.id === SELECT_COLUMN_ID);\n const slots = cardSlots(\n columns\n .filter((column) => column.id !== SELECT_COLUMN_ID)\n .map((column) => ({ id: column.id, mobile: column.columnDef.meta?.mobile, column })),\n );\n const trigger = clsx(\n 'block w-full min-w-0 text-left focus-visible:outline-none',\n \"after:absolute after:inset-0 after:content-['']\",\n 'focus-visible:after:ring-2 focus-visible:after:ring-inset focus-visible:after:ring-brand',\n );\n\n return (\n // Card mode un-truncates: on touch there is no hover tooltip, so a clipped value would be\n // unreadable. `.truncate` cell renderers wrap here instead.\n <ul\n aria-label={label}\n className=\"divide-y divide-default [&_.truncate]:whitespace-normal [&_.truncate]:[overflow-wrap:anywhere]\"\n >\n {table.getRowModel().rows.map((row) => {\n const cells = new Map(row.getVisibleCells().map((cell) => [cell.column.id, cell]));\n const render = (id: string | undefined) => {\n const cell = id ? cells.get(id) : undefined;\n return cell ? flexRender(cell.column.columnDef.cell, cell.getContext()) : null;\n };\n const href = getRowHref?.(row.original);\n const titleContent = render(slots.title?.id);\n const tone = getRowTone?.(row.original);\n\n return (\n <li\n key={row.id}\n data-state={row.getIsSelected() ? 'selected' : undefined}\n data-tone={tone && tone !== 'default' ? tone : undefined}\n data-dimmed={getRowDimmed?.(row.original) || undefined}\n className={cn(\n 'relative flex flex-col gap-3 p-4 transition-colors',\n (href || onRowClick) && 'hover:bg-default-secondary/50',\n 'data-[tone=muted]:bg-default-secondary data-[tone=brand]:bg-brand-tertiary',\n 'data-[tone=positive]:bg-positive-tertiary data-[tone=warning]:bg-warning-tertiary',\n 'data-[tone=danger]:bg-danger-tertiary data-[dimmed]:opacity-60',\n 'data-[state=selected]:bg-brand-tertiary',\n )}\n >\n <div className=\"flex items-start gap-3\">\n {selectable && <div className=\"relative z-raised shrink-0 pt-0.5\">{render(SELECT_COLUMN_ID)}</div>}\n <div className=\"min-w-0 flex-1\">\n {href ? (\n renderRowLink({ href, [ROW_LINK_ATTR]: '', className: trigger, children: titleContent })\n ) : onRowClick ? (\n <button\n type=\"button\"\n className={trigger}\n aria-label={getRowLabel?.(row.original)}\n onClick={() => onRowClick(row.original)}\n >\n {titleContent}\n </button>\n ) : (\n titleContent\n )}\n </div>\n {slots.status && (\n // A status pill is `nowrap`, so a long label would spill off the card. Let it\n // wrap inside the cap instead.\n <div className=\"flex max-w-[45%] shrink-0 justify-end [&_.whitespace-nowrap]:whitespace-normal\">\n {render(slots.status.id)}\n </div>\n )}\n {slots.actions && (\n <div className=\"relative z-raised shrink-0\">\n <CellInteractionGuard>{render(slots.actions.id)}</CellInteractionGuard>\n </div>\n )}\n </div>\n\n {slots.fields.length > 0 && (\n <dl className=\"grid grid-cols-[repeat(auto-fill,minmax(min(100%,8.5rem),1fr))] gap-x-4 gap-y-2.5\">\n {slots.fields.map(({ id, column }) => (\n <div key={id} className={clsx('min-w-0', column.columnDef.meta?.interactive && 'relative z-raised')}>\n <dt className=\"text-body-tiny text-default-secondary\">{columnLabel(column)}</dt>\n <dd className=\"mt-0.5 min-w-0 text-body-xs text-default\">\n {column.columnDef.meta?.interactive ? (\n <CellInteractionGuard>{render(id)}</CellInteractionGuard>\n ) : (\n render(id)\n )}\n </dd>\n </div>\n ))}\n </dl>\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport {\n DataTableColumnHeader,\n DataTablePagination,\n DataTableViewOptions,\n createSelectColumn,\n SELECT_COLUMN_ID,\n} from './data-table-parts';\nexport type {\n DataTableColumnHeaderProps,\n DataTablePaginationProps,\n DataTableViewOptionsProps,\n CreateSelectColumnOptions,\n} from './data-table-parts';\nexport type { ColumnMobileRole } from './data-table-layout';\nexport {\n TableCellLeadText,\n TableCellText,\n TableCellBadge,\n TableCellProgress,\n} from './data-table-cells';\nexport type {\n TableCellSize,\n TableCellLeadTextProps,\n TableCellTextProps,\n TableCellBadgeProps,\n TableCellProgressProps,\n} from './data-table-cells';\n","import { useEffect, useLayoutEffect, useState } from 'react';\n\n/** `useLayoutEffect` in the browser, `useEffect` during a server render (which has no layout). */\nconst useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\n/**\n * Tracks an element's rendered content-box width. New in 0.7.0, from SCIC.\n *\n * Use this when a component must switch *structure*, not just styling, based on the space it\n * actually has, e.g. `DataTable` swapping table rows for cards. Viewport breakpoints lie there:\n * a docked drawer or a one-third-width detail panel shrinks a component without the viewport\n * changing.\n *\n * Returns `[ref, width]`. `width` is `undefined` until the first measurement, which happens in\n * a layout effect so the first paint already uses it. Attach `ref` to a node whose width does\n * NOT depend on the structure you switch (typically the component's outer wrapper), or the\n * switch becomes a feedback loop.\n */\nexport function useElementWidth<T extends HTMLElement = HTMLElement>(): [\n (node: T | null) => void,\n number | undefined,\n] {\n // State rather than a ref so the observer is re-attached if React swaps the node.\n const [node, setNode] = useState<T | null>(null);\n const [width, setWidth] = useState<number | undefined>(undefined);\n\n useIsomorphicLayoutEffect(() => {\n if (!node) return;\n const apply = (next: number) => {\n // A hidden subtree (a display:none tab panel) measures 0. Keep the last width rather\n // than flipping layouts while invisible.\n if (next <= 0) return;\n setWidth((prev) => (prev !== undefined && Math.abs(prev - next) < 1 ? prev : next));\n };\n apply(node.getBoundingClientRect().width);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) apply(entry.contentRect.width);\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, [node]);\n\n return [setNode, width];\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\n\nexport type EmptyStateVariant = 'empty' | 'loading' | 'error';\nexport type EmptyStateSize = 'sm' | 'md' | 'lg';\n\n/**\n * Vertical padding. The eighteen source copies used `py-8`, with divergent siblings\n * at `py-10`, `py-12` and `py-16` — these three sizes absorb all four.\n */\nconst SIZES: Record<EmptyStateSize, string> = {\n sm: 'py-8',\n md: 'py-12',\n lg: 'py-16',\n};\n\nconst TONES: Record<EmptyStateVariant, string> = {\n empty: 'text-default-secondary',\n loading: 'text-default-secondary',\n error: 'text-danger',\n};\n\nexport interface EmptyStateProps {\n message: string;\n /** `error` is the only variant that changes colour; `loading` exists for intent. */\n variant?: EmptyStateVariant;\n size?: EmptyStateSize;\n icon?: ReactNode;\n /** A primary action, e.g. \"Add your first source\". */\n action?: ReactNode;\n className?: string;\n}\n\n/**\n * Centred placeholder for an empty list, a loading list, or a failed fetch.\n *\n * Replaces eighteen copies of `py-8 text-center text-body-sm\n * text-default-secondary` plus four divergent variants. Loading and empty were\n * always the same markup in this codebase, so they are one component with a\n * `variant` rather than two near-identical ones.\n *\n * `aria-live` is set for the loading and error variants so a screen reader announces\n * the state change instead of silently swapping list content.\n */\nexport function EmptyState({\n message,\n variant = 'empty',\n size = 'sm',\n icon,\n action,\n className,\n}: EmptyStateProps) {\n return (\n <div\n data-variant={variant}\n className={clsx(\n 'flex flex-col items-center justify-center gap-2 px-4 text-center text-body-sm',\n SIZES[size],\n TONES[variant],\n className,\n )}\n aria-live={variant === 'empty' ? undefined : 'polite'}\n >\n {icon && <span className=\"text-default-tertiary\">{icon}</span>}\n <p>{message}</p>\n {action}\n </div>\n );\n}\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport clsx from 'clsx';\n\nexport type SkeletonShape = 'line' | 'block' | 'circle';\n\nexport interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n shape?: SkeletonShape;\n /** Number of stacked lines. Only meaningful for `line`. */\n lines?: number;\n}\n\nconst SHAPE: Record<SkeletonShape, string> = {\n line: 'h-4 rounded',\n block: 'h-full w-full rounded-lg',\n circle: 'aspect-square rounded-full',\n};\n\n/**\n * Loading placeholder.\n *\n * `aria-hidden` and no role: a skeleton is a picture of content that does not exist yet,\n * so announcing it produces a burst of meaningless nodes. The *region* it sits in should\n * carry the loading state — `EmptyState variant=\"loading\"` or `aria-busy` on the\n * container — which is a decision only the caller can make.\n *\n * The pulse is suppressed by the preset's `prefers-reduced-motion` rule, leaving a plain\n * tinted block.\n */\nexport const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(function Skeleton(\n { shape = 'line', lines = 1, className, ...rest },\n ref,\n) {\n if (shape === 'line' && lines > 1) {\n return (\n <div ref={ref} aria-hidden data-slot=\"skeleton-group\" className=\"flex flex-col gap-2\" {...rest}>\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={clsx(\n 'animate-pulse bg-default-tertiary',\n SHAPE.line,\n // A ragged last line reads as a paragraph rather than a solid slab.\n index === lines - 1 ? 'w-3/5' : 'w-full',\n className,\n )}\n />\n ))}\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n aria-hidden\n data-slot=\"skeleton\"\n className={clsx('animate-pulse bg-default-tertiary', SHAPE[shape], className)}\n {...rest}\n />\n );\n});\n","/**\n * DataTable's responsive decisions, as pure functions. Ported from SCIC in 0.7.0.\n *\n * Kept out of `data-table.tsx` so they are unit-testable without a DOM or React.\n *\n * Every decision is keyed on the TABLE CONTAINER's measured width, never the viewport: a nav\n * rail, page padding, a docked drawer or a one-third-width detail panel all shrink a table\n * without the window changing.\n */\n\nexport type TableLayoutMode = 'table' | 'cards';\n\n/** How a column appears in card mode. */\nexport type ColumnMobileRole = 'title' | 'status' | 'actions' | 'field' | 'hidden';\n\nexport interface LayoutColumn {\n id: string;\n mobile?: ColumnMobileRole;\n}\n\n/**\n * Container width below which rows render as cards. Fits a 390px phone (≈358px of content)\n * and keeps a 768px tablet (≈632px beside a nav rail) in table mode.\n */\nexport const DEFAULT_CARD_BREAKPOINT_PX = 560;\n\n/**\n * How far past the breakpoint the width must travel before the layout follows it.\n *\n * Load-bearing, not polish: switching modes changes the table's height, which can add or\n * remove the page's vertical scrollbar (15–17px on Windows), which changes the very width\n * that was measured. A margin narrower than a scrollbar is a two-state oscillator.\n */\nexport const LAYOUT_HYSTERESIS_PX = 24;\n\nconst FALLBACK_COLUMN_WIDTH_PX = 160;\n\n/** Only `Npx` and `Nrem` are parsed. An exotic value must not throw, only mis-estimate. */\nexport function widthToPx(width: string | undefined): number {\n if (!width) return FALLBACK_COLUMN_WIDTH_PX;\n const px = /^(\\d+(?:\\.\\d+)?)px$/.exec(width);\n if (px) return Number(px[1]);\n const rem = /^(\\d+(?:\\.\\d+)?)rem$/.exec(width);\n if (rem) return Number(rem[1]) * 16;\n return FALLBACK_COLUMN_WIDTH_PX;\n}\n\n/**\n * Card or table, holding still inside the hysteresis band. A fixed point:\n * `nextLayoutMode(nextLayoutMode(m, w), w) === nextLayoutMode(m, w)`, which is what makes it\n * safe to re-run on every render and ResizeObserver callback.\n */\nexport function nextLayoutMode(\n current: TableLayoutMode,\n widthPx: number | undefined,\n breakpointPx: number = DEFAULT_CARD_BREAKPOINT_PX,\n): TableLayoutMode {\n if (widthPx === undefined || !Number.isFinite(widthPx) || widthPx <= 0) return current;\n if (breakpointPx <= 0) return 'table';\n if (current === 'table') return widthPx < breakpointPx - LAYOUT_HYSTERESIS_PX ? 'cards' : 'table';\n return widthPx >= breakpointPx + LAYOUT_HYSTERESIS_PX ? 'table' : 'cards';\n}\n\nexport interface CardSlots<C extends LayoutColumn> {\n title: C | undefined;\n status?: C;\n actions?: C;\n fields: C[];\n}\n\n/**\n * Which column plays which part in a row card.\n *\n * The title falls back to the first column so an un-annotated table still produces sensible\n * cards: its identity column leads and everything else becomes labelled fields.\n */\nexport function cardSlots<C extends LayoutColumn>(columns: C[]): CardSlots<C> {\n const title = columns.find((c) => c.mobile === 'title') ?? columns[0];\n const status = columns.find((c) => c.mobile === 'status' && c !== title);\n const actions = columns.find((c) => c.mobile === 'actions' && c !== title);\n const fields = columns.filter(\n (c) => c !== title && c !== status && c !== actions && c.mobile !== 'hidden',\n );\n return { title, status, actions, fields };\n}\n","import type { ReactNode } from 'react';\nimport type { Column, ColumnDef, Table as TanstackTable } from '@tanstack/react-table';\nimport { ChevronDownIcon, ChevronUpIcon, ChevronsUpDownIcon, Columns3Icon } from 'lucide-react';\n\nimport { cn } from '../../lib/cn';\nimport { FOCUS_RING } from '../../lib/focus-ring';\nimport { Button } from '../forms/button';\nimport { Checkbox } from '../forms/checkbox';\nimport { PaginationBar } from '../chrome/pagination';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from '../overlays/dropdown-menu';\n\n/**\n * The composable parts of `DataTable`. `DataTable` renders all of them for you; they are\n * exported for a table that needs its own layout around them (a toolbar elsewhere on the\n * page, a pager in a sticky footer) or a custom header renderer.\n */\n\n/** The id `createSelectColumn` gives its column, so `DataTable` can find and place it. */\nexport const SELECT_COLUMN_ID = 'select';\n\n/**\n * A column's human name: `meta.label`, else its string `header`, else its id.\n *\n * Needed wherever a column is named outside its own header cell (the column visibility menu,\n * card-mode field labels, the sort button), because `header` may be a render function.\n */\nexport function columnLabel<TData>(column: Column<TData, unknown>): string {\n const meta = column.columnDef.meta;\n if (meta?.label) return meta.label;\n const header = column.columnDef.header;\n return typeof header === 'string' ? header : column.id;\n}\n\n// ── Column header ──────────────────────────────────────────────────────────────\n\nexport interface DataTableColumnHeaderProps<TData, TValue> {\n column: Column<TData, TValue>;\n /** Header text. Defaults to the column's label. */\n title?: string;\n className?: string;\n}\n\n/**\n * A header that sorts its column when the column can sort, and plain text when it cannot.\n * `DataTable` uses it for every string `header`. Use it yourself inside a `header` render\n * function to keep the sort control while adding something next to it.\n *\n * A click cycles the sort (ascending → descending → off). Shift-click adds the column to a\n * multi-column sort. The direction is announced through `aria-sort` on the `<th>`, which\n * `DataTable` sets, so this button carries only the visible chevron.\n */\nexport function DataTableColumnHeader<TData, TValue>({\n column,\n title,\n className,\n}: DataTableColumnHeaderProps<TData, TValue>) {\n const text = title ?? columnLabel(column as Column<TData, unknown>);\n const hidden = column.columnDef.meta?.hideHeader;\n\n if (!column.getCanSort()) {\n return (\n <span className={cn(hidden ? 'sr-only' : 'inline-block w-max whitespace-nowrap', className)}>\n {text}\n </span>\n );\n }\n\n const sorted = column.getIsSorted();\n const Icon = sorted === 'asc' ? ChevronUpIcon : sorted === 'desc' ? ChevronDownIcon : ChevronsUpDownIcon;\n\n return (\n <button\n type=\"button\"\n onClick={column.getToggleSortingHandler()}\n data-sorted={sorted || undefined}\n className={cn(\n // w-max + nowrap: a header is never truncated; its column widens to fit it instead.\n 'inline-flex w-max items-center gap-1 whitespace-nowrap rounded-sm transition-colors hover:text-default',\n 'data-[sorted]:text-default',\n FOCUS_RING,\n className,\n )}\n >\n <span className={cn(hidden && 'sr-only')}>{text}</span>\n <Icon\n aria-hidden\n data-sorted={sorted || undefined}\n className=\"size-3.5 shrink-0 text-icon-default-secondary data-[sorted]:text-icon-brand\"\n />\n </button>\n );\n}\n\n// ── Selection column ───────────────────────────────────────────────────────────\n\nexport interface CreateSelectColumnOptions<TData> {\n /** Names each row's checkbox, e.g. `(row) => \\`Select ${row.name}\\``. Default \"Select row\". */\n getRowLabel?: (row: TData) => string;\n /** Names the header checkbox. Default \"Select all rows on this page\". */\n selectAllLabel?: string;\n}\n\n/**\n * A leading checkbox column. `DataTable` adds one automatically when `enableRowSelection` is\n * set and the columns have none, so call this only to place it yourself or to name the rows.\n *\n * The header checkbox selects the current *page*, which is what a user can see, and shows\n * indeterminate while some of the page is selected.\n */\nexport function createSelectColumn<TData>(\n options: CreateSelectColumnOptions<TData> = {},\n): ColumnDef<TData, unknown> {\n const { getRowLabel, selectAllLabel = 'Select all rows on this page' } = options;\n return {\n id: SELECT_COLUMN_ID,\n header: ({ table }) => (\n <Checkbox\n aria-label={selectAllLabel}\n checked={table.getIsAllPageRowsSelected()}\n indeterminate={table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected()}\n onCheckedChange={(checked) => table.toggleAllPageRowsSelected(checked)}\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n aria-label={getRowLabel ? getRowLabel(row.original) : 'Select row'}\n checked={row.getIsSelected()}\n disabled={!row.getCanSelect()}\n onCheckedChange={(checked) => row.toggleSelected(checked)}\n />\n ),\n enableSorting: false,\n enableHiding: false,\n enableGlobalFilter: false,\n meta: { width: '48px', interactive: true, mobile: 'hidden', label: 'Select' },\n };\n}\n\n// ── Column visibility ──────────────────────────────────────────────────────────\n\nexport interface DataTableViewOptionsProps<TData> {\n table: TanstackTable<TData>;\n /** Trigger text. Default \"Columns\". */\n label?: string;\n}\n\n/** A \"Columns\" menu that shows and hides every column whose `enableHiding` is not false. */\nexport function DataTableViewOptions<TData>({ table, label = 'Columns' }: DataTableViewOptionsProps<TData>) {\n const columns = table.getAllLeafColumns().filter((column) => column.getCanHide());\n if (columns.length === 0) return null;\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"neutral\" size=\"sm\" leadingIcon={<Columns3Icon aria-hidden />}>\n {label}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Show columns</DropdownMenuLabel>\n {columns.map((column) => (\n <DropdownMenuCheckboxItem\n key={column.id}\n checked={column.getIsVisible()}\n onCheckedChange={(visible) => column.toggleVisibility(visible)}\n >\n {columnLabel(column as Column<TData, unknown>)}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n// ── Pagination ─────────────────────────────────────────────────────────────────\n\nexport interface DataTablePaginationProps<TData> {\n table: TanstackTable<TData>;\n /** Page sizes on offer. An empty array hides the selector. Default `[10, 20, 50]`. */\n pageSizeOptions?: number[];\n /** Replaces the \"Showing 1–10 of 57\" summary. */\n summary?: ReactNode;\n}\n\n/** The pager row: a range summary, a page-size selector, and page buttons. */\nexport function DataTablePagination<TData>({\n table,\n pageSizeOptions = [10, 20, 50],\n summary,\n}: DataTablePaginationProps<TData>) {\n const { pageIndex, pageSize } = table.getState().pagination;\n return (\n <PaginationBar\n page={pageIndex + 1}\n pageSize={pageSize}\n total={table.getRowCount()}\n onPageChange={(page) => table.setPageIndex(page - 1)}\n onPageSizeChange={(size) => table.setPageSize(size)}\n pageSizeOptions={pageSizeOptions}\n summary={summary}\n label=\"Table pages\"\n />\n );\n}\n","import clsx from 'clsx';\nimport type { ReactNode } from 'react';\nimport { ProgressBar } from '../feedback/progress-bar';\nimport type { ProgressBarTone } from '../feedback/progress-bar';\n\n/**\n * Cell renderers for `DataTable` (and the `Table` parts). Unchanged in 0.7.0; moved out of\n * `data-table.tsx` when the table itself was rebuilt on TanStack Table.\n */\n\n// ── Cell components ────────────────────────────────────────────────────────────\n\n/**\n * Cell type scale.\n *\n * Named `size`, not `density`, and deliberately *not* inherited from the table: the two\n * real compact tables disagree about the mapping — the audit table wants default\n * padding with small cell text — so inheritance could not express it anyway, and it\n * would make these render one size inside a table and another outside one.\n */\nexport type TableCellSize = 'sm' | 'md';\n\nexport interface TableCellLeadTextProps {\n primary: string;\n secondary?: string;\n size?: TableCellSize;\n className?: string;\n}\n\n/** Primary text plus an optional muted subtitle — for lead entity/name cells. */\nexport function TableCellLeadText({ primary, secondary, size = 'md', className }: TableCellLeadTextProps) {\n return (\n <div className={clsx('flex flex-col gap-0.5', className)}>\n <span\n className={clsx(\n 'font-medium leading-snug text-default',\n size === 'sm' ? 'text-body-xs' : 'text-body-sm',\n )}\n >\n {primary}\n </span>\n {secondary && (\n <span\n className={clsx(\n 'font-normal leading-tight text-default-secondary',\n size === 'sm' ? 'text-body-tiny' : 'text-body-xs',\n )}\n >\n {secondary}\n </span>\n )}\n </div>\n );\n}\n\nexport interface TableCellTextProps {\n children: ReactNode;\n /** Muted (secondary) by default; pass false for the primary colour. */\n muted?: boolean;\n size?: TableCellSize;\n /** Ellipsise instead of wrapping, so every row keeps the same height. */\n truncate?: boolean;\n className?: string;\n}\n\n/** Plain text cell. */\nexport function TableCellText({\n children,\n muted = true,\n size = 'md',\n truncate = false,\n className,\n}: TableCellTextProps) {\n return (\n <span\n className={clsx(\n 'font-normal leading-snug',\n size === 'sm' ? 'text-body-tiny' : 'text-body-xs',\n truncate ? 'block truncate' : 'whitespace-nowrap',\n muted ? 'text-default-secondary' : 'text-default',\n className,\n )}\n >\n {children}\n </span>\n );\n}\n\nexport interface TableCellBadgeProps {\n label: string;\n className?: string;\n}\n\n/** Small outlined chip — entity type labels, categories. */\nexport function TableCellBadge({ label, className }: TableCellBadgeProps) {\n return (\n <span\n className={clsx(\n 'inline-flex items-center rounded-md border border-default bg-default-secondary px-2 py-0.5 text-body-tiny font-medium text-default-secondary whitespace-nowrap',\n className,\n )}\n >\n {label}\n </span>\n );\n}\n\nexport interface TableCellProgressProps {\n percent: number;\n /**\n * Bar colour. `brand` is 0.2.0's default and byte-identical to it — `bg-brand`\n * resolves to the same `--prim-brand-900` the old raw-hex default hardcoded.\n */\n tone?: ProgressBarTone;\n size?: TableCellSize;\n className?: string;\n}\n\n/** Mini progress bar with a percentage label below. */\nexport function TableCellProgress({\n percent,\n tone = 'brand',\n size = 'md',\n className,\n}: TableCellProgressProps) {\n const clamped = Math.min(100, Math.max(0, percent));\n return (\n <div className={clsx('flex flex-col gap-1', className)}>\n {/* Delegates to ProgressBar rather than hand-rolling a second bar, which is what\n 0.2.0 did — the two then disagreed on the track colour. */}\n <ProgressBar\n value={clamped}\n tone={tone}\n size=\"sm\"\n // `size` used to drive the label's font size, which was `text-[10px]` — off the type\n // scale, whose smallest step is 11px. The label is now `text-body-tiny` at both\n // sizes, so `size` drives the bar's width instead: 48 / 64px, both on the Space ramp.\n className={size === 'sm' ? 'w-12' : 'w-16'}\n aria-label={`${clamped}%`}\n />\n <span className=\"text-body-tiny leading-none text-default-secondary\">\n {percent}%\n </span>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { CircleCheckBigIcon, InfoIcon, TriangleAlertIcon } from 'lucide-react';\n\nexport type InlineAlertTone = 'info' | 'warning' | 'danger' | 'positive';\n\nexport interface InlineAlertProps {\n tone: InlineAlertTone;\n children: ReactNode;\n /** Overrides the per-tone default glyph. Pass `null` for no icon. */\n icon?: ReactNode | null;\n className?: string;\n}\n\nconst toneStyles: Record<InlineAlertTone, string> = {\n info: 'border-brand-tertiary bg-brand-tertiary text-brand',\n warning: 'border-warning-tertiary bg-warning-tertiary text-warning',\n danger: 'border-danger-tertiary bg-danger-tertiary text-danger',\n positive: 'border-positive-tertiary bg-positive-tertiary text-positive',\n};\n\nconst toneIcons: Record<InlineAlertTone, ReactNode> = {\n info: <InfoIcon className=\"size-4\" />,\n warning: <TriangleAlertIcon className=\"size-4\" />,\n danger: <TriangleAlertIcon className=\"size-4\" />,\n positive: <CircleCheckBigIcon className=\"size-4\" />,\n};\n\n/** Banner for inline messaging — form errors, destructive-action warnings, success confirmations.\n *\n * Replaces four byte-identical raw-`amber-*` callouts, five competing error-text styles and a\n * standalone `Banner` component. `danger` renders as `role=\"alert\"`; the rest as `role=\"status\"`. */\nexport function InlineAlert({ tone, children, icon, className }: InlineAlertProps) {\n const glyph = icon === undefined ? toneIcons[tone] : icon;\n\n return (\n <div\n data-tone={tone}\n role={tone === 'danger' ? 'alert' : 'status'}\n className={clsx(\n 'flex items-start gap-3 rounded-xl border p-4 text-body-xs',\n toneStyles[tone],\n className,\n )}\n >\n {/* The glyph restates the tone the text already carries, so it is decoration —\n `lucide-react` hides its own SVGs, but any node can be passed here, so the wrapper\n hides it rather than trusting the glyph to keep out of a `role=\"alert\"` region. */}\n {glyph && (\n <span aria-hidden className=\"mt-px shrink-0\">\n {glyph}\n </span>\n )}\n <div className=\"min-w-0\">{children}</div>\n </div>\n );\n}\n","import { Component, type ErrorInfo, type ReactNode } from 'react';\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n /** Shown in place of the children when they throw. Default a quiet \"Something went wrong\". */\n fallback?: ReactNode;\n /** Changing this resets the boundary. Use the identity of whatever is being rendered. */\n resetKey?: string;\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n error: Error | null;\n}\n\n/**\n * Stops one broken subtree from taking down the whole app. New in 0.7.0, from SCIC.\n *\n * React unmounts the entire root when a render throws with no boundary above it, so one widget\n * that trips over an unexpected API shape blanks the screen instead of one card. This is the\n * floor under that: everything outside the boundary keeps working.\n *\n * A class, because error boundaries can only be classes. The error is still logged: the\n * fallback deliberately says nothing technical, so the console is how the cause is found.\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { error };\n }\n\n componentDidUpdate(previous: ErrorBoundaryProps) {\n if (this.state.error && previous.resetKey !== this.props.resetKey) {\n this.setState({ error: null });\n }\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error('[ErrorBoundary]', error, info.componentStack);\n this.props.onError?.(error, info);\n }\n\n render() {\n if (!this.state.error) return this.props.children;\n return (\n this.props.fallback ?? (\n <div\n role=\"status\"\n data-slot=\"error-boundary\"\n className=\"flex h-full w-full items-center justify-center rounded-lg border border-default bg-default p-4 text-center text-body-xs text-default-secondary\"\n >\n Something went wrong loading this.\n </div>\n )\n );\n }\n}\n","import { forwardRef, useId, type HTMLAttributes, type ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { CircleCheckBigIcon, InfoIcon, TriangleAlertIcon, XIcon } from 'lucide-react';\nimport { IconButton } from '../forms/icon-button';\nimport type { InlineAlertTone } from './inline-alert';\n\nexport type BannerVariant = 'message' | 'alert';\n\n// `title` is omitted from the base attributes because the HTML `title` attribute is a\n// string that renders a native tooltip — the same collision that made 0.2.0's\n// `Modal.title` become `Modal.label`. Here the prop is the more useful one, so the\n// attribute gives way.\nexport interface BannerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Bold first line. Matches Figma's `Title`. */\n title: ReactNode;\n /** Supporting copy. Matches Figma's `Body`. */\n children?: ReactNode;\n /**\n * Matches Figma's `Variant` axis. `message` is informational; `alert` is urgent and is\n * announced immediately.\n */\n variant?: BannerVariant;\n tone?: InlineAlertTone;\n /** Replaces the tone glyph. Pass `null` to suppress it. Matches `Icon` / `Has Icon`. */\n icon?: ReactNode | null;\n /** Trailing action slot. Matches `Has Button`. */\n action?: ReactNode;\n /** Renders a dismiss button. Matches `Dismissible`. */\n onDismiss?: () => void;\n}\n\nconst TONE_STYLES: Record<InlineAlertTone, string> = {\n info: 'border-brand-tertiary bg-brand-tertiary text-default',\n positive: 'border-positive-tertiary bg-positive-tertiary text-default',\n warning: 'border-warning-tertiary bg-warning-tertiary text-default',\n danger: 'border-danger-tertiary bg-danger-tertiary text-default',\n};\n\nconst TONE_ICON_COLOR: Record<InlineAlertTone, string> = {\n info: 'text-icon-brand',\n positive: 'text-icon-positive',\n warning: 'text-icon-warning',\n danger: 'text-icon-danger',\n};\n\nconst TONE_ICON: Record<InlineAlertTone, ReactNode> = {\n info: <InfoIcon aria-hidden className=\"size-5\" />,\n positive: <CircleCheckBigIcon aria-hidden className=\"size-5\" />,\n warning: <TriangleAlertIcon aria-hidden className=\"size-5\" />,\n danger: <TriangleAlertIcon aria-hidden className=\"size-5\" />,\n};\n\n/**\n * A page- or section-level banner with a title, body, optional action and optional dismiss.\n *\n * This is Figma's `Notification` set (`Variant: Message | Alert`, with `Title`, `Body`,\n * `Has Icon`, `Has Button` and `Dismissible`). Worth being precise about the name: its\n * Figma keywords are \"message, alert, feedback, callout, banner\" — it is a *persistent,\n * in-flow* notice, **not** a toast. A toast is transient, stacked, and announced from a\n * live region that already exists; that is `Toast`, and it is a different component.\n *\n * `InlineAlert` remains the compact single-line form for use inside a form or a card.\n * `Banner` is the one with a heading and an action.\n *\n * `variant` drives the announcement, not just the styling: `alert` is `role=\"alert\"`\n * (interrupts), `message` is `role=\"status\"` (waits its turn).\n */\nexport const Banner = forwardRef<HTMLDivElement, BannerProps>(function Banner(\n {\n title,\n children,\n variant = 'message',\n tone = 'info',\n icon,\n action,\n onDismiss,\n className,\n ...rest\n },\n ref,\n) {\n const titleId = useId();\n const glyph = icon === undefined ? TONE_ICON[tone] : icon;\n\n return (\n <div\n data-tone={tone}\n data-variant={variant}\n ref={ref}\n role={variant === 'alert' ? 'alert' : 'status'}\n aria-labelledby={titleId}\n data-slot=\"banner\"\n className={clsx(\n 'flex w-full items-start gap-3 rounded-xl border p-4',\n TONE_STYLES[tone],\n className,\n )}\n {...rest}\n >\n {glyph && (\n <span aria-hidden className={clsx('mt-px shrink-0', TONE_ICON_COLOR[tone])}>\n {glyph}\n </span>\n )}\n <div className=\"min-w-0 flex-1\">\n <p id={titleId} className=\"text-body-sm font-semibold text-default\">\n {title}\n </p>\n {children && <div className=\"mt-1 text-body-xs text-default-secondary\">{children}</div>}\n {action && <div className=\"mt-3 flex items-center gap-2\">{action}</div>}\n </div>\n {onDismiss && (\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n // Named with the title, so several stacked banners do not all announce\n // \"Dismiss\" identically.\n aria-label={typeof title === 'string' ? `Dismiss: ${title}` : 'Dismiss'}\n onClick={onDismiss}\n className=\"-mr-1 -mt-1 shrink-0\"\n >\n <XIcon aria-hidden size={16} />\n </IconButton>\n )}\n </div>\n );\n});\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport clsx from 'clsx';\nimport { CircleCheckBigIcon, InfoIcon, TriangleAlertIcon, XIcon } from 'lucide-react';\nimport { IconButton } from '../forms/icon-button';\nimport { Portal } from '../overlays/portal';\nimport { TOASTER_ATTRIBUTE } from '../overlays/toaster-guard';\nimport type { InlineAlertTone } from './inline-alert';\n\nexport type ToastTone = InlineAlertTone;\nexport type ToasterPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface ToastOptions {\n title: ReactNode;\n description?: ReactNode;\n tone?: ToastTone;\n /** Milliseconds before auto-dismiss. `0` keeps it until dismissed. Default `5000`. */\n duration?: number;\n action?: ReactNode;\n}\n\nexport interface ToastRecord extends ToastOptions {\n id: string;\n}\n\ninterface ToastContextValue {\n toast: (options: ToastOptions) => string;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\n/**\n * Queue a toast. Must be called under a `<Toaster>`.\n *\n * Returns the toast's id so a long-running action can dismiss its own \"Saving…\" toast when\n * it finishes.\n */\nexport function useToast(): ToastContextValue {\n const context = useContext(ToastContext);\n if (!context) throw new Error('useToast() must be used inside <Toaster>');\n return context;\n}\n\nconst TONE_ICON: Record<ToastTone, ReactNode> = {\n info: <InfoIcon aria-hidden className=\"size-4\" />,\n positive: <CircleCheckBigIcon aria-hidden className=\"size-4\" />,\n warning: <TriangleAlertIcon aria-hidden className=\"size-4\" />,\n danger: <TriangleAlertIcon aria-hidden className=\"size-4\" />,\n};\n\nconst TONE_ICON_COLOR: Record<ToastTone, string> = {\n info: 'text-icon-brand',\n positive: 'text-icon-positive',\n warning: 'text-icon-warning',\n danger: 'text-icon-danger',\n};\n\nconst POSITION: Record<ToasterPosition, string> = {\n 'top-left': 'top-4 left-4 items-start',\n 'top-center': 'top-4 left-1/2 -translate-x-1/2 items-center',\n 'top-right': 'top-4 right-4 items-end',\n 'bottom-left': 'bottom-4 left-4 items-start',\n 'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2 items-center',\n 'bottom-right': 'bottom-4 right-4 items-end',\n};\n\nexport interface ToasterProps {\n children: ReactNode;\n position?: ToasterPosition;\n /** Maximum simultaneous toasts. Oldest are dropped first. Default `4`. */\n max?: number;\n /** Default auto-dismiss for toasts that do not set their own. Default `5000`. */\n duration?: number;\n}\n\n/**\n * Provider plus the region toasts render into. Mount once, near the app root.\n *\n * The library had no toast and — more importantly — **no persistent live region at all**,\n * so nothing could announce an event that happened away from focus. The distinction that\n * matters here: a live region must already exist in the DOM before content is put into it.\n * A region that mounts at the same moment as its message is frequently not announced,\n * which is why the wrapper below renders unconditionally and only its children come and go.\n *\n * `aria-live=\"polite\"` on the container, and `role=\"alert\"` on individual `danger` toasts\n * so a failure interrupts rather than queueing behind a success message.\n */\nexport function Toaster({\n children,\n position = 'bottom-right',\n max = 4,\n duration = 5000,\n}: ToasterProps) {\n const [toasts, setToasts] = useState<ToastRecord[]>([]);\n const timers = useRef(new Map<string, ReturnType<typeof setTimeout>>());\n const counter = useRef(0);\n\n const dismiss = useCallback((id: string) => {\n const timer = timers.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timers.current.delete(id);\n }\n setToasts((current) => current.filter((entry) => entry.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => {\n for (const timer of timers.current.values()) clearTimeout(timer);\n timers.current.clear();\n setToasts([]);\n }, []);\n\n const toast = useCallback(\n (options: ToastOptions) => {\n // A monotonic counter rather than a random id: `Math.random()` in a render-adjacent\n // path is a hydration hazard, and the value only has to be unique within the session.\n counter.current += 1;\n const id = `toast-${counter.current}`;\n const record: ToastRecord = { tone: 'info', duration, ...options, id };\n\n setToasts((current) => [...current, record].slice(-max));\n\n if (record.duration && record.duration > 0) {\n timers.current.set(\n id,\n setTimeout(() => dismiss(id), record.duration),\n );\n }\n return id;\n },\n [duration, max, dismiss],\n );\n\n useEffect(() => {\n const map = timers.current;\n return () => {\n for (const timer of map.values()) clearTimeout(timer);\n map.clear();\n };\n }, []);\n\n const context = useMemo(() => ({ toast, dismiss, dismissAll }), [toast, dismiss, dismissAll]);\n\n return (\n <ToastContext.Provider value={context}>\n {children}\n <Portal>\n <div\n // Unconditionally rendered, and empty most of the time. See the note above: a\n // live region has to pre-exist its content to be announced reliably.\n aria-live=\"polite\"\n aria-atomic=\"false\"\n // Lets an open Modal recognise a press on a toast as not-outside (see\n // overlays/toaster-guard.ts). `aria-live` already keeps the region out of the\n // set Radix hides from assistive tech behind a modal.\n {...{ [TOASTER_ATTRIBUTE]: '' }}\n className={clsx(\n 'pointer-events-none fixed z-toast flex w-full max-w-[380px] flex-col gap-2',\n POSITION[position],\n )}\n >\n {toasts.map((entry) => (\n <ToastItem key={entry.id} toast={entry} onDismiss={() => dismiss(entry.id)} />\n ))}\n </div>\n </Portal>\n </ToastContext.Provider>\n );\n}\n\nfunction ToastItem({ toast, onDismiss }: { toast: ToastRecord; onDismiss: () => void }) {\n const tone = toast.tone ?? 'info';\n\n return (\n <div\n // The container is polite; a danger toast escalates to assertive so a failure is not\n // read out after two successes.\n role={tone === 'danger' ? 'alert' : 'status'}\n // Re-enabled per toast — the container is pointer-events-none so it never blocks\n // clicks on the page behind an empty region.\n className={clsx(\n 'pointer-events-auto flex w-full items-start gap-3 rounded-xl border border-default',\n 'bg-default p-4 shadow-400',\n )}\n >\n <span aria-hidden className={clsx('mt-px shrink-0', TONE_ICON_COLOR[tone])}>\n {TONE_ICON[tone]}\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-body-sm font-semibold text-default\">{toast.title}</p>\n {toast.description && (\n <p className=\"mt-0.5 text-body-xs text-default-secondary\">{toast.description}</p>\n )}\n {toast.action && <div className=\"mt-2 flex items-center gap-2\">{toast.action}</div>}\n </div>\n <IconButton\n variant=\"subtle\"\n size=\"sm\"\n aria-label={typeof toast.title === 'string' ? `Dismiss: ${toast.title}` : 'Dismiss'}\n onClick={onDismiss}\n className=\"-mr-1 -mt-1 shrink-0\"\n >\n <XIcon aria-hidden size={14} />\n </IconButton>\n </div>\n );\n}\n","import { forwardRef, useState } from 'react';\nimport { EyeIcon, EyeOffIcon } from 'lucide-react';\n\nimport { Input, type InputProps } from './input';\n\nexport type PasswordInputProps = Omit<InputProps, 'type' | 'trailingIcon' | 'trailingAction'>;\n\n/** Password field with a show/hide visibility toggle. */\nexport const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>(function PasswordInput(props, ref) {\n const [visible, setVisible] = useState(false);\n\n return (\n <Input\n ref={ref}\n {...props}\n type={visible ? 'text' : 'password'}\n trailingAction={\n <button\n type=\"button\"\n aria-label={visible ? 'Hide password' : 'Show password'}\n onClick={() => setVisible((v) => !v)}\n className=\"flex items-center justify-center rounded transition-colors hover:text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand\"\n >\n {visible ? (\n <EyeOffIcon aria-hidden className=\"size-4\" />\n ) : (\n <EyeIcon aria-hidden className=\"size-4\" />\n )}\n </button>\n }\n />\n );\n});\n","import clsx from 'clsx';\nimport { ArrowRightIcon, SearchIcon } from 'lucide-react';\n\nexport interface AIChatBarProps {\n placeholder?: string;\n className?: string;\n}\n\nexport function AIChatBar({\n placeholder = 'Ask Intelligence about any entity, supplier, or risk…',\n className,\n}: AIChatBarProps) {\n return (\n <div\n className={clsx(\n 'flex h-16 items-center gap-3 rounded-2xl border border-default bg-default px-6 shadow-panel',\n className,\n )}\n >\n <span aria-hidden className=\"shrink-0 text-icon-default-secondary\">\n <SearchIcon className=\"size-4\" />\n </span>\n <p className=\"flex-1 text-body-sm text-default-tertiary truncate\">{placeholder}</p>\n <button\n type=\"button\"\n className=\"inline-flex shrink-0 items-center gap-2 rounded-xl bg-brand px-4 py-3 text-body-sm font-semibold text-brand-on-brand hover:bg-brand-hover transition-colors\"\n >\n Ask\n <ArrowRightIcon aria-hidden className=\"size-4\" />\n </button>\n </div>\n );\n}\n","import clsx from 'clsx';\nimport { ArrowRightIcon, CpuIcon } from 'lucide-react';\n\nexport interface AISuggestionChipProps {\n prompt: string;\n onClick?: () => void;\n className?: string;\n}\n\nexport function AISuggestionChip({ prompt, onClick, className }: AISuggestionChipProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={clsx(\n 'flex h-12 w-full items-center gap-3 rounded-xl border border-default bg-default px-3 text-left hover:bg-default-hover transition-colors',\n className,\n )}\n >\n <span aria-hidden className=\"shrink-0 text-icon-brand\">\n <CpuIcon className=\"size-4\" />\n </span>\n <span className=\"flex-1 text-body-sm text-default truncate\">{prompt}</span>\n <span aria-hidden className=\"shrink-0 text-icon-default-secondary\">\n <ArrowRightIcon className=\"size-3.5\" strokeWidth={2.5} />\n </span>\n </button>\n );\n}\n","import clsx from 'clsx';\nimport { TagPill } from '../status/tag-pill';\n\nexport interface QuickAction {\n label: string;\n value: string;\n}\n\nexport interface QuickActionsBarProps {\n actions: QuickAction[];\n active?: string;\n onSelect?: (value: string) => void;\n className?: string;\n}\n\nexport function QuickActionsBar({ actions, active, onSelect, className }: QuickActionsBarProps) {\n return (\n <div className={clsx('flex flex-wrap items-center gap-3', className)}>\n {actions.map((action) => {\n const isActive = active === action.value;\n return (\n <button\n key={action.value}\n type=\"button\"\n // `aria-pressed` because these are toggles, not navigation — through 0.3.0 the\n // `active` prop was conveyed by the pill's fill colour only.\n aria-pressed={isActive}\n onClick={() => onSelect?.(action.value)}\n // Was `focus:outline-none` with no replacement — the UA indicator removed and\n // nothing put back, a straight WCAG 2.4.7 failure.\n className=\"rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1 focus-visible:ring-offset-default\"\n >\n <TagPill label={action.label} tone={isActive ? 'brand' : 'default'} />\n </button>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport clsx from 'clsx';\nimport { CpuIcon } from 'lucide-react';\nimport { cn } from '../../lib/cn';\n\n/**\n * Presentational pieces of an AI chat transcript, ported from SCIC in 0.7.0. Markup only: the\n * conversation state and streaming stay in the app. SCIC's hard-coded hex colours are replaced\n * by tokens, so the bubbles follow dark mode.\n */\n\nexport interface AiAvatarProps {\n className?: string;\n /** The glyph. Default a chip, SCIC's assistant mark. */\n icon?: ReactNode;\n}\n\n/** The assistant's round mark, decorative. */\nexport function AiAvatar({ className, icon }: AiAvatarProps) {\n return (\n <span\n aria-hidden\n className={cn('flex size-8 shrink-0 items-center justify-center rounded-full bg-brand text-icon-brand-on-brand', className)}\n >\n {icon ?? <CpuIcon className=\"size-3.5\" />}\n </span>\n );\n}\n\nexport interface TypingIndicatorProps {\n /** What the assistant is doing, read aloud. Default \"Assistant is typing\". */\n label?: string;\n className?: string;\n}\n\n/**\n * \"The assistant is working\": an avatar, the label and three pulsing dots. A polite live region,\n * so a screen reader hears the label once rather than nothing. The dots stop under\n * `prefers-reduced-motion`.\n */\nexport function TypingIndicator({ label = 'Assistant is typing', className }: TypingIndicatorProps) {\n return (\n <div role=\"status\" aria-live=\"polite\" className={cn('flex items-center gap-3', className)}>\n <AiAvatar />\n <div className=\"flex items-center gap-2 rounded-2xl rounded-tl-sm border border-default bg-default-secondary px-5 py-3\">\n <span className=\"text-body-xs text-default-secondary\">{label}</span>\n <span aria-hidden className=\"flex gap-1\">\n {[0, 1, 2].map((index) => (\n <span\n key={index}\n className=\"inline-block size-1.5 rounded-full bg-default-tertiary motion-safe:animate-bounce\"\n style={{ animationDelay: `${index * 0.15}s` }}\n />\n ))}\n </span>\n </div>\n </div>\n );\n}\n\nexport type ChatBubbleSender = 'user' | 'assistant';\n\nexport interface ChatBubbleProps {\n /**\n * Who wrote the message. Called `role` in SCIC; renamed so it cannot be mistaken for (or\n * linted as) an ARIA role.\n */\n sender: ChatBubbleSender;\n children: ReactNode;\n /** `assistant` only: the failed-turn palette, set as `data-state=\"failed\"`. */\n failed?: boolean;\n className?: string;\n}\n\n/** One message. The user's sits right in a dark bubble; the assistant's spans the column. */\nexport function ChatBubble({ sender, children, failed = false, className }: ChatBubbleProps) {\n if (sender === 'user') {\n return (\n <div data-sender=\"user\" className={cn('flex justify-end', className)}>\n <div className=\"max-w-[85%] rounded-[18px] rounded-tr-sm bg-neutral px-5 py-3.5 text-body-sm leading-relaxed text-neutral-on-neutral md:max-w-[441px] md:px-7 md:py-4\">\n {children}\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-sender=\"assistant\"\n data-state={failed ? 'failed' : undefined}\n className={cn(\n 'rounded-2xl rounded-tl-sm border px-5 py-4 text-body-sm leading-relaxed',\n clsx(\n 'border-default bg-default-secondary text-default',\n 'data-[state=failed]:border-danger-secondary data-[state=failed]:bg-danger-tertiary data-[state=failed]:text-danger',\n ),\n className,\n )}\n >\n {children}\n </div>\n );\n}\n","/** Soft aurora atmosphere used by the public-facing screens (auth, event\n * onboarding) — mirrors AuroraBackground in pages/intelligence. Blobs are\n * corner-anchored so the effect scales from phones to kiosk displays.\n * Render inside a `relative overflow-hidden` container; content goes on top\n * with `relative`. */\nexport function AuroraBackdrop() {\n return (\n <div className=\"pointer-events-none absolute inset-0\" aria-hidden>\n <div className=\"absolute -left-24 -top-28\" style={{ width: 380, height: 380, background: 'radial-gradient(ellipse, rgba(249,133,133,0.45) 0%, transparent 70%)' }} />\n <div className=\"absolute -top-24 right-[-4%]\" style={{ width: 320, height: 320, background: 'radial-gradient(ellipse, rgba(254,160,160,0.4) 0%, transparent 70%)' }} />\n <div className=\"absolute bottom-[-10%] right-[14%]\" style={{ width: 420, height: 420, background: 'radial-gradient(ellipse, rgba(196,181,253,0.3) 0%, transparent 70%)' }} />\n <div className=\"absolute bottom-[-6%] left-[4%]\" style={{ width: 280, height: 280, background: 'radial-gradient(ellipse, rgba(147,197,253,0.25) 0%, transparent 70%)' }} />\n <div className=\"absolute left-[20%] top-[30%]\" style={{ width: 240, height: 240, background: 'radial-gradient(ellipse, rgba(173,216,255,0.18) 0%, transparent 70%)' }} />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["import_react","import_clsx","import_clsx","Slot","clsx","import_react","import_clsx","Spinner","size","clsx","import_react","import_jsx_runtime","size","import_jsx_runtime","clsx","Button","size","import_react","import_clsx","import_jsx_runtime","variantStyles","clsx","sizeStyles","IconButton","size","import_clsx","import_jsx_runtime","clsx","size","import_clsx","import_jsx_runtime","sizeStyles","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_react","import_jsx_runtime","size","FieldSet","import_react","import_clsx","import_jsx_runtime","size","clsx","Input","InputControl","import_react","import_clsx","import_jsx_runtime","Textarea","size","TextareaControl","clsx","import_react","import_clsx","import_react","import_react","import_react","import_clsx","import_clsx","clsx","clsx","import_react","import_react","lockScroll","import_react","import_jsx_runtime","import_jsx_runtime","SelectControl","size","clsx","Select","import_react","import_clsx","import_lucide_react","import_jsx_runtime","inputBase","iconWrap","DatePicker","size","clsx","DateInput","import_clsx","import_lucide_react","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_lucide_react","import_jsx_runtime","SIZE","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Switch","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Toggle","size","clsx","ToggleGroupItem","import_react","import_clsx","import_jsx_runtime","InputOTP","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_react","import_clsx","import_clsx","import_lucide_react","import_jsx_runtime","size","clsx","import_jsx_runtime","clsx","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","size","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","size","clsx","import_jsx_runtime","size","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","TONE_STYLES","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_jsx_runtime","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","sizeStyles","toneStyles","size","clsx","import_react","import_clsx","import_clsx","import_lucide_react","import_jsx_runtime","size","clsx","import_jsx_runtime","LABEL_TEXT","Checkbox","size","clsx","import_react","import_clsx","import_jsx_runtime","RadioGroup","size","clsx","LABEL_TEXT","Radio","import_react","import_clsx","import_jsx_runtime","RadioCards","size","SIZE","RadioCardsItem","clsx","import_react","import_jsx_runtime","CheckboxGroup","size","CheckboxGroupItem","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","Slider","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Label","size","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","offset","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","HEIGHT","InputGroup","size","clsx","InputGroupInput","InputGroupAddon","InputGroupText","SearchInput","import_react","import_lucide_react","import_jsx_runtime","SIZE","Modal","DialogPrimitive","ModalShell","size","ModalTrigger","ModalClose","ModalHeader","ModalTitle","ModalDescription","ModalBody","ModalFooter","import_react","import_radix_ui","import_jsx_runtime","TooltipPrimitive","import_react","import_radix_ui","import_jsx_runtime","PopoverPrimitive","PopoverTrigger","PopoverContent","PopoverClose","PopoverAnchor","import_react","import_radix_ui","import_jsx_runtime","HoverCardPrimitive","import_react","import_radix_ui","import_react","import_clsx","import_lucide_react","import_jsx_runtime","clsx","RadioGroup","Label","Separator","import_jsx_runtime","ContextMenuPrimitive","ContextMenuTrigger","ContextMenuContent","import_react","import_radix_ui","import_jsx_runtime","Menubar","MenubarPrimitive","MenubarTrigger","MenubarContent","parts","import_react","import_radix_ui","import_lucide_react","import_react","import_clsx","import_jsx_runtime","ScrollArea","clsx","import_jsx_runtime","Drawer","DialogPrimitive","extractTrigger","withoutTrigger","DrawerPanel","DrawerTrigger","DrawerClose","isTrigger","DrawerHeader","DrawerTitle","DrawerDescription","DrawerBody","DrawerFooter","import_react","import_jsx_runtime","size","import_react","import_jsx_runtime","size","import_react","import_radix_ui","import_lucide_react","import_jsx_runtime","DropdownMenuPrimitive","DropdownMenuTrigger","DropdownMenuContent","parts","import_jsx_runtime","import_react","import_radix_ui","import_lucide_react","import_jsx_runtime","DialogPrimitive","import_react","import_radix_ui","import_jsx_runtime","VisuallyHidden","VisuallyHiddenPrimitive","import_radix_ui","import_jsx_runtime","AccessibleIconPrimitive","import_react","import_jsx_runtime","FOOTER_ALIGN","size","import_react","import_clsx","import_radix_ui","import_lucide_react","import_jsx_runtime","Accordion","AccordionPrimitive","AccordionItem","AccordionTrigger","Heading","clsx","AccordionContent","import_react","import_radix_ui","import_jsx_runtime","Collapsible","CollapsiblePrimitive","CollapsibleTrigger","CollapsibleContent","import_react","import_jsx_runtime","GAP","PAD","Box","Flex","Grid","Container","size","Section","import_react","import_clsx","import_jsx_runtime","AspectRatio","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","size","clsx","import_clsx","import_jsx_runtime","size","clsx","import_clsx","import_lucide_react","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_jsx_runtime","GAP","size","clsx","import_react","import_clsx","import_radix_ui","import_jsx_runtime","SIZE","clsx","size","TabsPrimitive","TabsList","TabsTrigger","TabsContent","import_clsx","import_jsx_runtime","SIZE","VARIANT","clsx","size","import_clsx","import_jsx_runtime","clsx","import_react","import_clsx","import_jsx_runtime","Separator","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","Kbd","size","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","Breadcrumb","clsx","BreadcrumbItem","BreadcrumbEllipsis","import_react","import_clsx","import_lucide_react","import_jsx_runtime","GAP","clsx","Pagination","size","import_react","import_clsx","import_jsx_runtime","NavigationMenu","clsx","NavigationMenuItem","import_react","import_clsx","import_jsx_runtime","TONE","Component","Blockquote","TextLink","clsx","TextList","TextListItem","import_clsx","import_clsx","import_jsx_runtime","sizeStyles","size","clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","size","clsx","size","import_react","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","sizeStyles","size","clsx","import_clsx","import_jsx_runtime","SIZE","TONE","size","clsx","import_clsx","import_jsx_runtime","COLUMNS","clsx","import_clsx","import_jsx_runtime","SIZE","size","labelClass","clsx","import_clsx","import_jsx_runtime","SIZE","size","offset","clsx","import_clsx","import_jsx_runtime","SIZE","size","clsx","import_react","import_clsx","import_jsx_runtime","SIZE","size","clsx","import_clsx","import_jsx_runtime","SIZE","size","clsx","offset","import_clsx","import_clsx","import_jsx_runtime","size","clsx","import_jsx_runtime","size","clsx","import_clsx","import_lucide_react","import_jsx_runtime","SIZE","WEIGHT","size","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","GAP","ALIGN","clsx","import_clsx","import_react","import_jsx_runtime","SIZE","size","import_jsx_runtime","GAP","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","COLUMNS","import_react","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_lucide_react","import_jsx_runtime","COLUMNS","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","size","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","Table","clsx","TableCaption","TableHeader","TableBody","TableFooter","TableRow","ALIGN","TableHead","TableCell","import_react","import_clsx","import_react","useIsomorphicLayoutEffect","import_clsx","import_jsx_runtime","size","clsx","import_react","import_clsx","import_jsx_runtime","SHAPE","Skeleton","clsx","import_lucide_react","import_jsx_runtime","size","import_clsx","import_jsx_runtime","size","clsx","import_jsx_runtime","DENSITY","padding","clsx","import_react_table","import_clsx","import_lucide_react","import_jsx_runtime","toneStyles","clsx","import_react","import_jsx_runtime","import_react","import_clsx","import_lucide_react","import_jsx_runtime","TONE_STYLES","TONE_ICON","Banner","clsx","import_react","import_clsx","import_lucide_react","import_jsx_runtime","TONE_ICON","TONE_ICON_COLOR","clsx","import_react","import_lucide_react","import_jsx_runtime","PasswordInput","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_clsx","import_lucide_react","import_jsx_runtime","clsx","import_jsx_runtime"]}
|