namps-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme.tsx","../src/icons.tsx","../src/utils.ts","../src/components/Button.tsx","../src/components/Form.tsx","../src/components/Display.tsx","../src/components/Accordion.tsx","../src/components/Tabs.tsx","../src/components/Navigation.tsx","../src/components/Table.tsx","../src/components/Alert.tsx","../src/components/Toast.tsx","../src/components/Overlay.tsx","../src/components/Extras.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Sun, Moon } from \"./icons\";\nimport { cx } from \"./utils\";\n\nexport type Theme = \"light\" | \"dark\";\n\ninterface ThemeContextValue {\n theme: Theme;\n setTheme: (t: Theme) => void;\n toggle: () => void;\n}\n\nconst ThemeContext = React.createContext<ThemeContextValue | null>(null);\n\nexport interface ThemeProviderProps {\n children: React.ReactNode;\n /** Initial theme when nothing is stored. Default \"light\". */\n defaultTheme?: Theme;\n /** localStorage key for persistence. Default \"pui-theme\". Pass null to disable. */\n storageKey?: string | null;\n /** Element to stamp `data-theme` on. Default document.documentElement. */\n attributeTarget?: \"html\" | \"self\";\n}\n\n/**\n * Wrap your app once. Sets `data-theme` on <html> (or a wrapper div) and\n * persists the choice. Read/control via the `useTheme()` hook.\n */\nexport function ThemeProvider({\n children,\n defaultTheme = \"light\",\n storageKey = \"pui-theme\",\n attributeTarget = \"html\",\n}: ThemeProviderProps) {\n const [theme, setThemeState] = React.useState<Theme>(defaultTheme);\n\n React.useEffect(() => {\n if (storageKey) {\n const stored = window.localStorage.getItem(storageKey) as Theme | null;\n if (stored === \"light\" || stored === \"dark\") setThemeState(stored);\n }\n }, [storageKey]);\n\n React.useEffect(() => {\n if (attributeTarget === \"html\") {\n document.documentElement.setAttribute(\"data-theme\", theme);\n }\n if (storageKey) window.localStorage.setItem(storageKey, theme);\n }, [theme, attributeTarget, storageKey]);\n\n const value = React.useMemo<ThemeContextValue>(\n () => ({\n theme,\n setTheme: setThemeState,\n toggle: () => setThemeState((t) => (t === \"light\" ? \"dark\" : \"light\")),\n }),\n [theme],\n );\n\n return (\n <ThemeContext.Provider value={value}>\n {attributeTarget === \"self\" ? <div data-theme={theme}>{children}</div> : children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme(): ThemeContextValue {\n const ctx = React.useContext(ThemeContext);\n if (!ctx) throw new Error(\"useTheme must be used within a <ThemeProvider>\");\n return ctx;\n}\n\n/** Drop-in icon button that flips the theme. */\nexport function ThemeToggle({ className, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement>) {\n const { theme, toggle } = useTheme();\n return (\n <button\n type=\"button\"\n aria-label=\"Toggle color theme\"\n onClick={toggle}\n className={cx(\"pui-btn\", \"pui-btn--secondary\", \"pui-btn--icon\", className)}\n {...props}\n >\n {theme === \"light\" ? <Moon className=\"pui-icon\" /> : <Sun className=\"pui-icon\" />}\n </button>\n );\n}\n","import * as React from \"react\";\n\ntype IconProps = React.SVGProps<SVGSVGElement>;\n\nconst base = (path: React.ReactNode) =>\n function Icon({ className, ...props }: IconProps) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.8}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className ?? \"pui-icon\"}\n aria-hidden=\"true\"\n {...props}\n >\n {path}\n </svg>\n );\n };\n\nexport const ChevronDown = base(<path d=\"M6 9l6 6 6-6\" />);\nexport const ChevronRight = base(<path d=\"M9 6l6 6-6 6\" />);\nexport const ChevronLeft = base(<path d=\"M15 6l-6 6 6 6\" />);\nexport const Check = base(<path d=\"M5 12l4 4 10-10\" />);\nexport const X = base(<path d=\"M6 6l12 12M18 6L6 18\" />);\nexport const Search = base(<><circle cx=\"11\" cy=\"11\" r=\"7\" /><path d=\"M21 21l-4.3-4.3\" /></>);\nexport const Plus = base(<path d=\"M12 5v14M5 12h14\" />);\nexport const Sun = base(<><circle cx=\"12\" cy=\"12\" r=\"4\" /><path d=\"M12 2v2M12 20v2M4 12H2M22 12h-2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M18.4 5.6L17 7M7 17l-1.4 1.4\" /></>);\nexport const Moon = base(<path d=\"M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8Z\" />);\nexport const Info = base(<><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M12 11v5M12 8h.01\" /></>);\nexport const AlertTriangle = base(<><path d=\"M10.3 3.3 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.3a2 2 0 0 0-3.4 0Z\" /><path d=\"M12 9v4M12 17h.01\" /></>);\nexport const CheckCircle = base(<><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M8 12l3 3 5-6\" /></>);\nexport const XCircle = base(<><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M15 9l-6 6M9 9l6 6\" /></>);\nexport const ArrowRight = base(<path d=\"M5 12h14M13 6l6 6-6 6\" />);\nexport const Sort = base(<path d=\"M8 9l4-4 4 4M8 15l4 4 4-4\" />);\n\nexport function DotsVertical({ className, ...props }: IconProps) {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className={className ?? \"pui-icon\"} aria-hidden=\"true\" {...props}>\n <circle cx=\"12\" cy=\"5\" r=\"1.6\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.6\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.6\" />\n </svg>\n );\n}\n","/** Tiny classNames helper — joins truthy class fragments. */\nexport function cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n\n/** Derive up-to-two-letter initials from a full name. */\nexport function initials(name: string): string {\n const words = name.trim().split(/\\s+/);\n if (words.length === 0) return \"?\";\n if (words.length === 1) return words[0].slice(0, 2).toUpperCase();\n return (words[0][0] + words[words.length - 1][0]).toUpperCase();\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"outline\" | \"ghost\" | \"danger\";\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Renders a spinner and disables the button. */\n loading?: boolean;\n /** Icon-only square button. Pass an icon as the single child. */\n iconOnly?: boolean;\n /** Stretch to full container width. */\n block?: boolean;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n}\n\n/**\n * The primary action element. Five variants, three sizes, loading + icon support.\n *\n * @example\n * <Button variant=\"primary\" leftIcon={<Plus/>}>Create key</Button>\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = \"primary\",\n size = \"md\",\n loading = false,\n iconOnly = false,\n block = false,\n leftIcon,\n rightIcon,\n disabled,\n className,\n children,\n ...props\n },\n ref,\n) {\n return (\n <button\n ref={ref}\n disabled={disabled || loading}\n className={cx(\n \"pui-btn\",\n `pui-btn--${variant}`,\n size !== \"md\" && `pui-btn--${size}`,\n iconOnly && \"pui-btn--icon\",\n block && \"pui-btn--block\",\n className,\n )}\n {...props}\n >\n {loading && <span className=\"pui-btn__spinner\" aria-hidden=\"true\" />}\n {!loading && leftIcon}\n {children}\n {!loading && rightIcon}\n </button>\n );\n});\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { Check, ChevronDown, Search as SearchIcon, XCircle } from \"../icons\";\n\n/* ---------------- Field wrapper ---------------- */\nexport interface FieldProps {\n label?: React.ReactNode;\n hint?: React.ReactNode;\n error?: React.ReactNode;\n htmlFor?: string;\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Labelled wrapper: renders label, control, and hint/error text. */\nexport function Field({ label, hint, error, htmlFor, children, className, style }: FieldProps) {\n return (\n <div className={cx(\"pui-field\", className)} style={style}>\n {label && (\n <label className=\"pui-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n {error ? (\n <span className=\"pui-error\">\n <XCircle style={{ width: 13, height: 13 }} />\n {error}\n </span>\n ) : (\n hint && <span className=\"pui-hint\">{hint}</span>\n )}\n </div>\n );\n}\n\n/* ---------------- Input ---------------- */\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n invalid?: boolean;\n}\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n { invalid, className, ...props },\n ref,\n) {\n return (\n <input\n ref={ref}\n aria-invalid={invalid || undefined}\n className={cx(\"pui-input\", invalid && \"pui-input--invalid\", className)}\n {...props}\n />\n );\n});\n\n/** Input with a leading search glyph. */\nexport const SearchInput = React.forwardRef<HTMLInputElement, InputProps>(function SearchInput(\n { className, ...props },\n ref,\n) {\n return (\n <span className=\"pui-input-wrap\">\n <SearchIcon className=\"pui-input-wrap__icon\" />\n <Input ref={ref} className={className} {...props} />\n </span>\n );\n});\n\n/* ---------------- Textarea ---------------- */\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n invalid?: boolean;\n}\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n { invalid, className, rows = 3, ...props },\n ref,\n) {\n return (\n <textarea\n ref={ref}\n rows={rows}\n aria-invalid={invalid || undefined}\n className={cx(\"pui-textarea\", invalid && \"pui-textarea--invalid\", className)}\n {...props}\n />\n );\n});\n\n/* ---------------- Select (native, styled) ---------------- */\nexport interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {\n options?: Array<{ label: string; value: string }>;\n}\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(function Select(\n { options, className, children, ...props },\n ref,\n) {\n return (\n <span className=\"pui-select-wrap\">\n <select ref={ref} className={cx(\"pui-select\", className)} {...props}>\n {options\n ? options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))\n : children}\n </select>\n <ChevronDown className=\"pui-select-wrap__caret\" />\n </span>\n );\n});\n\n/* ---------------- Checkbox ---------------- */\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n label?: React.ReactNode;\n}\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n { label, disabled, className, ...props },\n ref,\n) {\n return (\n <label className={cx(\"pui-checkbox\", disabled && \"pui-checkbox--disabled\", className)}>\n <input ref={ref} type=\"checkbox\" disabled={disabled} {...props} />\n <span className=\"pui-checkbox__box\">\n <Check />\n </span>\n {label}\n </label>\n );\n});\n\n/* ---------------- Switch ---------------- */\nexport interface SwitchProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\"> {}\nexport const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(function Switch(\n { className, ...props },\n ref,\n) {\n return (\n <label className={cx(\"pui-switch\", className)}>\n <input ref={ref} type=\"checkbox\" role=\"switch\" {...props} />\n <span className=\"pui-switch__track\" />\n </label>\n );\n});\n\n/* ---------------- RadioGroup ---------------- */\nexport interface RadioOption {\n value: string;\n title: React.ReactNode;\n description?: React.ReactNode;\n}\nexport interface RadioGroupProps {\n name: string;\n value: string;\n onValueChange: (value: string) => void;\n options: RadioOption[];\n className?: string;\n}\n/** Card-style radio group. Controlled via `value` / `onValueChange`. */\nexport function RadioGroup({ name, value, onValueChange, options, className }: RadioGroupProps) {\n return (\n <div className={cx(\"pui-radio-group\", className)} role=\"radiogroup\">\n {options.map((o) => (\n <label key={o.value} className=\"pui-radio-card\">\n <input\n type=\"radio\"\n name={name}\n value={o.value}\n checked={value === o.value}\n onChange={() => onValueChange(o.value)}\n />\n <span className=\"pui-radio-card__dot\" />\n <span>\n <span className=\"pui-radio-card__title\">{o.title}</span>\n {o.description && <span className=\"pui-radio-card__desc\">{o.description}</span>}\n </span>\n </label>\n ))}\n </div>\n );\n}\n\n/* ---------------- Slider ---------------- */\nexport interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\" | \"value\" | \"onChange\"> {\n value: number;\n min?: number;\n max?: number;\n onValueChange: (value: number) => void;\n}\nexport function Slider({ value, min = 0, max = 100, onValueChange, className, ...props }: SliderProps) {\n const pct = ((value - min) / (max - min)) * 100;\n return (\n <div className={cx(\"pui-slider\", className)}>\n <div className=\"pui-slider__row\">\n <div className=\"pui-slider__track\" />\n <div className=\"pui-slider__fill\" style={{ width: `${pct}%` }} />\n <input\n type=\"range\"\n min={min}\n max={max}\n value={value}\n onChange={(e) => onValueChange(Number(e.target.value))}\n {...props}\n />\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx, initials as toInitials } from \"../utils\";\nimport { X } from \"../icons\";\n\nexport type Tone = \"neutral\" | \"green\" | \"amber\" | \"red\" | \"blue\" | \"accent\";\n\n/* ---------------- Badge ---------------- */\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n tone?: Tone;\n solid?: boolean;\n dot?: boolean;\n}\nexport function Badge({ tone = \"neutral\", solid, dot, className, children, ...props }: BadgeProps) {\n return (\n <span\n className={cx(\"pui-badge\", className)}\n data-tone={tone === \"neutral\" ? undefined : tone}\n data-solid={solid || undefined}\n {...props}\n >\n {dot && <span className=\"pui-badge__dot\" />}\n {children}\n </span>\n );\n}\n\n/* ---------------- Tag (removable) ---------------- */\nexport interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {\n onRemove?: () => void;\n}\nexport function Tag({ onRemove, className, children, ...props }: TagProps) {\n return (\n <span className={cx(\"pui-tag\", className)} {...props}>\n {children}\n {onRemove && (\n <button type=\"button\" className=\"pui-tag__close\" aria-label=\"Remove\" onClick={onRemove}>\n <X />\n </button>\n )}\n </span>\n );\n}\n\n/* ---------------- Avatar ---------------- */\nexport type AvatarSize = \"sm\" | \"md\" | \"lg\";\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n name: string;\n src?: string;\n size?: AvatarSize;\n tone?: \"accent\" | \"blue\" | \"green\" | \"amber\";\n status?: \"online\" | \"busy\" | \"away\";\n}\nexport function Avatar({ name, src, size = \"md\", tone = \"accent\", status, className, ...props }: AvatarProps) {\n return (\n <span\n className={cx(\"pui-avatar\", className)}\n data-size={size}\n data-tone={tone === \"accent\" ? undefined : tone}\n title={name}\n {...props}\n >\n {src ? <img src={src} alt={name} /> : toInitials(name)}\n {status && <span className=\"pui-avatar__status\" data-status={status} />}\n </span>\n );\n}\n\nexport interface AvatarGroupProps {\n /** Avatar elements. */\n children: React.ReactNode;\n /** Show at most this many, collapsing the rest into a \"+N\". */\n max?: number;\n size?: AvatarSize;\n className?: string;\n}\nexport function AvatarGroup({ children, max, size = \"md\", className }: AvatarGroupProps) {\n const items = React.Children.toArray(children);\n const shown = max ? items.slice(0, max) : items;\n const extra = max ? items.length - shown.length : 0;\n return (\n <div className={cx(\"pui-avatar-group\", className)}>\n {shown}\n {extra > 0 && (\n <span className=\"pui-avatar pui-avatar-group__more\" data-size={size}>\n +{extra}\n </span>\n )}\n </div>\n );\n}\n\n/* ---------------- Card ---------------- */\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n padded?: boolean;\n}\nexport function Card({ padded = true, className, children, ...props }: CardProps) {\n return (\n <div className={cx(\"pui-card\", padded && \"pui-card--pad\", className)} {...props}>\n {children}\n </div>\n );\n}\n\n/* ---------------- StatCard ---------------- */\nexport interface StatCardProps {\n label: React.ReactNode;\n value: React.ReactNode;\n delta?: { value: React.ReactNode; direction: \"up\" | \"down\" };\n className?: string;\n}\nexport function StatCard({ label, value, delta, className }: StatCardProps) {\n return (\n <div className={cx(\"pui-stat\", className)}>\n <div className=\"pui-stat__label\">{label}</div>\n <div className=\"pui-stat__value\">{value}</div>\n {delta && (\n <div className=\"pui-stat__delta\" data-dir={delta.direction}>\n {delta.direction === \"up\" ? \"▲\" : \"▼\"} {delta.value}\n </div>\n )}\n </div>\n );\n}\n\n/* ---------------- Progress ---------------- */\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** 0–100. Omit for an indeterminate bar. */\n value?: number;\n}\nexport function Progress({ value, className, ...props }: ProgressProps) {\n const indeterminate = value == null;\n return (\n <div\n className={cx(\"pui-progress\", className)}\n data-indeterminate={indeterminate || undefined}\n role=\"progressbar\"\n aria-valuenow={indeterminate ? undefined : value}\n aria-valuemin={0}\n aria-valuemax={100}\n {...props}\n >\n <div className=\"pui-progress__bar\" style={indeterminate ? undefined : { width: `${value}%` }} />\n </div>\n );\n}\n\n/* ---------------- Spinner ---------------- */\nexport function Spinner({ size = 30, className, style, ...props }: { size?: number } & React.HTMLAttributes<HTMLSpanElement>) {\n return <span role=\"status\" aria-label=\"Loading\" className={cx(\"pui-spinner\", className)} style={{ width: size, height: size, ...style }} {...props} />;\n}\n\n/* ---------------- Skeleton ---------------- */\nexport function Skeleton({ width, height = 11, className, style, ...props }: { width?: number | string; height?: number | string } & React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cx(\"pui-skeleton\", className)} style={{ width, height, ...style }} {...props} />;\n}\n\n/* ---------------- EmptyState ---------------- */\nexport interface EmptyStateProps {\n icon?: React.ReactNode;\n title: React.ReactNode;\n description?: React.ReactNode;\n action?: React.ReactNode;\n className?: string;\n}\nexport function EmptyState({ icon, title, description, action, className }: EmptyStateProps) {\n return (\n <div className={cx(\"pui-empty\", className)}>\n {icon && <span className=\"pui-empty__icon\">{icon}</span>}\n <div className=\"pui-empty__title\">{title}</div>\n {description && <div className=\"pui-empty__desc\">{description}</div>}\n {action && <div style={{ marginTop: 10 }}>{action}</div>}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { ChevronDown } from \"../icons\";\n\ninterface AccordionContextValue {\n isOpen: (value: string) => boolean;\n toggle: (value: string) => void;\n}\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\nexport interface AccordionProps {\n children: React.ReactNode;\n /** \"single\" (default) collapses others; \"multiple\" allows many open. */\n type?: \"single\" | \"multiple\";\n defaultValue?: string | string[];\n className?: string;\n}\n\n/**\n * Collapsible disclosure list.\n * @example\n * <Accordion defaultValue=\"a\">\n * <AccordionItem value=\"a\" title=\"How is usage metered?\">…</AccordionItem>\n * <AccordionItem value=\"b\" title=\"Can I rotate keys?\">…</AccordionItem>\n * </Accordion>\n */\nexport function Accordion({ children, type = \"single\", defaultValue, className }: AccordionProps) {\n const [open, setOpen] = React.useState<string[]>(\n defaultValue == null ? [] : Array.isArray(defaultValue) ? defaultValue : [defaultValue],\n );\n\n const value = React.useMemo<AccordionContextValue>(\n () => ({\n isOpen: (v) => open.includes(v),\n toggle: (v) =>\n setOpen((prev) => {\n const has = prev.includes(v);\n if (type === \"single\") return has ? [] : [v];\n return has ? prev.filter((x) => x !== v) : [...prev, v];\n }),\n }),\n [open, type],\n );\n\n return (\n <div className={cx(\"pui-accordion\", className)}>\n <AccordionContext.Provider value={value}>{children}</AccordionContext.Provider>\n </div>\n );\n}\n\nexport interface AccordionItemProps {\n value: string;\n title: React.ReactNode;\n children: React.ReactNode;\n}\nexport function AccordionItem({ value, title, children }: AccordionItemProps) {\n const ctx = React.useContext(AccordionContext);\n if (!ctx) throw new Error(\"AccordionItem must be used within <Accordion>\");\n const open = ctx.isOpen(value);\n return (\n <div className=\"pui-accordion__item\" data-open={open || undefined}>\n <button\n type=\"button\"\n className=\"pui-accordion__trigger\"\n aria-expanded={open}\n onClick={() => ctx.toggle(value)}\n >\n {title}\n <ChevronDown className=\"pui-accordion__chevron\" />\n </button>\n {open && <div className=\"pui-accordion__panel\">{children}</div>}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\n\ninterface TabsContextValue {\n value: string;\n setValue: (v: string) => void;\n}\nconst TabsContext = React.createContext<TabsContextValue | null>(null);\n\nexport interface TabsProps {\n children: React.ReactNode;\n defaultValue: string;\n value?: string;\n onValueChange?: (v: string) => void;\n className?: string;\n}\n\n/**\n * Underline tab set.\n * @example\n * <Tabs defaultValue=\"overview\">\n * <TabList>\n * <Tab value=\"overview\">Overview</Tab>\n * <Tab value=\"activity\">Activity</Tab>\n * </TabList>\n * <TabPanel value=\"overview\">…</TabPanel>\n * <TabPanel value=\"activity\">…</TabPanel>\n * </Tabs>\n */\nexport function Tabs({ children, defaultValue, value, onValueChange, className }: TabsProps) {\n const [internal, setInternal] = React.useState(defaultValue);\n const current = value ?? internal;\n const setValue = (v: string) => {\n if (value === undefined) setInternal(v);\n onValueChange?.(v);\n };\n return (\n <TabsContext.Provider value={{ value: current, setValue }}>\n <div className={className}>{children}</div>\n </TabsContext.Provider>\n );\n}\n\nfunction useTabs(component: string) {\n const ctx = React.useContext(TabsContext);\n if (!ctx) throw new Error(`${component} must be used within <Tabs>`);\n return ctx;\n}\n\nexport function TabList({ children, className }: { children: React.ReactNode; className?: string }) {\n return (\n <div role=\"tablist\" className={cx(\"pui-tabs__list\", className)}>\n {children}\n </div>\n );\n}\n\nexport function Tab({ value, children }: { value: string; children: React.ReactNode }) {\n const ctx = useTabs(\"Tab\");\n const active = ctx.value === value;\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n data-active={active || undefined}\n className=\"pui-tabs__tab\"\n onClick={() => ctx.setValue(value)}\n >\n {children}\n </button>\n );\n}\n\nexport function TabPanel({ value, children, className }: { value: string; children: React.ReactNode; className?: string }) {\n const ctx = useTabs(\"TabPanel\");\n if (ctx.value !== value) return null;\n return (\n <div role=\"tabpanel\" className={cx(\"pui-tabs__panel\", className)}>\n {children}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { ChevronRight, ChevronLeft } from \"../icons\";\n\n/* ============================================================\n Breadcrumbs\n ============================================================ */\nexport interface Crumb {\n label: React.ReactNode;\n href?: string;\n}\nexport function Breadcrumbs({ items, className }: { items: Crumb[]; className?: string }) {\n return (\n <nav aria-label=\"Breadcrumb\" className={cx(\"pui-breadcrumbs\", className)}>\n {items.map((c, i) => {\n const last = i === items.length - 1;\n return (\n <React.Fragment key={i}>\n {last || !c.href ? (\n <span className={last ? \"pui-breadcrumbs__current\" : undefined} aria-current={last ? \"page\" : undefined}>\n {c.label}\n </span>\n ) : (\n <a href={c.href}>{c.label}</a>\n )}\n {!last && <ChevronRight className=\"pui-breadcrumbs__sep\" />}\n </React.Fragment>\n );\n })}\n </nav>\n );\n}\n\n/* ============================================================\n Pagination\n ============================================================ */\nexport interface PaginationProps {\n page: number;\n count: number;\n onChange: (page: number) => void;\n /** How many sibling pages to show around the current one. Default 1. */\n siblings?: number;\n className?: string;\n}\n\nfunction range(start: number, end: number) {\n return Array.from({ length: end - start + 1 }, (_, i) => start + i);\n}\n\nexport function Pagination({ page, count, onChange, siblings = 1, className }: PaginationProps) {\n const pages = React.useMemo<(number | \"…\")[]>(() => {\n const total = count;\n const left = Math.max(2, page - siblings);\n const right = Math.min(total - 1, page + siblings);\n const out: (number | \"…\")[] = [1];\n if (left > 2) out.push(\"…\");\n out.push(...range(left, right));\n if (right < total - 1) out.push(\"…\");\n if (total > 1) out.push(total);\n return out.filter((v, i, a) => v !== a[i - 1]);\n }, [page, count, siblings]);\n\n return (\n <nav className={cx(\"pui-pagination\", className)} aria-label=\"Pagination\">\n <button className=\"pui-pagination__btn\" disabled={page <= 1} onClick={() => onChange(page - 1)}>\n <ChevronLeft />\n Prev\n </button>\n {pages.map((p, i) =>\n p === \"…\" ? (\n <span key={`e${i}`} className=\"pui-pagination__ellipsis\">\n …\n </span>\n ) : (\n <button\n key={p}\n className=\"pui-pagination__btn\"\n data-active={p === page || undefined}\n aria-current={p === page ? \"page\" : undefined}\n onClick={() => onChange(p)}\n >\n {p}\n </button>\n ),\n )}\n <button className=\"pui-pagination__btn\" disabled={page >= count} onClick={() => onChange(page + 1)}>\n Next\n <ChevronRight />\n </button>\n </nav>\n );\n}\n\n/* ============================================================\n Segmented control\n ============================================================ */\nexport interface SegmentedProps {\n options: Array<{ label: React.ReactNode; value: string }>;\n value: string;\n onValueChange: (value: string) => void;\n className?: string;\n}\nexport function Segmented({ options, value, onValueChange, className }: SegmentedProps) {\n return (\n <div className={cx(\"pui-segmented\", className)} role=\"tablist\">\n {options.map((o) => (\n <button\n key={o.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={value === o.value}\n data-active={value === o.value || undefined}\n className=\"pui-segmented__btn\"\n onClick={() => onValueChange(o.value)}\n >\n {o.label}\n </button>\n ))}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { Sort } from \"../icons\";\n\nexport interface Column<T> {\n key: string;\n header: React.ReactNode;\n /** Cell renderer. Receives the row. */\n cell: (row: T) => React.ReactNode;\n sortable?: boolean;\n /** Comparator used when this column is sorted. */\n sortValue?: (row: T) => string | number;\n width?: string;\n align?: \"left\" | \"right\" | \"center\";\n}\n\nexport interface TableProps<T> {\n columns: Column<T>[];\n data: T[];\n rowKey: (row: T, index: number) => React.Key;\n className?: string;\n}\n\n/**\n * Data-driven table with optional client-side sorting.\n * @example\n * <Table rowKey={(r) => r.id} data={members} columns={[\n * { key: \"name\", header: \"Member\", cell: (r) => r.name, sortable: true, sortValue: (r) => r.name },\n * { key: \"role\", header: \"Role\", cell: (r) => r.role },\n * ]} />\n */\nexport function Table<T>({ columns, data, rowKey, className }: TableProps<T>) {\n const [sort, setSort] = React.useState<{ key: string; dir: \"asc\" | \"desc\" } | null>(null);\n\n const sorted = React.useMemo(() => {\n if (!sort) return data;\n const col = columns.find((c) => c.key === sort.key);\n if (!col?.sortValue) return data;\n const next = [...data].sort((a, b) => {\n const va = col.sortValue!(a);\n const vb = col.sortValue!(b);\n if (va < vb) return sort.dir === \"asc\" ? -1 : 1;\n if (va > vb) return sort.dir === \"asc\" ? 1 : -1;\n return 0;\n });\n return next;\n }, [data, columns, sort]);\n\n const onSort = (col: Column<T>) => {\n if (!col.sortable) return;\n setSort((prev) =>\n prev?.key === col.key\n ? { key: col.key, dir: prev.dir === \"asc\" ? \"desc\" : \"asc\" }\n : { key: col.key, dir: \"asc\" },\n );\n };\n\n return (\n <div className={cx(\"pui-table-wrap\", className)}>\n <table className=\"pui-table\">\n <thead>\n <tr>\n {columns.map((col) => (\n <th\n key={col.key}\n data-sortable={col.sortable || undefined}\n onClick={() => onSort(col)}\n style={{ width: col.width, textAlign: col.align }}\n >\n {col.sortable ? (\n <span className=\"pui-table__sort\">\n {col.header}\n <Sort style={{ width: 13, height: 13 }} />\n </span>\n ) : (\n col.header\n )}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {sorted.map((row, i) => (\n <tr key={rowKey(row, i)}>\n {columns.map((col) => (\n <td key={col.key} style={{ textAlign: col.align }}>\n {col.cell(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { Info, CheckCircle, AlertTriangle, XCircle, X } from \"../icons\";\n\nexport type AlertTone = \"info\" | \"success\" | \"warning\" | \"danger\";\n\nconst ICONS: Record<AlertTone, React.ComponentType<React.SVGProps<SVGSVGElement>>> = {\n info: Info,\n success: CheckCircle,\n warning: AlertTriangle,\n danger: XCircle,\n};\n\nexport interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n tone?: AlertTone;\n title?: React.ReactNode;\n onDismiss?: () => void;\n}\n\n/** Inline banner for four intents. */\nexport function Alert({ tone = \"info\", title, onDismiss, className, children, ...props }: AlertProps) {\n const Icon = ICONS[tone];\n return (\n <div className={cx(\"pui-alert\", className)} data-tone={tone === \"info\" ? undefined : tone} role=\"alert\" {...props}>\n <Icon className=\"pui-alert__icon\" />\n <div style={{ flex: 1 }}>\n {title && <div className=\"pui-alert__title\">{title}</div>}\n {children && <div className=\"pui-alert__body\">{children}</div>}\n </div>\n {onDismiss && (\n <button type=\"button\" className=\"pui-alert__close\" aria-label=\"Dismiss\" onClick={onDismiss}>\n <X style={{ width: 16, height: 16 }} />\n </button>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { CheckCircle, XCircle, Info, X } from \"../icons\";\n\nexport type ToastTone = \"info\" | \"success\" | \"danger\";\n\nexport interface ToastOptions {\n title: React.ReactNode;\n description?: React.ReactNode;\n tone?: ToastTone;\n /** Auto-dismiss after this many ms. Default 4500. 0 = sticky. */\n duration?: number;\n}\n\ninterface ToastItem extends ToastOptions {\n id: number;\n}\n\ninterface ToastContextValue {\n toast: (opts: ToastOptions) => number;\n dismiss: (id: number) => void;\n}\n\nconst ToastContext = React.createContext<ToastContextValue | null>(null);\n\nconst ICONS = { info: Info, success: CheckCircle, danger: XCircle };\n\n/** Wrap your app once; call notifications with the `useToast()` hook. */\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\n const [items, setItems] = React.useState<ToastItem[]>([]);\n const timers = React.useRef<Record<number, ReturnType<typeof setTimeout>>>({});\n\n const dismiss = React.useCallback((id: number) => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n if (timers.current[id]) {\n clearTimeout(timers.current[id]);\n delete timers.current[id];\n }\n }, []);\n\n const toast = React.useCallback(\n (opts: ToastOptions) => {\n const id = Date.now() + Math.random();\n setItems((prev) => [...prev, { id, ...opts }]);\n const duration = opts.duration ?? 4500;\n if (duration > 0) timers.current[id] = setTimeout(() => dismiss(id), duration);\n return id;\n },\n [dismiss],\n );\n\n React.useEffect(() => () => Object.values(timers.current).forEach(clearTimeout), []);\n\n return (\n <ToastContext.Provider value={{ toast, dismiss }}>\n {children}\n <div className=\"pui-toast-region\" role=\"region\" aria-label=\"Notifications\">\n {items.map((t) => {\n const Icon = ICONS[t.tone ?? \"info\"];\n return (\n <div key={t.id} className=\"pui-toast\">\n <span className=\"pui-toast__icon\" data-tone={t.tone ?? \"info\"}>\n <Icon />\n </span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div className=\"pui-toast__title\">{t.title}</div>\n {t.description && <div className=\"pui-toast__desc\">{t.description}</div>}\n </div>\n <button className=\"pui-toast__close\" aria-label=\"Dismiss\" onClick={() => dismiss(t.id)}>\n <X style={{ width: 15, height: 15 }} />\n </button>\n </div>\n );\n })}\n </div>\n </ToastContext.Provider>\n );\n}\n\nexport function useToast(): ToastContextValue {\n const ctx = React.useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a <ToastProvider>\");\n return ctx;\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { X } from \"../icons\";\n\n/* ============================================================\n Tooltip\n ============================================================ */\nexport interface TooltipProps {\n label: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n/** Hover/focus tooltip. Wraps a single focusable child. */\nexport function Tooltip({ label, children, className }: TooltipProps) {\n return (\n <span className={cx(\"pui-tooltip\", className)}>\n {children}\n <span role=\"tooltip\" className=\"pui-tooltip__bubble\">\n {label}\n </span>\n </span>\n );\n}\n\n/* ============================================================\n Hook: close on outside click / Escape\n ============================================================ */\nfunction useDismiss(open: boolean, onClose: () => void) {\n const ref = React.useRef<HTMLDivElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) onClose();\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && onClose();\n document.addEventListener(\"mousedown\", onClick);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onClick);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open, onClose]);\n return ref;\n}\n\n/* ============================================================\n DropdownMenu\n ============================================================ */\nexport interface MenuItem {\n label: React.ReactNode;\n icon?: React.ReactNode;\n onSelect?: () => void;\n tone?: \"default\" | \"danger\";\n}\nexport interface DropdownMenuProps {\n trigger: React.ReactNode;\n children?: React.ReactNode;\n items?: MenuItem[];\n align?: \"start\" | \"end\";\n className?: string;\n}\n/**\n * Click-to-open menu. Provide `items` for a simple list, or `children`\n * for custom content. Closes on outside click and Escape.\n */\nexport function DropdownMenu({ trigger, children, items, align = \"start\", className }: DropdownMenuProps) {\n const [open, setOpen] = React.useState(false);\n const ref = useDismiss(open, () => setOpen(false));\n return (\n <div className={cx(\"pui-menu\", className)} ref={ref}>\n <span onClick={() => setOpen((o) => !o)}>{trigger}</span>\n {open && (\n <div className=\"pui-menu__panel\" data-align={align} role=\"menu\">\n {items\n ? items.map((item, i) => (\n <button\n key={i}\n type=\"button\"\n role=\"menuitem\"\n className=\"pui-menu__item\"\n data-tone={item.tone === \"danger\" ? \"danger\" : undefined}\n onClick={() => {\n item.onSelect?.();\n setOpen(false);\n }}\n >\n {item.icon}\n {item.label}\n </button>\n ))\n : children}\n </div>\n )}\n </div>\n );\n}\n\nexport function MenuSeparator() {\n return <div className=\"pui-menu__sep\" />;\n}\n\n/* ============================================================\n Modal\n ============================================================ */\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n /** Decorative icon shown beside the title. */\n icon?: React.ReactNode;\n}\n/** Overlay dialog. Closes on backdrop click and Escape. */\nexport function Modal({ open, onClose, title, children, footer, icon }: ModalProps) {\n React.useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && onClose();\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, onClose]);\n\n if (!open) return null;\n return (\n <div className=\"pui-overlay\" onClick={onClose}>\n <div className=\"pui-dialog\" role=\"dialog\" aria-modal=\"true\" onClick={(e) => e.stopPropagation()}>\n <div className=\"pui-dialog__head\">\n <div style={{ display: \"flex\", gap: 13, alignItems: \"flex-start\" }}>\n {icon}\n {title && <div className=\"pui-dialog__title\">{title}</div>}\n </div>\n <button type=\"button\" className=\"pui-dialog__close\" aria-label=\"Close\" onClick={onClose}>\n <X style={{ width: 20, height: 20 }} />\n </button>\n </div>\n {children && <div className=\"pui-dialog__body\">{children}</div>}\n {footer && <div className=\"pui-dialog__footer\">{footer}</div>}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cx } from \"../utils\";\nimport { X, Check } from \"../icons\";\n\n/* ============================================================\n Separator\n ============================================================ */\nexport interface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: \"horizontal\" | \"vertical\";\n}\nexport function Separator({ orientation = \"horizontal\", className, ...props }: SeparatorProps) {\n return (\n <div\n role=\"separator\"\n aria-orientation={orientation}\n data-orientation={orientation}\n className={cx(\"pui-separator\", className)}\n {...props}\n />\n );\n}\n\n/* ============================================================\n Kbd\n ============================================================ */\nexport function Kbd({ children, className }: { children: React.ReactNode; className?: string }) {\n return <kbd className={cx(\"pui-kbd\", className)}>{children}</kbd>;\n}\n\n/* ============================================================\n Link\n ============================================================ */\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n external?: boolean;\n}\nexport function Link({ external, className, children, ...props }: LinkProps) {\n return (\n <a\n className={cx(\"pui-link\", className)}\n {...(external ? { target: \"_blank\", rel: \"noreferrer\" } : {})}\n {...props}\n >\n {children}\n </a>\n );\n}\n\n/* ============================================================\n close-on-outside-click / Escape hook\n ============================================================ */\nfunction useDismiss(open: boolean, onClose: () => void) {\n const ref = React.useRef<HTMLDivElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) onClose();\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && onClose();\n document.addEventListener(\"mousedown\", onClick);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onClick);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open, onClose]);\n return ref;\n}\n\n/* ============================================================\n Popover\n ============================================================ */\nexport interface PopoverProps {\n trigger: React.ReactNode;\n children: React.ReactNode;\n align?: \"start\" | \"end\";\n className?: string;\n}\nexport function Popover({ trigger, children, align = \"start\", className }: PopoverProps) {\n const [open, setOpen] = React.useState(false);\n const ref = useDismiss(open, () => setOpen(false));\n return (\n <div className={cx(\"pui-menu\", className)} ref={ref}>\n <span onClick={() => setOpen((o) => !o)}>{trigger}</span>\n {open && (\n <div className=\"pui-popover\" data-align={align} role=\"dialog\">\n {children}\n </div>\n )}\n </div>\n );\n}\n\n/* ============================================================\n Drawer (side sheet)\n ============================================================ */\nexport interface DrawerProps {\n open: boolean;\n onClose: () => void;\n side?: \"left\" | \"right\";\n title?: React.ReactNode;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n}\nexport function Drawer({ open, onClose, side = \"right\", title, children, footer }: DrawerProps) {\n React.useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && onClose();\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, onClose]);\n\n if (!open) return null;\n return (\n <div className=\"pui-drawer-overlay\" onClick={onClose}>\n <div className=\"pui-drawer\" data-side={side} role=\"dialog\" aria-modal=\"true\" onClick={(e) => e.stopPropagation()}>\n <div className=\"pui-drawer__head\">\n {title && <div className=\"pui-drawer__title\">{title}</div>}\n <button type=\"button\" className=\"pui-dialog__close\" aria-label=\"Close\" onClick={onClose}>\n <X style={{ width: 20, height: 20 }} />\n </button>\n </div>\n <div className=\"pui-drawer__body\">{children}</div>\n {footer && <div className=\"pui-drawer__footer\">{footer}</div>}\n </div>\n </div>\n );\n}\n\n/* ============================================================\n ToggleGroup (single-select)\n ============================================================ */\nexport interface ToggleOption {\n value: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n}\nexport interface ToggleGroupProps {\n options: ToggleOption[];\n value: string;\n onValueChange: (value: string) => void;\n className?: string;\n}\nexport function ToggleGroup({ options, value, onValueChange, className }: ToggleGroupProps) {\n return (\n <div className={cx(\"pui-toggle-group\", className)} role=\"group\">\n {options.map((o) => (\n <button\n key={o.value}\n type=\"button\"\n aria-pressed={value === o.value}\n data-active={value === o.value || undefined}\n className=\"pui-toggle\"\n onClick={() => onValueChange(o.value)}\n >\n {o.icon}\n {o.label}\n </button>\n ))}\n </div>\n );\n}\n\n/* ============================================================\n Stepper\n ============================================================ */\nexport interface Step {\n label: React.ReactNode;\n description?: React.ReactNode;\n}\nexport interface StepperProps {\n steps: Step[];\n /** Zero-based index of the active step. Earlier steps render as complete. */\n current: number;\n className?: string;\n}\nexport function Stepper({ steps, current, className }: StepperProps) {\n return (\n <ol className={cx(\"pui-stepper\", className)}>\n {steps.map((s, i) => {\n const state = i < current ? \"done\" : i === current ? \"current\" : \"upcoming\";\n return (\n <li key={i} className=\"pui-step\" data-state={state}>\n <span className=\"pui-step__marker\">{i < current ? <Check /> : i + 1}</span>\n <span className=\"pui-step__body\">\n <span className=\"pui-step__label\">{s.label}</span>\n {s.description && <span className=\"pui-step__desc\">{s.description}</span>}\n </span>\n </li>\n );\n })}\n </ol>\n );\n}\n\n/* ============================================================\n CodeBlock\n ============================================================ */\nexport interface CodeBlockProps {\n code: string;\n filename?: React.ReactNode;\n className?: string;\n}\nexport function CodeBlock({ code, filename, className }: CodeBlockProps) {\n return (\n <div className={cx(\"pui-code\", className)}>\n {filename && <div className=\"pui-code__bar\">{filename}</div>}\n <pre className=\"pui-code__pre\">\n <code>{code}</code>\n </pre>\n </div>\n );\n}\n\n/* ============================================================\n List / ListItem\n ============================================================ */\nexport function List({ children, className }: { children: React.ReactNode; className?: string }) {\n return <ul className={cx(\"pui-list\", className)}>{children}</ul>;\n}\nexport function ListItem({ children, className, ...props }: React.LiHTMLAttributes<HTMLLIElement>) {\n return (\n <li className={cx(\"pui-list-item\", className)} {...props}>\n {children}\n </li>\n );\n}\n"],"mappings":"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","names":["jsx","React","jsx","jsxs","Button","React","jsx","jsxs","Input","SearchInput","Textarea","Select","Checkbox","Switch","React","jsx","jsxs","React","jsx","jsxs","React","jsx","React","jsx","jsxs","React","jsx","jsxs","jsx","jsxs","React","jsx","jsxs","ICONS","React","jsx","jsxs","React","jsx","jsxs","useDismiss"]}
@@ -0,0 +1,416 @@
1
+ /* ============================================================
2
+ paper-ui — warm, accessible component styles
3
+ Import once at your app root: import "paper-ui/styles.css"
4
+ Theme is controlled by a `data-theme="light|dark"` attribute
5
+ on <html> (or any ancestor). See <ThemeProvider>.
6
+ ============================================================ */
7
+
8
+ /* ---- Fonts (optional). The library works with any fonts; these
9
+ close substitutes mirror Anthropic's Styrene / Tiempos feel. ---- */
10
+ @import url("https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700&family=Newsreader:opsz,wght@6..72,400;6..72,500;6..72,600&family=JetBrains+Mono:wght@400;500&display=swap");
11
+
12
+ /* ---- Design tokens ---- */
13
+ [data-theme="light"], :root {
14
+ --pui-bg: #FAF9F5;
15
+ --pui-panel: #F1EEE6;
16
+ --pui-card: #FFFFFF;
17
+ --pui-text: #1A1915;
18
+ --pui-muted: #78746C;
19
+ --pui-border: #E8E3D7;
20
+ --pui-border-strong: #DCD6C7;
21
+ --pui-accent: #CC785C;
22
+ --pui-accent-strong: #B5614A;
23
+ --pui-accent-bg: rgba(204, 120, 92, 0.12);
24
+ --pui-ring: rgba(204, 120, 92, 0.30);
25
+ --pui-green: #3E7B53; --pui-green-bg: rgba(62, 123, 83, 0.12);
26
+ --pui-amber: #946E1E; --pui-amber-bg: rgba(148, 110, 30, 0.14);
27
+ --pui-red: #B14638; --pui-red-bg: rgba(177, 70, 56, 0.12);
28
+ --pui-blue: #42699B; --pui-blue-bg: rgba(66, 105, 155, 0.12);
29
+ --pui-shadow: 0 1px 2px rgba(26, 25, 21, 0.05), 0 10px 28px -14px rgba(26, 25, 21, 0.18);
30
+ --pui-shadow-lg: 0 28px 64px -22px rgba(26, 25, 21, 0.38);
31
+ --pui-code-bg: #211F1B; --pui-code-text: #ECE9DF;
32
+ --pui-skel-a: #EFEBDF; --pui-skel-b: #E2DCCC;
33
+
34
+ /* Scale */
35
+ --pui-radius-sm: 7px;
36
+ --pui-radius: 9px;
37
+ --pui-radius-lg: 14px;
38
+ --pui-radius-xl: 18px;
39
+ --pui-font-sans: "Hanken Grotesk", system-ui, -apple-system, sans-serif;
40
+ --pui-font-serif: "Newsreader", Georgia, serif;
41
+ --pui-font-mono: "JetBrains Mono", ui-monospace, monospace;
42
+ }
43
+
44
+ [data-theme="dark"] {
45
+ --pui-bg: #1A1915;
46
+ --pui-panel: #23211B;
47
+ --pui-card: #272520;
48
+ --pui-text: #F2F0E7;
49
+ --pui-muted: #A39F94;
50
+ --pui-border: #34322B;
51
+ --pui-border-strong: #433F36;
52
+ --pui-accent: #DB8A6E;
53
+ --pui-accent-strong: #E9A488;
54
+ --pui-accent-bg: rgba(219, 138, 110, 0.16);
55
+ --pui-ring: rgba(219, 138, 110, 0.32);
56
+ --pui-green: #5FA277; --pui-green-bg: rgba(95, 162, 119, 0.16);
57
+ --pui-amber: #C9A24E; --pui-amber-bg: rgba(201, 162, 78, 0.16);
58
+ --pui-red: #D87063; --pui-red-bg: rgba(216, 112, 99, 0.16);
59
+ --pui-blue: #7BA0CE; --pui-blue-bg: rgba(123, 160, 206, 0.16);
60
+ --pui-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 10px 30px -14px rgba(0, 0, 0, 0.6);
61
+ --pui-shadow-lg: 0 30px 72px -26px rgba(0, 0, 0, 0.72);
62
+ --pui-code-bg: #121110; --pui-code-text: #ECE9DF;
63
+ --pui-skel-a: #2A2820; --pui-skel-b: #332F26;
64
+ }
65
+
66
+ /* ---- Keyframes ---- */
67
+ @keyframes pui-spin { to { transform: rotate(360deg); } }
68
+ @keyframes pui-indet { 0% { transform: translateX(-100%); } 100% { transform: translateX(320%); } }
69
+ @keyframes pui-toast-in { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
70
+ @keyframes pui-shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
71
+ @keyframes pui-fade { from { opacity: 0; } to { opacity: 1; } }
72
+ @keyframes pui-pop { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }
73
+
74
+ /* ============================================================
75
+ Button
76
+ ============================================================ */
77
+ .pui-btn {
78
+ display: inline-flex; align-items: center; justify-content: center; gap: 8px;
79
+ font-family: var(--pui-font-sans); font-weight: 600; font-size: 14px; line-height: 1;
80
+ border-radius: var(--pui-radius); border: 1px solid transparent;
81
+ padding: 9px 16px; cursor: pointer; white-space: nowrap;
82
+ transition: background .15s ease, border-color .15s ease, filter .15s ease, opacity .15s ease;
83
+ user-select: none;
84
+ }
85
+ .pui-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--pui-ring); }
86
+ .pui-btn:disabled { opacity: .45; cursor: not-allowed; }
87
+ .pui-btn--primary { background: var(--pui-accent); border-color: var(--pui-accent); color: #fff; }
88
+ .pui-btn--primary:not(:disabled):hover { background: var(--pui-accent-strong); border-color: var(--pui-accent-strong); }
89
+ .pui-btn--secondary { background: var(--pui-card); border-color: var(--pui-border-strong); color: var(--pui-text); }
90
+ .pui-btn--secondary:not(:disabled):hover { background: var(--pui-panel); }
91
+ .pui-btn--outline { background: transparent; border-color: var(--pui-accent); color: var(--pui-accent); }
92
+ .pui-btn--outline:not(:disabled):hover { background: var(--pui-accent-bg); }
93
+ .pui-btn--ghost { background: transparent; color: var(--pui-text); }
94
+ .pui-btn--ghost:not(:disabled):hover { background: var(--pui-panel); }
95
+ .pui-btn--danger { background: var(--pui-red); border-color: var(--pui-red); color: #fff; }
96
+ .pui-btn--danger:not(:disabled):hover { filter: brightness(.94); }
97
+ .pui-btn--sm { padding: 6px 12px; font-size: 13px; border-radius: var(--pui-radius-sm); }
98
+ .pui-btn--lg { padding: 12px 22px; font-size: 15px; border-radius: var(--pui-radius-lg); }
99
+ .pui-btn--icon { padding: 0; width: 38px; height: 38px; }
100
+ .pui-btn--icon.pui-btn--sm { width: 32px; height: 32px; }
101
+ .pui-btn--block { width: 100%; }
102
+ .pui-btn__spinner { width: 15px; height: 15px; border-radius: 999px; border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; animation: pui-spin .7s linear infinite; }
103
+ .pui-btn--secondary .pui-btn__spinner, .pui-btn--ghost .pui-btn__spinner, .pui-btn--outline .pui-btn__spinner { border-color: var(--pui-border-strong); border-top-color: var(--pui-accent); }
104
+ .pui-icon { width: 1em; height: 1em; flex-shrink: 0; }
105
+
106
+ /* ============================================================
107
+ Form fields
108
+ ============================================================ */
109
+ .pui-field { display: flex; flex-direction: column; gap: 7px; }
110
+ .pui-label { font-family: var(--pui-font-sans); font-size: 13px; font-weight: 600; color: var(--pui-text); }
111
+ .pui-hint { font-size: 12px; color: var(--pui-muted); }
112
+ .pui-error { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--pui-red); }
113
+ .pui-input, .pui-textarea, .pui-select {
114
+ width: 100%; font-family: var(--pui-font-sans); font-size: 14px; color: var(--pui-text);
115
+ background: var(--pui-bg); border: 1px solid var(--pui-border-strong); border-radius: var(--pui-radius);
116
+ padding: 10px 13px; transition: border-color .15s ease, box-shadow .15s ease;
117
+ }
118
+ .pui-textarea { resize: vertical; line-height: 1.55; }
119
+ .pui-input:focus, .pui-textarea:focus, .pui-select:focus { outline: none; border-color: var(--pui-accent); box-shadow: 0 0 0 3px var(--pui-ring); }
120
+ .pui-input::placeholder, .pui-textarea::placeholder { color: var(--pui-muted); }
121
+ .pui-input--invalid, .pui-textarea--invalid { border-color: var(--pui-red); box-shadow: 0 0 0 3px var(--pui-red-bg); }
122
+ .pui-input:disabled, .pui-textarea:disabled, .pui-select:disabled { opacity: .55; cursor: not-allowed; }
123
+ .pui-input-wrap { position: relative; display: flex; align-items: center; }
124
+ .pui-input-wrap .pui-input { padding-left: 36px; }
125
+ .pui-input-wrap__icon { position: absolute; left: 12px; width: 16px; height: 16px; color: var(--pui-muted); pointer-events: none; }
126
+ .pui-select-wrap { position: relative; }
127
+ .pui-select { appearance: none; padding-right: 38px; cursor: pointer; }
128
+ .pui-select-wrap__caret { position: absolute; right: 13px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--pui-muted); pointer-events: none; }
129
+
130
+ /* Checkbox & radio */
131
+ .pui-checkbox, .pui-radio-card { display: flex; align-items: center; gap: 11px; font-family: var(--pui-font-sans); font-size: 14px; color: var(--pui-text); cursor: pointer; }
132
+ .pui-checkbox input, .pui-radio-card input { position: absolute; opacity: 0; width: 0; height: 0; }
133
+ .pui-checkbox__box { width: 20px; height: 20px; flex-shrink: 0; border-radius: 6px; border: 1px solid var(--pui-border-strong); background: var(--pui-bg); display: flex; align-items: center; justify-content: center; transition: background .12s, border-color .12s; }
134
+ .pui-checkbox__box svg { width: 14px; height: 14px; color: #fff; opacity: 0; }
135
+ .pui-checkbox input:checked + .pui-checkbox__box { background: var(--pui-accent); border-color: var(--pui-accent); }
136
+ .pui-checkbox input:checked + .pui-checkbox__box svg { opacity: 1; }
137
+ .pui-checkbox input:focus-visible + .pui-checkbox__box { box-shadow: 0 0 0 3px var(--pui-ring); }
138
+ .pui-checkbox--disabled { opacity: .5; cursor: not-allowed; }
139
+
140
+ .pui-radio-group { display: flex; flex-direction: column; gap: 10px; }
141
+ .pui-radio-card { padding: 13px 15px; border-radius: var(--pui-radius-lg); border: 1.5px solid var(--pui-border-strong); background: var(--pui-bg); transition: border-color .12s, background .12s; }
142
+ .pui-radio-card__dot { width: 19px; height: 19px; flex-shrink: 0; border-radius: 999px; border: 2px solid var(--pui-border-strong); display: flex; align-items: center; justify-content: center; transition: border-color .12s, background .12s; }
143
+ .pui-radio-card__dot::after { content: ""; width: 8px; height: 8px; border-radius: 999px; background: #fff; transform: scale(0); transition: transform .12s; }
144
+ .pui-radio-card input:checked ~ .pui-radio-card__dot { border-color: var(--pui-accent); background: var(--pui-accent); }
145
+ .pui-radio-card input:checked ~ .pui-radio-card__dot::after { transform: scale(1); }
146
+ .pui-radio-card:has(input:checked) { border-color: var(--pui-accent); background: var(--pui-accent-bg); }
147
+ .pui-radio-card__title { font-weight: 600; font-size: 14px; }
148
+ .pui-radio-card__desc { display: block; font-size: 12.5px; color: var(--pui-muted); }
149
+
150
+ /* Switch */
151
+ .pui-switch { display: inline-flex; align-items: center; cursor: pointer; }
152
+ .pui-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
153
+ .pui-switch__track { width: 42px; height: 24px; border-radius: 999px; background: var(--pui-border-strong); position: relative; transition: background .15s; flex-shrink: 0; }
154
+ .pui-switch__track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 999px; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: left .15s; }
155
+ .pui-switch input:checked + .pui-switch__track { background: var(--pui-accent); }
156
+ .pui-switch input:checked + .pui-switch__track::after { left: 20px; }
157
+ .pui-switch input:focus-visible + .pui-switch__track { box-shadow: 0 0 0 3px var(--pui-ring); }
158
+
159
+ /* Slider */
160
+ .pui-slider { width: 100%; }
161
+ .pui-slider__row { position: relative; height: 24px; display: flex; align-items: center; }
162
+ .pui-slider__track { position: absolute; left: 0; right: 0; height: 6px; border-radius: 999px; background: var(--pui-panel); }
163
+ .pui-slider__fill { position: absolute; left: 0; height: 6px; border-radius: 999px; background: var(--pui-accent); }
164
+ .pui-slider input[type="range"] { position: absolute; left: 0; right: 0; width: 100%; margin: 0; height: 24px; background: transparent; -webkit-appearance: none; appearance: none; cursor: pointer; }
165
+ .pui-slider input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 999px; background: #fff; border: 2px solid var(--pui-accent); box-shadow: var(--pui-shadow); cursor: grab; }
166
+ .pui-slider input[type="range"]::-moz-range-thumb { width: 18px; height: 18px; border-radius: 999px; background: #fff; border: 2px solid var(--pui-accent); cursor: grab; }
167
+
168
+ /* ============================================================
169
+ Badge / Tag
170
+ ============================================================ */
171
+ .pui-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; font-family: var(--pui-font-sans); font-size: 12px; font-weight: 600; color: var(--pui-text); background: var(--pui-panel); }
172
+ .pui-badge__dot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; }
173
+ .pui-badge[data-tone="green"] { color: var(--pui-green); background: var(--pui-green-bg); }
174
+ .pui-badge[data-tone="amber"] { color: var(--pui-amber); background: var(--pui-amber-bg); }
175
+ .pui-badge[data-tone="red"] { color: var(--pui-red); background: var(--pui-red-bg); }
176
+ .pui-badge[data-tone="blue"] { color: var(--pui-blue); background: var(--pui-blue-bg); }
177
+ .pui-badge[data-tone="accent"] { color: var(--pui-accent); background: var(--pui-accent-bg); }
178
+ .pui-badge[data-solid="true"] { color: #fff; background: var(--pui-accent); }
179
+ .pui-badge[data-solid="true"][data-tone="green"] { background: var(--pui-green); }
180
+ .pui-badge[data-solid="true"][data-tone="red"] { background: var(--pui-red); }
181
+ .pui-tag { display: inline-flex; align-items: center; gap: 7px; padding: 4px 8px 4px 12px; border-radius: 999px; font-family: var(--pui-font-sans); font-size: 12.5px; font-weight: 600; color: var(--pui-text); background: var(--pui-panel); border: 1px solid var(--pui-border-strong); }
182
+ .pui-tag__close { width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center; background: var(--pui-border-strong); border: none; border-radius: 999px; color: var(--pui-text); cursor: pointer; padding: 0; }
183
+ .pui-tag__close svg { width: 11px; height: 11px; }
184
+
185
+ /* ============================================================
186
+ Avatar
187
+ ============================================================ */
188
+ .pui-avatar { position: relative; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; font-family: var(--pui-font-sans); font-weight: 600; color: var(--pui-accent); background: var(--pui-accent-bg); overflow: visible; flex-shrink: 0; }
189
+ .pui-avatar img { width: 100%; height: 100%; border-radius: 999px; object-fit: cover; }
190
+ .pui-avatar[data-size="sm"] { width: 28px; height: 28px; font-size: 11px; }
191
+ .pui-avatar[data-size="md"] { width: 38px; height: 38px; font-size: 14px; }
192
+ .pui-avatar[data-size="lg"] { width: 48px; height: 48px; font-size: 17px; }
193
+ .pui-avatar[data-tone="blue"] { color: var(--pui-blue); background: var(--pui-blue-bg); }
194
+ .pui-avatar[data-tone="green"] { color: var(--pui-green); background: var(--pui-green-bg); }
195
+ .pui-avatar[data-tone="amber"] { color: var(--pui-amber); background: var(--pui-amber-bg); }
196
+ .pui-avatar__status { position: absolute; right: 1px; bottom: 1px; width: 30%; height: 30%; border-radius: 999px; border: 2.5px solid var(--pui-card); }
197
+ .pui-avatar__status[data-status="online"] { background: var(--pui-green); }
198
+ .pui-avatar__status[data-status="busy"] { background: var(--pui-red); }
199
+ .pui-avatar__status[data-status="away"] { background: var(--pui-amber); }
200
+ .pui-avatar-group { display: flex; }
201
+ .pui-avatar-group > .pui-avatar { border: 2.5px solid var(--pui-card); }
202
+ .pui-avatar-group > .pui-avatar + .pui-avatar { margin-left: -12px; }
203
+ .pui-avatar-group__more { color: var(--pui-muted); background: var(--pui-panel); }
204
+
205
+ /* ============================================================
206
+ Card / Stat
207
+ ============================================================ */
208
+ .pui-card { background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-xl); box-shadow: var(--pui-shadow); }
209
+ .pui-card--pad { padding: 22px; }
210
+ .pui-stat { border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); padding: 16px 18px; background: var(--pui-card); }
211
+ .pui-stat__label { font-size: 12.5px; color: var(--pui-muted); margin-bottom: 8px; }
212
+ .pui-stat__value { font-family: var(--pui-font-serif); font-size: 30px; font-weight: 500; letter-spacing: -.01em; color: var(--pui-text); }
213
+ .pui-stat__delta { display: inline-flex; align-items: center; gap: 4px; margin-top: 6px; font-size: 12px; font-weight: 600; }
214
+ .pui-stat__delta[data-dir="up"] { color: var(--pui-green); }
215
+ .pui-stat__delta[data-dir="down"] { color: var(--pui-red); }
216
+
217
+ /* ============================================================
218
+ Accordion
219
+ ============================================================ */
220
+ .pui-accordion { background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); box-shadow: var(--pui-shadow); overflow: hidden; }
221
+ .pui-accordion__item + .pui-accordion__item { border-top: 1px solid var(--pui-border); }
222
+ .pui-accordion__trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 22px; background: none; border: none; font-family: var(--pui-font-sans); font-weight: 600; font-size: 15px; color: var(--pui-text); cursor: pointer; text-align: left; }
223
+ .pui-accordion__trigger:hover { background: var(--pui-panel); }
224
+ .pui-accordion__chevron { width: 18px; height: 18px; color: var(--pui-muted); transition: transform .2s ease; flex-shrink: 0; }
225
+ .pui-accordion__item[data-open="true"] .pui-accordion__chevron { transform: rotate(180deg); }
226
+ .pui-accordion__panel { padding: 0 22px 20px; font-size: 14px; color: var(--pui-muted); line-height: 1.6; }
227
+
228
+ /* ============================================================
229
+ Tabs
230
+ ============================================================ */
231
+ .pui-tabs__list { display: flex; gap: 24px; padding: 0 22px; border-bottom: 1px solid var(--pui-border); }
232
+ .pui-tabs__tab { padding: 14px 2px; margin-bottom: -1px; background: none; border: none; border-bottom: 2px solid transparent; font-family: var(--pui-font-sans); font-weight: 500; font-size: 14px; color: var(--pui-muted); cursor: pointer; }
233
+ .pui-tabs__tab:hover { color: var(--pui-text); }
234
+ .pui-tabs__tab[data-active="true"] { color: var(--pui-text); font-weight: 600; border-bottom-color: var(--pui-accent); }
235
+ .pui-tabs__panel { padding: 22px; font-size: 14px; color: var(--pui-muted); line-height: 1.6; }
236
+
237
+ /* ============================================================
238
+ Table
239
+ ============================================================ */
240
+ .pui-table-wrap { background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); box-shadow: var(--pui-shadow); overflow: hidden; }
241
+ .pui-table { width: 100%; border-collapse: collapse; font-family: var(--pui-font-sans); }
242
+ .pui-table thead th { text-align: left; padding: 12px 20px; background: var(--pui-panel); font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--pui-muted); }
243
+ .pui-table th[data-sortable="true"] { cursor: pointer; }
244
+ .pui-table th .pui-table__sort { display: inline-flex; align-items: center; gap: 5px; }
245
+ .pui-table tbody td { padding: 13px 20px; border-top: 1px solid var(--pui-border); font-size: 14px; color: var(--pui-text); vertical-align: middle; }
246
+ .pui-table tbody tr:hover td { background: var(--pui-panel); }
247
+
248
+ /* ============================================================
249
+ Alert
250
+ ============================================================ */
251
+ .pui-alert { display: flex; gap: 13px; padding: 15px 18px; border-radius: var(--pui-radius-lg); background: var(--pui-blue-bg); border: 1px solid color-mix(in srgb, var(--pui-blue) 30%, transparent); }
252
+ .pui-alert__icon { width: 20px; height: 20px; flex-shrink: 0; color: var(--pui-blue); }
253
+ .pui-alert__title { font-weight: 600; font-size: 14px; color: var(--pui-blue); }
254
+ .pui-alert__body { font-size: 13.5px; color: var(--pui-text); opacity: .85; margin-top: 2px; line-height: 1.5; }
255
+ .pui-alert__close { background: none; border: none; cursor: pointer; padding: 2px; height: fit-content; color: inherit; }
256
+ .pui-alert[data-tone="success"] { background: var(--pui-green-bg); border-color: color-mix(in srgb, var(--pui-green) 30%, transparent); }
257
+ .pui-alert[data-tone="success"] .pui-alert__icon, .pui-alert[data-tone="success"] .pui-alert__title { color: var(--pui-green); }
258
+ .pui-alert[data-tone="warning"] { background: var(--pui-amber-bg); border-color: color-mix(in srgb, var(--pui-amber) 30%, transparent); }
259
+ .pui-alert[data-tone="warning"] .pui-alert__icon, .pui-alert[data-tone="warning"] .pui-alert__title { color: var(--pui-amber); }
260
+ .pui-alert[data-tone="danger"] { background: var(--pui-red-bg); border-color: color-mix(in srgb, var(--pui-red) 30%, transparent); }
261
+ .pui-alert[data-tone="danger"] .pui-alert__icon, .pui-alert[data-tone="danger"] .pui-alert__title { color: var(--pui-red); }
262
+
263
+ /* ============================================================
264
+ Toast
265
+ ============================================================ */
266
+ .pui-toast-region { position: fixed; right: 22px; bottom: 22px; z-index: 90; display: flex; flex-direction: column; gap: 11px; width: 320px; max-width: calc(100vw - 44px); }
267
+ .pui-toast { display: flex; gap: 11px; padding: 14px 15px; background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); box-shadow: var(--pui-shadow-lg); animation: pui-toast-in .25s cubic-bezier(.2,.9,.3,1); }
268
+ .pui-toast__icon { width: 30px; height: 30px; border-radius: var(--pui-radius-sm); flex-shrink: 0; display: flex; align-items: center; justify-content: center; background: var(--pui-accent-bg); color: var(--pui-accent); }
269
+ .pui-toast__icon[data-tone="success"] { background: var(--pui-green-bg); color: var(--pui-green); }
270
+ .pui-toast__icon[data-tone="danger"] { background: var(--pui-red-bg); color: var(--pui-red); }
271
+ .pui-toast__icon[data-tone="info"] { background: var(--pui-blue-bg); color: var(--pui-blue); }
272
+ .pui-toast__icon svg { width: 16px; height: 16px; }
273
+ .pui-toast__title { font-weight: 600; font-size: 13.5px; color: var(--pui-text); }
274
+ .pui-toast__desc { font-size: 12.5px; color: var(--pui-muted); margin-top: 1px; line-height: 1.45; }
275
+ .pui-toast__close { background: none; border: none; color: var(--pui-muted); cursor: pointer; padding: 1px; height: fit-content; }
276
+
277
+ /* ============================================================
278
+ Tooltip
279
+ ============================================================ */
280
+ .pui-tooltip { position: relative; display: inline-flex; }
281
+ .pui-tooltip__bubble { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(5px); background: var(--pui-text); color: var(--pui-bg); padding: 6px 11px; border-radius: var(--pui-radius-sm); font-family: var(--pui-font-sans); font-size: 12.5px; font-weight: 500; white-space: nowrap; box-shadow: var(--pui-shadow); opacity: 0; pointer-events: none; transition: opacity .15s ease, transform .15s ease; z-index: 70; }
282
+ .pui-tooltip:hover .pui-tooltip__bubble, .pui-tooltip:focus-within .pui-tooltip__bubble { opacity: 1; transform: translateX(-50%) translateY(0); }
283
+ .pui-tooltip__bubble::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--pui-text); }
284
+
285
+ /* ============================================================
286
+ Dropdown menu
287
+ ============================================================ */
288
+ .pui-menu { position: relative; display: inline-flex; }
289
+ .pui-menu__panel { position: absolute; top: calc(100% + 6px); min-width: 200px; background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); box-shadow: var(--pui-shadow-lg); padding: 6px; z-index: 60; animation: pui-pop .14s ease; }
290
+ .pui-menu__panel[data-align="end"] { right: 0; }
291
+ .pui-menu__panel[data-align="start"] { left: 0; }
292
+ .pui-menu__item { width: 100%; display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--pui-radius-sm); font-family: var(--pui-font-sans); font-size: 13.5px; color: var(--pui-text); background: none; border: none; cursor: pointer; text-align: left; }
293
+ .pui-menu__item:hover { background: var(--pui-panel); }
294
+ .pui-menu__item[data-tone="danger"] { color: var(--pui-red); }
295
+ .pui-menu__item[data-tone="danger"]:hover { background: var(--pui-red-bg); }
296
+ .pui-menu__item svg { width: 16px; height: 16px; }
297
+ .pui-menu__sep { height: 1px; background: var(--pui-border); margin: 4px 0; }
298
+ .pui-menu__label { padding: 8px 10px 9px; }
299
+
300
+ /* ============================================================
301
+ Modal
302
+ ============================================================ */
303
+ .pui-overlay { position: fixed; inset: 0; z-index: 80; background: rgba(20,18,14,.5); backdrop-filter: blur(3px); display: flex; align-items: center; justify-content: center; padding: 24px; animation: pui-fade .15s ease; }
304
+ .pui-dialog { width: 100%; max-width: 440px; background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-xl); box-shadow: var(--pui-shadow-lg); padding: 26px; animation: pui-pop .18s ease; }
305
+ .pui-dialog__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
306
+ .pui-dialog__title { font-family: var(--pui-font-serif); font-size: 20px; font-weight: 500; color: var(--pui-text); }
307
+ .pui-dialog__close { background: none; border: none; color: var(--pui-muted); cursor: pointer; padding: 2px; }
308
+ .pui-dialog__body { font-size: 14px; color: var(--pui-muted); line-height: 1.6; margin: 14px 0 22px; }
309
+ .pui-dialog__footer { display: flex; justify-content: flex-end; gap: 10px; }
310
+
311
+ /* ============================================================
312
+ Breadcrumbs / Pagination / Segmented
313
+ ============================================================ */
314
+ .pui-breadcrumbs { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-family: var(--pui-font-sans); font-size: 13.5px; color: var(--pui-muted); }
315
+ .pui-breadcrumbs a { font-weight: 500; }
316
+ .pui-breadcrumbs a:hover { color: var(--pui-text); }
317
+ .pui-breadcrumbs__sep { width: 14px; height: 14px; color: var(--pui-border-strong); }
318
+ .pui-breadcrumbs__current { font-weight: 600; color: var(--pui-text); }
319
+
320
+ .pui-pagination { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-family: var(--pui-font-sans); }
321
+ .pui-pagination__btn { min-width: 36px; height: 36px; padding: 0 10px; display: inline-flex; align-items: center; justify-content: center; gap: 5px; border-radius: var(--pui-radius-sm); border: 1px solid var(--pui-border); background: var(--pui-card); color: var(--pui-text); font-size: 14px; font-weight: 500; cursor: pointer; }
322
+ .pui-pagination__btn:hover:not(:disabled) { background: var(--pui-panel); }
323
+ .pui-pagination__btn:disabled { opacity: .45; cursor: not-allowed; }
324
+ .pui-pagination__btn[data-active="true"] { background: var(--pui-accent); border-color: var(--pui-accent); color: #fff; font-weight: 600; }
325
+ .pui-pagination__ellipsis { color: var(--pui-muted); padding: 0 4px; }
326
+ .pui-pagination__btn svg { width: 15px; height: 15px; }
327
+
328
+ .pui-segmented { display: inline-flex; gap: 3px; padding: 3px; background: var(--pui-panel); border-radius: var(--pui-radius-lg); }
329
+ .pui-segmented__btn { padding: 7px 16px; border-radius: var(--pui-radius-sm); border: none; background: transparent; color: var(--pui-muted); font-family: var(--pui-font-sans); font-weight: 500; font-size: 13px; cursor: pointer; }
330
+ .pui-segmented__btn[data-active="true"] { background: var(--pui-card); color: var(--pui-text); font-weight: 600; box-shadow: var(--pui-shadow); }
331
+
332
+ /* ============================================================
333
+ Progress / Spinner / Skeleton / EmptyState
334
+ ============================================================ */
335
+ .pui-progress { height: 8px; border-radius: 999px; background: var(--pui-panel); overflow: hidden; }
336
+ .pui-progress__bar { height: 100%; border-radius: 999px; background: var(--pui-accent); transition: width .3s ease; }
337
+ .pui-progress[data-indeterminate="true"] { position: relative; }
338
+ .pui-progress[data-indeterminate="true"] .pui-progress__bar { position: absolute; width: 30%; animation: pui-indet 1.3s ease-in-out infinite; }
339
+ .pui-spinner { display: inline-block; border-radius: 999px; border: 3px solid var(--pui-panel); border-top-color: var(--pui-accent); animation: pui-spin .8s linear infinite; width: 30px; height: 30px; }
340
+ .pui-skeleton { border-radius: 6px; background: linear-gradient(90deg, var(--pui-skel-a) 25%, var(--pui-skel-b) 37%, var(--pui-skel-a) 63%); background-size: 200% 100%; animation: pui-shimmer 1.4s linear infinite; }
341
+ .pui-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 38px 26px; background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); }
342
+ .pui-empty__icon { width: 54px; height: 54px; border-radius: var(--pui-radius-lg); background: var(--pui-panel); display: flex; align-items: center; justify-content: center; color: var(--pui-muted); margin-bottom: 6px; }
343
+ .pui-empty__title { font-weight: 600; font-size: 16px; color: var(--pui-text); }
344
+ .pui-empty__desc { font-size: 13.5px; color: var(--pui-muted); max-width: 34ch; }
345
+
346
+ /* ============================================================
347
+ Separator / Kbd / Link
348
+ ============================================================ */
349
+ .pui-separator { background: var(--pui-border); border: none; }
350
+ .pui-separator[data-orientation="horizontal"] { height: 1px; width: 100%; }
351
+ .pui-separator[data-orientation="vertical"] { width: 1px; align-self: stretch; min-height: 1em; }
352
+ .pui-kbd { display: inline-flex; align-items: center; padding: 2px 7px; font-family: var(--pui-font-mono); font-size: 12px; color: var(--pui-muted); background: var(--pui-panel); border: 1px solid var(--pui-border-strong); border-bottom-width: 2px; border-radius: 6px; }
353
+ .pui-link { color: var(--pui-accent); font-weight: 500; border-bottom: 1px solid transparent; cursor: pointer; }
354
+ .pui-link:hover { border-bottom-color: currentColor; }
355
+
356
+ /* ============================================================
357
+ Popover
358
+ ============================================================ */
359
+ .pui-popover { position: absolute; top: calc(100% + 6px); min-width: 220px; background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); box-shadow: var(--pui-shadow-lg); padding: 14px; z-index: 60; animation: pui-pop .14s ease; }
360
+ .pui-popover[data-align="end"] { right: 0; }
361
+ .pui-popover[data-align="start"] { left: 0; }
362
+
363
+ /* ============================================================
364
+ Drawer
365
+ ============================================================ */
366
+ @keyframes pui-drawer-r { from { transform: translateX(100%); } to { transform: none; } }
367
+ @keyframes pui-drawer-l { from { transform: translateX(-100%); } to { transform: none; } }
368
+ .pui-drawer-overlay { position: fixed; inset: 0; z-index: 80; background: rgba(20, 18, 14, .5); backdrop-filter: blur(3px); display: flex; animation: pui-fade .15s ease; }
369
+ .pui-drawer { position: absolute; top: 0; bottom: 0; width: 380px; max-width: calc(100vw - 48px); background: var(--pui-card); box-shadow: var(--pui-shadow-lg); padding: 22px; display: flex; flex-direction: column; }
370
+ .pui-drawer[data-side="right"] { right: 0; border-left: 1px solid var(--pui-border); animation: pui-drawer-r .2s cubic-bezier(.2,.9,.3,1); }
371
+ .pui-drawer[data-side="left"] { left: 0; border-right: 1px solid var(--pui-border); animation: pui-drawer-l .2s cubic-bezier(.2,.9,.3,1); }
372
+ .pui-drawer__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
373
+ .pui-drawer__title { font-family: var(--pui-font-serif); font-size: 19px; font-weight: 500; color: var(--pui-text); }
374
+ .pui-drawer__body { flex: 1; overflow: auto; font-size: 14px; color: var(--pui-muted); line-height: 1.6; }
375
+ .pui-drawer__footer { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
376
+
377
+ /* ============================================================
378
+ ToggleGroup
379
+ ============================================================ */
380
+ .pui-toggle-group { display: inline-flex; border: 1px solid var(--pui-border-strong); border-radius: var(--pui-radius); overflow: hidden; }
381
+ .pui-toggle { display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px; background: var(--pui-card); border: none; border-right: 1px solid var(--pui-border-strong); font-family: var(--pui-font-sans); font-size: 13px; font-weight: 600; color: var(--pui-muted); cursor: pointer; }
382
+ .pui-toggle:last-child { border-right: none; }
383
+ .pui-toggle:hover { background: var(--pui-panel); }
384
+ .pui-toggle[data-active="true"] { background: var(--pui-accent-bg); color: var(--pui-accent); }
385
+ .pui-toggle svg { width: 16px; height: 16px; }
386
+
387
+ /* ============================================================
388
+ Stepper
389
+ ============================================================ */
390
+ .pui-stepper { list-style: none; margin: 0; padding: 0; }
391
+ .pui-step { display: flex; gap: 13px; padding-bottom: 22px; position: relative; }
392
+ .pui-step:last-child { padding-bottom: 0; }
393
+ .pui-step:not(:last-child)::before { content: ""; position: absolute; left: 13px; top: 30px; bottom: 4px; width: 2px; background: var(--pui-border); }
394
+ .pui-step[data-state="done"]:not(:last-child)::before { background: var(--pui-accent); }
395
+ .pui-step__marker { width: 28px; height: 28px; flex-shrink: 0; border-radius: 999px; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; background: var(--pui-panel); color: var(--pui-muted); border: 2px solid var(--pui-border); z-index: 1; }
396
+ .pui-step__marker svg { width: 15px; height: 15px; }
397
+ .pui-step[data-state="current"] .pui-step__marker,
398
+ .pui-step[data-state="done"] .pui-step__marker { background: var(--pui-accent); color: #fff; border-color: var(--pui-accent); }
399
+ .pui-step__label { display: block; font-weight: 600; font-size: 14px; color: var(--pui-text); }
400
+ .pui-step[data-state="upcoming"] .pui-step__label { color: var(--pui-muted); }
401
+ .pui-step__desc { font-size: 13px; color: var(--pui-muted); }
402
+
403
+ /* ============================================================
404
+ CodeBlock
405
+ ============================================================ */
406
+ .pui-code { background: var(--pui-code-bg); border-radius: var(--pui-radius-lg); overflow: hidden; }
407
+ .pui-code__bar { padding: 9px 16px; border-bottom: 1px solid rgba(255, 255, 255, .07); font-family: var(--pui-font-mono); font-size: 12px; color: var(--pui-muted); }
408
+ .pui-code__pre { margin: 0; padding: 16px 18px; overflow: auto; font-family: var(--pui-font-mono); font-size: 12.5px; line-height: 1.7; color: var(--pui-code-text); }
409
+
410
+ /* ============================================================
411
+ List
412
+ ============================================================ */
413
+ .pui-list { list-style: none; margin: 0; padding: 0; background: var(--pui-card); border: 1px solid var(--pui-border); border-radius: var(--pui-radius-lg); box-shadow: var(--pui-shadow); overflow: hidden; }
414
+ .pui-list-item { display: flex; align-items: center; gap: 12px; padding: 13px 16px; font-size: 14px; color: var(--pui-text); }
415
+ .pui-list-item + .pui-list-item { border-top: 1px solid var(--pui-border); }
416
+ .pui-list-item:hover { background: var(--pui-panel); }