@tomny-dev/uzi 0.2.4 → 0.2.5
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/dist/index.cjs +1925 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1145 -881
- package/dist/index.js.map +1 -1
- package/dist/style.css +2025 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/utils/cx.ts","../src/components/button/button.module.css","../src/components/button/Button.tsx","../src/components/avatar/avatar.module.css","../src/components/avatar/Avatar.tsx","../src/components/card/card.module.css","../src/components/card/Card.tsx","../src/components/pill/pill.module.css","../src/components/pill/Pill.tsx","../src/components/modal/modal.module.css","../src/components/modal/Modal.tsx","../src/components/alert/alert.module.css","../src/components/alert/Alert.tsx","../src/components/toast/toast.module.css","../src/components/toast/ToastContext.tsx","../src/components/input/input.module.css","../src/components/input/Input.tsx","../src/components/label/label.module.css","../src/components/label/Label.tsx","../src/components/checkbox/checkbox.module.css","../src/components/checkbox/Checkbox.tsx","../src/components/multi-select/multi-select.module.css","../src/components/multi-select/MultiSelect.tsx","../src/components/select/select.module.css","../src/components/select/Select.tsx","../src/components/dropdown/Dropdown.tsx","../src/components/dropdown-menu/dropdown-menu.module.css","../src/components/dropdown-menu/DropdownMenu.tsx","../src/theme/constants.ts","../src/theme/ThemeProvider.tsx","../src/components/theme-toggle-button/theme-toggle-button.module.css","../src/components/theme-toggle-button/ThemeToggleButton.tsx","../src/components/top-bar/top-bar.module.css","../src/components/top-bar/TopBar.tsx","../src/components/app-shell/app-shell.module.css","../src/components/app-shell/AppShell.tsx","../src/components/sidebar-nav/sidebar-nav.module.css","../src/components/sidebar-nav/SidebarNav.tsx","../src/components/skeleton/skeleton.module.css","../src/components/skeleton/Skeleton.tsx","../src/components/progress/progress.module.css","../src/components/progress/Progress.tsx","../src/components/segmented-toggle/segmented-toggle.module.css","../src/components/segmented-toggle/SegmentedToggle.tsx"],"sourcesContent":["export function cx(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n",".button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n font-family: inherit;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n text-decoration: none;\n transition:\n opacity 0.15s,\n border-color 0.15s,\n color 0.15s,\n background 0.15s;\n white-space: nowrap;\n line-height: 1;\n}\n\n.button:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.button svg {\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n}\n\n.button:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n/* Sizes */\n.sizeSm {\n font-size: 0.82rem;\n min-height: 2rem;\n padding: 6px 14px;\n}\n\n.sizeMd {\n font-size: 0.95rem;\n min-height: 2.25rem;\n padding: 10px 22px;\n}\n\n.sizeLg {\n font-size: 1rem;\n min-height: 2.5rem;\n padding: 12px 28px;\n}\n\n.sizeIcon {\n width: 2.25rem;\n height: 2.25rem;\n padding: 0;\n}\n\n/* Variants */\n.variantPrimary {\n background: var(--ts-btn-primary-bg, var(--primary));\n color: var(--ts-btn-primary-text, var(--primary-foreground));\n}\n\n.variantPrimary:hover:not(:disabled) {\n opacity: 0.88;\n}\n\n.variantSecondary {\n background: var(--ts-btn-secondary-bg, var(--secondary));\n color: var(--ts-btn-secondary-text, var(--secondary-foreground));\n border-color: var(--ts-btn-secondary-border, var(--border));\n}\n\n.variantSecondary:hover:not(:disabled) {\n background: var(--ts-btn-secondary-hover-bg, color-mix(in srgb, var(--secondary) 90%, black));\n}\n\n.variantOutline {\n background: var(--ts-btn-outline-bg, var(--background));\n color: var(--ts-btn-outline-text, var(--foreground));\n border-color: var(--ts-btn-outline-border, var(--border));\n}\n\n.variantOutline:hover:not(:disabled) {\n background: var(--ts-btn-outline-hover-bg, var(--accent));\n color: var(--ts-btn-outline-hover-text, var(--accent-foreground));\n}\n\n.variantGhost {\n background: transparent;\n color: var(--ts-btn-ghost-text, var(--muted-foreground));\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.variantGhost:hover:not(:disabled) {\n background: var(--ts-btn-ghost-hover-bg, var(--accent));\n color: var(--ts-btn-ghost-hover-text, var(--accent-foreground));\n}\n\n.variantDestructive {\n background: var(--ts-btn-danger-bg, var(--destructive));\n color: var(--ts-btn-danger-text, var(--destructive-foreground));\n}\n\n.variantDestructive:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n.variantLink {\n background: transparent;\n color: var(--ts-btn-link-text, var(--primary));\n border-color: transparent;\n min-height: auto;\n padding: 0;\n border-radius: 0;\n}\n\n.variantLink:hover:not(:disabled) {\n text-decoration: underline;\n text-underline-offset: 0.2em;\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./button.module.css\";\n\nexport type ButtonVariant =\n | \"default\"\n | \"primary\"\n | \"secondary\"\n | \"outline\"\n | \"ghost\"\n | \"destructive\"\n | \"link\";\nexport type ButtonSize = \"default\" | \"sm\" | \"md\" | \"lg\" | \"icon\";\n\ntype BaseProps = {\n variant?: ButtonVariant;\n size?: ButtonSize;\n className?: string;\n children?: React.ReactNode;\n asChild?: boolean;\n};\n\ntype AsButton = BaseProps &\n React.ButtonHTMLAttributes<HTMLButtonElement> & { as?: \"button\" };\n\ntype AsAnchor = BaseProps &\n React.AnchorHTMLAttributes<HTMLAnchorElement> & { as: \"a\" };\n\nexport type ButtonProps = AsButton | AsAnchor;\n\nconst variantClass: Record<ButtonVariant, string> = {\n default: \"variantPrimary\",\n primary: \"variantPrimary\",\n secondary: \"variantSecondary\",\n outline: \"variantOutline\",\n ghost: \"variantGhost\",\n destructive: \"variantDestructive\",\n link: \"variantLink\",\n};\n\nconst sizeClass: Record<ButtonSize, string> = {\n default: \"sizeMd\",\n sm: \"sizeSm\",\n md: \"sizeMd\",\n lg: \"sizeLg\",\n icon: \"sizeIcon\",\n};\n\nexport function Button({\n as,\n variant = \"default\",\n size = \"default\",\n className,\n children,\n asChild = false,\n ...rest\n}: ButtonProps) {\n const classes = cx(\n styles.button,\n styles[variantClass[variant]],\n styles[sizeClass[size]],\n className,\n );\n\n if (asChild) {\n return (\n <Slot className={classes} {...rest}>\n {children}\n </Slot>\n );\n }\n\n if (as === \"a\") {\n return (\n <a\n className={classes}\n {...(rest as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {children}\n </a>\n );\n }\n\n return (\n <button\n type=\"button\"\n className={classes}\n {...(rest as React.ButtonHTMLAttributes<HTMLButtonElement>)}\n >\n {children}\n </button>\n );\n}\n",".avatar {\n position: relative;\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border-radius: 999px;\n background: var(--ts-avatar-bg, var(--muted));\n color: var(--ts-avatar-fg, var(--muted-foreground));\n}\n\n.size-sm {\n width: 1.75rem;\n height: 1.75rem;\n}\n\n.size-md {\n width: 2rem;\n height: 2rem;\n}\n\n.size-lg {\n width: 2.25rem;\n height: 2.25rem;\n}\n\n.size-xl {\n width: 4rem;\n height: 4rem;\n}\n\n.image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.fallback {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n border-radius: inherit;\n background: var(--ts-avatar-fallback-bg, var(--muted));\n color: var(--ts-avatar-fallback-fg, var(--muted-foreground));\n font-size: 0.85rem;\n font-weight: 700;\n line-height: 1;\n text-transform: uppercase;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./avatar.module.css\";\n\nexport type AvatarSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport type AvatarProps = React.ComponentProps<typeof AvatarPrimitive.Root> & {\n size?: AvatarSize;\n};\n\nexport function Avatar({\n className,\n size = \"md\",\n ...props\n}: AvatarProps) {\n const sizeClass =\n size === \"sm\" ? styles[\"size-sm\"] : size === \"lg\" ? styles[\"size-lg\"] : size === \"xl\" ? styles[\"size-xl\"] : styles[\"size-md\"];\n\n return (\n <AvatarPrimitive.Root\n className={cx(styles.avatar, sizeClass, className)}\n {...props}\n />\n );\n}\n\nexport function AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n className={cx(styles.image, className)}\n {...props}\n />\n );\n}\n\nexport function AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n className={cx(styles.fallback, className)}\n {...props}\n />\n );\n}\n",".card {\n position: relative;\n overflow: visible;\n border-radius: var(--ts-card-radius, 12px);\n border: 1px solid var(--ts-card-border, var(--border));\n background: var(--ts-card-bg, var(--panel));\n color: var(--ts-card-fg, var(--foreground));\n box-shadow: var(--ts-card-shadow, 0 16px 36px rgba(0, 0, 0, 0.28));\n padding: var(--ts-card-padding, 16px);\n transition:\n transform 140ms ease,\n box-shadow 140ms ease,\n border-color 140ms ease,\n background-color 140ms ease;\n}\n\n.tone-default {\n --ts-card-bg: var(--panel);\n --ts-card-border: var(--border);\n --ts-card-shadow: 0 16px 36px rgba(0, 0, 0, 0.28);\n}\n\n.tone-muted {\n --ts-card-bg: var(--muted);\n --ts-card-border: var(--border);\n --ts-card-shadow: 0 10px 26px rgba(0, 0, 0, 0.22);\n}\n\n.tone-contrast {\n --ts-card-bg: var(--ts-card-contrast-bg, color-mix(in srgb, var(--background) 60%, black));\n --ts-card-border: var(--border);\n --ts-card-shadow: 0 18px 50px rgba(0, 0, 0, 0.32);\n}\n\n.interactive {\n cursor: default;\n}\n\n.interactive:hover {\n transform: translateY(-1px);\n box-shadow: 0 22px 60px rgba(0, 0, 0, 0.32);\n border-color: var(--ts-card-hover-border, color-mix(in srgb, var(--primary) 40%, transparent));\n}\n\n.interactive:focus-within {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.padding-none { --ts-card-padding: 0; }\n.padding-sm { --ts-card-padding: 10px; }\n.padding-md { --ts-card-padding: 16px; }\n.padding-lg { --ts-card-padding: 20px; }\n","/**\n * Lightweight container component used for panels across the app.\n *\n * @remarks\n * Supports tone variants, padding presets, and an optional interactive affordance.\n *\n * @param props.as - Semantic element to render (defaults to `div`).\n * @param props.tone - Visual tone variant.\n * @param props.padding - Padding preset.\n * @param props.interactive - Enables hover/focus affordance.\n */\nimport type { HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./card.module.css\";\n\nexport type CardTone = \"default\" | \"muted\" | \"contrast\";\nexport type CardPadding = \"none\" | \"sm\" | \"md\" | \"lg\";\n\ntype CardElement = \"div\" | \"section\" | \"article\";\n\nexport type CardProps = HTMLAttributes<HTMLElement> & {\n /** Optional semantic element type. Defaults to `div`. */\n as?: CardElement;\n /** Visual tone; drives background/border CSS vars. */\n tone?: CardTone;\n /** Padding preset; maps to CSS variables so consumers can override globally. */\n padding?: CardPadding;\n /** Adds hover/focus affordance (lift + outline). */\n interactive?: boolean;\n};\n\nexport function Card({\n as,\n tone = \"default\",\n padding = \"md\",\n interactive = false,\n className,\n children,\n ...rest\n}: CardProps) {\n const Component: CardElement = as ?? \"div\";\n const TONE_CLASS: Record<CardTone, string | null> = { default: null, muted: \"tone-muted\", contrast: \"tone-contrast\" };\n const PADDING_CLASS: Record<CardPadding, string> = { none: \"padding-none\", sm: \"padding-sm\", md: \"padding-md\", lg: \"padding-lg\" };\n const classes = cx(\n styles.card,\n TONE_CLASS[tone] ? styles[TONE_CLASS[tone]] : null,\n styles[PADDING_CLASS[padding]],\n interactive && styles.interactive,\n className,\n );\n\n return (\n <Component className={classes} {...rest}>\n {children}\n </Component>\n );\n}\n",".pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n border: 1px solid var(--ts-pill-border, var(--border));\n background: var(--ts-pill-bg, color-mix(in srgb, var(--foreground) 4%, transparent));\n color: var(--ts-pill-fg, var(--muted-foreground));\n font-size: 12px;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n line-height: 1.2;\n white-space: nowrap;\n}\n\n.size-sm {\n padding: 3px 8px;\n font-size: 11px;\n}\n\n.size-md {\n padding: 4px 10px;\n}\n\n.tone-success {\n color: var(--success);\n border-color: color-mix(in srgb, var(--success) 45%, transparent);\n background: color-mix(in srgb, var(--success) 12%, transparent);\n}\n\n.tone-warning {\n color: var(--warning);\n border-color: color-mix(in srgb, var(--warning) 45%, transparent);\n background: color-mix(in srgb, var(--warning) 12%, transparent);\n}\n\n.tone-info {\n color: var(--primary);\n border-color: color-mix(in srgb, var(--primary) 50%, transparent);\n background: color-mix(in srgb, var(--primary) 12%, transparent);\n}\n\n.tone-danger {\n color: var(--destructive);\n border-color: color-mix(in srgb, var(--destructive) 45%, transparent);\n background: color-mix(in srgb, var(--destructive) 12%, transparent);\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n}\n\n.content {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n","/**\n * Compact label component for status chips and tags.\n *\n * @remarks\n * Supports tone and size presets, and can render any inline element.\n *\n * @param props.as - Element to render (defaults to `span`).\n * @param props.tone - Visual tone variant.\n * @param props.size - Size preset.\n * @param props.icon - Optional leading icon.\n */\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./pill.module.css\";\n\nexport type PillTone = \"neutral\" | \"success\" | \"warning\" | \"info\" | \"danger\";\nexport type PillSize = \"sm\" | \"md\";\n\ntype PillElement = \"span\" | \"div\" | \"button\";\n\nexport type PillProps = HTMLAttributes<HTMLElement> & {\n /** Optional rendered element; defaults to `span`. */\n as?: PillElement;\n /** Visual tone; adjusts color and border. */\n tone?: PillTone;\n /** Size preset. */\n size?: PillSize;\n /** Leading icon node (not focusable). */\n icon?: ReactNode;\n};\n\nexport function Pill({\n as,\n tone = \"neutral\",\n size = \"md\",\n icon,\n className,\n children,\n ...rest\n}: PillProps) {\n const Component: PillElement = as ?? \"span\";\n const classes = cx(styles.pill, styles[`tone-${tone}`], styles[`size-${size}`], className);\n\n return (\n <Component className={classes} {...rest}>\n {icon ? (\n <span className={styles.icon} aria-hidden=\"true\">\n {icon}\n </span>\n ) : null}\n <span className={styles.content}>{children}</span>\n </Component>\n );\n}\n",".portalLayer {\n position: fixed;\n inset: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n}\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n}\n\n.backdrop[data-state=\"open\"] {\n animation: backdropFadeIn 160ms ease;\n}\n\n.backdrop[data-state=\"closed\"] {\n animation: backdropFadeOut 140ms ease;\n}\n\n.overlayContent {\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n max-width: 100%;\n max-height: 100%;\n outline: none;\n}\n\n.overlayContent[data-state=\"open\"] {\n animation: modalContentIn 180ms ease;\n}\n\n.overlayContent[data-state=\"closed\"] {\n animation: modalContentOut 140ms ease;\n}\n\n.modal {\n background: var(--background);\n border: 1px solid var(--border);\n border-radius: 14px;\n padding: 24px;\n width: min(500px, 100%);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.55);\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n\n/* Size variants */\n.size-sm { width: min(380px, 100%); }\n.size-md { width: min(500px, 100%); }\n.size-lg { width: min(640px, 100%); }\n.size-xl { width: min(900px, 100%); }\n\n.header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.titles {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.title {\n font-weight: 700;\n font-size: 16px;\n color: var(--foreground);\n line-height: 1.3;\n}\n\n.subtitle {\n font-size: 13px;\n color: var(--muted-foreground);\n line-height: 1.4;\n}\n\n.closeButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n color: var(--muted-foreground);\n cursor: pointer;\n transition: background 0.12s, color 0.12s;\n padding: 0;\n}\n\n.closeButton:hover {\n background: color-mix(in srgb, var(--foreground) 7%, transparent);\n color: var(--foreground);\n}\n\n.closeButton:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.footer {\n display: flex;\n gap: 8px;\n margin-top: 20px;\n}\n\n@keyframes backdropFadeIn {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n@keyframes backdropFadeOut {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0;\n }\n}\n\n@keyframes modalContentIn {\n from {\n opacity: 0;\n transform: translateY(6px) scale(0.98);\n }\n\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes modalContentOut {\n from {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n\n to {\n opacity: 0;\n transform: translateY(4px) scale(0.98);\n }\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./modal.module.css\";\n\n// ── ModalOverlay ─────────────────────────────────────────────────────────────\n// Bare backdrop + container. No opinions on layout inside.\n// Use this when you need a full-custom layout (e.g. wide media modals).\n\nexport type ModalOverlayProps = {\n open: boolean;\n onClose: () => void;\n /** Extra class applied to the backdrop */\n className?: string;\n children: ReactNode;\n};\n\nexport function ModalOverlay({ open, onClose, className, children }: ModalOverlayProps) {\n return (\n <DialogPrimitive.Root\n open={open}\n onOpenChange={(nextOpen: boolean) => {\n if (!nextOpen) onClose();\n }}\n >\n <DialogPrimitive.Portal>\n <div className={styles.portalLayer}>\n <DialogPrimitive.Overlay className={cx(styles.backdrop, className)} />\n <DialogPrimitive.Content className={styles.overlayContent}>\n {children}\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// ── Modal ─────────────────────────────────────────────────────────────────────\n// Opinionated dialog: header (title + close button), scrollable body, footer.\n\nexport type ModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport type ModalProps = {\n open: boolean;\n onClose: () => void;\n title: string;\n subtitle?: string;\n size?: ModalSize;\n children: ReactNode;\n footer?: ReactNode;\n};\n\nexport function Modal({ open, onClose, title, subtitle, size = \"md\", children, footer }: ModalProps) {\n return (\n <ModalOverlay open={open} onClose={onClose}>\n <div className={cx(styles.modal, styles[`size-${size}`])}>\n <div className={styles.header}>\n <div className={styles.titles}>\n <DialogPrimitive.Title className={styles.title}>{title}</DialogPrimitive.Title>\n {subtitle ? (\n <DialogPrimitive.Description className={styles.subtitle}>\n {subtitle}\n </DialogPrimitive.Description>\n ) : null}\n </div>\n <DialogPrimitive.Close asChild>\n <button className={styles.closeButton} aria-label=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </DialogPrimitive.Close>\n </div>\n\n <div className={styles.body}>{children}</div>\n\n {footer && <div className={styles.footer}>{footer}</div>}\n </div>\n </ModalOverlay>\n );\n}\n",".alert {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n border-radius: 0.375rem;\n border: 1px solid;\n padding: 0.625rem 0.875rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.success {\n border-color: color-mix(in srgb, var(--success) 35%, transparent);\n background: color-mix(in srgb, var(--success) 10%, transparent);\n color: color-mix(in srgb, var(--success) 90%, var(--foreground));\n}\n\n.error {\n border-color: color-mix(in srgb, var(--destructive) 35%, transparent);\n background: color-mix(in srgb, var(--destructive) 10%, transparent);\n color: color-mix(in srgb, var(--destructive) 90%, var(--foreground));\n}\n\n.warning {\n border-color: color-mix(in srgb, var(--warning) 35%, transparent);\n background: color-mix(in srgb, var(--warning) 10%, transparent);\n color: color-mix(in srgb, var(--warning) 90%, var(--foreground));\n}\n\n.info {\n border-color: color-mix(in srgb, var(--primary) 35%, transparent);\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n color: color-mix(in srgb, var(--primary) 90%, var(--foreground));\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./alert.module.css\";\n\nexport type AlertTone = \"success\" | \"error\" | \"warning\" | \"info\";\n\nexport type AlertProps = {\n tone: AlertTone;\n children: ReactNode;\n className?: string;\n};\n\nexport function Alert({ tone, children, className }: AlertProps) {\n return (\n <div className={cx(styles.alert, styles[tone], className)} role=\"alert\">\n {children}\n </div>\n );\n}\n",".stack {\n position: fixed;\n z-index: 2147483000;\n display: flex;\n flex-direction: column;\n gap: 10px;\n pointer-events: none;\n}\n\n.topRight {\n top: 16px;\n right: 16px;\n align-items: flex-end;\n}\n\n.topLeft {\n top: 16px;\n left: 16px;\n align-items: flex-start;\n}\n\n.topCenter {\n top: 16px;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n}\n\n.bottomRight {\n bottom: 16px;\n right: 16px;\n align-items: flex-end;\n}\n\n.bottomLeft {\n bottom: 16px;\n left: 16px;\n align-items: flex-start;\n}\n\n.bottomCenter {\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n}\n\n.toast {\n pointer-events: auto;\n position: relative;\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 280px;\n max-width: min(420px, calc(100vw - 32px));\n padding: 12px 12px 12px 14px;\n border-radius: 10px;\n border: 1px solid var(--toast-border, var(--border));\n background: var(--toast-bg, var(--popover));\n color: var(--toast-text, var(--popover-foreground));\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10), 0 2px 6px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n animation: toastSlideIn 180ms ease-out;\n}\n\n/* Left accent strip */\n.toast::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--toast-accent, transparent);\n border-radius: 10px 0 0 10px;\n}\n\n.toast[data-state=\"closed\"] {\n animation: toastSlideOut 160ms ease-in forwards;\n}\n\n.toast[data-swipe=\"move\"] {\n transform: translateX(var(--radix-toast-swipe-move-x));\n}\n\n.toast[data-swipe=\"cancel\"] {\n transform: translateX(0);\n transition: transform 180ms ease-out;\n}\n\n.toast[data-swipe=\"end\"] {\n animation: toastSwipeOut 160ms ease-out forwards;\n}\n\n.icon {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--toast-accent, var(--foreground));\n margin-top: 1px;\n}\n\n.body {\n flex: 1;\n min-width: 0;\n display: grid;\n gap: 6px;\n}\n\n.message {\n word-break: break-word;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.actionButton {\n padding: 5px 10px;\n font-size: 12px;\n font-weight: 600;\n border-radius: 6px;\n border: 1px solid var(--toast-action-border, var(--border));\n background: var(--toast-action-bg, color-mix(in srgb, var(--foreground) 8%, transparent));\n color: var(--toast-text, var(--popover-foreground));\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.actionButton:hover {\n background: color-mix(in srgb, var(--toast-action-bg, var(--foreground)), var(--foreground) 10%);\n}\n\n.controls {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 2px;\n margin: -2px -2px -2px 0;\n}\n\n.iconButton {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: 5px;\n background: transparent;\n color: var(--toast-text, var(--popover-foreground));\n opacity: 0.5;\n cursor: pointer;\n transition: opacity 120ms ease, background 120ms ease;\n}\n\n.iconButton:hover {\n opacity: 1;\n background: color-mix(in srgb, var(--foreground) 8%, transparent);\n}\n\n.iconButtonError {\n opacity: 1;\n color: var(--destructive);\n}\n\n.iconButton:focus-visible,\n.actionButton:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n@keyframes toastSlideIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes toastSlideOut {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-6px);\n }\n}\n\n@keyframes toastSwipeOut {\n from {\n opacity: 1;\n transform: translateX(var(--radix-toast-swipe-end-x));\n }\n\n to {\n opacity: 0;\n transform: translateX(calc(var(--radix-toast-swipe-end-x) * 1.05));\n }\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport * as ToastPrimitive from \"@radix-ui/react-toast\";\nimport { cx } from \"../../utils/cx\";\nimport type {\n Toast,\n ToastConfig,\n ToastContextValue,\n ToastOptions,\n ToastPosition,\n ToastType,\n} from \"./types\";\nimport styles from \"./toast.module.css\";\n\n/** Default provider configuration. */\nconst DEFAULT_CONFIG: Required<ToastConfig> = {\n position: \"top-right\",\n maxToasts: 5,\n defaultDuration: 4000,\n pauseOnHover: true,\n pauseOnFocusLoss: true,\n};\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\nlet toastIdCounter = 0;\nconst generateToastId = () => `toast-${++toastIdCounter}-${Date.now()}`;\n\n/**\n * Toast notification context provider.\n *\n * @remarks\n * Wrap your app (or a section) to enable `useToast` calls. Supports configurable placement,\n * maximum visible toasts, and pause behavior on hover or window blur.\n *\n * @param props.children - React subtree that can consume the toast context.\n * @param props.config - Optional provider configuration overrides.\n */\nexport function ToastProvider({\n children,\n config,\n}: {\n children: ReactNode;\n config?: ToastConfig;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [isPaused, setIsPaused] = useState(false);\n const merged = useMemo(() => ({ ...DEFAULT_CONFIG, ...config }), [config]);\n\n const push = useCallback(\n (message: string, options: ToastOptions = {}) => {\n const id = generateToastId();\n setToasts((prev) => {\n const next: Toast[] = [\n ...prev,\n {\n id,\n message,\n type: options.type ?? \"info\",\n duration: options.duration ?? (options.type === \"error\" ? 6000 : merged.defaultDuration),\n dismissible: options.dismissible ?? true,\n copyable: options.copyable ?? false,\n action: options.action,\n },\n ];\n if (next.length > merged.maxToasts) next.shift();\n return next;\n });\n return id;\n },\n [merged.defaultDuration, merged.maxToasts],\n );\n\n const success = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) => push(message, { ...options, type: \"success\" }),\n [push],\n );\n const error = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) =>\n push(message, { copyable: true, ...options, type: \"error\" }),\n [push],\n );\n const warning = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) => push(message, { ...options, type: \"warning\" }),\n [push],\n );\n const info = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) => push(message, { ...options, type: \"info\" }),\n [push],\n );\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => setToasts([]), []);\n\n useEffect(() => {\n if (!merged.pauseOnFocusLoss) return;\n const handleVisibility = () => setIsPaused(document.visibilityState !== \"visible\");\n document.addEventListener(\"visibilitychange\", handleVisibility);\n return () => document.removeEventListener(\"visibilitychange\", handleVisibility);\n }, [merged.pauseOnFocusLoss]);\n\n const value = useMemo<ToastContextValue>(\n () => ({ toasts, push, success, error, warning, info, dismiss, dismissAll }),\n [toasts, push, success, error, warning, info, dismiss, dismissAll],\n );\n\n return (\n <ToastContext.Provider value={value}>\n <ToastPrimitive.Provider swipeDirection=\"right\">\n {children}\n <ToastContainer\n toasts={toasts}\n position={merged.position}\n pauseOnHover={merged.pauseOnHover}\n isPaused={isPaused}\n onDismiss={dismiss}\n onPauseChange={setIsPaused}\n />\n </ToastPrimitive.Provider>\n </ToastContext.Provider>\n );\n}\n\n/**\n * Hook to access the toast API.\n *\n * @remarks\n * Exposes `push`, intent helpers (`success`, `error`, `warning`, `info`), and dismissal helpers.\n * Must be called within a `ToastProvider`.\n *\n * @throws Error if used outside of a `ToastProvider`.\n */\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a ToastProvider\");\n return ctx;\n}\n\n/** Renders the positioned toast stack. */\nfunction ToastContainer({\n toasts,\n position,\n pauseOnHover,\n isPaused,\n onDismiss,\n onPauseChange,\n}: {\n toasts: Toast[];\n position: ToastPosition;\n pauseOnHover: boolean;\n isPaused: boolean;\n onDismiss: (id: string) => void;\n onPauseChange: (paused: boolean) => void;\n}) {\n const posClass = (() => {\n switch (position) {\n case \"top-left\":\n return \"topLeft\";\n case \"top-center\":\n return \"topCenter\";\n case \"bottom-right\":\n return \"bottomRight\";\n case \"bottom-left\":\n return \"bottomLeft\";\n case \"bottom-center\":\n return \"bottomCenter\";\n case \"top-right\":\n default:\n return \"topRight\";\n }\n })();\n\n return (\n <>\n {toasts.map((toast) => (\n <ToastItem key={toast.id} toast={toast} isPaused={isPaused} onDismiss={onDismiss} />\n ))}\n <ToastPrimitive.Viewport\n className={cx(styles.stack, styles[posClass])}\n label=\"Notifications\"\n onMouseEnter={() => pauseOnHover && onPauseChange(true)}\n onMouseLeave={() => pauseOnHover && onPauseChange(false)}\n />\n </>\n );\n}\n\n/** Individual toast item with timers and actions. */\nfunction ToastItem({\n toast,\n isPaused,\n onDismiss,\n}: {\n toast: Toast;\n isPaused: boolean;\n onDismiss: (id: string) => void;\n}) {\n const [open, setOpen] = useState(true);\n const [copyState, setCopyState] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\");\n const copyTimerRef = useRef<number | null>(null);\n const timerRef = useRef<number | null>(null);\n const startRef = useRef<number>(0);\n const remainingRef = useRef<number>(toast.duration ?? 0);\n const closingRef = useRef(false);\n\n const palette = getPalette(toast.type);\n const styleVars: CSSProperties = {\n [\"--toast-bg\" as any]: palette.background,\n [\"--toast-border\" as any]: palette.border,\n [\"--toast-accent\" as any]: palette.accent,\n [\"--toast-text\" as any]: palette.text,\n [\"--toast-action-bg\" as any]: palette.actionBg,\n [\"--toast-action-border\" as any]: palette.actionBorder,\n };\n\n const stopTimer = () => {\n if (timerRef.current) {\n window.clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const triggerDismiss = useCallback(() => {\n if (closingRef.current) return;\n closingRef.current = true;\n setOpen(false);\n stopTimer();\n window.setTimeout(() => onDismiss(toast.id), 160);\n }, [onDismiss, toast.id]);\n\n const schedule = useCallback(\n (delay: number) => {\n if (!delay || delay <= 0) {\n triggerDismiss();\n return;\n }\n startRef.current = performance.now();\n stopTimer();\n timerRef.current = window.setTimeout(() => triggerDismiss(), delay);\n },\n [triggerDismiss],\n );\n\n useEffect(() => {\n if (!toast.duration || toast.duration <= 0) return undefined;\n schedule(toast.duration);\n return stopTimer;\n }, [schedule, toast.duration]);\n\n useEffect(() => {\n if (!toast.duration || toast.duration <= 0) return;\n if (isPaused) {\n const elapsed = performance.now() - startRef.current;\n remainingRef.current = Math.max(0, remainingRef.current - elapsed);\n stopTimer();\n } else {\n schedule(remainingRef.current);\n }\n }, [isPaused, schedule, toast.duration]);\n\n useEffect(() => {\n return () => {\n if (copyTimerRef.current) window.clearTimeout(copyTimerRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (copyTimerRef.current) window.clearTimeout(copyTimerRef.current);\n try {\n if (!navigator.clipboard) throw new Error(\"Clipboard API unavailable\");\n await navigator.clipboard.writeText(toast.message);\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n copyTimerRef.current = window.setTimeout(() => setCopyState(\"idle\"), 1800);\n }, [toast.message]);\n\n const icon = getIcon(toast.type);\n\n return (\n <ToastPrimitive.Root\n open={open}\n onOpenChange={(nextOpen: boolean) => {\n if (!nextOpen) triggerDismiss();\n }}\n duration={2147483647}\n className={styles.toast}\n style={styleVars}\n >\n <span className={styles.icon} aria-hidden>\n {icon}\n </span>\n <div className={styles.body}>\n <ToastPrimitive.Description className={styles.message}>\n {toast.message}\n </ToastPrimitive.Description>\n {toast.action && (\n <div className={styles.actions}>\n <ToastPrimitive.Action asChild altText={toast.action.label}>\n <button\n type=\"button\"\n className={styles.actionButton}\n onClick={() => {\n toast.action?.onClick();\n triggerDismiss();\n }}\n >\n {toast.action.label}\n </button>\n </ToastPrimitive.Action>\n </div>\n )}\n </div>\n <div className={styles.controls}>\n {toast.copyable && (\n <button\n type=\"button\"\n className={cx(styles.iconButton, copyState === \"failed\" && styles.iconButtonError)}\n aria-label=\"Copy message\"\n onClick={handleCopy}\n >\n {copyState === \"copied\" ? (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <path d=\"M2 6.5l3 3 6-6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ) : copyState === \"failed\" ? (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <path d=\"M10 3L3 10M3 3l7 7\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n ) : (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <rect x=\"4.5\" y=\"1.5\" width=\"7\" height=\"7\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.25\" />\n <path d=\"M1.5 5.5v5a1.5 1.5 0 001.5 1.5h5\" stroke=\"currentColor\" strokeWidth=\"1.25\" strokeLinecap=\"round\" />\n </svg>\n )}\n </button>\n )}\n {toast.dismissible !== false && (\n <ToastPrimitive.Close asChild>\n <button\n type=\"button\"\n className={styles.iconButton}\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <path d=\"M10 3L3 10M3 3l7 7\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </ToastPrimitive.Close>\n )}\n </div>\n </ToastPrimitive.Root>\n );\n}\n\nfunction getPalette(type: ToastType) {\n switch (type) {\n case \"success\":\n return {\n background: \"color-mix(in srgb, var(--success) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--success) 30%, transparent)\",\n accent: \"var(--success)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--success) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--success) 35%, transparent)\",\n };\n case \"error\":\n return {\n background: \"color-mix(in srgb, var(--destructive) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--destructive) 30%, transparent)\",\n accent: \"var(--destructive)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--destructive) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--destructive) 35%, transparent)\",\n };\n case \"warning\":\n return {\n background: \"color-mix(in srgb, var(--warning) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--warning) 30%, transparent)\",\n accent: \"var(--warning)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--warning) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--warning) 35%, transparent)\",\n };\n case \"info\":\n default:\n return {\n background: \"color-mix(in srgb, var(--primary) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--primary) 30%, transparent)\",\n accent: \"var(--primary)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--primary) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--primary) 35%, transparent)\",\n };\n }\n}\n\nfunction getIcon(type: ToastType) {\n switch (type) {\n case \"success\":\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M3 8l3.5 3.5L13 4.5\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n case \"error\":\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M4 4l8 8M12 4l-8 8\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" />\n </svg>\n );\n case \"warning\":\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M8 3v6M8 11.5v1\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" />\n </svg>\n );\n case \"info\":\n default:\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M8 7v5M8 4.5v.5\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n}\n",".input {\n display: flex;\n width: 100%;\n min-height: 2.25rem;\n border-radius: 0.5rem;\n border: 1px solid var(--ts-input-border, var(--input));\n background: var(--ts-input-bg, var(--background));\n color: var(--ts-input-fg, var(--foreground));\n padding: 0.25rem 0.75rem;\n font-size: 0.875rem;\n line-height: 1.25rem;\n box-shadow: var(--ts-input-shadow, 0 1px 2px rgba(0, 0, 0, 0.04));\n transition: border-color 0.15s ease, background 0.15s ease;\n}\n\n.input::placeholder {\n color: var(--ts-input-placeholder, var(--muted-foreground));\n}\n\n.input:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n","import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./input.module.css\";\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n ref={ref}\n type={type}\n className={cx(styles.input, className)}\n {...props}\n />\n );\n },\n);\n\nInput.displayName = \"Input\";\n",".label {\n font-size: 0.875rem;\n font-weight: 500;\n line-height: 1.2;\n color: var(--ts-label-fg, inherit);\n}\n","import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./label.module.css\";\n\nexport type LabelProps = React.LabelHTMLAttributes<HTMLLabelElement>;\n\nexport const Label = React.forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, ...props }, ref) => (\n <label ref={ref} className={cx(styles.label, className)} {...props} />\n ),\n);\n\nLabel.displayName = \"Label\";\n",".checkbox {\n width: 1rem;\n height: 1rem;\n margin: 0;\n border-radius: 0.25rem;\n border: 1px solid var(--ts-checkbox-border, var(--border));\n background: var(--ts-checkbox-bg, var(--background));\n accent-color: var(--ts-checkbox-accent, var(--primary));\n cursor: pointer;\n}\n\n.checkbox:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.checkbox:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n","import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./checkbox.module.css\";\n\nexport type CheckboxProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, ...props }, ref) => {\n return (\n <input\n ref={ref}\n type=\"checkbox\"\n className={cx(styles.checkbox, className)}\n {...props}\n />\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n",".wrapper {\n position: relative;\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n}\n\n.wrapperFullWidth {\n width: 100%;\n}\n\n.trigger {\n width: 100%;\n min-width: 0;\n min-height: var(--uzi-control-min-height);\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.625rem;\n border-radius: var(--uzi-control-radius);\n border: 1px solid var(--ts-dropdown-border, var(--border));\n background: var(--ts-dropdown-bg, var(--panel));\n color: var(--ts-dropdown-text, var(--foreground));\n padding:\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x-compact)\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x);\n font-size: var(--uzi-control-font-size);\n line-height: var(--uzi-control-line-height);\n font-family: inherit;\n box-shadow: var(--uzi-control-shadow);\n transition:\n border-color 0.15s ease,\n background 0.15s ease,\n color 0.15s ease,\n box-shadow 0.15s ease;\n cursor: pointer;\n text-align: left;\n}\n\n.trigger:hover:not(:disabled) {\n border-color: var(--ts-dropdown-accent, var(--accent));\n box-shadow: var(--uzi-control-shadow-hover);\n}\n\n.trigger:focus-visible,\n.trigger[data-state=\"open\"] {\n border-color: var(--ts-dropdown-accent, var(--primary));\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n box-shadow: none;\n}\n\n.value {\n min-width: 0;\n display: flex;\n flex: 1;\n flex-wrap: wrap;\n gap: 0.375rem;\n align-items: center;\n}\n\n.placeholder {\n color: var(--muted-foreground);\n}\n\n.chip {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n padding: 2px 8px;\n border-radius: 999px;\n border: 1px solid color-mix(in srgb, var(--primary) 32%, transparent);\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n color: var(--ts-dropdown-text, var(--foreground));\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1.2;\n white-space: nowrap;\n}\n\n.chipSummary {\n color: var(--primary);\n}\n\n.chevron {\n width: 10px;\n height: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--muted-foreground);\n flex-shrink: 0;\n transition: transform 0.15s ease, color 0.15s ease;\n}\n\n.trigger:hover:not(:disabled) .chevron,\n.trigger[data-state=\"open\"] .chevron {\n color: var(--ts-dropdown-text, var(--foreground));\n}\n\n.trigger[data-state=\"open\"] .chevron {\n transform: rotate(180deg);\n}\n\n.menu {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 50;\n min-width: 100%;\n max-height: 16rem;\n overflow-y: auto;\n border: 1px solid var(--ts-menu-border, var(--border));\n border-radius: var(--uzi-menu-radius);\n background: var(--ts-menu-bg, var(--popover));\n color: var(--ts-menu-fg, var(--popover-foreground));\n padding: var(--uzi-menu-padding);\n box-shadow: var(--uzi-menu-shadow);\n animation: menuFadeIn 140ms ease;\n}\n\n.option {\n width: 100%;\n display: flex;\n align-items: center;\n gap: var(--uzi-menu-item-gap);\n border: none;\n border-radius: var(--uzi-menu-item-radius);\n background: transparent;\n color: inherit;\n padding: var(--uzi-menu-item-padding-y) var(--uzi-menu-item-padding-x);\n font: inherit;\n cursor: pointer;\n text-align: left;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.option:hover:not(:disabled),\n.option:focus-visible,\n.option[data-highlighted] {\n background: var(--ts-menu-hover-bg, var(--accent));\n color: var(--ts-menu-hover-fg, var(--accent-foreground));\n outline: none;\n}\n\n.optionDisabled,\n.option[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.optionSelected .optionLabel {\n color: var(--primary);\n}\n\n.indicator {\n width: 1rem;\n height: 1rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: 0.3125rem;\n border: 1px solid var(--border);\n color: transparent;\n background: transparent;\n transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;\n}\n\n.indicatorSelected {\n border-color: color-mix(in srgb, var(--primary) 55%, transparent);\n background: color-mix(in srgb, var(--primary) 12%, transparent);\n color: var(--primary);\n}\n\n.indicatorDisabled {\n opacity: 0.65;\n}\n\n.optionLabel {\n min-width: 0;\n flex: 1;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./multi-select.module.css\";\n\nexport type MultiSelectOption = {\n label: string;\n value: string;\n disabled?: boolean;\n};\n\nexport type MultiSelectProps = {\n options: MultiSelectOption[];\n value: string[];\n onChange: (value: string[]) => void;\n placeholder?: string;\n fullWidth?: boolean;\n maxVisibleValues?: number;\n className?: string;\n disabled?: boolean;\n name?: string;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n};\n\nexport const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(\n (\n {\n options,\n value,\n onChange,\n placeholder = \"Select options\",\n fullWidth = true,\n maxVisibleValues = 2,\n className,\n disabled = false,\n name,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n },\n ref,\n ) => {\n const selectedSet = React.useMemo(() => new Set(value), [value]);\n const selectedOptions = React.useMemo(\n () => options.filter((opt) => selectedSet.has(opt.value)),\n [options, selectedSet],\n );\n\n const toggleValue = React.useCallback(\n (nextValue: string) => {\n if (selectedSet.has(nextValue)) {\n onChange(value.filter((entry) => entry !== nextValue));\n return;\n }\n\n onChange([...value, nextValue]);\n },\n [onChange, selectedSet, value],\n );\n\n const visibleCount = Math.max(1, maxVisibleValues);\n const visibleOptions = selectedOptions.slice(0, visibleCount);\n const overflowCount = Math.max(\n 0,\n selectedOptions.length - visibleOptions.length,\n );\n\n return (\n <DropdownMenuPrimitive.Root modal={false}>\n <div\n className={cx(\n styles.wrapper,\n fullWidth && styles.wrapperFullWidth,\n className,\n )}\n >\n <DropdownMenuPrimitive.Trigger asChild>\n <button\n ref={ref}\n type=\"button\"\n className={styles.trigger}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n disabled={disabled}\n >\n <span className={styles.value}>\n {selectedOptions.length === 0 ? (\n <span className={styles.placeholder}>{placeholder}</span>\n ) : (\n <>\n {visibleOptions.map((option) => (\n <span key={option.value} className={styles.chip}>\n {option.label}\n </span>\n ))}\n {overflowCount > 0 ? (\n <span\n className={cx(\n styles.chip,\n styles.chipSummary,\n )}\n >\n +{overflowCount}\n </span>\n ) : null}\n </>\n )}\n </span>\n <span className={styles.chevron} aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n >\n <path\n d=\"M2 3.5L5 6.5L8 3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n </DropdownMenuPrimitive.Trigger>\n\n {name\n ? value.map((entry) => (\n <input key={entry} type=\"hidden\" name={name} value={entry} />\n ))\n : null}\n\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n className={styles.menu}\n sideOffset={4}\n align=\"start\"\n >\n {options.map((option) => {\n const selected = selectedSet.has(option.value);\n\n return (\n <DropdownMenuPrimitive.CheckboxItem\n key={option.value}\n className={cx(\n styles.option,\n selected && styles.optionSelected,\n option.disabled && styles.optionDisabled,\n )}\n checked={selected}\n disabled={option.disabled}\n onCheckedChange={() => toggleValue(option.value)}\n onSelect={(event) => event.preventDefault()}\n >\n <span\n className={cx(\n styles.indicator,\n selected && styles.indicatorSelected,\n option.disabled && styles.indicatorDisabled,\n )}\n aria-hidden=\"true\"\n >\n <DropdownMenuPrimitive.ItemIndicator forceMount>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n <span className={styles.optionLabel}>{option.label}</span>\n </DropdownMenuPrimitive.CheckboxItem>\n );\n })}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </div>\n </DropdownMenuPrimitive.Root>\n );\n },\n);\n\nMultiSelect.displayName = \"MultiSelect\";\n",".wrapper {\n position: relative;\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n}\n\n.wrapperFullWidth {\n width: 100%;\n}\n\n.wrapper:not(.wrapperFullWidth) .trigger {\n width: auto;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.625rem;\n width: 100%;\n min-width: 0;\n min-height: var(--uzi-control-min-height);\n border-radius: var(--uzi-control-radius);\n border: 1px solid var(--ts-dropdown-border, var(--border));\n background: var(--ts-dropdown-bg, var(--panel));\n color: var(--ts-dropdown-text, var(--foreground));\n padding:\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x-compact)\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x);\n font-size: var(--uzi-control-font-size);\n line-height: var(--uzi-control-line-height);\n font-family: inherit;\n font-weight: 500;\n box-shadow: var(--uzi-control-shadow);\n transition:\n border-color 0.15s ease,\n background 0.15s ease,\n color 0.15s ease,\n box-shadow 0.15s ease;\n cursor: pointer;\n text-align: left;\n}\n\n.value {\n min-width: 0;\n flex: 1 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.trigger:hover:not(:disabled) {\n border-color: var(--ts-dropdown-accent, var(--accent));\n box-shadow: var(--uzi-control-shadow-hover);\n}\n\n.trigger:focus-visible {\n border-color: var(--ts-dropdown-accent, var(--primary));\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);\n}\n\n.trigger[data-placeholder] {\n color: var(--muted-foreground);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n box-shadow: none;\n}\n\n.chevron {\n width: 10px;\n height: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--muted-foreground);\n flex-shrink: 0;\n position: relative;\n top: -1px;\n transition: transform 0.15s ease, color 0.15s ease;\n}\n\n.chevron svg {\n display: block;\n}\n\n.trigger:hover:not(:disabled) .chevron,\n.trigger[data-state=\"open\"] .chevron {\n color: var(--ts-dropdown-text, var(--foreground));\n}\n\n.trigger[data-state=\"open\"] .chevron {\n transform: rotate(180deg);\n}\n\n.content {\n z-index: 50;\n min-width: var(--radix-select-trigger-width);\n max-height: min(18rem, var(--radix-select-content-available-height));\n overflow: hidden;\n border: 1px solid var(--ts-menu-border, var(--border));\n border-radius: var(--uzi-menu-radius);\n background: var(--ts-menu-bg, var(--popover));\n color: var(--ts-menu-fg, var(--popover-foreground));\n padding: var(--uzi-menu-padding);\n box-shadow: var(--uzi-menu-shadow);\n animation: selectFadeIn 140ms ease;\n}\n\n.viewport {\n max-height: inherit;\n overflow-y: auto;\n}\n\n.item {\n position: relative;\n display: flex;\n width: 100%;\n cursor: default;\n user-select: none;\n align-items: center;\n gap: var(--uzi-menu-item-gap);\n border-radius: var(--uzi-menu-item-radius);\n padding:\n var(--uzi-menu-item-padding-y)\n var(--uzi-menu-item-padding-x)\n var(--uzi-menu-item-padding-y)\n 2rem;\n font-size: 0.875rem;\n line-height: 1.25rem;\n outline: none;\n}\n\n.item[data-highlighted] {\n background: var(--ts-menu-hover-bg, var(--accent));\n color: var(--ts-menu-hover-fg, var(--accent-foreground));\n}\n\n.item[data-disabled] {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.item[data-state=\"checked\"] {\n color: var(--primary);\n}\n\n.indicator {\n position: absolute;\n left: 0.625rem;\n display: inline-flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n color: currentColor;\n}\n\n.indicatorIcon {\n display: block;\n}\n\n@keyframes selectFadeIn {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./select.module.css\";\n\nexport type SelectOption = {\n label: string;\n value: string;\n disabled?: boolean;\n};\n\nexport type SelectProps = {\n options: SelectOption[];\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n allowEmptyOption?: boolean;\n fullWidth?: boolean;\n className?: string;\n id?: string;\n name?: string;\n disabled?: boolean;\n required?: boolean;\n autoComplete?: string;\n form?: string;\n title?: string;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n};\n\nconst EMPTY_OPTION_VALUE = \"__uzi_select_empty__\";\n\nexport const Select = React.forwardRef<HTMLButtonElement, SelectProps>(\n (\n {\n options,\n value,\n onChange,\n placeholder,\n allowEmptyOption = false,\n fullWidth = true,\n className,\n id,\n name,\n disabled,\n required,\n autoComplete,\n form,\n title,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n onBlur,\n onFocus,\n },\n ref,\n ) => {\n return (\n <div\n className={cx(\n styles.wrapper,\n fullWidth && styles.wrapperFullWidth,\n className,\n )}\n >\n <SelectPrimitive.Root\n value={value}\n onValueChange={(nextValue: string) =>\n onChange(nextValue === EMPTY_OPTION_VALUE ? \"\" : nextValue)\n }\n name={name}\n disabled={disabled}\n required={required}\n autoComplete={autoComplete}\n form={form}\n >\n <SelectPrimitive.Trigger\n ref={ref}\n id={id}\n className={styles.trigger}\n title={title}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onBlur={onBlur}\n onFocus={onFocus}\n >\n <SelectPrimitive.Value\n className={styles.value}\n placeholder={placeholder}\n />\n <SelectPrimitive.Icon\n className={styles.chevron}\n aria-hidden=\"true\"\n >\n <svg\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n >\n <path\n d=\"M2 3.5L5 6.5L8 3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n className={styles.content}\n position=\"popper\"\n sideOffset={4}\n align=\"start\"\n >\n <SelectPrimitive.Viewport className={styles.viewport}>\n {placeholder && allowEmptyOption ? (\n <SelectPrimitive.Item\n value={EMPTY_OPTION_VALUE}\n className={styles.item}\n >\n <span className={styles.indicator}>\n <SelectPrimitive.ItemIndicator>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.indicatorIcon}\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{placeholder}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n ) : null}\n\n {options.map((opt) => (\n <SelectPrimitive.Item\n key={opt.value}\n value={opt.value}\n disabled={opt.disabled}\n className={styles.item}\n >\n <span className={styles.indicator}>\n <SelectPrimitive.ItemIndicator>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.indicatorIcon}\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{opt.label}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n ))}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n </div>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Select, type SelectOption, type SelectProps } from \"../select/Select\";\n\nexport interface DropdownOption extends SelectOption {}\n\nexport interface DropdownProps\n extends Omit<\n SelectProps,\n \"allowEmptyOption\" | \"fullWidth\" | \"placeholder\" | \"options\"\n > {\n /** List of options to display in the menu. */\n options: DropdownOption[];\n /** Label shown when no option is selected. Defaults to \"All\". */\n placeholder?: string;\n /** Whether to show the placeholder as a clearable option. Defaults to true. */\n allowClear?: boolean;\n}\n\n/**\n * @deprecated Use Select for value selection and DropdownMenu for action menus.\n * Dropdown remains as a compatibility alias during migration.\n */\nexport const Dropdown = React.forwardRef<HTMLButtonElement, DropdownProps>(\n (\n {\n options,\n value,\n onChange,\n placeholder = \"All\",\n allowClear = true,\n ...rest\n },\n ref,\n ) => {\n return (\n <Select\n ref={ref}\n options={options}\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n allowEmptyOption={allowClear}\n fullWidth={false}\n {...rest}\n />\n );\n },\n);\n\nDropdown.displayName = \"Dropdown\";\n",".content {\n z-index: 50;\n min-width: 8rem;\n max-height: var(--radix-dropdown-menu-content-available-height);\n overflow-x: hidden;\n overflow-y: auto;\n border: 1px solid var(--ts-menu-border, var(--border));\n border-radius: var(--uzi-menu-radius);\n background: var(--ts-menu-bg, var(--popover));\n color: var(--ts-menu-fg, var(--popover-foreground));\n padding: var(--uzi-menu-padding);\n box-shadow: var(--uzi-menu-shadow);\n transform-origin: var(--radix-dropdown-menu-content-transform-origin);\n animation: menuFadeIn 140ms ease;\n}\n\n.item {\n position: relative;\n display: flex;\n width: 100%;\n cursor: default;\n user-select: none;\n align-items: center;\n gap: var(--uzi-menu-item-gap);\n border-radius: var(--uzi-menu-item-radius);\n padding: var(--uzi-menu-item-padding-y) var(--uzi-menu-item-padding-x);\n font-size: 0.875rem;\n line-height: 1.25rem;\n outline: none;\n}\n\n.item[data-inset=\"true\"] {\n padding-left: 2rem;\n}\n\n.item[data-highlighted] {\n background: var(--ts-menu-hover-bg, var(--accent));\n color: var(--ts-menu-hover-fg, var(--accent-foreground));\n}\n\n.item[data-disabled] {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.itemDestructive {\n color: var(--ts-menu-danger, var(--destructive));\n}\n\n.itemDestructive[data-highlighted] {\n background: color-mix(in srgb, var(--destructive) 15%, transparent);\n color: var(--ts-menu-danger-fg, var(--destructive));\n}\n\n.insetItem {\n padding-left: 2rem;\n}\n\n.indicator {\n position: absolute;\n left: 0.5rem;\n display: inline-flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n color: currentColor;\n}\n\n.indicatorIcon {\n display: block;\n}\n\n.radioDot {\n display: block;\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 999px;\n background: currentColor;\n}\n\n.label {\n padding: var(--uzi-menu-item-padding-y) var(--uzi-menu-item-padding-x);\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1.25rem;\n}\n\n.label[data-inset=\"true\"] {\n padding-left: 2rem;\n}\n\n.separator {\n height: 1px;\n margin: 0.25rem -0.25rem;\n background: var(--ts-menu-separator, var(--border));\n}\n\n.chevron {\n margin-left: auto;\n flex-shrink: 0;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./dropdown-menu.module.css\";\n\nexport function DropdownMenu(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>,\n) {\n return <DropdownMenuPrimitive.Root {...props} />;\n}\n\nexport function DropdownMenuTrigger(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>,\n) {\n return <DropdownMenuPrimitive.Trigger {...props} />;\n}\n\nexport function DropdownMenuGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>,\n) {\n return <DropdownMenuPrimitive.Group {...props} />;\n}\n\nexport function DropdownMenuPortal(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>,\n) {\n return <DropdownMenuPrimitive.Portal {...props} />;\n}\n\nexport function DropdownMenuSub(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>,\n) {\n return <DropdownMenuPrimitive.Sub {...props} />;\n}\n\nexport function DropdownMenuRadioGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,\n) {\n return <DropdownMenuPrimitive.RadioGroup {...props} />;\n}\n\nexport function DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n sideOffset={sideOffset}\n className={cx(styles.content, className)}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport function DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-inset={inset ? \"true\" : undefined}\n className={cx(\n styles.item,\n variant === \"destructive\" && styles.itemDestructive,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuCheckboxItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n className={cx(\n styles.item,\n styles.insetItem,\n className,\n )}\n {...props}\n >\n <span className={styles.indicator}>\n <DropdownMenuPrimitive.ItemIndicator>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.indicatorIcon}\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nexport function DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n className={cx(\n styles.item,\n styles.insetItem,\n className,\n )}\n {...props}\n >\n <span className={styles.indicator}>\n <DropdownMenuPrimitive.ItemIndicator>\n <span className={styles.radioDot} />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nexport function DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-inset={inset ? \"true\" : undefined}\n className={cx(styles.label, className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n className={cx(styles.separator, className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-inset={inset ? \"true\" : undefined}\n className={cx(styles.item, className)}\n {...props}\n >\n {children}\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.chevron}\n >\n <path\n d=\"M6 3.5 10.5 8 6 12.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nexport function DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n className={cx(styles.content, className)}\n {...props}\n />\n );\n}\n","export const UZI_THEMES = [\"light\", \"dark\", \"system\"] as const;\nexport const UZI_ACCENTS = [\"blue\", \"cyan\", \"violet\", \"emerald\", \"amber\", \"rose\"] as const;\n\nexport const THEME_STORAGE_KEY = \"uzi-theme\";\nexport const ACCENT_STORAGE_KEY = \"uzi-accent\";\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { UZI_THEMES, UZI_ACCENTS, THEME_STORAGE_KEY as DEFAULT_THEME_KEY, ACCENT_STORAGE_KEY as DEFAULT_ACCENT_KEY } from \"./constants\";\nimport { ToastProvider } from \"../components/toast/ToastContext\";\nimport type { ToastConfig } from \"../components/toast/types\";\n\nexport type UziTheme = typeof UZI_THEMES[number];\nexport type UziResolvedTheme = \"light\" | \"dark\";\nexport type UziAccent = typeof UZI_ACCENTS[number];\n\ntype ThemeContextValue = {\n theme: UziTheme;\n resolvedTheme: UziResolvedTheme;\n accent: UziAccent;\n setTheme: (theme: UziTheme) => void;\n setAccent: (accent: UziAccent) => void;\n toggleTheme: () => void;\n};\n\ntype ThemeProviderProps = {\n children: ReactNode;\n theme?: UziTheme;\n defaultTheme?: UziTheme;\n accent?: UziAccent;\n defaultAccent?: UziAccent;\n onThemeChange?: (theme: UziTheme) => void;\n onAccentChange?: (accent: UziAccent) => void;\n storageKey?: string;\n accentStorageKey?: string;\n disableStorage?: boolean;\n toastConfig?: ToastConfig;\n};\n\nconst THEME_STORAGE_KEY = DEFAULT_THEME_KEY;\nconst ACCENT_STORAGE_KEY = DEFAULT_ACCENT_KEY;\nconst THEME_ATTRIBUTE = \"data-uzi-theme\";\nconst ACCENT_ATTRIBUTE = \"data-uzi-accent\";\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\nfunction isTheme(value: string | null): value is UziTheme {\n return UZI_THEMES.includes(value as UziTheme);\n}\n\nfunction isAccent(value: string | null): value is UziAccent {\n return UZI_ACCENTS.includes(value as UziAccent);\n}\n\nfunction getSystemTheme(): UziResolvedTheme {\n if (typeof window === \"undefined\") return \"light\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nexport function ThemeProvider({\n children,\n theme,\n defaultTheme = \"system\",\n accent,\n defaultAccent = \"blue\",\n onThemeChange,\n onAccentChange,\n storageKey = THEME_STORAGE_KEY,\n accentStorageKey = ACCENT_STORAGE_KEY,\n disableStorage = false,\n toastConfig,\n}: ThemeProviderProps) {\n const [internalTheme, setInternalTheme] = useState<UziTheme>(defaultTheme);\n const [internalAccent, setInternalAccent] = useState<UziAccent>(defaultAccent);\n const [systemTheme, setSystemTheme] = useState<UziResolvedTheme>(\"light\");\n\n useEffect(() => {\n setSystemTheme(getSystemTheme());\n if (!disableStorage) {\n const storedTheme = window.localStorage.getItem(storageKey);\n if (isTheme(storedTheme)) setInternalTheme(storedTheme);\n const storedAccent = window.localStorage.getItem(accentStorageKey);\n if (isAccent(storedAccent)) setInternalAccent(storedAccent);\n }\n }, [disableStorage, storageKey, accentStorageKey]);\n\n const isThemeControlled = theme !== undefined;\n const isAccentControlled = accent !== undefined;\n\n const currentTheme = isThemeControlled ? theme : internalTheme;\n const currentAccent = isAccentControlled ? accent : internalAccent;\n const resolvedTheme = currentTheme === \"system\" ? systemTheme : currentTheme;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handleChange = () => setSystemTheme(mediaQuery.matches ? \"dark\" : \"light\");\n\n handleChange();\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, []);\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.setAttribute(THEME_ATTRIBUTE, resolvedTheme);\n root.setAttribute(ACCENT_ATTRIBUTE, currentAccent);\n root.style.colorScheme = resolvedTheme;\n root.classList.toggle(\"dark\", resolvedTheme === \"dark\");\n }, [currentAccent, resolvedTheme]);\n\n const setTheme = useCallback(\n (nextTheme: UziTheme) => {\n if (!isThemeControlled) setInternalTheme(nextTheme);\n if (!disableStorage && typeof window !== \"undefined\") {\n window.localStorage.setItem(storageKey, nextTheme);\n }\n onThemeChange?.(nextTheme);\n },\n [disableStorage, isThemeControlled, onThemeChange, storageKey],\n );\n\n const setAccent = useCallback(\n (nextAccent: UziAccent) => {\n if (!isAccentControlled) setInternalAccent(nextAccent);\n if (!disableStorage && typeof window !== \"undefined\") {\n window.localStorage.setItem(accentStorageKey, nextAccent);\n }\n onAccentChange?.(nextAccent);\n },\n [accentStorageKey, disableStorage, isAccentControlled, onAccentChange],\n );\n\n const toggleTheme = useCallback(() => {\n setTheme(resolvedTheme === \"dark\" ? \"light\" : \"dark\");\n }, [resolvedTheme, setTheme]);\n\n const value = useMemo<ThemeContextValue>(\n () => ({\n theme: currentTheme,\n resolvedTheme,\n accent: currentAccent,\n setTheme,\n setAccent,\n toggleTheme,\n }),\n [currentAccent, currentTheme, resolvedTheme, setAccent, setTheme, toggleTheme],\n );\n\n return (\n <ThemeContext.Provider value={value}>\n <ToastProvider config={toastConfig}>{children}</ToastProvider>\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const context = useContext(ThemeContext);\n if (!context) throw new Error(\"useTheme must be used within a ThemeProvider\");\n return context;\n}\n",".withLabel {\n padding-left: 12px;\n padding-right: 12px;\n}\n","\"use client\";\n\nimport type { ButtonHTMLAttributes } from \"react\";\nimport { Button } from \"../button/Button\";\nimport { useTheme } from \"../../theme/ThemeProvider\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./theme-toggle-button.module.css\";\n\nexport type ThemeToggleButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> & {\n showLabel?: boolean;\n lightLabel?: string;\n darkLabel?: string;\n};\n\nfunction MoonIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" width=\"16\" height=\"16\" fill=\"none\">\n <path\n d=\"M20 15.2A8.5 8.5 0 0 1 8.8 4 9 9 0 1 0 20 15.2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SunIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" width=\"16\" height=\"16\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.8\" />\n <path\n d=\"M12 2.75v2.5M12 18.75v2.5M21.25 12h-2.5M5.25 12h-2.5M18.54 5.46l-1.77 1.77M7.23 16.77l-1.77 1.77M18.54 18.54l-1.77-1.77M7.23 7.23 5.46 5.46\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\nexport function ThemeToggleButton({\n showLabel = false,\n lightLabel = \"Light mode\",\n darkLabel = \"Dark mode\",\n className,\n onClick,\n ...rest\n}: ThemeToggleButtonProps) {\n const { resolvedTheme, toggleTheme } = useTheme();\n const nextThemeLabel = resolvedTheme === \"dark\" ? lightLabel : darkLabel;\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size={showLabel ? \"sm\" : \"icon\"}\n className={cx(showLabel && styles.withLabel, className)}\n aria-label={`Switch to ${nextThemeLabel.toLowerCase()}`}\n title={`Switch to ${nextThemeLabel.toLowerCase()}`}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) toggleTheme();\n }}\n {...rest}\n >\n {resolvedTheme === \"dark\" ? <SunIcon /> : <MoonIcon />}\n {showLabel && <span>{nextThemeLabel}</span>}\n </Button>\n );\n}\n",".topBar {\n position: sticky;\n top: 0;\n z-index: 30;\n border-bottom: 1px solid var(--ts-topbar-border, var(--border));\n background: var(--ts-topbar-bg, color-mix(in srgb, var(--background) 92%, transparent));\n box-shadow: var(--ts-topbar-shadow, 0 1px 2px rgba(0, 0, 0, 0.06));\n backdrop-filter: blur(12px);\n}\n\n.topBarStatic {\n position: relative;\n}\n\n.topBarInner {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n min-height: 4.25rem;\n padding: env(safe-area-inset-top, 0) 1rem 0 1rem;\n}\n\n.topBarStart {\n display: flex;\n align-items: center;\n gap: 0.875rem;\n min-width: 0;\n flex: 1 1 auto;\n}\n\n.topBarBrand {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n min-width: 0;\n color: var(--ts-topbar-brand-fg, var(--foreground));\n text-decoration: none;\n}\n\n.topBarBrandContent {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.topBarCenter {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.topBarCenterGroup {\n display: inline-flex;\n align-items: center;\n gap: 1rem;\n min-width: 0;\n}\n\n.topBarActions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 0.75rem;\n min-width: 0;\n flex: 1 1 auto;\n}\n\n@media (max-width: 768px) {\n .topBarInner {\n min-height: 4rem;\n gap: 0.75rem;\n padding-left: max(0.75rem, env(safe-area-inset-left));\n padding-right: max(0.75rem, env(safe-area-inset-right));\n }\n\n .topBarStart {\n gap: 0.75rem;\n }\n\n .topBarActions {\n gap: 0.5rem;\n }\n}\n","\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport {\n ThemeToggleButton,\n type ThemeToggleButtonProps,\n} from \"../theme-toggle-button/ThemeToggleButton\";\nimport styles from \"./top-bar.module.css\";\n\nexport type TopBarProps = HTMLAttributes<HTMLElement> & {\n leading?: ReactNode;\n brand?: ReactNode;\n brandHref?: string;\n brandingLocation?: \"left\" | \"center\";\n /** Content rendered after the brand in the left region (e.g. breadcrumbs, search). */\n start?: ReactNode;\n /** Content rendered in the center region. */\n center?: ReactNode;\n actions?: ReactNode;\n showThemeToggle?: boolean;\n themeToggleProps?: ThemeToggleButtonProps;\n innerClassName?: string;\n isSticky?: boolean;\n sticky?: boolean;\n};\n\nexport function TopBar({\n leading,\n brand,\n brandHref,\n brandingLocation = \"left\",\n start,\n center,\n actions,\n showThemeToggle = false,\n themeToggleProps,\n className,\n innerClassName,\n isSticky,\n sticky = true,\n children,\n ...rest\n}: TopBarProps) {\n const shouldStick = isSticky ?? sticky;\n const brandNode = !brand ? null : brandHref ? (\n <a href={brandHref} className={styles.topBarBrand}>\n <span className={styles.topBarBrandContent}>{brand}</span>\n </a>\n ) : (\n <div className={styles.topBarBrand}>\n <span className={styles.topBarBrandContent}>{brand}</span>\n </div>\n );\n\n return (\n <header\n className={cx(styles.topBar, !shouldStick && styles.topBarStatic, className)}\n {...rest}\n >\n <div className={cx(styles.topBarInner, innerClassName)}>\n <div className={styles.topBarStart}>\n {leading}\n {brandingLocation === \"left\" && brandNode}\n {start}\n </div>\n {(brandNode && brandingLocation === \"center\") || center || children ? (\n <div className={styles.topBarCenter}>\n <div className={styles.topBarCenterGroup}>\n {brandingLocation === \"center\" && brandNode}\n {center ?? children}\n </div>\n </div>\n ) : null}\n <div className={styles.topBarActions}>\n {showThemeToggle && <ThemeToggleButton {...themeToggleProps} />}\n {actions}\n </div>\n </div>\n </header>\n );\n}\n",".appShell {\n display: grid;\n grid-template-rows: calc(var(--app-shell-topbar-height, 64px) + env(safe-area-inset-top)) 1fr;\n grid-template-columns: var(--app-shell-sidebar-width, 240px) 1fr;\n height: 100vh;\n height: 100dvh;\n}\n\n.appShellAnimated {\n transition: grid-template-columns 200ms ease;\n}\n\n.appShell.appShellOpen {\n grid-template-columns: var(--app-shell-sidebar-width, 240px) 1fr;\n}\n\n.appShell.appShellCollapsed {\n grid-template-columns: 0 1fr;\n}\n\n.appShellTopbar {\n --ts-topbar-bg: var(--surface-topbar, color-mix(in srgb, var(--background) 92%, transparent));\n --ts-topbar-border: var(--border);\n --ts-topbar-brand-fg: var(--foreground);\n grid-column: 1 / -1;\n min-height: calc(var(--app-shell-topbar-height, 64px) + env(safe-area-inset-top));\n padding-left: 0;\n padding-right: 0;\n box-shadow: none;\n}\n\n.appShellTopbarLeft {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.appShellTopbarStart {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n}\n\n.appShellTopbarRight {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex-shrink: 0;\n}\n\n.appShellTopbarRight > * {\n min-width: 0;\n}\n\n.appShellBrand {\n font-size: 26px;\n color: var(--foreground);\n text-decoration: none;\n display: flex;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.appShellHamburger {\n background: transparent;\n border: none;\n padding: 0;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--foreground);\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.appShellHamburger:hover {\n background: var(--accent);\n}\n\n.appShellHamburger:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.appShellHamburger svg {\n width: 28px;\n height: 28px;\n}\n\n.appShellSidebar {\n border-right: 1px solid var(--border);\n background: var(--panel);\n padding: 24px;\n overflow-y: auto;\n}\n\n.appShellAnimated .appShellSidebar {\n transition: transform 200ms ease, opacity 200ms ease;\n}\n\n.appShell.appShellCollapsed .appShellSidebar {\n transform: translateX(-110%);\n opacity: 0;\n pointer-events: none;\n}\n\n.appShellMain {\n overflow-y: auto;\n min-height: 0;\n flex: 1 1 0;\n}\n\n.appShellBackdrop {\n display: none;\n}\n\n@media (max-width: 960px) {\n .appShellBackdrop {\n display: block;\n position: fixed;\n inset: 0;\n top: calc(var(--app-shell-topbar-height, 56px) + env(safe-area-inset-top));\n background: rgba(0, 0, 0, 0.5);\n z-index: 14;\n }\n\n .appShell {\n --app-shell-topbar-height: 56px;\n grid-template-columns: 1fr;\n grid-template-rows: calc(var(--app-shell-topbar-height, 56px) + env(safe-area-inset-top)) 1fr;\n }\n\n .appShell.appShellOpen,\n .appShell.appShellCollapsed {\n grid-template-columns: 1fr;\n }\n\n .appShellSidebar {\n display: block;\n position: fixed;\n top: calc(var(--app-shell-topbar-height, 56px) + env(safe-area-inset-top));\n left: 0;\n bottom: 0;\n width: var(--app-shell-sidebar-width, 240px);\n max-width: 80vw;\n background: var(--panel);\n padding: 16px 12px;\n transform: translateX(-105%);\n z-index: 15;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);\n }\n\n .appShellSidebar.appShellSidebarOpen {\n transform: translateX(0);\n }\n\n .appShellTopbar {\n padding-left: max(12px, env(safe-area-inset-left));\n padding-right: max(12px, env(safe-area-inset-right));\n gap: 10px;\n }\n\n .appShellTopbarLeft {\n gap: 10px;\n flex: 1;\n }\n\n .appShellTopbarStart {\n min-width: 0;\n }\n\n .appShellTopbarRight {\n gap: 6px;\n }\n\n .appShellBrand {\n font-size: 24px;\n max-width: 50vw;\n }\n\n .appShellHamburger {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n }\n\n .appShellHamburger svg {\n width: 24px;\n height: 24px;\n }\n}\n\n@media (max-width: 640px) {\n .appShellTopbar {\n gap: 8px;\n }\n\n .appShellBrand {\n font-size: 22px;\n max-width: 34vw;\n }\n\n .appShellTopbarRight {\n max-width: 44vw;\n }\n}\n\n@media (max-width: 480px) {\n .appShellBrand {\n font-size: 20px;\n max-width: 30vw;\n }\n}\n","\"use client\";\n\nimport {\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport { TopBar, type TopBarProps } from \"../top-bar/TopBar\";\nimport styles from \"./app-shell.module.css\";\n\nconst DESKTOP_BREAKPOINT = 960;\n\nfunction getIsDesktop() {\n if (typeof window === \"undefined\") return false;\n return window.innerWidth >= DESKTOP_BREAKPOINT;\n}\n\nexport type AppShellProps = {\n /** Primary page content rendered in the main area. */\n children: ReactNode;\n /** Sidebar navigation or custom content. */\n sidebar: ReactNode;\n /** Brand element rendered next to the hamburger (text or JSX). */\n brand?: ReactNode;\n /** Optional brand href; when provided the brand renders as an anchor. */\n brandHref?: string;\n /** Optional content after the brand on the left side of the top bar. */\n topbarStart?: ReactNode;\n /** Optional content aligned to the right side of the top bar. */\n topbarEnd?: ReactNode;\n /** Optional built-in theme toggle for the top bar. */\n showThemeToggle?: boolean;\n themeToggleProps?: TopBarProps[\"themeToggleProps\"];\n topBarBrandingLocation?: TopBarProps[\"brandingLocation\"];\n /** Custom class names for styling overrides. */\n className?: string;\n sidebarClassName?: string;\n topbarClassName?: string;\n mainClassName?: string;\n /** Sets the sidebar width (e.g., `260`, `\"18rem\"`). */\n sidebarWidth?: number | string;\n /**\n * Closes the sidebar on mobile whenever this value changes.\n * Useful for reacting to route/pathname changes.\n */\n closeSidebarOnChangeKey?: unknown;\n /** Label for the hamburger button (aria-label). */\n hamburgerLabel?: string;\n /** Optional callback fired whenever the sidebar open state changes. */\n onSidebarToggle?: (open: boolean) => void;\n};\n\n/**\n * Responsive application shell with a collapsible sidebar and sticky top bar.\n *\n * - Sidebar opens by default on desktop, collapses on mobile.\n * - Closes on outside click/scroll/touch when in mobile mode.\n * - Provides optional hook to close the sidebar when a prop value changes\n * (e.g., route transitions).\n */\nexport function AppShell({\n children,\n sidebar,\n brand,\n brandHref,\n topbarStart,\n topbarEnd,\n showThemeToggle = false,\n themeToggleProps,\n topBarBrandingLocation = \"left\",\n className,\n sidebarClassName,\n topbarClassName,\n mainClassName,\n sidebarWidth,\n closeSidebarOnChangeKey,\n hamburgerLabel = \"Toggle navigation\",\n onSidebarToggle,\n}: AppShellProps) {\n const [isDesktop, setIsDesktop] = useState(false);\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [transitionsReady, setTransitionsReady] = useState(false);\n const prevIsDesktopRef = useRef(false);\n const closeKeyRef = useRef(closeSidebarOnChangeKey);\n\n const sidebarRef = useRef<HTMLElement | null>(null);\n const hamburgerRef = useRef<HTMLButtonElement | null>(null);\n const mainRef = useRef<HTMLElement | null>(null);\n const sidebarId = useId();\n\n useEffect(() => {\n const desktop = getIsDesktop();\n setIsDesktop(desktop);\n setSidebarOpen(desktop);\n prevIsDesktopRef.current = desktop;\n const transitionFrame = window.requestAnimationFrame(() => {\n setTransitionsReady(true);\n });\n\n const handleResize = () => {\n const nowDesktop = getIsDesktop();\n setIsDesktop(nowDesktop);\n if (nowDesktop !== prevIsDesktopRef.current) {\n setSidebarOpen(nowDesktop);\n prevIsDesktopRef.current = nowDesktop;\n }\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.cancelAnimationFrame(transitionFrame);\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n // Close the sidebar when clicking outside or scrolling on mobile.\n useEffect(() => {\n if (isDesktop || !sidebarOpen) return;\n\n const mainElement = mainRef.current;\n const closeSidebar = () => setSidebarOpen(false);\n\n const onPointerDown = (e: PointerEvent) => {\n const target = e.target as Node | null;\n if (!target) return;\n if (sidebarRef.current?.contains(target)) return;\n if (hamburgerRef.current?.contains(target)) return;\n closeSidebar();\n };\n\n const timeoutId = window.setTimeout(() => {\n document.addEventListener(\"pointerdown\", onPointerDown);\n window.addEventListener(\"scroll\", closeSidebar, { passive: true });\n mainElement?.addEventListener(\"scroll\", closeSidebar, { passive: true });\n document.addEventListener(\"touchmove\", closeSidebar, { passive: true });\n }, 10);\n\n return () => {\n window.clearTimeout(timeoutId);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n window.removeEventListener(\"scroll\", closeSidebar);\n mainElement?.removeEventListener(\"scroll\", closeSidebar);\n document.removeEventListener(\"touchmove\", closeSidebar);\n };\n }, [sidebarOpen, isDesktop]);\n\n // Allow consumers to request a mobile sidebar close when a value changes (e.g., pathname).\n useEffect(() => {\n if (!isDesktop && closeKeyRef.current !== closeSidebarOnChangeKey) {\n setSidebarOpen(false);\n }\n closeKeyRef.current = closeSidebarOnChangeKey;\n }, [closeSidebarOnChangeKey, isDesktop]);\n\n useEffect(() => {\n onSidebarToggle?.(sidebarOpen);\n }, [sidebarOpen, onSidebarToggle]);\n\n const toggleSidebar = () => setSidebarOpen((open) => !open);\n\n const sidebarWidthValue =\n sidebarWidth === undefined\n ? undefined\n : typeof sidebarWidth === \"number\"\n ? `${sidebarWidth}px`\n : sidebarWidth;\n\n const shellStyle: CSSProperties | undefined = sidebarWidthValue\n ? { [\"--app-shell-sidebar-width\" as string]: sidebarWidthValue }\n : undefined;\n\n const shellClasses = cx(\n styles.appShell,\n transitionsReady && styles.appShellAnimated,\n sidebarOpen ? styles.appShellOpen : styles.appShellCollapsed,\n className,\n );\n\n const sidebarClasses = cx(\n styles.appShellSidebar,\n sidebarOpen && styles.appShellSidebarOpen,\n sidebarClassName,\n );\n\n return (\n <div\n className={shellClasses}\n style={shellStyle}\n data-app-shell\n data-desktop={isDesktop ? \"true\" : \"false\"}\n data-sidebar-open={sidebarOpen ? \"true\" : \"false\"}\n >\n <TopBar\n className={cx(styles.appShellTopbar, topbarClassName)}\n leading={\n <button\n ref={hamburgerRef}\n type=\"button\"\n className={styles.appShellHamburger}\n onClick={toggleSidebar}\n aria-label={hamburgerLabel}\n aria-expanded={sidebarOpen}\n aria-controls={sidebarId}\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M3 6h18M3 12h18M3 18h18\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n }\n brand={brand}\n brandHref={brandHref}\n brandingLocation={topBarBrandingLocation}\n start={topbarStart}\n actions={topbarEnd}\n showThemeToggle={showThemeToggle}\n themeToggleProps={themeToggleProps}\n />\n {!isDesktop && sidebarOpen && (\n <div\n className={styles.appShellBackdrop}\n onClick={() => setSidebarOpen(false)}\n onTouchStart={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n />\n )}\n <aside ref={sidebarRef} id={sidebarId} className={sidebarClasses} aria-label=\"Sidebar navigation\">\n {sidebar}\n </aside>\n <main ref={mainRef} className={cx(styles.appShellMain, mainClassName)}>\n {children}\n </main>\n </div>\n );\n}\n",".sidebarNav {\n --sidebar-nav-icon-size: 18px;\n --sidebar-nav-icon-size-mobile: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n min-height: 0;\n}\n\n.sidebarNavCollapsed {\n gap: 10px;\n}\n\n.header,\n.footer {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.footer {\n margin-top: auto;\n padding-top: 12px;\n border-top: 1px solid var(--border);\n}\n\n.sections {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 14px;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionItems {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionLabel {\n padding: 0 10px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--muted-foreground);\n opacity: 0.75;\n}\n\n.item {\n color: var(--foreground);\n background: transparent;\n border: none;\n box-shadow: none;\n padding: 10px 12px 10px 10px;\n border-radius: 10px;\n text-decoration: none;\n font-size: 14px;\n display: grid;\n grid-template-columns: var(--sidebar-nav-icon-size) minmax(0, 1fr);\n align-items: center;\n column-gap: 10px;\n width: 100%;\n text-align: left;\n box-sizing: border-box;\n line-height: 1.2;\n transition: background 120ms ease, color 120ms ease;\n}\n\nbutton.item {\n font-family: inherit;\n cursor: pointer;\n}\n\n.item:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.item:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n}\n\n.item.itemActive {\n background: color-mix(in srgb, var(--primary) 18%, transparent);\n color: var(--foreground);\n font-weight: 700;\n}\n\n.itemCollapsed {\n grid-template-columns: 1fr;\n justify-items: center;\n padding-right: 10px;\n padding-left: 10px;\n}\n\n.itemDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.icon {\n width: var(--sidebar-nav-icon-size);\n height: var(--sidebar-nav-icon-size);\n min-width: var(--sidebar-nav-icon-size);\n color: var(--muted-foreground);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n}\n\n.icon > * {\n width: 100% !important;\n height: 100% !important;\n max-width: 100%;\n max-height: 100%;\n}\n\n.icon :where(svg) {\n width: 100%;\n height: 100%;\n display: block;\n stroke: currentColor;\n}\n\n.item.itemActive .icon {\n color: var(--primary);\n}\n\n.itemBody {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 3px;\n overflow: hidden;\n}\n\n.labelRow {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n}\n\n.label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 12px;\n line-height: 1.35;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: color-mix(in srgb, var(--foreground) 4%, transparent);\n color: var(--muted-foreground);\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n@media (max-width: 960px) {\n .sidebarNav {\n gap: 10px;\n }\n\n .sections {\n gap: 12px;\n }\n\n .sectionItems {\n gap: 6px;\n }\n\n .item {\n padding: 9px 10px 9px 8px;\n border-radius: 9px;\n font-size: 14px;\n grid-template-columns: var(--sidebar-nav-icon-size-mobile) minmax(0, 1fr);\n column-gap: 8px;\n }\n\n .icon {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n min-width: var(--sidebar-nav-icon-size-mobile);\n }\n\n .icon :where(svg) {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n }\n\n .description {\n font-size: 11px;\n }\n}\n\n@media (max-width: 480px) {\n .item {\n padding: 8px 9px 8px 7px;\n font-size: 13px;\n }\n}\n","\"use client\";\n\nimport { type AnchorHTMLAttributes, type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./sidebar-nav.module.css\";\n\nexport type SidebarNavItem = {\n label: string;\n href?: string;\n icon?: ReactNode;\n description?: ReactNode;\n badge?: ReactNode;\n active?: boolean;\n disabled?: boolean;\n /**\n * When `true`, this item uses exact matching (matches its own path and paths starting with `{href}/`)\n * instead of prefix matching. This flag takes precedence over the global `matchStrategy` prop on a\n * per-item basis — even when `matchStrategy=\"prefix\"`, an item with `exact: true` will use exact matching.\n * When `matchStrategy=\"most-specific\"`, exact-flagged items participate in the length-based tiebreaker\n * like all other candidates, provided they pass their own match check first.\n */\n exact?: boolean;\n title?: string;\n target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n rel?: AnchorHTMLAttributes<HTMLAnchorElement>[\"rel\"];\n onClick?: () => void;\n};\n\nexport type SidebarNavSection = {\n id?: string;\n label?: ReactNode;\n items: SidebarNavItem[];\n};\n\nexport type SidebarNavProps = {\n items?: SidebarNavItem[];\n sections?: SidebarNavSection[];\n currentPath?: string;\n getIsActive?: (item: SidebarNavItem, currentPath?: string) => boolean;\n matchStrategy?: \"prefix\" | \"most-specific\";\n onItemClick?: (item: SidebarNavItem) => void;\n header?: ReactNode;\n footer?: ReactNode;\n ariaLabel?: string;\n collapsed?: boolean;\n iconSize?: number | string;\n className?: string;\n itemClassName?: string;\n sectionClassName?: string;\n};\n\nconst isActivePrefix = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n if (item.href === \"/\") return path === \"/\";\n return path.startsWith(item.href);\n};\n\nconst isActiveExact = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n // Root href \"/\" must match exactly — otherwise every path would match.\n if (item.href === \"/\") return path === \"/\";\n // Normalize trailing slashes for consistent matching with findMostSpecific length computation.\n const normalizedHref = item.href.endsWith(\"/\") ? item.href.slice(0, -1) : item.href;\n return normalizedHref === path || path.startsWith(`${normalizedHref}/`);\n};\n\n// Natural matching helpers that ignore manual `active` overrides — used inside findMostSpecific\n// so that manually-set active flags don't hijack the length-based tiebreaker.\nconst isNaturalPrefixMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n return path.startsWith(href);\n};\n\nconst isNaturalExactMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n const normalizedHref = href.endsWith(\"/\") ? href.slice(0, -1) : href;\n return normalizedHref === path;\n};\n\nconst hrefLength = (href: string) => (href.endsWith(\"/\") ? href.length - 1 : href.length);\n\nconst findMostSpecific = (items: SidebarNavItem[], currentPath?: string): Set<string> => {\n const result = new Set<string>();\n if (!currentPath) return result;\n\n // Collect all items that naturally match the path — use natural matching helpers so that\n // manually-set `active` flags don't participate in the length-based tiebreaker.\n // Exclude disabled items from matching since they are not interactive targets.\n const matchingItems = items.filter(item => {\n if (item.disabled || !item.href) return false;\n return item.exact\n ? isNaturalExactMatch(item.href, currentPath)\n : isNaturalPrefixMatch(item.href, currentPath);\n });\n\n if (matchingItems.length === 0) return result;\n\n // Find the longest href among prefix matches.\n let maxLen = 0;\n for (const item of matchingItems) {\n if (!item.href) continue;\n const len = hrefLength(item.href);\n if (len > maxLen) maxLen = len;\n }\n\n // Only the items with the longest href are active.\n for (const item of matchingItems) {\n if (!item.href) continue;\n if (hrefLength(item.href) === maxLen) result.add(item.href);\n }\n\n return result;\n};\n\nexport function SidebarNav({\n items = [],\n sections,\n currentPath,\n getIsActive,\n matchStrategy = \"prefix\",\n onItemClick,\n header,\n footer,\n ariaLabel = \"Sidebar navigation\",\n collapsed = false,\n iconSize,\n className,\n itemClassName,\n sectionClassName,\n}: SidebarNavProps) {\n const resolvedSections = useMemo(() => {\n return sections?.length ? sections : [{ id: \"default\", items }];\n }, [sections, items]);\n\n // Stable reference to all items — avoids recreating on every render when `sections` is falsy.\n const allItems = useMemo(() => resolvedSections.flatMap(section => section.items), [resolvedSections]);\n\n // Build the default isActive function based on matchStrategy.\n const defaultIsActiveFn = useMemo<(item: SidebarNavItem, path?: string) => boolean>(() => {\n if (matchStrategy === \"most-specific\") {\n const mostSpecificHrefs = findMostSpecific(allItems, currentPath);\n return (item: SidebarNavItem) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n // Exact-flagged items participate in the length-based tiebreaker like all other candidates.\n return mostSpecificHrefs.has(item.href);\n };\n } else {\n return (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (item.exact) return isActiveExact(item, path);\n return isActivePrefix(item, path);\n };\n }\n }, [matchStrategy, allItems, currentPath]);\n\n const resolvedGetIsActive = getIsActive ?? defaultIsActiveFn;\n\n const style =\n iconSize !== undefined\n ? ({\n [\"--sidebar-nav-icon-size\" as string]:\n typeof iconSize === \"number\" ? `${iconSize}px` : iconSize,\n } satisfies CSSProperties)\n : undefined;\n\n return (\n <nav\n className={cx(\n styles.sidebarNav,\n collapsed && styles.sidebarNavCollapsed,\n className,\n )}\n aria-label={ariaLabel}\n style={style}\n >\n {header ? <div className={styles.header}>{header}</div> : null}\n <div className={styles.sections}>\n {resolvedSections.map((section, sectionIndex) => (\n <div\n key={section.id ?? `section-${sectionIndex}`}\n className={cx(styles.section, sectionClassName)}\n >\n {section.label && !collapsed ? (\n <div className={styles.sectionLabel}>{section.label}</div>\n ) : null}\n <div className={styles.sectionItems}>\n {section.items.map((item, itemIndex) => (\n <SidebarNavEntry\n key={`${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`}\n item={item}\n active={resolvedGetIsActive(item, currentPath)}\n collapsed={collapsed}\n itemClassName={itemClassName}\n onItemClick={onItemClick}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </nav>\n );\n}\n\ntype SidebarNavEntryProps = {\n item: SidebarNavItem;\n active: boolean;\n collapsed: boolean;\n itemClassName?: string;\n onItemClick?: (item: SidebarNavItem) => void;\n};\n\nfunction SidebarNavEntry({\n item,\n active,\n collapsed,\n itemClassName,\n onItemClick,\n}: SidebarNavEntryProps) {\n const rel = item.rel ?? (item.target === \"_blank\" ? \"noreferrer\" : undefined);\n const title = item.title ?? (typeof item.label === \"string\" ? item.label : undefined);\n const classes = cx(\n styles.item,\n active && styles.itemActive,\n collapsed && styles.itemCollapsed,\n item.disabled && styles.itemDisabled,\n itemClassName,\n );\n const content = (\n <>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {!collapsed ? (\n <span className={styles.itemBody}>\n <span className={styles.labelRow}>\n <span className={styles.label}>{item.label}</span>\n {item.badge && <span className={styles.badge}>{item.badge}</span>}\n </span>\n {item.description ? <span className={styles.description}>{item.description}</span> : null}\n </span>\n ) : null}\n </>\n );\n\n const handleClick = () => {\n if (item.disabled) return;\n item.onClick?.();\n onItemClick?.(item);\n };\n\n if (!item.href) {\n return (\n <button\n type=\"button\"\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={item.disabled ? \"true\" : undefined}\n disabled={item.disabled}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </button>\n );\n }\n\n if (item.disabled) {\n return (\n <div\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled=\"true\"\n title={collapsed ? title : undefined}\n >\n {content}\n </div>\n );\n }\n\n return (\n <a\n className={classes}\n href={item.href}\n target={item.target}\n rel={rel}\n aria-current={active ? \"page\" : undefined}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </a>\n );\n}\n",".skeleton {\n background: color-mix(in srgb, var(--muted-foreground) 14%, var(--background));\n animation: skeleton-pulse 1.6s ease-in-out infinite;\n}\n\n@keyframes skeleton-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.45; }\n}\n\n.radius-sm { border-radius: 4px; }\n.radius-md { border-radius: 8px; }\n.radius-lg { border-radius: 12px; }\n.radius-full { border-radius: 9999px; }\n","\"use client\";\n\nimport type { HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./skeleton.module.css\";\n\nexport type SkeletonProps = HTMLAttributes<HTMLDivElement> & {\n /** Width as a CSS value. */\n width?: string;\n /** Height as a CSS value. */\n height?: string;\n /** Border radius preset. Defaults to \"md\". */\n radius?: \"sm\" | \"md\" | \"lg\" | \"full\";\n};\n\nexport function Skeleton({\n width,\n height,\n radius = \"md\",\n className,\n style,\n ...rest\n}: SkeletonProps) {\n return (\n <div\n className={cx(styles.skeleton, styles[`radius-${radius}`], className)}\n style={{ width, height, ...style }}\n aria-hidden=\"true\"\n {...rest}\n />\n );\n}\n",".track {\n height: 8px;\n border-radius: 9999px;\n overflow: hidden;\n background: color-mix(in srgb, var(--border) 60%, transparent);\n}\n\n.fill {\n height: 100%;\n border-radius: 9999px;\n transition: width 0.4s ease;\n}\n\n.tone-default { background: var(--foreground); }\n.tone-success { background: var(--success); }\n.tone-warning { background: var(--warning); }\n.tone-danger { background: var(--destructive); }\n","import type { HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./progress.module.css\";\n\nexport type ProgressTone = \"default\" | \"success\" | \"warning\" | \"danger\";\n\nexport type ProgressProps = HTMLAttributes<HTMLDivElement> & {\n /** Value 0–100. */\n value: number;\n /** Visual tone. Defaults to \"default\". */\n tone?: ProgressTone;\n /** Accessible label. */\n \"aria-label\"?: string;\n};\n\nexport function Progress({\n value,\n tone = \"default\",\n className,\n \"aria-label\": ariaLabel,\n ...rest\n}: ProgressProps) {\n const clamped = Math.max(0, Math.min(100, value));\n return (\n <div\n className={cx(styles.track, className)}\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={ariaLabel}\n {...rest}\n >\n <div\n className={cx(styles.fill, styles[`tone-${tone}`])}\n style={{ width: `${clamped}%` }}\n />\n </div>\n );\n}\n",".track {\n display: inline-flex;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: var(--card);\n padding: 4px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n gap: 2px;\n}\n\n.option {\n border-radius: 999px;\n padding: 6px 16px;\n font-size: var(--uzi-control-font-size);\n font-weight: 500;\n line-height: var(--uzi-control-line-height);\n background: transparent;\n color: var(--muted-foreground);\n border: none;\n cursor: pointer;\n transition:\n color 120ms ease,\n background 120ms ease;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n}\n\n.label {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.option:hover:not([aria-checked=\"true\"]):not(:disabled) {\n color: var(--foreground);\n}\n\n.option[aria-checked=\"true\"] {\n background: var(--foreground);\n color: var(--background);\n}\n\n.option:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.option:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./segmented-toggle.module.css\";\n\nexport type SegmentedToggleOption<T extends string = string> = {\n label: ReactNode;\n value: T;\n disabled?: boolean;\n};\n\nexport type SegmentedToggleProps<T extends string = string> = {\n options: SegmentedToggleOption<T>[];\n value: T;\n onChange: (value: T) => void;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n className?: string;\n};\n\nexport function SegmentedToggle<T extends string = string>({\n options,\n value,\n onChange,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n className,\n}: SegmentedToggleProps<T>) {\n const itemRefs = React.useRef<Array<HTMLButtonElement | null>>([]);\n const selectedIndex = options.findIndex((opt) => opt.value === value);\n const fallbackIndex = options.findIndex((opt) => !opt.disabled);\n let lastEnabledIndex = -1;\n for (let index = options.length - 1; index >= 0; index -= 1) {\n if (!options[index]?.disabled) {\n lastEnabledIndex = index;\n break;\n }\n }\n const tabbableIndex =\n selectedIndex >= 0 && !options[selectedIndex]?.disabled\n ? selectedIndex\n : fallbackIndex;\n\n const focusItem = (index: number) => {\n itemRefs.current[index]?.focus();\n };\n\n const findEnabledIndex = (\n startIndex: number,\n direction: 1 | -1,\n ): number => {\n if (options.length === 0) return -1;\n\n let nextIndex = startIndex;\n for (let i = 0; i < options.length; i += 1) {\n nextIndex = (nextIndex + direction + options.length) % options.length;\n if (!options[nextIndex]?.disabled) {\n return nextIndex;\n }\n }\n\n return startIndex;\n };\n\n const selectIndex = (index: number) => {\n const nextOption = options[index];\n if (!nextOption || nextOption.disabled || nextOption.value === value) {\n return;\n }\n onChange(nextOption.value);\n };\n\n const handleKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\": {\n event.preventDefault();\n const nextIndex = findEnabledIndex(index, 1);\n focusItem(nextIndex);\n selectIndex(nextIndex);\n break;\n }\n case \"ArrowLeft\":\n case \"ArrowUp\": {\n event.preventDefault();\n const nextIndex = findEnabledIndex(index, -1);\n focusItem(nextIndex);\n selectIndex(nextIndex);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n focusItem(fallbackIndex);\n if (fallbackIndex >= 0) {\n selectIndex(fallbackIndex);\n }\n break;\n }\n case \"End\": {\n event.preventDefault();\n if (lastEnabledIndex >= 0) {\n focusItem(lastEnabledIndex);\n selectIndex(lastEnabledIndex);\n }\n break;\n }\n default:\n break;\n }\n };\n\n return (\n <div\n className={cx(styles.track, className)}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {options.map((opt, index) => (\n <button\n key={opt.value}\n ref={(node) => {\n itemRefs.current[index] = node;\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={opt.value === value}\n disabled={opt.disabled}\n tabIndex={\n opt.disabled\n ? -1\n : index === tabbableIndex\n ? 0\n : -1\n }\n onClick={() => {\n if (opt.value !== value) {\n onChange(opt.value);\n }\n }}\n onKeyDown={(event) => handleKeyDown(event, index)}\n className={cx(styles.option)}\n >\n <span className={styles.label}>{opt.label}</span>\n </button>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/utils/cx.ts","../src/components/button/button.module.css","../src/components/button/Button.tsx","../src/components/avatar/avatar.module.css","../src/components/avatar/Avatar.tsx","../src/components/card/card.module.css","../src/components/card/Card.tsx","../src/components/pill/pill.module.css","../src/components/pill/Pill.tsx","../src/components/modal/modal.module.css","../src/components/modal/Modal.tsx","../src/components/alert/alert.module.css","../src/components/alert/Alert.tsx","../src/components/toast/toast.module.css","../src/components/toast/ToastContext.tsx","../src/components/input/input.module.css","../src/components/input/Input.tsx","../src/components/label/label.module.css","../src/components/label/Label.tsx","../src/components/checkbox/checkbox.module.css","../src/components/checkbox/Checkbox.tsx","../src/components/multi-select/multi-select.module.css","../src/components/multi-select/MultiSelect.tsx","../src/components/select/select.module.css","../src/components/select/Select.tsx","../src/components/dropdown/Dropdown.tsx","../src/components/dropdown-menu/dropdown-menu.module.css","../src/components/dropdown-menu/DropdownMenu.tsx","../src/theme/constants.ts","../src/theme/ThemeProvider.tsx","../src/components/theme-toggle-button/theme-toggle-button.module.css","../src/components/theme-toggle-button/ThemeToggleButton.tsx","../src/components/top-bar/top-bar.module.css","../src/components/top-bar/TopBar.tsx","../src/components/app-shell/app-shell.module.css","../src/components/app-shell/AppShell.tsx","../src/components/sidebar-nav/sidebar-nav.module.css","../src/components/sidebar-nav/SidebarNav.tsx","../src/components/skeleton/skeleton.module.css","../src/components/skeleton/Skeleton.tsx","../src/components/progress/progress.module.css","../src/components/progress/Progress.tsx","../src/components/segmented-toggle/segmented-toggle.module.css","../src/components/segmented-toggle/SegmentedToggle.tsx"],"sourcesContent":["export function cx(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n",".button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n font-family: inherit;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n text-decoration: none;\n transition:\n opacity 0.15s,\n border-color 0.15s,\n color 0.15s,\n background 0.15s;\n white-space: nowrap;\n line-height: 1;\n}\n\n.button:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.button svg {\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n}\n\n.button:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n/* Sizes */\n.sizeSm {\n font-size: 0.82rem;\n min-height: 2rem;\n padding: 6px 14px;\n}\n\n.sizeMd {\n font-size: 0.95rem;\n min-height: 2.25rem;\n padding: 10px 22px;\n}\n\n.sizeLg {\n font-size: 1rem;\n min-height: 2.5rem;\n padding: 12px 28px;\n}\n\n.sizeIcon {\n width: 2.25rem;\n height: 2.25rem;\n padding: 0;\n}\n\n/* Variants */\n.variantPrimary {\n background: var(--ts-btn-primary-bg, var(--primary));\n color: var(--ts-btn-primary-text, var(--primary-foreground));\n}\n\n.variantPrimary:hover:not(:disabled) {\n opacity: 0.88;\n}\n\n.variantSecondary {\n background: var(--ts-btn-secondary-bg, var(--secondary));\n color: var(--ts-btn-secondary-text, var(--secondary-foreground));\n border-color: var(--ts-btn-secondary-border, var(--border));\n}\n\n.variantSecondary:hover:not(:disabled) {\n background: var(--ts-btn-secondary-hover-bg, color-mix(in srgb, var(--secondary) 90%, black));\n}\n\n.variantOutline {\n background: var(--ts-btn-outline-bg, var(--background));\n color: var(--ts-btn-outline-text, var(--foreground));\n border-color: var(--ts-btn-outline-border, var(--border));\n}\n\n.variantOutline:hover:not(:disabled) {\n background: var(--ts-btn-outline-hover-bg, var(--accent));\n color: var(--ts-btn-outline-hover-text, var(--accent-foreground));\n}\n\n.variantGhost {\n background: transparent;\n color: var(--ts-btn-ghost-text, var(--muted-foreground));\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.variantGhost:hover:not(:disabled) {\n background: var(--ts-btn-ghost-hover-bg, var(--accent));\n color: var(--ts-btn-ghost-hover-text, var(--accent-foreground));\n}\n\n.variantDestructive {\n background: var(--ts-btn-danger-bg, var(--destructive));\n color: var(--ts-btn-danger-text, var(--destructive-foreground));\n}\n\n.variantDestructive:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n.variantLink {\n background: transparent;\n color: var(--ts-btn-link-text, var(--primary));\n border-color: transparent;\n min-height: auto;\n padding: 0;\n border-radius: 0;\n}\n\n.variantLink:hover:not(:disabled) {\n text-decoration: underline;\n text-underline-offset: 0.2em;\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./button.module.css\";\n\nexport type ButtonVariant =\n | \"default\"\n | \"primary\"\n | \"secondary\"\n | \"outline\"\n | \"ghost\"\n | \"destructive\"\n | \"link\";\nexport type ButtonSize = \"default\" | \"sm\" | \"md\" | \"lg\" | \"icon\";\n\ntype BaseProps = {\n variant?: ButtonVariant;\n size?: ButtonSize;\n className?: string;\n children?: React.ReactNode;\n asChild?: boolean;\n};\n\ntype AsButton = BaseProps &\n React.ButtonHTMLAttributes<HTMLButtonElement> & { as?: \"button\" };\n\ntype AsAnchor = BaseProps &\n React.AnchorHTMLAttributes<HTMLAnchorElement> & { as: \"a\" };\n\nexport type ButtonProps = AsButton | AsAnchor;\n\nconst variantClass: Record<ButtonVariant, string> = {\n default: \"variantPrimary\",\n primary: \"variantPrimary\",\n secondary: \"variantSecondary\",\n outline: \"variantOutline\",\n ghost: \"variantGhost\",\n destructive: \"variantDestructive\",\n link: \"variantLink\",\n};\n\nconst sizeClass: Record<ButtonSize, string> = {\n default: \"sizeMd\",\n sm: \"sizeSm\",\n md: \"sizeMd\",\n lg: \"sizeLg\",\n icon: \"sizeIcon\",\n};\n\nexport function Button({\n as,\n variant = \"default\",\n size = \"default\",\n className,\n children,\n asChild = false,\n ...rest\n}: ButtonProps) {\n const classes = cx(\n styles.button,\n styles[variantClass[variant]],\n styles[sizeClass[size]],\n className,\n );\n\n if (asChild) {\n return (\n <Slot className={classes} {...rest}>\n {children}\n </Slot>\n );\n }\n\n if (as === \"a\") {\n return (\n <a\n className={classes}\n {...(rest as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {children}\n </a>\n );\n }\n\n return (\n <button\n type=\"button\"\n className={classes}\n {...(rest as React.ButtonHTMLAttributes<HTMLButtonElement>)}\n >\n {children}\n </button>\n );\n}\n",".avatar {\n position: relative;\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border-radius: 999px;\n background: var(--ts-avatar-bg, var(--muted));\n color: var(--ts-avatar-fg, var(--muted-foreground));\n}\n\n.size-sm {\n width: 1.75rem;\n height: 1.75rem;\n}\n\n.size-md {\n width: 2rem;\n height: 2rem;\n}\n\n.size-lg {\n width: 2.25rem;\n height: 2.25rem;\n}\n\n.size-xl {\n width: 4rem;\n height: 4rem;\n}\n\n.image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.fallback {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n border-radius: inherit;\n background: var(--ts-avatar-fallback-bg, var(--muted));\n color: var(--ts-avatar-fallback-fg, var(--muted-foreground));\n font-size: 0.85rem;\n font-weight: 700;\n line-height: 1;\n text-transform: uppercase;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./avatar.module.css\";\n\nexport type AvatarSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport type AvatarProps = React.ComponentProps<typeof AvatarPrimitive.Root> & {\n size?: AvatarSize;\n};\n\nexport function Avatar({\n className,\n size = \"md\",\n ...props\n}: AvatarProps) {\n const sizeClass =\n size === \"sm\" ? styles[\"size-sm\"] : size === \"lg\" ? styles[\"size-lg\"] : size === \"xl\" ? styles[\"size-xl\"] : styles[\"size-md\"];\n\n return (\n <AvatarPrimitive.Root\n className={cx(styles.avatar, sizeClass, className)}\n {...props}\n />\n );\n}\n\nexport function AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n className={cx(styles.image, className)}\n {...props}\n />\n );\n}\n\nexport function AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n className={cx(styles.fallback, className)}\n {...props}\n />\n );\n}\n",".card {\n position: relative;\n overflow: visible;\n border-radius: var(--ts-card-radius, 12px);\n border: 1px solid var(--ts-card-border, var(--border));\n background: var(--ts-card-bg, var(--panel));\n color: var(--ts-card-fg, var(--foreground));\n box-shadow: var(--ts-card-shadow, 0 16px 36px rgba(0, 0, 0, 0.28));\n padding: var(--ts-card-padding, 16px);\n transition:\n transform 140ms ease,\n box-shadow 140ms ease,\n border-color 140ms ease,\n background-color 140ms ease;\n}\n\n.tone-default {\n --ts-card-bg: var(--panel);\n --ts-card-border: var(--border);\n --ts-card-shadow: 0 16px 36px rgba(0, 0, 0, 0.28);\n}\n\n.tone-muted {\n --ts-card-bg: var(--muted);\n --ts-card-border: var(--border);\n --ts-card-shadow: 0 10px 26px rgba(0, 0, 0, 0.22);\n}\n\n.tone-contrast {\n --ts-card-bg: var(--ts-card-contrast-bg, color-mix(in srgb, var(--background) 60%, black));\n --ts-card-border: var(--border);\n --ts-card-shadow: 0 18px 50px rgba(0, 0, 0, 0.32);\n}\n\n.interactive {\n cursor: default;\n}\n\n.interactive:hover {\n transform: translateY(-1px);\n box-shadow: 0 22px 60px rgba(0, 0, 0, 0.32);\n border-color: var(--ts-card-hover-border, color-mix(in srgb, var(--primary) 40%, transparent));\n}\n\n.interactive:focus-within {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.padding-none { --ts-card-padding: 0; }\n.padding-sm { --ts-card-padding: 10px; }\n.padding-md { --ts-card-padding: 16px; }\n.padding-lg { --ts-card-padding: 20px; }\n","/**\n * Lightweight container component used for panels across the app.\n *\n * @remarks\n * Supports tone variants, padding presets, and an optional interactive affordance.\n *\n * @param props.as - Semantic element to render (defaults to `div`).\n * @param props.tone - Visual tone variant.\n * @param props.padding - Padding preset.\n * @param props.interactive - Enables hover/focus affordance.\n */\nimport type { HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./card.module.css\";\n\nexport type CardTone = \"default\" | \"muted\" | \"contrast\";\nexport type CardPadding = \"none\" | \"sm\" | \"md\" | \"lg\";\n\ntype CardElement = \"div\" | \"section\" | \"article\";\n\nexport type CardProps = HTMLAttributes<HTMLElement> & {\n /** Optional semantic element type. Defaults to `div`. */\n as?: CardElement;\n /** Visual tone; drives background/border CSS vars. */\n tone?: CardTone;\n /** Padding preset; maps to CSS variables so consumers can override globally. */\n padding?: CardPadding;\n /** Adds hover/focus affordance (lift + outline). */\n interactive?: boolean;\n};\n\nexport function Card({\n as,\n tone = \"default\",\n padding = \"md\",\n interactive = false,\n className,\n children,\n ...rest\n}: CardProps) {\n const Component: CardElement = as ?? \"div\";\n const TONE_CLASS: Record<CardTone, string | null> = { default: null, muted: \"tone-muted\", contrast: \"tone-contrast\" };\n const PADDING_CLASS: Record<CardPadding, string> = { none: \"padding-none\", sm: \"padding-sm\", md: \"padding-md\", lg: \"padding-lg\" };\n const classes = cx(\n styles.card,\n TONE_CLASS[tone] ? styles[TONE_CLASS[tone]] : null,\n styles[PADDING_CLASS[padding]],\n interactive && styles.interactive,\n className,\n );\n\n return (\n <Component className={classes} {...rest}>\n {children}\n </Component>\n );\n}\n",".pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n border: 1px solid var(--ts-pill-border, var(--border));\n background: var(--ts-pill-bg, color-mix(in srgb, var(--foreground) 4%, transparent));\n color: var(--ts-pill-fg, var(--muted-foreground));\n font-size: 12px;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n line-height: 1.2;\n white-space: nowrap;\n}\n\n.size-sm {\n padding: 3px 8px;\n font-size: 11px;\n}\n\n.size-md {\n padding: 4px 10px;\n}\n\n.tone-success {\n color: var(--success);\n border-color: color-mix(in srgb, var(--success) 45%, transparent);\n background: color-mix(in srgb, var(--success) 12%, transparent);\n}\n\n.tone-warning {\n color: var(--warning);\n border-color: color-mix(in srgb, var(--warning) 45%, transparent);\n background: color-mix(in srgb, var(--warning) 12%, transparent);\n}\n\n.tone-info {\n color: var(--primary);\n border-color: color-mix(in srgb, var(--primary) 50%, transparent);\n background: color-mix(in srgb, var(--primary) 12%, transparent);\n}\n\n.tone-danger {\n color: var(--destructive);\n border-color: color-mix(in srgb, var(--destructive) 45%, transparent);\n background: color-mix(in srgb, var(--destructive) 12%, transparent);\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n}\n\n.content {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n","/**\n * Compact label component for status chips and tags.\n *\n * @remarks\n * Supports tone and size presets, and can render any inline element.\n *\n * @param props.as - Element to render (defaults to `span`).\n * @param props.tone - Visual tone variant.\n * @param props.size - Size preset.\n * @param props.icon - Optional leading icon.\n */\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./pill.module.css\";\n\nexport type PillTone = \"neutral\" | \"success\" | \"warning\" | \"info\" | \"danger\";\nexport type PillSize = \"sm\" | \"md\";\n\ntype PillElement = \"span\" | \"div\" | \"button\";\n\nexport type PillProps = HTMLAttributes<HTMLElement> & {\n /** Optional rendered element; defaults to `span`. */\n as?: PillElement;\n /** Visual tone; adjusts color and border. */\n tone?: PillTone;\n /** Size preset. */\n size?: PillSize;\n /** Leading icon node (not focusable). */\n icon?: ReactNode;\n};\n\nexport function Pill({\n as,\n tone = \"neutral\",\n size = \"md\",\n icon,\n className,\n children,\n ...rest\n}: PillProps) {\n const Component: PillElement = as ?? \"span\";\n const classes = cx(styles.pill, styles[`tone-${tone}`], styles[`size-${size}`], className);\n\n return (\n <Component className={classes} {...rest}>\n {icon ? (\n <span className={styles.icon} aria-hidden=\"true\">\n {icon}\n </span>\n ) : null}\n <span className={styles.content}>{children}</span>\n </Component>\n );\n}\n",".portalLayer {\n position: fixed;\n inset: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n}\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n}\n\n.backdrop[data-state=\"open\"] {\n animation: backdropFadeIn 160ms ease;\n}\n\n.backdrop[data-state=\"closed\"] {\n animation: backdropFadeOut 140ms ease;\n}\n\n.overlayContent {\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n max-width: 100%;\n max-height: 100%;\n outline: none;\n}\n\n.overlayContent[data-state=\"open\"] {\n animation: modalContentIn 180ms ease;\n}\n\n.overlayContent[data-state=\"closed\"] {\n animation: modalContentOut 140ms ease;\n}\n\n.modal {\n background: var(--background);\n border: 1px solid var(--border);\n border-radius: 14px;\n padding: 24px;\n width: min(500px, 100%);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.55);\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n\n/* Size variants */\n.size-sm { width: min(380px, 100%); }\n.size-md { width: min(500px, 100%); }\n.size-lg { width: min(640px, 100%); }\n.size-xl { width: min(900px, 100%); }\n\n.header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.titles {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.title {\n font-weight: 700;\n font-size: 16px;\n color: var(--foreground);\n line-height: 1.3;\n}\n\n.subtitle {\n font-size: 13px;\n color: var(--muted-foreground);\n line-height: 1.4;\n}\n\n.closeButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n color: var(--muted-foreground);\n cursor: pointer;\n transition: background 0.12s, color 0.12s;\n padding: 0;\n}\n\n.closeButton:hover {\n background: color-mix(in srgb, var(--foreground) 7%, transparent);\n color: var(--foreground);\n}\n\n.closeButton:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.footer {\n display: flex;\n gap: 8px;\n margin-top: 20px;\n}\n\n@keyframes backdropFadeIn {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n@keyframes backdropFadeOut {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0;\n }\n}\n\n@keyframes modalContentIn {\n from {\n opacity: 0;\n transform: translateY(6px) scale(0.98);\n }\n\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes modalContentOut {\n from {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n\n to {\n opacity: 0;\n transform: translateY(4px) scale(0.98);\n }\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./modal.module.css\";\n\n// ── ModalOverlay ─────────────────────────────────────────────────────────────\n// Bare backdrop + container. No opinions on layout inside.\n// Use this when you need a full-custom layout (e.g. wide media modals).\n\nexport type ModalOverlayProps = {\n open: boolean;\n onClose: () => void;\n /** Extra class applied to the backdrop */\n className?: string;\n children: ReactNode;\n};\n\nexport function ModalOverlay({ open, onClose, className, children }: ModalOverlayProps) {\n return (\n <DialogPrimitive.Root\n open={open}\n onOpenChange={(nextOpen: boolean) => {\n if (!nextOpen) onClose();\n }}\n >\n <DialogPrimitive.Portal>\n <div className={styles.portalLayer}>\n <DialogPrimitive.Overlay className={cx(styles.backdrop, className)} />\n <DialogPrimitive.Content className={styles.overlayContent}>\n {children}\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// ── Modal ─────────────────────────────────────────────────────────────────────\n// Opinionated dialog: header (title + close button), scrollable body, footer.\n\nexport type ModalSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport type ModalProps = {\n open: boolean;\n onClose: () => void;\n title: string;\n subtitle?: string;\n size?: ModalSize;\n children: ReactNode;\n footer?: ReactNode;\n};\n\nexport function Modal({ open, onClose, title, subtitle, size = \"md\", children, footer }: ModalProps) {\n return (\n <ModalOverlay open={open} onClose={onClose}>\n <div className={cx(styles.modal, styles[`size-${size}`])}>\n <div className={styles.header}>\n <div className={styles.titles}>\n <DialogPrimitive.Title className={styles.title}>{title}</DialogPrimitive.Title>\n {subtitle ? (\n <DialogPrimitive.Description className={styles.subtitle}>\n {subtitle}\n </DialogPrimitive.Description>\n ) : null}\n </div>\n <DialogPrimitive.Close asChild>\n <button className={styles.closeButton} aria-label=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </DialogPrimitive.Close>\n </div>\n\n <div className={styles.body}>{children}</div>\n\n {footer && <div className={styles.footer}>{footer}</div>}\n </div>\n </ModalOverlay>\n );\n}\n",".alert {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n border-radius: 0.375rem;\n border: 1px solid;\n padding: 0.625rem 0.875rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.success {\n border-color: color-mix(in srgb, var(--success) 35%, transparent);\n background: color-mix(in srgb, var(--success) 10%, transparent);\n color: color-mix(in srgb, var(--success) 90%, var(--foreground));\n}\n\n.error {\n border-color: color-mix(in srgb, var(--destructive) 35%, transparent);\n background: color-mix(in srgb, var(--destructive) 10%, transparent);\n color: color-mix(in srgb, var(--destructive) 90%, var(--foreground));\n}\n\n.warning {\n border-color: color-mix(in srgb, var(--warning) 35%, transparent);\n background: color-mix(in srgb, var(--warning) 10%, transparent);\n color: color-mix(in srgb, var(--warning) 90%, var(--foreground));\n}\n\n.info {\n border-color: color-mix(in srgb, var(--primary) 35%, transparent);\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n color: color-mix(in srgb, var(--primary) 90%, var(--foreground));\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./alert.module.css\";\n\nexport type AlertTone = \"success\" | \"error\" | \"warning\" | \"info\";\n\nexport type AlertProps = {\n tone: AlertTone;\n children: ReactNode;\n className?: string;\n};\n\nexport function Alert({ tone, children, className }: AlertProps) {\n return (\n <div className={cx(styles.alert, styles[tone], className)} role=\"alert\">\n {children}\n </div>\n );\n}\n",".stack {\n position: fixed;\n z-index: 2147483000;\n display: flex;\n flex-direction: column;\n gap: 10px;\n pointer-events: none;\n}\n\n.topRight {\n top: 16px;\n right: 16px;\n align-items: flex-end;\n}\n\n.topLeft {\n top: 16px;\n left: 16px;\n align-items: flex-start;\n}\n\n.topCenter {\n top: 16px;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n}\n\n.bottomRight {\n bottom: 16px;\n right: 16px;\n align-items: flex-end;\n}\n\n.bottomLeft {\n bottom: 16px;\n left: 16px;\n align-items: flex-start;\n}\n\n.bottomCenter {\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n}\n\n.toast {\n pointer-events: auto;\n position: relative;\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 280px;\n max-width: min(420px, calc(100vw - 32px));\n padding: 12px 12px 12px 14px;\n border-radius: 10px;\n border: 1px solid var(--toast-border, var(--border));\n background: var(--toast-bg, var(--popover));\n color: var(--toast-text, var(--popover-foreground));\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10), 0 2px 6px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n animation: toastSlideIn 180ms ease-out;\n}\n\n/* Left accent strip */\n.toast::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--toast-accent, transparent);\n border-radius: 10px 0 0 10px;\n}\n\n.toast[data-state=\"closed\"] {\n animation: toastSlideOut 160ms ease-in forwards;\n}\n\n.toast[data-swipe=\"move\"] {\n transform: translateX(var(--radix-toast-swipe-move-x));\n}\n\n.toast[data-swipe=\"cancel\"] {\n transform: translateX(0);\n transition: transform 180ms ease-out;\n}\n\n.toast[data-swipe=\"end\"] {\n animation: toastSwipeOut 160ms ease-out forwards;\n}\n\n.icon {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--toast-accent, var(--foreground));\n margin-top: 1px;\n}\n\n.body {\n flex: 1;\n min-width: 0;\n display: grid;\n gap: 6px;\n}\n\n.message {\n word-break: break-word;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.actionButton {\n padding: 5px 10px;\n font-size: 12px;\n font-weight: 600;\n border-radius: 6px;\n border: 1px solid var(--toast-action-border, var(--border));\n background: var(--toast-action-bg, color-mix(in srgb, var(--foreground) 8%, transparent));\n color: var(--toast-text, var(--popover-foreground));\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.actionButton:hover {\n background: color-mix(in srgb, var(--toast-action-bg, var(--foreground)), var(--foreground) 10%);\n}\n\n.controls {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 2px;\n margin: -2px -2px -2px 0;\n}\n\n.iconButton {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: 5px;\n background: transparent;\n color: var(--toast-text, var(--popover-foreground));\n opacity: 0.5;\n cursor: pointer;\n transition: opacity 120ms ease, background 120ms ease;\n}\n\n.iconButton:hover {\n opacity: 1;\n background: color-mix(in srgb, var(--foreground) 8%, transparent);\n}\n\n.iconButtonError {\n opacity: 1;\n color: var(--destructive);\n}\n\n.iconButton:focus-visible,\n.actionButton:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n@keyframes toastSlideIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes toastSlideOut {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-6px);\n }\n}\n\n@keyframes toastSwipeOut {\n from {\n opacity: 1;\n transform: translateX(var(--radix-toast-swipe-end-x));\n }\n\n to {\n opacity: 0;\n transform: translateX(calc(var(--radix-toast-swipe-end-x) * 1.05));\n }\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport * as ToastPrimitive from \"@radix-ui/react-toast\";\nimport { cx } from \"../../utils/cx\";\nimport type {\n Toast,\n ToastConfig,\n ToastContextValue,\n ToastOptions,\n ToastPosition,\n ToastType,\n} from \"./types\";\nimport styles from \"./toast.module.css\";\n\n/** Default provider configuration. */\nconst DEFAULT_CONFIG: Required<ToastConfig> = {\n position: \"top-right\",\n maxToasts: 5,\n defaultDuration: 4000,\n pauseOnHover: true,\n pauseOnFocusLoss: true,\n};\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\nlet toastIdCounter = 0;\nconst generateToastId = () => `toast-${++toastIdCounter}-${Date.now()}`;\n\n/**\n * Toast notification context provider.\n *\n * @remarks\n * Wrap your app (or a section) to enable `useToast` calls. Supports configurable placement,\n * maximum visible toasts, and pause behavior on hover or window blur.\n *\n * @param props.children - React subtree that can consume the toast context.\n * @param props.config - Optional provider configuration overrides.\n */\nexport function ToastProvider({\n children,\n config,\n}: {\n children: ReactNode;\n config?: ToastConfig;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [isPaused, setIsPaused] = useState(false);\n const merged = useMemo(() => ({ ...DEFAULT_CONFIG, ...config }), [config]);\n\n const push = useCallback(\n (message: string, options: ToastOptions = {}) => {\n const id = generateToastId();\n setToasts((prev) => {\n const next: Toast[] = [\n ...prev,\n {\n id,\n message,\n type: options.type ?? \"info\",\n duration: options.duration ?? (options.type === \"error\" ? 6000 : merged.defaultDuration),\n dismissible: options.dismissible ?? true,\n copyable: options.copyable ?? false,\n action: options.action,\n },\n ];\n if (next.length > merged.maxToasts) next.shift();\n return next;\n });\n return id;\n },\n [merged.defaultDuration, merged.maxToasts],\n );\n\n const success = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) => push(message, { ...options, type: \"success\" }),\n [push],\n );\n const error = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) =>\n push(message, { copyable: true, ...options, type: \"error\" }),\n [push],\n );\n const warning = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) => push(message, { ...options, type: \"warning\" }),\n [push],\n );\n const info = useCallback(\n (message: string, options?: Omit<ToastOptions, \"type\">) => push(message, { ...options, type: \"info\" }),\n [push],\n );\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => setToasts([]), []);\n\n useEffect(() => {\n if (!merged.pauseOnFocusLoss) return;\n const handleVisibility = () => setIsPaused(document.visibilityState !== \"visible\");\n document.addEventListener(\"visibilitychange\", handleVisibility);\n return () => document.removeEventListener(\"visibilitychange\", handleVisibility);\n }, [merged.pauseOnFocusLoss]);\n\n const value = useMemo<ToastContextValue>(\n () => ({ toasts, push, success, error, warning, info, dismiss, dismissAll }),\n [toasts, push, success, error, warning, info, dismiss, dismissAll],\n );\n\n return (\n <ToastContext.Provider value={value}>\n <ToastPrimitive.Provider swipeDirection=\"right\">\n {children}\n <ToastContainer\n toasts={toasts}\n position={merged.position}\n pauseOnHover={merged.pauseOnHover}\n isPaused={isPaused}\n onDismiss={dismiss}\n onPauseChange={setIsPaused}\n />\n </ToastPrimitive.Provider>\n </ToastContext.Provider>\n );\n}\n\n/**\n * Hook to access the toast API.\n *\n * @remarks\n * Exposes `push`, intent helpers (`success`, `error`, `warning`, `info`), and dismissal helpers.\n * Must be called within a `ToastProvider`.\n *\n * @throws Error if used outside of a `ToastProvider`.\n */\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a ToastProvider\");\n return ctx;\n}\n\n/** Renders the positioned toast stack. */\nfunction ToastContainer({\n toasts,\n position,\n pauseOnHover,\n isPaused,\n onDismiss,\n onPauseChange,\n}: {\n toasts: Toast[];\n position: ToastPosition;\n pauseOnHover: boolean;\n isPaused: boolean;\n onDismiss: (id: string) => void;\n onPauseChange: (paused: boolean) => void;\n}) {\n const posClass = (() => {\n switch (position) {\n case \"top-left\":\n return \"topLeft\";\n case \"top-center\":\n return \"topCenter\";\n case \"bottom-right\":\n return \"bottomRight\";\n case \"bottom-left\":\n return \"bottomLeft\";\n case \"bottom-center\":\n return \"bottomCenter\";\n case \"top-right\":\n default:\n return \"topRight\";\n }\n })();\n\n return (\n <>\n {toasts.map((toast) => (\n <ToastItem key={toast.id} toast={toast} isPaused={isPaused} onDismiss={onDismiss} />\n ))}\n <ToastPrimitive.Viewport\n className={cx(styles.stack, styles[posClass])}\n label=\"Notifications\"\n onMouseEnter={() => pauseOnHover && onPauseChange(true)}\n onMouseLeave={() => pauseOnHover && onPauseChange(false)}\n />\n </>\n );\n}\n\n/** Individual toast item with timers and actions. */\nfunction ToastItem({\n toast,\n isPaused,\n onDismiss,\n}: {\n toast: Toast;\n isPaused: boolean;\n onDismiss: (id: string) => void;\n}) {\n const [open, setOpen] = useState(true);\n const [copyState, setCopyState] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\");\n const copyTimerRef = useRef<number | null>(null);\n const timerRef = useRef<number | null>(null);\n const startRef = useRef<number>(0);\n const remainingRef = useRef<number>(toast.duration ?? 0);\n const closingRef = useRef(false);\n\n const palette = getPalette(toast.type);\n const styleVars: CSSProperties = {\n [\"--toast-bg\" as any]: palette.background,\n [\"--toast-border\" as any]: palette.border,\n [\"--toast-accent\" as any]: palette.accent,\n [\"--toast-text\" as any]: palette.text,\n [\"--toast-action-bg\" as any]: palette.actionBg,\n [\"--toast-action-border\" as any]: palette.actionBorder,\n };\n\n const stopTimer = () => {\n if (timerRef.current) {\n window.clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const triggerDismiss = useCallback(() => {\n if (closingRef.current) return;\n closingRef.current = true;\n setOpen(false);\n stopTimer();\n window.setTimeout(() => onDismiss(toast.id), 160);\n }, [onDismiss, toast.id]);\n\n const schedule = useCallback(\n (delay: number) => {\n if (!delay || delay <= 0) {\n triggerDismiss();\n return;\n }\n startRef.current = performance.now();\n stopTimer();\n timerRef.current = window.setTimeout(() => triggerDismiss(), delay);\n },\n [triggerDismiss],\n );\n\n useEffect(() => {\n if (!toast.duration || toast.duration <= 0) return undefined;\n schedule(toast.duration);\n return stopTimer;\n }, [schedule, toast.duration]);\n\n useEffect(() => {\n if (!toast.duration || toast.duration <= 0) return;\n if (isPaused) {\n const elapsed = performance.now() - startRef.current;\n remainingRef.current = Math.max(0, remainingRef.current - elapsed);\n stopTimer();\n } else {\n schedule(remainingRef.current);\n }\n }, [isPaused, schedule, toast.duration]);\n\n useEffect(() => {\n return () => {\n if (copyTimerRef.current) window.clearTimeout(copyTimerRef.current);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n if (copyTimerRef.current) window.clearTimeout(copyTimerRef.current);\n try {\n if (!navigator.clipboard) throw new Error(\"Clipboard API unavailable\");\n await navigator.clipboard.writeText(toast.message);\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"failed\");\n }\n copyTimerRef.current = window.setTimeout(() => setCopyState(\"idle\"), 1800);\n }, [toast.message]);\n\n const icon = getIcon(toast.type);\n\n return (\n <ToastPrimitive.Root\n open={open}\n onOpenChange={(nextOpen: boolean) => {\n if (!nextOpen) triggerDismiss();\n }}\n duration={2147483647}\n className={styles.toast}\n style={styleVars}\n >\n <span className={styles.icon} aria-hidden>\n {icon}\n </span>\n <div className={styles.body}>\n <ToastPrimitive.Description className={styles.message}>\n {toast.message}\n </ToastPrimitive.Description>\n {toast.action && (\n <div className={styles.actions}>\n <ToastPrimitive.Action asChild altText={toast.action.label}>\n <button\n type=\"button\"\n className={styles.actionButton}\n onClick={() => {\n toast.action?.onClick();\n triggerDismiss();\n }}\n >\n {toast.action.label}\n </button>\n </ToastPrimitive.Action>\n </div>\n )}\n </div>\n <div className={styles.controls}>\n {toast.copyable && (\n <button\n type=\"button\"\n className={cx(styles.iconButton, copyState === \"failed\" && styles.iconButtonError)}\n aria-label=\"Copy message\"\n onClick={handleCopy}\n >\n {copyState === \"copied\" ? (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <path d=\"M2 6.5l3 3 6-6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ) : copyState === \"failed\" ? (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <path d=\"M10 3L3 10M3 3l7 7\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n ) : (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <rect x=\"4.5\" y=\"1.5\" width=\"7\" height=\"7\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.25\" />\n <path d=\"M1.5 5.5v5a1.5 1.5 0 001.5 1.5h5\" stroke=\"currentColor\" strokeWidth=\"1.25\" strokeLinecap=\"round\" />\n </svg>\n )}\n </button>\n )}\n {toast.dismissible !== false && (\n <ToastPrimitive.Close asChild>\n <button\n type=\"button\"\n className={styles.iconButton}\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 13 13\" fill=\"none\" aria-hidden>\n <path d=\"M10 3L3 10M3 3l7 7\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </ToastPrimitive.Close>\n )}\n </div>\n </ToastPrimitive.Root>\n );\n}\n\nfunction getPalette(type: ToastType) {\n switch (type) {\n case \"success\":\n return {\n background: \"color-mix(in srgb, var(--success) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--success) 30%, transparent)\",\n accent: \"var(--success)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--success) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--success) 35%, transparent)\",\n };\n case \"error\":\n return {\n background: \"color-mix(in srgb, var(--destructive) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--destructive) 30%, transparent)\",\n accent: \"var(--destructive)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--destructive) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--destructive) 35%, transparent)\",\n };\n case \"warning\":\n return {\n background: \"color-mix(in srgb, var(--warning) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--warning) 30%, transparent)\",\n accent: \"var(--warning)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--warning) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--warning) 35%, transparent)\",\n };\n case \"info\":\n default:\n return {\n background: \"color-mix(in srgb, var(--primary) 12%, var(--popover))\",\n border: \"color-mix(in srgb, var(--primary) 30%, transparent)\",\n accent: \"var(--primary)\",\n text: \"var(--popover-foreground)\",\n actionBg: \"color-mix(in srgb, var(--primary) 14%, transparent)\",\n actionBorder: \"color-mix(in srgb, var(--primary) 35%, transparent)\",\n };\n }\n}\n\nfunction getIcon(type: ToastType) {\n switch (type) {\n case \"success\":\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M3 8l3.5 3.5L13 4.5\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n case \"error\":\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M4 4l8 8M12 4l-8 8\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" />\n </svg>\n );\n case \"warning\":\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M8 3v6M8 11.5v1\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" />\n </svg>\n );\n case \"info\":\n default:\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden>\n <path d=\"M8 7v5M8 4.5v.5\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n}\n",".input {\n display: flex;\n width: 100%;\n min-height: 2.25rem;\n border-radius: 0.5rem;\n border: 1px solid var(--ts-input-border, var(--input));\n background: var(--ts-input-bg, var(--background));\n color: var(--ts-input-fg, var(--foreground));\n padding: 0.25rem 0.75rem;\n font-size: 0.875rem;\n line-height: 1.25rem;\n box-shadow: var(--ts-input-shadow, 0 1px 2px rgba(0, 0, 0, 0.04));\n transition: border-color 0.15s ease, background 0.15s ease;\n}\n\n.input::placeholder {\n color: var(--ts-input-placeholder, var(--muted-foreground));\n}\n\n.input:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n","import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./input.module.css\";\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n ref={ref}\n type={type}\n className={cx(styles.input, className)}\n {...props}\n />\n );\n },\n);\n\nInput.displayName = \"Input\";\n",".label {\n font-size: 0.875rem;\n font-weight: 500;\n line-height: 1.2;\n color: var(--ts-label-fg, inherit);\n}\n","import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./label.module.css\";\n\nexport type LabelProps = React.LabelHTMLAttributes<HTMLLabelElement>;\n\nexport const Label = React.forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, ...props }, ref) => (\n <label ref={ref} className={cx(styles.label, className)} {...props} />\n ),\n);\n\nLabel.displayName = \"Label\";\n",".checkbox {\n width: 1rem;\n height: 1rem;\n margin: 0;\n border-radius: 0.25rem;\n border: 1px solid var(--ts-checkbox-border, var(--border));\n background: var(--ts-checkbox-bg, var(--background));\n accent-color: var(--ts-checkbox-accent, var(--primary));\n cursor: pointer;\n}\n\n.checkbox:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.checkbox:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n","import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./checkbox.module.css\";\n\nexport type CheckboxProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, ...props }, ref) => {\n return (\n <input\n ref={ref}\n type=\"checkbox\"\n className={cx(styles.checkbox, className)}\n {...props}\n />\n );\n },\n);\n\nCheckbox.displayName = \"Checkbox\";\n",".wrapper {\n position: relative;\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n}\n\n.wrapperFullWidth {\n width: 100%;\n}\n\n.trigger {\n width: 100%;\n min-width: 0;\n min-height: var(--uzi-control-min-height);\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.625rem;\n border-radius: var(--uzi-control-radius);\n border: 1px solid var(--ts-dropdown-border, var(--border));\n background: var(--ts-dropdown-bg, var(--panel));\n color: var(--ts-dropdown-text, var(--foreground));\n padding:\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x-compact)\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x);\n font-size: var(--uzi-control-font-size);\n line-height: var(--uzi-control-line-height);\n font-family: inherit;\n box-shadow: var(--uzi-control-shadow);\n transition:\n border-color 0.15s ease,\n background 0.15s ease,\n color 0.15s ease,\n box-shadow 0.15s ease;\n cursor: pointer;\n text-align: left;\n}\n\n.trigger:hover:not(:disabled) {\n border-color: var(--ts-dropdown-accent, var(--accent));\n box-shadow: var(--uzi-control-shadow-hover);\n}\n\n.trigger:focus-visible,\n.trigger[data-state=\"open\"] {\n border-color: var(--ts-dropdown-accent, var(--primary));\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n box-shadow: none;\n}\n\n.value {\n min-width: 0;\n display: flex;\n flex: 1;\n flex-wrap: wrap;\n gap: 0.375rem;\n align-items: center;\n}\n\n.placeholder {\n color: var(--muted-foreground);\n}\n\n.chip {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n padding: 2px 8px;\n border-radius: 999px;\n border: 1px solid color-mix(in srgb, var(--primary) 32%, transparent);\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n color: var(--ts-dropdown-text, var(--foreground));\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1.2;\n white-space: nowrap;\n}\n\n.chipSummary {\n color: var(--primary);\n}\n\n.chevron {\n width: 10px;\n height: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--muted-foreground);\n flex-shrink: 0;\n transition: transform 0.15s ease, color 0.15s ease;\n}\n\n.trigger:hover:not(:disabled) .chevron,\n.trigger[data-state=\"open\"] .chevron {\n color: var(--ts-dropdown-text, var(--foreground));\n}\n\n.trigger[data-state=\"open\"] .chevron {\n transform: rotate(180deg);\n}\n\n.menu {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 50;\n min-width: 100%;\n max-height: 16rem;\n overflow-y: auto;\n border: 1px solid var(--ts-menu-border, var(--border));\n border-radius: var(--uzi-menu-radius);\n background: var(--ts-menu-bg, var(--popover));\n color: var(--ts-menu-fg, var(--popover-foreground));\n padding: var(--uzi-menu-padding);\n box-shadow: var(--uzi-menu-shadow);\n animation: menuFadeIn 140ms ease;\n}\n\n.option {\n width: 100%;\n display: flex;\n align-items: center;\n gap: var(--uzi-menu-item-gap);\n border: none;\n border-radius: var(--uzi-menu-item-radius);\n background: transparent;\n color: inherit;\n padding: var(--uzi-menu-item-padding-y) var(--uzi-menu-item-padding-x);\n font: inherit;\n cursor: pointer;\n text-align: left;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.option:hover:not(:disabled),\n.option:focus-visible,\n.option[data-highlighted] {\n background: var(--ts-menu-hover-bg, var(--accent));\n color: var(--ts-menu-hover-fg, var(--accent-foreground));\n outline: none;\n}\n\n.optionDisabled,\n.option[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.optionSelected .optionLabel {\n color: var(--primary);\n}\n\n.indicator {\n width: 1rem;\n height: 1rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: 0.3125rem;\n border: 1px solid var(--border);\n color: transparent;\n background: transparent;\n transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;\n}\n\n.indicatorSelected {\n border-color: color-mix(in srgb, var(--primary) 55%, transparent);\n background: color-mix(in srgb, var(--primary) 12%, transparent);\n color: var(--primary);\n}\n\n.indicatorDisabled {\n opacity: 0.65;\n}\n\n.optionLabel {\n min-width: 0;\n flex: 1;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./multi-select.module.css\";\n\nexport type MultiSelectOption = {\n label: string;\n value: string;\n disabled?: boolean;\n};\n\nexport type MultiSelectProps = {\n options: MultiSelectOption[];\n value: string[];\n onChange: (value: string[]) => void;\n placeholder?: string;\n fullWidth?: boolean;\n maxVisibleValues?: number;\n className?: string;\n disabled?: boolean;\n name?: string;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n};\n\nexport const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(\n (\n {\n options,\n value,\n onChange,\n placeholder = \"Select options\",\n fullWidth = true,\n maxVisibleValues = 2,\n className,\n disabled = false,\n name,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n },\n ref,\n ) => {\n const selectedSet = React.useMemo(() => new Set(value), [value]);\n const selectedOptions = React.useMemo(\n () => options.filter((opt) => selectedSet.has(opt.value)),\n [options, selectedSet],\n );\n\n const toggleValue = React.useCallback(\n (nextValue: string) => {\n if (selectedSet.has(nextValue)) {\n onChange(value.filter((entry) => entry !== nextValue));\n return;\n }\n\n onChange([...value, nextValue]);\n },\n [onChange, selectedSet, value],\n );\n\n const visibleCount = Math.max(1, maxVisibleValues);\n const visibleOptions = selectedOptions.slice(0, visibleCount);\n const overflowCount = Math.max(\n 0,\n selectedOptions.length - visibleOptions.length,\n );\n\n return (\n <DropdownMenuPrimitive.Root modal={false}>\n <div\n className={cx(\n styles.wrapper,\n fullWidth && styles.wrapperFullWidth,\n className,\n )}\n >\n <DropdownMenuPrimitive.Trigger asChild>\n <button\n ref={ref}\n type=\"button\"\n className={styles.trigger}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n disabled={disabled}\n >\n <span className={styles.value}>\n {selectedOptions.length === 0 ? (\n <span className={styles.placeholder}>{placeholder}</span>\n ) : (\n <>\n {visibleOptions.map((option) => (\n <span key={option.value} className={styles.chip}>\n {option.label}\n </span>\n ))}\n {overflowCount > 0 ? (\n <span\n className={cx(\n styles.chip,\n styles.chipSummary,\n )}\n >\n +{overflowCount}\n </span>\n ) : null}\n </>\n )}\n </span>\n <span className={styles.chevron} aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n >\n <path\n d=\"M2 3.5L5 6.5L8 3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n </DropdownMenuPrimitive.Trigger>\n\n {name\n ? value.map((entry) => (\n <input key={entry} type=\"hidden\" name={name} value={entry} />\n ))\n : null}\n\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n className={styles.menu}\n sideOffset={4}\n align=\"start\"\n >\n {options.map((option) => {\n const selected = selectedSet.has(option.value);\n\n return (\n <DropdownMenuPrimitive.CheckboxItem\n key={option.value}\n className={cx(\n styles.option,\n selected && styles.optionSelected,\n option.disabled && styles.optionDisabled,\n )}\n checked={selected}\n disabled={option.disabled}\n onCheckedChange={() => toggleValue(option.value)}\n onSelect={(event) => event.preventDefault()}\n >\n <span\n className={cx(\n styles.indicator,\n selected && styles.indicatorSelected,\n option.disabled && styles.indicatorDisabled,\n )}\n aria-hidden=\"true\"\n >\n <DropdownMenuPrimitive.ItemIndicator forceMount>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n <span className={styles.optionLabel}>{option.label}</span>\n </DropdownMenuPrimitive.CheckboxItem>\n );\n })}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </div>\n </DropdownMenuPrimitive.Root>\n );\n },\n);\n\nMultiSelect.displayName = \"MultiSelect\";\n",".wrapper {\n position: relative;\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n}\n\n.wrapperFullWidth {\n width: 100%;\n}\n\n.wrapper:not(.wrapperFullWidth) .trigger {\n width: auto;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.625rem;\n width: 100%;\n min-width: 0;\n min-height: var(--uzi-control-min-height);\n border-radius: var(--uzi-control-radius);\n border: 1px solid var(--ts-dropdown-border, var(--border));\n background: var(--ts-dropdown-bg, var(--panel));\n color: var(--ts-dropdown-text, var(--foreground));\n padding:\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x-compact)\n var(--uzi-control-padding-y)\n var(--uzi-control-padding-x);\n font-size: var(--uzi-control-font-size);\n line-height: var(--uzi-control-line-height);\n font-family: inherit;\n font-weight: 500;\n box-shadow: var(--uzi-control-shadow);\n transition:\n border-color 0.15s ease,\n background 0.15s ease,\n color 0.15s ease,\n box-shadow 0.15s ease;\n cursor: pointer;\n text-align: left;\n}\n\n.value {\n min-width: 0;\n flex: 1 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.trigger:hover:not(:disabled) {\n border-color: var(--ts-dropdown-accent, var(--accent));\n box-shadow: var(--uzi-control-shadow-hover);\n}\n\n.trigger:focus-visible {\n border-color: var(--ts-dropdown-accent, var(--primary));\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);\n}\n\n.trigger[data-placeholder] {\n color: var(--muted-foreground);\n}\n\n.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n box-shadow: none;\n}\n\n.chevron {\n width: 10px;\n height: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--muted-foreground);\n flex-shrink: 0;\n position: relative;\n top: -1px;\n transition: transform 0.15s ease, color 0.15s ease;\n}\n\n.chevron svg {\n display: block;\n}\n\n.trigger:hover:not(:disabled) .chevron,\n.trigger[data-state=\"open\"] .chevron {\n color: var(--ts-dropdown-text, var(--foreground));\n}\n\n.trigger[data-state=\"open\"] .chevron {\n transform: rotate(180deg);\n}\n\n.content {\n z-index: 50;\n min-width: var(--radix-select-trigger-width);\n max-height: min(18rem, var(--radix-select-content-available-height));\n overflow: hidden;\n border: 1px solid var(--ts-menu-border, var(--border));\n border-radius: var(--uzi-menu-radius);\n background: var(--ts-menu-bg, var(--popover));\n color: var(--ts-menu-fg, var(--popover-foreground));\n padding: var(--uzi-menu-padding);\n box-shadow: var(--uzi-menu-shadow);\n animation: selectFadeIn 140ms ease;\n}\n\n.viewport {\n max-height: inherit;\n overflow-y: auto;\n}\n\n.item {\n position: relative;\n display: flex;\n width: 100%;\n cursor: default;\n user-select: none;\n align-items: center;\n gap: var(--uzi-menu-item-gap);\n border-radius: var(--uzi-menu-item-radius);\n padding:\n var(--uzi-menu-item-padding-y)\n var(--uzi-menu-item-padding-x)\n var(--uzi-menu-item-padding-y)\n 2rem;\n font-size: 0.875rem;\n line-height: 1.25rem;\n outline: none;\n}\n\n.item[data-highlighted] {\n background: var(--ts-menu-hover-bg, var(--accent));\n color: var(--ts-menu-hover-fg, var(--accent-foreground));\n}\n\n.item[data-disabled] {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.item[data-state=\"checked\"] {\n color: var(--primary);\n}\n\n.indicator {\n position: absolute;\n left: 0.625rem;\n display: inline-flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n color: currentColor;\n}\n\n.indicatorIcon {\n display: block;\n}\n\n@keyframes selectFadeIn {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./select.module.css\";\n\nexport type SelectOption = {\n label: string;\n value: string;\n disabled?: boolean;\n};\n\nexport type SelectProps = {\n options: SelectOption[];\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n allowEmptyOption?: boolean;\n fullWidth?: boolean;\n className?: string;\n id?: string;\n name?: string;\n disabled?: boolean;\n required?: boolean;\n autoComplete?: string;\n form?: string;\n title?: string;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n};\n\nconst EMPTY_OPTION_VALUE = \"__uzi_select_empty__\";\n\nexport const Select = React.forwardRef<HTMLButtonElement, SelectProps>(\n (\n {\n options,\n value,\n onChange,\n placeholder,\n allowEmptyOption = false,\n fullWidth = true,\n className,\n id,\n name,\n disabled,\n required,\n autoComplete,\n form,\n title,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n onBlur,\n onFocus,\n },\n ref,\n ) => {\n return (\n <div\n className={cx(\n styles.wrapper,\n fullWidth && styles.wrapperFullWidth,\n className,\n )}\n >\n <SelectPrimitive.Root\n value={value}\n onValueChange={(nextValue: string) =>\n onChange(nextValue === EMPTY_OPTION_VALUE ? \"\" : nextValue)\n }\n name={name}\n disabled={disabled}\n required={required}\n autoComplete={autoComplete}\n form={form}\n >\n <SelectPrimitive.Trigger\n ref={ref}\n id={id}\n className={styles.trigger}\n title={title}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onBlur={onBlur}\n onFocus={onFocus}\n >\n <SelectPrimitive.Value\n className={styles.value}\n placeholder={placeholder}\n />\n <SelectPrimitive.Icon\n className={styles.chevron}\n aria-hidden=\"true\"\n >\n <svg\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n >\n <path\n d=\"M2 3.5L5 6.5L8 3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n className={styles.content}\n position=\"popper\"\n sideOffset={4}\n align=\"start\"\n >\n <SelectPrimitive.Viewport className={styles.viewport}>\n {placeholder && allowEmptyOption ? (\n <SelectPrimitive.Item\n value={EMPTY_OPTION_VALUE}\n className={styles.item}\n >\n <span className={styles.indicator}>\n <SelectPrimitive.ItemIndicator>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.indicatorIcon}\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{placeholder}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n ) : null}\n\n {options.map((opt) => (\n <SelectPrimitive.Item\n key={opt.value}\n value={opt.value}\n disabled={opt.disabled}\n className={styles.item}\n >\n <span className={styles.indicator}>\n <SelectPrimitive.ItemIndicator>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.indicatorIcon}\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{opt.label}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n ))}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n </div>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Select, type SelectOption, type SelectProps } from \"../select/Select\";\n\nexport interface DropdownOption extends SelectOption {}\n\nexport interface DropdownProps\n extends Omit<\n SelectProps,\n \"allowEmptyOption\" | \"fullWidth\" | \"placeholder\" | \"options\"\n > {\n /** List of options to display in the menu. */\n options: DropdownOption[];\n /** Label shown when no option is selected. Defaults to \"All\". */\n placeholder?: string;\n /** Whether to show the placeholder as a clearable option. Defaults to true. */\n allowClear?: boolean;\n}\n\n/**\n * @deprecated Use Select for value selection and DropdownMenu for action menus.\n * Dropdown remains as a compatibility alias during migration.\n */\nexport const Dropdown = React.forwardRef<HTMLButtonElement, DropdownProps>(\n (\n {\n options,\n value,\n onChange,\n placeholder = \"All\",\n allowClear = true,\n ...rest\n },\n ref,\n ) => {\n return (\n <Select\n ref={ref}\n options={options}\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n allowEmptyOption={allowClear}\n fullWidth={false}\n {...rest}\n />\n );\n },\n);\n\nDropdown.displayName = \"Dropdown\";\n",".content {\n z-index: 50;\n min-width: 8rem;\n max-height: var(--radix-dropdown-menu-content-available-height);\n overflow-x: hidden;\n overflow-y: auto;\n border: 1px solid var(--ts-menu-border, var(--border));\n border-radius: var(--uzi-menu-radius);\n background: var(--ts-menu-bg, var(--popover));\n color: var(--ts-menu-fg, var(--popover-foreground));\n padding: var(--uzi-menu-padding);\n box-shadow: var(--uzi-menu-shadow);\n transform-origin: var(--radix-dropdown-menu-content-transform-origin);\n animation: menuFadeIn 140ms ease;\n}\n\n.item {\n position: relative;\n display: flex;\n width: 100%;\n cursor: default;\n user-select: none;\n align-items: center;\n gap: var(--uzi-menu-item-gap);\n border-radius: var(--uzi-menu-item-radius);\n padding: var(--uzi-menu-item-padding-y) var(--uzi-menu-item-padding-x);\n font-size: 0.875rem;\n line-height: 1.25rem;\n outline: none;\n}\n\n.item[data-inset=\"true\"] {\n padding-left: 2rem;\n}\n\n.item[data-highlighted] {\n background: var(--ts-menu-hover-bg, var(--accent));\n color: var(--ts-menu-hover-fg, var(--accent-foreground));\n}\n\n.item[data-disabled] {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.itemDestructive {\n color: var(--ts-menu-danger, var(--destructive));\n}\n\n.itemDestructive[data-highlighted] {\n background: color-mix(in srgb, var(--destructive) 15%, transparent);\n color: var(--ts-menu-danger-fg, var(--destructive));\n}\n\n.insetItem {\n padding-left: 2rem;\n}\n\n.indicator {\n position: absolute;\n left: 0.5rem;\n display: inline-flex;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n color: currentColor;\n}\n\n.indicatorIcon {\n display: block;\n}\n\n.radioDot {\n display: block;\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 999px;\n background: currentColor;\n}\n\n.label {\n padding: var(--uzi-menu-item-padding-y) var(--uzi-menu-item-padding-x);\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1.25rem;\n}\n\n.label[data-inset=\"true\"] {\n padding-left: 2rem;\n}\n\n.separator {\n height: 1px;\n margin: 0.25rem -0.25rem;\n background: var(--ts-menu-separator, var(--border));\n}\n\n.chevron {\n margin-left: auto;\n flex-shrink: 0;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./dropdown-menu.module.css\";\n\nexport function DropdownMenu(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>,\n) {\n return <DropdownMenuPrimitive.Root {...props} />;\n}\n\nexport function DropdownMenuTrigger(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>,\n) {\n return <DropdownMenuPrimitive.Trigger {...props} />;\n}\n\nexport function DropdownMenuGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>,\n) {\n return <DropdownMenuPrimitive.Group {...props} />;\n}\n\nexport function DropdownMenuPortal(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>,\n) {\n return <DropdownMenuPrimitive.Portal {...props} />;\n}\n\nexport function DropdownMenuSub(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>,\n) {\n return <DropdownMenuPrimitive.Sub {...props} />;\n}\n\nexport function DropdownMenuRadioGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,\n) {\n return <DropdownMenuPrimitive.RadioGroup {...props} />;\n}\n\nexport function DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n sideOffset={sideOffset}\n className={cx(styles.content, className)}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport function DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-inset={inset ? \"true\" : undefined}\n className={cx(\n styles.item,\n variant === \"destructive\" && styles.itemDestructive,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuCheckboxItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n className={cx(\n styles.item,\n styles.insetItem,\n className,\n )}\n {...props}\n >\n <span className={styles.indicator}>\n <DropdownMenuPrimitive.ItemIndicator>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.indicatorIcon}\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nexport function DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n className={cx(\n styles.item,\n styles.insetItem,\n className,\n )}\n {...props}\n >\n <span className={styles.indicator}>\n <DropdownMenuPrimitive.ItemIndicator>\n <span className={styles.radioDot} />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nexport function DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-inset={inset ? \"true\" : undefined}\n className={cx(styles.label, className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n className={cx(styles.separator, className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-inset={inset ? \"true\" : undefined}\n className={cx(styles.item, className)}\n {...props}\n >\n {children}\n <svg\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n className={styles.chevron}\n >\n <path\n d=\"M6 3.5 10.5 8 6 12.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nexport function DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n className={cx(styles.content, className)}\n {...props}\n />\n );\n}\n","export const UZI_THEMES = [\"light\", \"dark\", \"system\"] as const;\nexport const UZI_ACCENTS = [\"blue\", \"cyan\", \"violet\", \"emerald\", \"amber\", \"rose\"] as const;\n\nexport const THEME_STORAGE_KEY = \"uzi-theme\";\nexport const ACCENT_STORAGE_KEY = \"uzi-accent\";\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { UZI_THEMES, UZI_ACCENTS, THEME_STORAGE_KEY as DEFAULT_THEME_KEY, ACCENT_STORAGE_KEY as DEFAULT_ACCENT_KEY } from \"./constants\";\nimport { ToastProvider } from \"../components/toast/ToastContext\";\nimport type { ToastConfig } from \"../components/toast/types\";\n\nexport type UziTheme = typeof UZI_THEMES[number];\nexport type UziResolvedTheme = \"light\" | \"dark\";\nexport type UziAccent = typeof UZI_ACCENTS[number];\n\ntype ThemeContextValue = {\n theme: UziTheme;\n resolvedTheme: UziResolvedTheme;\n accent: UziAccent;\n setTheme: (theme: UziTheme) => void;\n setAccent: (accent: UziAccent) => void;\n toggleTheme: () => void;\n};\n\ntype ThemeProviderProps = {\n children: ReactNode;\n theme?: UziTheme;\n defaultTheme?: UziTheme;\n accent?: UziAccent;\n defaultAccent?: UziAccent;\n onThemeChange?: (theme: UziTheme) => void;\n onAccentChange?: (accent: UziAccent) => void;\n storageKey?: string;\n accentStorageKey?: string;\n disableStorage?: boolean;\n toastConfig?: ToastConfig;\n};\n\nconst THEME_STORAGE_KEY = DEFAULT_THEME_KEY;\nconst ACCENT_STORAGE_KEY = DEFAULT_ACCENT_KEY;\nconst THEME_ATTRIBUTE = \"data-uzi-theme\";\nconst ACCENT_ATTRIBUTE = \"data-uzi-accent\";\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\nfunction isTheme(value: string | null): value is UziTheme {\n return UZI_THEMES.includes(value as UziTheme);\n}\n\nfunction isAccent(value: string | null): value is UziAccent {\n return UZI_ACCENTS.includes(value as UziAccent);\n}\n\nfunction getSystemTheme(): UziResolvedTheme {\n if (typeof window === \"undefined\") return \"light\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nexport function ThemeProvider({\n children,\n theme,\n defaultTheme = \"system\",\n accent,\n defaultAccent = \"blue\",\n onThemeChange,\n onAccentChange,\n storageKey = THEME_STORAGE_KEY,\n accentStorageKey = ACCENT_STORAGE_KEY,\n disableStorage = false,\n toastConfig,\n}: ThemeProviderProps) {\n const [internalTheme, setInternalTheme] = useState<UziTheme>(defaultTheme);\n const [internalAccent, setInternalAccent] = useState<UziAccent>(defaultAccent);\n const [systemTheme, setSystemTheme] = useState<UziResolvedTheme>(\"light\");\n\n useEffect(() => {\n setSystemTheme(getSystemTheme());\n if (!disableStorage) {\n const storedTheme = window.localStorage.getItem(storageKey);\n if (isTheme(storedTheme)) setInternalTheme(storedTheme);\n const storedAccent = window.localStorage.getItem(accentStorageKey);\n if (isAccent(storedAccent)) setInternalAccent(storedAccent);\n }\n }, [disableStorage, storageKey, accentStorageKey]);\n\n const isThemeControlled = theme !== undefined;\n const isAccentControlled = accent !== undefined;\n\n const currentTheme = isThemeControlled ? theme : internalTheme;\n const currentAccent = isAccentControlled ? accent : internalAccent;\n const resolvedTheme = currentTheme === \"system\" ? systemTheme : currentTheme;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handleChange = () => setSystemTheme(mediaQuery.matches ? \"dark\" : \"light\");\n\n handleChange();\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, []);\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.setAttribute(THEME_ATTRIBUTE, resolvedTheme);\n root.setAttribute(ACCENT_ATTRIBUTE, currentAccent);\n root.style.colorScheme = resolvedTheme;\n root.classList.toggle(\"dark\", resolvedTheme === \"dark\");\n }, [currentAccent, resolvedTheme]);\n\n const setTheme = useCallback(\n (nextTheme: UziTheme) => {\n if (!isThemeControlled) setInternalTheme(nextTheme);\n if (!disableStorage && typeof window !== \"undefined\") {\n window.localStorage.setItem(storageKey, nextTheme);\n }\n onThemeChange?.(nextTheme);\n },\n [disableStorage, isThemeControlled, onThemeChange, storageKey],\n );\n\n const setAccent = useCallback(\n (nextAccent: UziAccent) => {\n if (!isAccentControlled) setInternalAccent(nextAccent);\n if (!disableStorage && typeof window !== \"undefined\") {\n window.localStorage.setItem(accentStorageKey, nextAccent);\n }\n onAccentChange?.(nextAccent);\n },\n [accentStorageKey, disableStorage, isAccentControlled, onAccentChange],\n );\n\n const toggleTheme = useCallback(() => {\n setTheme(resolvedTheme === \"dark\" ? \"light\" : \"dark\");\n }, [resolvedTheme, setTheme]);\n\n const value = useMemo<ThemeContextValue>(\n () => ({\n theme: currentTheme,\n resolvedTheme,\n accent: currentAccent,\n setTheme,\n setAccent,\n toggleTheme,\n }),\n [currentAccent, currentTheme, resolvedTheme, setAccent, setTheme, toggleTheme],\n );\n\n return (\n <ThemeContext.Provider value={value}>\n <ToastProvider config={toastConfig}>{children}</ToastProvider>\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const context = useContext(ThemeContext);\n if (!context) throw new Error(\"useTheme must be used within a ThemeProvider\");\n return context;\n}\n",".withLabel {\n padding-left: 12px;\n padding-right: 12px;\n}\n","\"use client\";\n\nimport type { ButtonHTMLAttributes } from \"react\";\nimport { Button } from \"../button/Button\";\nimport { useTheme } from \"../../theme/ThemeProvider\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./theme-toggle-button.module.css\";\n\nexport type ThemeToggleButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> & {\n showLabel?: boolean;\n lightLabel?: string;\n darkLabel?: string;\n};\n\nfunction MoonIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" width=\"16\" height=\"16\" fill=\"none\">\n <path\n d=\"M20 15.2A8.5 8.5 0 0 1 8.8 4 9 9 0 1 0 20 15.2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SunIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" width=\"16\" height=\"16\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.8\" />\n <path\n d=\"M12 2.75v2.5M12 18.75v2.5M21.25 12h-2.5M5.25 12h-2.5M18.54 5.46l-1.77 1.77M7.23 16.77l-1.77 1.77M18.54 18.54l-1.77-1.77M7.23 7.23 5.46 5.46\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\nexport function ThemeToggleButton({\n showLabel = false,\n lightLabel = \"Light mode\",\n darkLabel = \"Dark mode\",\n className,\n onClick,\n ...rest\n}: ThemeToggleButtonProps) {\n const { resolvedTheme, toggleTheme } = useTheme();\n const nextThemeLabel = resolvedTheme === \"dark\" ? lightLabel : darkLabel;\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size={showLabel ? \"sm\" : \"icon\"}\n className={cx(showLabel && styles.withLabel, className)}\n aria-label={`Switch to ${nextThemeLabel.toLowerCase()}`}\n title={`Switch to ${nextThemeLabel.toLowerCase()}`}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) toggleTheme();\n }}\n {...rest}\n >\n {resolvedTheme === \"dark\" ? <SunIcon /> : <MoonIcon />}\n {showLabel && <span>{nextThemeLabel}</span>}\n </Button>\n );\n}\n",".topBar {\n position: sticky;\n top: 0;\n z-index: 30;\n border-bottom: 1px solid var(--ts-topbar-border, var(--border));\n background: var(--ts-topbar-bg, color-mix(in srgb, var(--background) 92%, transparent));\n box-shadow: var(--ts-topbar-shadow, 0 1px 2px rgba(0, 0, 0, 0.06));\n backdrop-filter: blur(12px);\n}\n\n.topBarStatic {\n position: relative;\n}\n\n.topBarInner {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n min-height: 4.25rem;\n padding: env(safe-area-inset-top, 0) 1rem 0 1rem;\n}\n\n.topBarStart {\n display: flex;\n align-items: center;\n gap: 0.875rem;\n min-width: 0;\n flex: 1 1 auto;\n}\n\n.topBarBrand {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n min-width: 0;\n color: var(--ts-topbar-brand-fg, var(--foreground));\n text-decoration: none;\n}\n\n.topBarBrandContent {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.topBarCenter {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.topBarCenterGroup {\n display: inline-flex;\n align-items: center;\n gap: 1rem;\n min-width: 0;\n}\n\n.topBarActions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 0.75rem;\n min-width: 0;\n flex: 1 1 auto;\n}\n\n@media (max-width: 768px) {\n .topBarInner {\n min-height: 4rem;\n gap: 0.75rem;\n padding-left: max(0.75rem, env(safe-area-inset-left));\n padding-right: max(0.75rem, env(safe-area-inset-right));\n }\n\n .topBarStart {\n gap: 0.75rem;\n }\n\n .topBarActions {\n gap: 0.5rem;\n }\n}\n","\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport {\n ThemeToggleButton,\n type ThemeToggleButtonProps,\n} from \"../theme-toggle-button/ThemeToggleButton\";\nimport styles from \"./top-bar.module.css\";\n\nexport type TopBarProps = HTMLAttributes<HTMLElement> & {\n leading?: ReactNode;\n brand?: ReactNode;\n brandHref?: string;\n brandingLocation?: \"left\" | \"center\";\n /** Content rendered after the brand in the left region (e.g. breadcrumbs, search). */\n start?: ReactNode;\n /** Content rendered in the center region. */\n center?: ReactNode;\n actions?: ReactNode;\n showThemeToggle?: boolean;\n themeToggleProps?: ThemeToggleButtonProps;\n innerClassName?: string;\n isSticky?: boolean;\n sticky?: boolean;\n};\n\nexport function TopBar({\n leading,\n brand,\n brandHref,\n brandingLocation = \"left\",\n start,\n center,\n actions,\n showThemeToggle = false,\n themeToggleProps,\n className,\n innerClassName,\n isSticky,\n sticky = true,\n children,\n ...rest\n}: TopBarProps) {\n const shouldStick = isSticky ?? sticky;\n const brandNode = !brand ? null : brandHref ? (\n <a href={brandHref} className={styles.topBarBrand}>\n <span className={styles.topBarBrandContent}>{brand}</span>\n </a>\n ) : (\n <div className={styles.topBarBrand}>\n <span className={styles.topBarBrandContent}>{brand}</span>\n </div>\n );\n\n return (\n <header\n className={cx(styles.topBar, !shouldStick && styles.topBarStatic, className)}\n {...rest}\n >\n <div className={cx(styles.topBarInner, innerClassName)}>\n <div className={styles.topBarStart}>\n {leading}\n {brandingLocation === \"left\" && brandNode}\n {start}\n </div>\n {(brandNode && brandingLocation === \"center\") || center || children ? (\n <div className={styles.topBarCenter}>\n <div className={styles.topBarCenterGroup}>\n {brandingLocation === \"center\" && brandNode}\n {center ?? children}\n </div>\n </div>\n ) : null}\n <div className={styles.topBarActions}>\n {showThemeToggle && <ThemeToggleButton {...themeToggleProps} />}\n {actions}\n </div>\n </div>\n </header>\n );\n}\n",".appShell {\n display: grid;\n grid-template-rows: calc(var(--app-shell-topbar-height, 64px) + env(safe-area-inset-top)) 1fr;\n grid-template-columns: var(--app-shell-sidebar-width, 240px) 1fr;\n height: 100vh;\n height: 100dvh;\n}\n\n.appShellAnimated {\n transition: grid-template-columns 200ms ease;\n}\n\n.appShell.appShellOpen {\n grid-template-columns: var(--app-shell-sidebar-width, 240px) 1fr;\n}\n\n.appShell.appShellCollapsed {\n grid-template-columns: 0 1fr;\n}\n\n.appShellTopbar {\n --ts-topbar-bg: var(--surface-topbar, color-mix(in srgb, var(--background) 92%, transparent));\n --ts-topbar-border: var(--border);\n --ts-topbar-brand-fg: var(--foreground);\n grid-column: 1 / -1;\n min-height: calc(var(--app-shell-topbar-height, 64px) + env(safe-area-inset-top));\n padding-left: 0;\n padding-right: 0;\n box-shadow: none;\n}\n\n.appShellTopbarLeft {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.appShellTopbarStart {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n}\n\n.appShellTopbarRight {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex-shrink: 0;\n}\n\n.appShellTopbarRight > * {\n min-width: 0;\n}\n\n.appShellBrand {\n font-size: 26px;\n color: var(--foreground);\n text-decoration: none;\n display: flex;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.appShellHamburger {\n background: transparent;\n border: none;\n padding: 0;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--foreground);\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.appShellHamburger:hover {\n background: var(--accent);\n}\n\n.appShellHamburger:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.appShellHamburger svg {\n width: 28px;\n height: 28px;\n}\n\n.appShellSidebar {\n border-right: 1px solid var(--border);\n background: var(--panel);\n padding: 24px;\n overflow-y: auto;\n}\n\n.appShellAnimated .appShellSidebar {\n transition: transform 200ms ease, opacity 200ms ease;\n}\n\n.appShell.appShellCollapsed .appShellSidebar {\n transform: translateX(-110%);\n opacity: 0;\n pointer-events: none;\n}\n\n.appShellMain {\n overflow-y: auto;\n min-height: 0;\n flex: 1 1 0;\n}\n\n.appShellBackdrop {\n display: none;\n}\n\n@media (max-width: 960px) {\n .appShellBackdrop {\n display: block;\n position: fixed;\n inset: 0;\n top: calc(var(--app-shell-topbar-height, 56px) + env(safe-area-inset-top));\n background: rgba(0, 0, 0, 0.5);\n z-index: 14;\n }\n\n .appShell {\n --app-shell-topbar-height: 56px;\n grid-template-columns: 1fr;\n grid-template-rows: calc(var(--app-shell-topbar-height, 56px) + env(safe-area-inset-top)) 1fr;\n }\n\n .appShell.appShellOpen,\n .appShell.appShellCollapsed {\n grid-template-columns: 1fr;\n }\n\n .appShellSidebar {\n display: block;\n position: fixed;\n top: calc(var(--app-shell-topbar-height, 56px) + env(safe-area-inset-top));\n left: 0;\n bottom: 0;\n width: var(--app-shell-sidebar-width, 240px);\n max-width: 80vw;\n background: var(--panel);\n padding: 16px 12px;\n transform: translateX(-105%);\n z-index: 15;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);\n }\n\n .appShellSidebar.appShellSidebarOpen {\n transform: translateX(0);\n }\n\n .appShellTopbar {\n padding-left: max(12px, env(safe-area-inset-left));\n padding-right: max(12px, env(safe-area-inset-right));\n gap: 10px;\n }\n\n .appShellTopbarLeft {\n gap: 10px;\n flex: 1;\n }\n\n .appShellTopbarStart {\n min-width: 0;\n }\n\n .appShellTopbarRight {\n gap: 6px;\n }\n\n .appShellBrand {\n font-size: 24px;\n max-width: 50vw;\n }\n\n .appShellHamburger {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n }\n\n .appShellHamburger svg {\n width: 24px;\n height: 24px;\n }\n}\n\n@media (max-width: 640px) {\n .appShellTopbar {\n gap: 8px;\n }\n\n .appShellBrand {\n font-size: 22px;\n max-width: 34vw;\n }\n\n .appShellTopbarRight {\n max-width: 44vw;\n }\n}\n\n@media (max-width: 480px) {\n .appShellBrand {\n font-size: 20px;\n max-width: 30vw;\n }\n}\n","\"use client\";\n\nimport {\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport { TopBar, type TopBarProps } from \"../top-bar/TopBar\";\nimport styles from \"./app-shell.module.css\";\n\nconst DESKTOP_BREAKPOINT = 960;\n\nfunction getIsDesktop() {\n if (typeof window === \"undefined\") return false;\n return window.innerWidth >= DESKTOP_BREAKPOINT;\n}\n\nexport type AppShellProps = {\n /** Primary page content rendered in the main area. */\n children: ReactNode;\n /** Sidebar navigation or custom content. */\n sidebar: ReactNode;\n /** Brand element rendered next to the hamburger (text or JSX). */\n brand?: ReactNode;\n /** Optional brand href; when provided the brand renders as an anchor. */\n brandHref?: string;\n /** Optional content after the brand on the left side of the top bar. */\n topbarStart?: ReactNode;\n /** Optional content aligned to the right side of the top bar. */\n topbarEnd?: ReactNode;\n /** Optional built-in theme toggle for the top bar. */\n showThemeToggle?: boolean;\n themeToggleProps?: TopBarProps[\"themeToggleProps\"];\n topBarBrandingLocation?: TopBarProps[\"brandingLocation\"];\n /** Custom class names for styling overrides. */\n className?: string;\n sidebarClassName?: string;\n topbarClassName?: string;\n mainClassName?: string;\n /** Sets the sidebar width (e.g., `260`, `\"18rem\"`). */\n sidebarWidth?: number | string;\n /**\n * Closes the sidebar on mobile whenever this value changes.\n * Useful for reacting to route/pathname changes.\n */\n closeSidebarOnChangeKey?: unknown;\n /** Label for the hamburger button (aria-label). */\n hamburgerLabel?: string;\n /** Optional callback fired whenever the sidebar open state changes. */\n onSidebarToggle?: (open: boolean) => void;\n};\n\n/**\n * Responsive application shell with a collapsible sidebar and sticky top bar.\n *\n * - Sidebar opens by default on desktop, collapses on mobile.\n * - Closes on outside click/scroll/touch when in mobile mode.\n * - Provides optional hook to close the sidebar when a prop value changes\n * (e.g., route transitions).\n */\nexport function AppShell({\n children,\n sidebar,\n brand,\n brandHref,\n topbarStart,\n topbarEnd,\n showThemeToggle = false,\n themeToggleProps,\n topBarBrandingLocation = \"left\",\n className,\n sidebarClassName,\n topbarClassName,\n mainClassName,\n sidebarWidth,\n closeSidebarOnChangeKey,\n hamburgerLabel = \"Toggle navigation\",\n onSidebarToggle,\n}: AppShellProps) {\n const [isDesktop, setIsDesktop] = useState(false);\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [transitionsReady, setTransitionsReady] = useState(false);\n const prevIsDesktopRef = useRef(false);\n const closeKeyRef = useRef(closeSidebarOnChangeKey);\n\n const sidebarRef = useRef<HTMLElement | null>(null);\n const hamburgerRef = useRef<HTMLButtonElement | null>(null);\n const mainRef = useRef<HTMLElement | null>(null);\n const sidebarId = useId();\n\n useEffect(() => {\n const desktop = getIsDesktop();\n setIsDesktop(desktop);\n setSidebarOpen(desktop);\n prevIsDesktopRef.current = desktop;\n const transitionFrame = window.requestAnimationFrame(() => {\n setTransitionsReady(true);\n });\n\n const handleResize = () => {\n const nowDesktop = getIsDesktop();\n setIsDesktop(nowDesktop);\n if (nowDesktop !== prevIsDesktopRef.current) {\n setSidebarOpen(nowDesktop);\n prevIsDesktopRef.current = nowDesktop;\n }\n };\n\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.cancelAnimationFrame(transitionFrame);\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n // Close the sidebar when clicking outside or scrolling on mobile.\n useEffect(() => {\n if (isDesktop || !sidebarOpen) return;\n\n const mainElement = mainRef.current;\n const closeSidebar = () => setSidebarOpen(false);\n\n const onPointerDown = (e: PointerEvent) => {\n const target = e.target as Node | null;\n if (!target) return;\n if (sidebarRef.current?.contains(target)) return;\n if (hamburgerRef.current?.contains(target)) return;\n closeSidebar();\n };\n\n const timeoutId = window.setTimeout(() => {\n document.addEventListener(\"pointerdown\", onPointerDown);\n window.addEventListener(\"scroll\", closeSidebar, { passive: true });\n mainElement?.addEventListener(\"scroll\", closeSidebar, { passive: true });\n document.addEventListener(\"touchmove\", closeSidebar, { passive: true });\n }, 10);\n\n return () => {\n window.clearTimeout(timeoutId);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n window.removeEventListener(\"scroll\", closeSidebar);\n mainElement?.removeEventListener(\"scroll\", closeSidebar);\n document.removeEventListener(\"touchmove\", closeSidebar);\n };\n }, [sidebarOpen, isDesktop]);\n\n // Allow consumers to request a mobile sidebar close when a value changes (e.g., pathname).\n useEffect(() => {\n if (!isDesktop && closeKeyRef.current !== closeSidebarOnChangeKey) {\n setSidebarOpen(false);\n }\n closeKeyRef.current = closeSidebarOnChangeKey;\n }, [closeSidebarOnChangeKey, isDesktop]);\n\n useEffect(() => {\n onSidebarToggle?.(sidebarOpen);\n }, [sidebarOpen, onSidebarToggle]);\n\n const toggleSidebar = () => setSidebarOpen((open) => !open);\n\n const sidebarWidthValue =\n sidebarWidth === undefined\n ? undefined\n : typeof sidebarWidth === \"number\"\n ? `${sidebarWidth}px`\n : sidebarWidth;\n\n const shellStyle: CSSProperties | undefined = sidebarWidthValue\n ? { [\"--app-shell-sidebar-width\" as string]: sidebarWidthValue }\n : undefined;\n\n const shellClasses = cx(\n styles.appShell,\n transitionsReady && styles.appShellAnimated,\n sidebarOpen ? styles.appShellOpen : styles.appShellCollapsed,\n className,\n );\n\n const sidebarClasses = cx(\n styles.appShellSidebar,\n sidebarOpen && styles.appShellSidebarOpen,\n sidebarClassName,\n );\n\n return (\n <div\n className={shellClasses}\n style={shellStyle}\n data-app-shell\n data-desktop={isDesktop ? \"true\" : \"false\"}\n data-sidebar-open={sidebarOpen ? \"true\" : \"false\"}\n >\n <TopBar\n className={cx(styles.appShellTopbar, topbarClassName)}\n leading={\n <button\n ref={hamburgerRef}\n type=\"button\"\n className={styles.appShellHamburger}\n onClick={toggleSidebar}\n aria-label={hamburgerLabel}\n aria-expanded={sidebarOpen}\n aria-controls={sidebarId}\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M3 6h18M3 12h18M3 18h18\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n }\n brand={brand}\n brandHref={brandHref}\n brandingLocation={topBarBrandingLocation}\n start={topbarStart}\n actions={topbarEnd}\n showThemeToggle={showThemeToggle}\n themeToggleProps={themeToggleProps}\n />\n {!isDesktop && sidebarOpen && (\n <div\n className={styles.appShellBackdrop}\n onClick={() => setSidebarOpen(false)}\n onTouchStart={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n />\n )}\n <aside ref={sidebarRef} id={sidebarId} className={sidebarClasses} aria-label=\"Sidebar navigation\">\n {sidebar}\n </aside>\n <main ref={mainRef} className={cx(styles.appShellMain, mainClassName)}>\n {children}\n </main>\n </div>\n );\n}\n",".sidebarNav {\n --sidebar-nav-icon-size: 18px;\n --sidebar-nav-icon-size-mobile: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n min-height: 0;\n}\n\n.sidebarNavCollapsed {\n gap: 10px;\n}\n\n.header,\n.footer {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.footer {\n margin-top: auto;\n padding-top: 12px;\n border-top: 1px solid var(--border);\n}\n\n.sections {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 14px;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionItems {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionLabel {\n padding: 0 10px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--muted-foreground);\n opacity: 0.75;\n}\n\n.item {\n color: var(--foreground);\n background: transparent;\n border: none;\n box-shadow: none;\n padding: 10px 12px 10px 10px;\n border-radius: 10px;\n text-decoration: none;\n font-size: 14px;\n display: grid;\n grid-template-columns: var(--sidebar-nav-icon-size) minmax(0, 1fr);\n align-items: center;\n column-gap: 10px;\n width: 100%;\n text-align: left;\n box-sizing: border-box;\n line-height: 1.2;\n transition: background 120ms ease, color 120ms ease;\n}\n\nbutton.item {\n font-family: inherit;\n cursor: pointer;\n}\n\n.item:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.item:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n}\n\n.item.itemActive {\n background: color-mix(in srgb, var(--primary) 18%, transparent);\n color: var(--foreground);\n font-weight: 700;\n}\n\n.itemCollapsed {\n grid-template-columns: 1fr;\n justify-items: center;\n padding-right: 10px;\n padding-left: 10px;\n}\n\n.itemDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.icon {\n width: var(--sidebar-nav-icon-size);\n height: var(--sidebar-nav-icon-size);\n min-width: var(--sidebar-nav-icon-size);\n color: var(--muted-foreground);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n}\n\n.icon > * {\n width: 100% !important;\n height: 100% !important;\n max-width: 100%;\n max-height: 100%;\n}\n\n.icon :where(svg) {\n width: 100%;\n height: 100%;\n display: block;\n stroke: currentColor;\n}\n\n.item.itemActive .icon {\n color: var(--primary);\n}\n\n.itemBody {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 3px;\n overflow: hidden;\n}\n\n.labelRow {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n}\n\n.label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 12px;\n line-height: 1.35;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: color-mix(in srgb, var(--foreground) 4%, transparent);\n color: var(--muted-foreground);\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n@media (max-width: 960px) {\n .sidebarNav {\n gap: 10px;\n }\n\n .sections {\n gap: 12px;\n }\n\n .sectionItems {\n gap: 6px;\n }\n\n .item {\n padding: 9px 10px 9px 8px;\n border-radius: 9px;\n font-size: 14px;\n grid-template-columns: var(--sidebar-nav-icon-size-mobile) minmax(0, 1fr);\n column-gap: 8px;\n }\n\n .icon {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n min-width: var(--sidebar-nav-icon-size-mobile);\n }\n\n .icon :where(svg) {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n }\n\n .description {\n font-size: 11px;\n }\n}\n\n@media (max-width: 480px) {\n .item {\n padding: 8px 9px 8px 7px;\n font-size: 13px;\n }\n}\n","\"use client\";\n\nimport { type AnchorHTMLAttributes, type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./sidebar-nav.module.css\";\n\nexport type SidebarNavItem = {\n label: string;\n href?: string;\n icon?: ReactNode;\n description?: ReactNode;\n badge?: ReactNode;\n active?: boolean;\n disabled?: boolean;\n /**\n * When `true`, this item uses exact matching (matches its own path and paths starting with `{href}/`)\n * instead of prefix matching. This flag takes precedence over the global `matchStrategy` prop on a\n * per-item basis — even when `matchStrategy=\"prefix\"`, an item with `exact: true` will use exact matching.\n * When `matchStrategy=\"most-specific\"`, exact-flagged items participate in the length-based tiebreaker\n * like all other candidates, provided they pass their own match check first.\n */\n exact?: boolean;\n title?: string;\n target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n rel?: AnchorHTMLAttributes<HTMLAnchorElement>[\"rel\"];\n onClick?: () => void;\n};\n\nexport type SidebarNavSection = {\n id?: string;\n label?: ReactNode;\n items: SidebarNavItem[];\n};\n\nexport type SidebarNavProps = {\n items?: SidebarNavItem[];\n sections?: SidebarNavSection[];\n currentPath?: string;\n getIsActive?: (item: SidebarNavItem, currentPath?: string) => boolean;\n matchStrategy?: \"prefix\" | \"most-specific\";\n onItemClick?: (item: SidebarNavItem) => void;\n header?: ReactNode;\n footer?: ReactNode;\n ariaLabel?: string;\n collapsed?: boolean;\n iconSize?: number | string;\n className?: string;\n itemClassName?: string;\n sectionClassName?: string;\n};\n\nconst isActivePrefix = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n if (item.href === \"/\") return path === \"/\";\n return path.startsWith(item.href);\n};\n\nconst isActiveExact = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n // Root href \"/\" must match exactly — otherwise every path would match.\n if (item.href === \"/\") return path === \"/\";\n // Normalize trailing slashes for consistent matching with findMostSpecific length computation.\n const normalizedHref = item.href.endsWith(\"/\") ? item.href.slice(0, -1) : item.href;\n return normalizedHref === path || path.startsWith(`${normalizedHref}/`);\n};\n\n// Natural matching helpers that ignore manual `active` overrides — used inside findMostSpecific\n// so that manually-set active flags don't hijack the length-based tiebreaker.\nconst isNaturalPrefixMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n return path.startsWith(href);\n};\n\nconst isNaturalExactMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n const normalizedHref = href.endsWith(\"/\") ? href.slice(0, -1) : href;\n return normalizedHref === path;\n};\n\nconst hrefLength = (href: string) => (href.endsWith(\"/\") ? href.length - 1 : href.length);\n\nconst findMostSpecific = (items: SidebarNavItem[], currentPath?: string): Set<string> => {\n const result = new Set<string>();\n if (!currentPath) return result;\n\n // Collect all items that naturally match the path — use natural matching helpers so that\n // manually-set `active` flags don't participate in the length-based tiebreaker.\n // Exclude disabled items from matching since they are not interactive targets.\n const matchingItems = items.filter(item => {\n if (item.disabled || !item.href) return false;\n return item.exact\n ? isNaturalExactMatch(item.href, currentPath)\n : isNaturalPrefixMatch(item.href, currentPath);\n });\n\n if (matchingItems.length === 0) return result;\n\n // Find the longest href among prefix matches.\n let maxLen = 0;\n for (const item of matchingItems) {\n if (!item.href) continue;\n const len = hrefLength(item.href);\n if (len > maxLen) maxLen = len;\n }\n\n // Only the items with the longest href are active.\n for (const item of matchingItems) {\n if (!item.href) continue;\n if (hrefLength(item.href) === maxLen) result.add(item.href);\n }\n\n return result;\n};\n\nexport function SidebarNav({\n items = [],\n sections,\n currentPath,\n getIsActive,\n matchStrategy = \"prefix\",\n onItemClick,\n header,\n footer,\n ariaLabel = \"Sidebar navigation\",\n collapsed = false,\n iconSize,\n className,\n itemClassName,\n sectionClassName,\n}: SidebarNavProps) {\n const resolvedSections = useMemo(() => {\n return sections?.length ? sections : [{ id: \"default\", items }];\n }, [sections, items]);\n\n // Stable reference to all items — avoids recreating on every render when `sections` is falsy.\n const allItems = useMemo(() => resolvedSections.flatMap(section => section.items), [resolvedSections]);\n\n // Build the default isActive function based on matchStrategy.\n const defaultIsActiveFn = useMemo<(item: SidebarNavItem, path?: string) => boolean>(() => {\n if (matchStrategy === \"most-specific\") {\n const mostSpecificHrefs = findMostSpecific(allItems, currentPath);\n return (item: SidebarNavItem) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n // Exact-flagged items participate in the length-based tiebreaker like all other candidates.\n return mostSpecificHrefs.has(item.href);\n };\n } else {\n return (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (item.exact) return isActiveExact(item, path);\n return isActivePrefix(item, path);\n };\n }\n }, [matchStrategy, allItems, currentPath]);\n\n const resolvedGetIsActive = getIsActive ?? defaultIsActiveFn;\n\n const style =\n iconSize !== undefined\n ? ({\n [\"--sidebar-nav-icon-size\" as string]:\n typeof iconSize === \"number\" ? `${iconSize}px` : iconSize,\n } satisfies CSSProperties)\n : undefined;\n\n return (\n <nav\n className={cx(\n styles.sidebarNav,\n collapsed && styles.sidebarNavCollapsed,\n className,\n )}\n aria-label={ariaLabel}\n style={style}\n >\n {header ? <div className={styles.header}>{header}</div> : null}\n <div className={styles.sections}>\n {resolvedSections.map((section, sectionIndex) => (\n <div\n key={section.id ?? `section-${sectionIndex}`}\n className={cx(styles.section, sectionClassName)}\n >\n {section.label && !collapsed ? (\n <div className={styles.sectionLabel}>{section.label}</div>\n ) : null}\n <div className={styles.sectionItems}>\n {section.items.map((item, itemIndex) => (\n <SidebarNavEntry\n key={`${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`}\n item={item}\n active={resolvedGetIsActive(item, currentPath)}\n collapsed={collapsed}\n itemClassName={itemClassName}\n onItemClick={onItemClick}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </nav>\n );\n}\n\ntype SidebarNavEntryProps = {\n item: SidebarNavItem;\n active: boolean;\n collapsed: boolean;\n itemClassName?: string;\n onItemClick?: (item: SidebarNavItem) => void;\n};\n\nfunction SidebarNavEntry({\n item,\n active,\n collapsed,\n itemClassName,\n onItemClick,\n}: SidebarNavEntryProps) {\n const rel = item.rel ?? (item.target === \"_blank\" ? \"noreferrer\" : undefined);\n const title = item.title ?? (typeof item.label === \"string\" ? item.label : undefined);\n const classes = cx(\n styles.item,\n active && styles.itemActive,\n collapsed && styles.itemCollapsed,\n item.disabled && styles.itemDisabled,\n itemClassName,\n );\n const content = (\n <>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {!collapsed ? (\n <span className={styles.itemBody}>\n <span className={styles.labelRow}>\n <span className={styles.label}>{item.label}</span>\n {item.badge && <span className={styles.badge}>{item.badge}</span>}\n </span>\n {item.description ? <span className={styles.description}>{item.description}</span> : null}\n </span>\n ) : null}\n </>\n );\n\n const handleClick = () => {\n if (item.disabled) return;\n item.onClick?.();\n onItemClick?.(item);\n };\n\n if (!item.href) {\n return (\n <button\n type=\"button\"\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={item.disabled ? \"true\" : undefined}\n disabled={item.disabled}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </button>\n );\n }\n\n if (item.disabled) {\n return (\n <div\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled=\"true\"\n title={collapsed ? title : undefined}\n >\n {content}\n </div>\n );\n }\n\n return (\n <a\n className={classes}\n href={item.href}\n target={item.target}\n rel={rel}\n aria-current={active ? \"page\" : undefined}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </a>\n );\n}\n",".skeleton {\n background: color-mix(in srgb, var(--muted-foreground) 14%, var(--background));\n animation: skeleton-pulse 1.6s ease-in-out infinite;\n}\n\n@keyframes skeleton-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.45; }\n}\n\n.radius-sm { border-radius: 4px; }\n.radius-md { border-radius: 8px; }\n.radius-lg { border-radius: 12px; }\n.radius-full { border-radius: 9999px; }\n","\"use client\";\n\nimport type { HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./skeleton.module.css\";\n\nexport type SkeletonProps = HTMLAttributes<HTMLDivElement> & {\n /** Width as a CSS value. */\n width?: string;\n /** Height as a CSS value. */\n height?: string;\n /** Border radius preset. Defaults to \"md\". */\n radius?: \"sm\" | \"md\" | \"lg\" | \"full\";\n};\n\nexport function Skeleton({\n width,\n height,\n radius = \"md\",\n className,\n style,\n ...rest\n}: SkeletonProps) {\n return (\n <div\n className={cx(styles.skeleton, styles[`radius-${radius}`], className)}\n style={{ width, height, ...style }}\n aria-hidden=\"true\"\n {...rest}\n />\n );\n}\n",".track {\n height: 8px;\n border-radius: 9999px;\n overflow: hidden;\n background: color-mix(in srgb, var(--border) 60%, transparent);\n}\n\n.fill {\n height: 100%;\n border-radius: 9999px;\n transition: width 0.4s ease;\n}\n\n.tone-default { background: var(--foreground); }\n.tone-success { background: var(--success); }\n.tone-warning { background: var(--warning); }\n.tone-danger { background: var(--destructive); }\n","import type { HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./progress.module.css\";\n\nexport type ProgressTone = \"default\" | \"success\" | \"warning\" | \"danger\";\n\nexport type ProgressProps = HTMLAttributes<HTMLDivElement> & {\n /** Value 0–100. */\n value: number;\n /** Visual tone. Defaults to \"default\". */\n tone?: ProgressTone;\n /** Accessible label. */\n \"aria-label\"?: string;\n};\n\nexport function Progress({\n value,\n tone = \"default\",\n className,\n \"aria-label\": ariaLabel,\n ...rest\n}: ProgressProps) {\n const clamped = Math.max(0, Math.min(100, value));\n return (\n <div\n className={cx(styles.track, className)}\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={ariaLabel}\n {...rest}\n >\n <div\n className={cx(styles.fill, styles[`tone-${tone}`])}\n style={{ width: `${clamped}%` }}\n />\n </div>\n );\n}\n",".track {\n display: inline-flex;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: var(--card);\n padding: 4px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n gap: 2px;\n}\n\n.option {\n border-radius: 999px;\n padding: 6px 16px;\n font-size: var(--uzi-control-font-size);\n font-weight: 500;\n line-height: var(--uzi-control-line-height);\n background: transparent;\n color: var(--muted-foreground);\n border: none;\n cursor: pointer;\n transition:\n color 120ms ease,\n background 120ms ease;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n}\n\n.label {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.option:hover:not([aria-checked=\"true\"]):not(:disabled) {\n color: var(--foreground);\n}\n\n.option[aria-checked=\"true\"] {\n background: var(--foreground);\n color: var(--background);\n}\n\n.option:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.option:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./segmented-toggle.module.css\";\n\nexport type SegmentedToggleOption<T extends string = string> = {\n label: ReactNode;\n value: T;\n disabled?: boolean;\n};\n\nexport type SegmentedToggleProps<T extends string = string> = {\n options: SegmentedToggleOption<T>[];\n value: T;\n onChange: (value: T) => void;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n className?: string;\n};\n\nexport function SegmentedToggle<T extends string = string>({\n options,\n value,\n onChange,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n className,\n}: SegmentedToggleProps<T>) {\n const itemRefs = React.useRef<Array<HTMLButtonElement | null>>([]);\n const selectedIndex = options.findIndex((opt) => opt.value === value);\n const fallbackIndex = options.findIndex((opt) => !opt.disabled);\n let lastEnabledIndex = -1;\n for (let index = options.length - 1; index >= 0; index -= 1) {\n if (!options[index]?.disabled) {\n lastEnabledIndex = index;\n break;\n }\n }\n const tabbableIndex =\n selectedIndex >= 0 && !options[selectedIndex]?.disabled\n ? selectedIndex\n : fallbackIndex;\n\n const focusItem = (index: number) => {\n itemRefs.current[index]?.focus();\n };\n\n const findEnabledIndex = (\n startIndex: number,\n direction: 1 | -1,\n ): number => {\n if (options.length === 0) return -1;\n\n let nextIndex = startIndex;\n for (let i = 0; i < options.length; i += 1) {\n nextIndex = (nextIndex + direction + options.length) % options.length;\n if (!options[nextIndex]?.disabled) {\n return nextIndex;\n }\n }\n\n return startIndex;\n };\n\n const selectIndex = (index: number) => {\n const nextOption = options[index];\n if (!nextOption || nextOption.disabled || nextOption.value === value) {\n return;\n }\n onChange(nextOption.value);\n };\n\n const handleKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\": {\n event.preventDefault();\n const nextIndex = findEnabledIndex(index, 1);\n focusItem(nextIndex);\n selectIndex(nextIndex);\n break;\n }\n case \"ArrowLeft\":\n case \"ArrowUp\": {\n event.preventDefault();\n const nextIndex = findEnabledIndex(index, -1);\n focusItem(nextIndex);\n selectIndex(nextIndex);\n break;\n }\n case \"Home\": {\n event.preventDefault();\n focusItem(fallbackIndex);\n if (fallbackIndex >= 0) {\n selectIndex(fallbackIndex);\n }\n break;\n }\n case \"End\": {\n event.preventDefault();\n if (lastEnabledIndex >= 0) {\n focusItem(lastEnabledIndex);\n selectIndex(lastEnabledIndex);\n }\n break;\n }\n default:\n break;\n }\n };\n\n return (\n <div\n className={cx(styles.track, className)}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {options.map((opt, index) => (\n <button\n key={opt.value}\n ref={(node) => {\n itemRefs.current[index] = node;\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={opt.value === value}\n disabled={opt.disabled}\n tabIndex={\n opt.disabled\n ? -1\n : index === tabbableIndex\n ? 0\n : -1\n }\n onClick={() => {\n if (opt.value !== value) {\n onChange(opt.value);\n }\n }}\n onKeyDown={(event) => handleKeyDown(event, index)}\n className={cx(styles.option)}\n >\n <span className={styles.label}>{opt.label}</span>\n </button>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
|