@xonic0506/sonic-ui 0.1.0 → 0.3.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.
Files changed (64) hide show
  1. package/AI-RULES.md +1 -1
  2. package/DESIGN.md +505 -16
  3. package/README.md +87 -38
  4. package/dist/components/accordion.d.ts +30 -0
  5. package/dist/components/accordion.js +44 -0
  6. package/dist/components/alert-dialog.d.ts +16 -0
  7. package/dist/components/alert-dialog.js +46 -0
  8. package/dist/components/badge.d.ts +8 -0
  9. package/dist/components/badge.js +77 -0
  10. package/dist/components/button.d.ts +11 -2
  11. package/dist/components/button.js +24 -14
  12. package/dist/components/checkbox.d.ts +30 -0
  13. package/dist/components/checkbox.js +48 -0
  14. package/dist/components/dialog.d.ts +11 -0
  15. package/dist/components/dialog.js +17 -14
  16. package/dist/components/empty-state.d.ts +11 -0
  17. package/dist/components/empty-state.js +17 -0
  18. package/dist/components/error-state.d.ts +12 -0
  19. package/dist/components/error-state.js +24 -0
  20. package/dist/components/field.d.ts +13 -0
  21. package/dist/components/field.js +33 -0
  22. package/dist/components/file-upload.d.ts +57 -0
  23. package/dist/components/file-upload.js +238 -0
  24. package/dist/components/input.d.ts +1 -0
  25. package/dist/components/input.js +5 -5
  26. package/dist/components/link.d.ts +9 -0
  27. package/dist/components/link.js +30 -0
  28. package/dist/components/menu.d.ts +33 -0
  29. package/dist/components/menu.js +44 -0
  30. package/dist/components/popover.d.ts +26 -0
  31. package/dist/components/popover.js +50 -0
  32. package/dist/components/popup-styles.d.ts +3 -0
  33. package/dist/components/popup-styles.js +5 -0
  34. package/dist/components/progress.d.ts +16 -0
  35. package/dist/components/progress.js +27 -0
  36. package/dist/components/radio-group.d.ts +20 -0
  37. package/dist/components/radio-group.js +40 -0
  38. package/dist/components/select.d.ts +30 -0
  39. package/dist/components/select.js +66 -0
  40. package/dist/components/separator.d.ts +7 -0
  41. package/dist/components/separator.js +14 -0
  42. package/dist/components/skeleton.d.ts +8 -0
  43. package/dist/components/skeleton.js +22 -0
  44. package/dist/components/state-layout.d.ts +11 -0
  45. package/dist/components/state-layout.js +31 -0
  46. package/dist/components/switch.d.ts +12 -0
  47. package/dist/components/switch.js +24 -0
  48. package/dist/components/table.d.ts +24 -0
  49. package/dist/components/table.js +46 -0
  50. package/dist/components/tabs.d.ts +31 -0
  51. package/dist/components/tabs.js +41 -0
  52. package/dist/components/textarea.d.ts +6 -0
  53. package/dist/components/textarea.js +20 -0
  54. package/dist/components/toast.d.ts +24 -0
  55. package/dist/components/toast.js +62 -0
  56. package/dist/components/toggle-group.d.ts +36 -0
  57. package/dist/components/toggle-group.js +44 -0
  58. package/dist/components/tooltip.d.ts +11 -0
  59. package/dist/components/tooltip.js +19 -0
  60. package/dist/index.d.ts +23 -0
  61. package/dist/index.js +28 -5
  62. package/dist/styles.css +2 -2
  63. package/dist/tailwind.css +15 -0
  64. package/package.json +9 -2
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { cn as e } from "../lib/cn.js";
3
+ import { Button as t } from "./button.js";
4
+ import * as n from "react";
5
+ import { CircleAlert as r, CircleCheck as i, Info as a, TriangleAlert as o, X as s } from "lucide-react";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ import { Toast as u } from "@base-ui/react/toast";
8
+ //#region src/components/toast.tsx
9
+ var d = {
10
+ neutral: /* @__PURE__ */ c(a, { className: "sn:text-muted" }),
11
+ success: /* @__PURE__ */ c(i, { className: "sn:text-success" }),
12
+ warning: /* @__PURE__ */ c(o, { className: "sn:text-warning" }),
13
+ danger: /* @__PURE__ */ c(r, { className: "sn:text-danger" })
14
+ };
15
+ function f() {
16
+ let { add: e, close: t } = u.useToastManager();
17
+ return n.useMemo(() => ({
18
+ add: ({ tone: t = "neutral", ...n }) => e({
19
+ ...n,
20
+ type: t,
21
+ priority: t === "danger" ? "high" : "low"
22
+ }),
23
+ close: (e) => t(e)
24
+ }), [e, t]);
25
+ }
26
+ function p({ timeout: e, children: t }) {
27
+ return /* @__PURE__ */ l(u.Provider, {
28
+ timeout: e,
29
+ children: [t, /* @__PURE__ */ c(u.Portal, { children: /* @__PURE__ */ c(u.Viewport, {
30
+ "aria-label": "알림",
31
+ className: "sn:fixed sn:right-4 sn:bottom-4 sn:z-50 sn:flex sn:w-90 sn:max-w-[calc(100vw-2*var(--sn-space-4))] sn:flex-col-reverse sn:gap-2 sn:outline-none",
32
+ children: /* @__PURE__ */ c(m, {})
33
+ }) })]
34
+ });
35
+ }
36
+ function m() {
37
+ let { toasts: n } = u.useToastManager();
38
+ return n.map((n) => /* @__PURE__ */ l(u.Root, {
39
+ toast: n,
40
+ className: "sn:box-border sn:flex sn:items-start sn:gap-3 sn:rounded-lg sn:border sn:border-default sn:bg-surface sn:p-3 sn:font-sans sn:text-default sn:transition-[opacity,translate] sn:duration-(--sn-duration-normal) sn:ease-standard sn:focus-visible:outline-2 sn:focus-visible:outline-offset-2 sn:focus-visible:outline-focus sn:data-starting-style:translate-y-2 sn:data-starting-style:opacity-0 sn:data-ending-style:translate-y-2 sn:data-ending-style:opacity-0 sn:data-limited:hidden sn:motion-reduce:transition-none",
41
+ children: [
42
+ /* @__PURE__ */ c("span", {
43
+ className: "sn:flex sn:h-7 sn:shrink-0 sn:items-center sn:[&_svg]:size-4",
44
+ children: d[n.type ?? "neutral"]
45
+ }),
46
+ /* @__PURE__ */ l("div", {
47
+ className: "sn:flex sn:min-w-0 sn:flex-1 sn:flex-col sn:gap-1 sn:pt-1",
48
+ children: [/* @__PURE__ */ c(u.Title, { className: "sn:m-0 sn:text-body-strong sn:text-default" }), /* @__PURE__ */ c(u.Description, { className: e("sn:m-0 sn:text-caption sn:text-muted", !n.description && "sn:hidden") })]
49
+ }),
50
+ /* @__PURE__ */ c(u.Close, {
51
+ render: /* @__PURE__ */ c(t, {
52
+ size: "icon-sm",
53
+ variant: "ghost",
54
+ "aria-label": "알림 닫기"
55
+ }),
56
+ children: /* @__PURE__ */ c(s, {})
57
+ })
58
+ ]
59
+ }, n.id));
60
+ }
61
+ //#endregion
62
+ export { p as ToastProvider, f as useToast };
@@ -0,0 +1,36 @@
1
+ import * as React from 'react';
2
+ interface ToggleGroupBaseProps {
3
+ disabled?: boolean;
4
+ className?: string;
5
+ 'aria-label'?: string;
6
+ children?: React.ReactNode;
7
+ }
8
+ /** 단일은 항상 하나가 눌려 있어요(다시 눌러도 꺼지지 않음). multiple이면 값이 배열이에요 */
9
+ export type ToggleGroupProps = ToggleGroupBaseProps & ({
10
+ multiple?: false;
11
+ value?: string;
12
+ defaultValue?: string;
13
+ onValueChange?: (value: string) => void;
14
+ } | {
15
+ multiple: true;
16
+ value?: string[];
17
+ defaultValue?: string[];
18
+ onValueChange?: (value: string[]) => void;
19
+ });
20
+ export declare function ToggleGroup(props: ToggleGroupProps): React.JSX.Element;
21
+ interface ToggleGroupItemBaseProps {
22
+ value: string;
23
+ disabled?: boolean;
24
+ className?: string;
25
+ children?: React.ReactNode;
26
+ }
27
+ /** 아이콘만 있는 항목은 읽을 글자가 없어서 aria-label이 필수예요 */
28
+ export type ToggleGroupItemProps = ToggleGroupItemBaseProps & ({
29
+ iconOnly?: false;
30
+ 'aria-label'?: string;
31
+ } | {
32
+ iconOnly: true;
33
+ 'aria-label': string;
34
+ });
35
+ export declare const ToggleGroupItem: React.ForwardRefExoticComponent<ToggleGroupItemProps & React.RefAttributes<HTMLButtonElement>>;
36
+ export {};
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { cn as e } from "../lib/cn.js";
3
+ import * as t from "react";
4
+ import { jsx as n } from "react/jsx-runtime";
5
+ import { ToggleGroup as r } from "@base-ui/react/toggle-group";
6
+ import { Toggle as i } from "@base-ui/react/toggle";
7
+ //#region src/components/toggle-group.tsx
8
+ var a = "sn:inline-flex sn:items-center sn:rounded-md sn:bg-subtle sn:p-1";
9
+ function o(i) {
10
+ let { disabled: o, className: s, children: c } = i, [l, u] = t.useState(i.multiple ? void 0 : i.defaultValue), d = {
11
+ disabled: o,
12
+ "aria-label": i["aria-label"],
13
+ className: e(a, s)
14
+ };
15
+ if (i.multiple) return /* @__PURE__ */ n(r, {
16
+ ...d,
17
+ multiple: !0,
18
+ value: i.value,
19
+ defaultValue: i.defaultValue,
20
+ onValueChange: i.onValueChange && ((e) => i.onValueChange(e)),
21
+ children: c
22
+ });
23
+ let f = i.value === void 0 ? l : i.value;
24
+ return /* @__PURE__ */ n(r, {
25
+ ...d,
26
+ value: f === void 0 ? [] : [f],
27
+ onValueChange: (e) => {
28
+ e.length && (u(e[0]), i.onValueChange?.(e[0]));
29
+ },
30
+ children: c
31
+ });
32
+ }
33
+ var s = "sn:box-border sn:inline-flex sn:h-6 sn:items-center sn:justify-center sn:gap-1 sn:rounded-sm sn:border sn:border-transparent sn:bg-transparent sn:px-2 sn:font-sans sn:text-label sn:text-muted sn:cursor-pointer sn:select-none sn:transition-colors sn:duration-(--sn-duration-fast) sn:ease-standard sn:hover:not-data-disabled:text-default sn:data-pressed:border-default sn:data-pressed:bg-surface sn:data-pressed:text-default sn:focus-visible:outline-2 sn:focus-visible:-outline-offset-2 sn:focus-visible:outline-focus sn:data-disabled:cursor-not-allowed sn:data-disabled:opacity-(--sn-opacity-disabled) sn:motion-reduce:transition-none sn:[&_svg]:size-4 sn:[&_svg]:shrink-0", c = t.forwardRef(function({ value: t, disabled: r, iconOnly: a, className: o, children: c, ...l }, u) {
34
+ return /* @__PURE__ */ n(i, {
35
+ ref: u,
36
+ value: t,
37
+ disabled: r,
38
+ "aria-label": l["aria-label"],
39
+ className: e(s, a && "sn:w-6 sn:px-0", o),
40
+ children: c
41
+ });
42
+ });
43
+ //#endregion
44
+ export { o as ToggleGroup, c as ToggleGroupItem };
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ export interface TooltipProps {
3
+ /** 보여 줄 짧은 이름. 중요한 정보나 클릭할 요소는 넣지 않아요 */
4
+ content: React.ReactNode;
5
+ side?: 'top' | 'bottom' | 'left' | 'right';
6
+ className?: string;
7
+ /** 대상 요소 하나 (보통 아이콘 버튼) */
8
+ children: React.ReactElement;
9
+ }
10
+ /** 마우스는 600ms 뒤, 키보드 포커스는 바로 보여요 */
11
+ export declare function Tooltip({ content, side, className, children }: TooltipProps): React.JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { cn as e } from "../lib/cn.js";
3
+ import "react";
4
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
5
+ import { Tooltip as r } from "@base-ui/react/tooltip";
6
+ //#region src/components/tooltip.tsx
7
+ function i({ content: i, side: a = "top", className: o, children: s }) {
8
+ return /* @__PURE__ */ n(r.Root, { children: [/* @__PURE__ */ t(r.Trigger, { render: s }), /* @__PURE__ */ t(r.Portal, { children: /* @__PURE__ */ t(r.Positioner, {
9
+ side: a,
10
+ sideOffset: 4,
11
+ className: "sn:z-50",
12
+ children: /* @__PURE__ */ t(r.Popup, {
13
+ className: e("sn:origin-(--transform-origin) sn:rounded-md sn:bg-inverse sn:px-2 sn:py-1 sn:font-sans sn:text-caption sn:text-inverse sn:transition-[opacity,scale] sn:duration-(--sn-duration-fast) sn:ease-standard sn:data-starting-style:scale-98 sn:data-starting-style:opacity-0 sn:data-ending-style:scale-98 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none", o),
14
+ children: i
15
+ })
16
+ }) })] });
17
+ }
18
+ //#endregion
19
+ export { i as Tooltip };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,29 @@
1
1
  export { Button, type ButtonProps } from './components/button';
2
2
  export { Input, type InputProps } from './components/input';
3
+ export { Textarea, type TextareaProps } from './components/textarea';
4
+ export { Checkbox, CheckboxGroup, type CheckboxProps, type CheckboxGroupProps } from './components/checkbox';
5
+ export { RadioGroup, Radio, type RadioGroupProps, type RadioProps } from './components/radio-group';
6
+ export { Switch, type SwitchProps } from './components/switch';
7
+ export { Select, type SelectProps, type SelectOption } from './components/select';
3
8
  export { Text, type TextProps, type TextVariant } from './components/text';
4
9
  export { Card, CardHeader, CardTitle, CardDescription, CardBody, CardFooter, type CardProps } from './components/card';
5
10
  export { Avatar, type AvatarProps } from './components/avatar';
11
+ export { Field, type FieldProps } from './components/field';
12
+ export { Skeleton, type SkeletonProps } from './components/skeleton';
13
+ export { EmptyState, type EmptyStateProps } from './components/empty-state';
14
+ export { ErrorState, type ErrorStateProps } from './components/error-state';
6
15
  export { Dialog, DialogTrigger, DialogPopup, DialogTitle, DialogDescription, DialogClose, DialogFooter, type DialogProps, type DialogButtonProps, type DialogPopupProps, } from './components/dialog';
16
+ export { AlertDialog, AlertDialogTrigger, AlertDialogPopup, AlertDialogTitle, AlertDialogDescription, AlertDialogClose, AlertDialogFooter, } from './components/alert-dialog';
17
+ export { Menu, MenuTrigger, MenuPopup, MenuItem, MenuSeparator, type MenuProps, type MenuTriggerProps, type MenuPopupProps, type MenuItemProps } from './components/menu';
18
+ export { Popover, PopoverTrigger, PopoverPopup, PopoverTitle, PopoverDescription, PopoverClose, type PopoverProps, type PopoverPopupProps } from './components/popover';
19
+ export { Tooltip, type TooltipProps } from './components/tooltip';
20
+ export { Tabs, TabsList, Tab, TabsPanel, type TabsProps, type TabsListProps, type TabProps } from './components/tabs';
21
+ export { Separator, type SeparatorProps } from './components/separator';
22
+ export { ToastProvider, useToast, type ToastProviderProps, type ToastOptions, type ToastTone } from './components/toast';
23
+ export { Badge, type BadgeProps } from './components/badge';
24
+ export { Progress, type ProgressProps } from './components/progress';
25
+ export { Link, type LinkProps } from './components/link';
26
+ export { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from './components/table';
27
+ export { ToggleGroup, ToggleGroupItem, type ToggleGroupProps, type ToggleGroupItemProps } from './components/toggle-group';
28
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionPanel, type AccordionProps, type AccordionItemProps } from './components/accordion';
29
+ export { FileDropzone, FileList, formatBytes, type FileDropzoneProps, type FileListProps, type FileItemData, type FileRejection } from './components/file-upload';
package/dist/index.js CHANGED
@@ -1,8 +1,31 @@
1
1
  "use client";
2
2
  import { Button as e } from "./components/button.js";
3
3
  import { Input as t } from "./components/input.js";
4
- import { Text as n } from "./components/text.js";
5
- import { Card as r, CardBody as i, CardDescription as a, CardFooter as o, CardHeader as s, CardTitle as c } from "./components/card.js";
6
- import { Avatar as l } from "./components/avatar.js";
7
- import { Dialog as u, DialogClose as d, DialogDescription as f, DialogFooter as p, DialogPopup as m, DialogTitle as h, DialogTrigger as g } from "./components/dialog.js";
8
- export { l as Avatar, e as Button, r as Card, i as CardBody, a as CardDescription, o as CardFooter, s as CardHeader, c as CardTitle, u as Dialog, d as DialogClose, f as DialogDescription, p as DialogFooter, m as DialogPopup, h as DialogTitle, g as DialogTrigger, t as Input, n as Text };
4
+ import { Textarea as n } from "./components/textarea.js";
5
+ import { Checkbox as r, CheckboxGroup as i } from "./components/checkbox.js";
6
+ import { Radio as a, RadioGroup as o } from "./components/radio-group.js";
7
+ import { Switch as s } from "./components/switch.js";
8
+ import { Select as c } from "./components/select.js";
9
+ import { Text as l } from "./components/text.js";
10
+ import { Card as u, CardBody as d, CardDescription as f, CardFooter as p, CardHeader as m, CardTitle as h } from "./components/card.js";
11
+ import { Avatar as g } from "./components/avatar.js";
12
+ import { Field as _ } from "./components/field.js";
13
+ import { Skeleton as v } from "./components/skeleton.js";
14
+ import { EmptyState as y } from "./components/empty-state.js";
15
+ import { ErrorState as b } from "./components/error-state.js";
16
+ import { Dialog as x, DialogClose as S, DialogDescription as C, DialogFooter as w, DialogPopup as T, DialogTitle as E, DialogTrigger as D } from "./components/dialog.js";
17
+ import { AlertDialog as O, AlertDialogClose as k, AlertDialogDescription as A, AlertDialogFooter as j, AlertDialogPopup as M, AlertDialogTitle as N, AlertDialogTrigger as P } from "./components/alert-dialog.js";
18
+ import { Menu as F, MenuItem as I, MenuPopup as L, MenuSeparator as R, MenuTrigger as z } from "./components/menu.js";
19
+ import { Popover as B, PopoverClose as V, PopoverDescription as H, PopoverPopup as U, PopoverTitle as W, PopoverTrigger as G } from "./components/popover.js";
20
+ import { Tooltip as K } from "./components/tooltip.js";
21
+ import { Tab as q, Tabs as J, TabsList as Y, TabsPanel as X } from "./components/tabs.js";
22
+ import { Separator as Z } from "./components/separator.js";
23
+ import { ToastProvider as Q, useToast as $ } from "./components/toast.js";
24
+ import { Badge as ee } from "./components/badge.js";
25
+ import { Progress as te } from "./components/progress.js";
26
+ import { Link as ne } from "./components/link.js";
27
+ import { Table as re, TableBody as ie, TableCell as ae, TableHead as oe, TableHeader as se, TableRow as ce } from "./components/table.js";
28
+ import { ToggleGroup as le, ToggleGroupItem as ue } from "./components/toggle-group.js";
29
+ import { Accordion as de, AccordionItem as fe, AccordionPanel as pe, AccordionTrigger as me } from "./components/accordion.js";
30
+ import { FileDropzone as he, FileList as ge, formatBytes as _e } from "./components/file-upload.js";
31
+ export { de as Accordion, fe as AccordionItem, pe as AccordionPanel, me as AccordionTrigger, O as AlertDialog, k as AlertDialogClose, A as AlertDialogDescription, j as AlertDialogFooter, M as AlertDialogPopup, N as AlertDialogTitle, P as AlertDialogTrigger, g as Avatar, ee as Badge, e as Button, u as Card, d as CardBody, f as CardDescription, p as CardFooter, m as CardHeader, h as CardTitle, r as Checkbox, i as CheckboxGroup, x as Dialog, S as DialogClose, C as DialogDescription, w as DialogFooter, T as DialogPopup, E as DialogTitle, D as DialogTrigger, y as EmptyState, b as ErrorState, _ as Field, he as FileDropzone, ge as FileList, t as Input, ne as Link, F as Menu, I as MenuItem, L as MenuPopup, R as MenuSeparator, z as MenuTrigger, B as Popover, V as PopoverClose, H as PopoverDescription, U as PopoverPopup, W as PopoverTitle, G as PopoverTrigger, te as Progress, a as Radio, o as RadioGroup, c as Select, Z as Separator, v as Skeleton, s as Switch, q as Tab, re as Table, ie as TableBody, ae as TableCell, oe as TableHead, se as TableHeader, ce as TableRow, J as Tabs, Y as TabsList, X as TabsPanel, l as Text, n as Textarea, Q as ToastProvider, le as ToggleGroup, ue as ToggleGroupItem, K as Tooltip, _e as formatBytes, $ as useToast };
package/dist/styles.css CHANGED
@@ -1,3 +1,3 @@
1
1
  /*! sonic-ui | 전체가 @layer sonic 안에 있어요. 쓰는 쪽: @layer theme, base, sonic, components, utilities; */
2
- @property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@layer sonic{/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
3
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-duration:initial;--tw-ease:initial;--tw-outline-style:solid;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme;@layer utilities{.sn\:fixed{position:fixed}.sn\:inset-0{inset:0}.sn\:top-1\/2{top:50%}.sn\:left-1\/2{left:50%}.sn\:z-50{z-index:50}.sn\:m-0{margin:0}.sn\:-mt-3{margin-top:calc(var(--sn-space-1) * -3)}.sn\:mt-2{margin-top:calc(var(--sn-space-1) * 2)}.sn\:mb-0{margin-bottom:0}.sn\:box-border{box-sizing:border-box}.sn\:flex{display:flex}.sn\:inline-flex{display:inline-flex}.sn\:size-6{width:calc(var(--sn-space-1) * 6);height:calc(var(--sn-space-1) * 6)}.sn\:size-8{width:calc(var(--sn-space-1) * 8);height:calc(var(--sn-space-1) * 8)}.sn\:size-10{width:calc(var(--sn-space-1) * 10);height:calc(var(--sn-space-1) * 10)}.sn\:size-full{width:100%;height:100%}.sn\:h-7{height:calc(var(--sn-space-1) * 7)}.sn\:h-8{height:calc(var(--sn-space-1) * 8)}.sn\:h-10{height:calc(var(--sn-space-1) * 10)}.sn\:w-110{width:calc(var(--sn-space-1) * 110)}.sn\:w-full{width:100%}.sn\:max-w-\[calc\(100vw-2\*var\(--sn-space-4\)\)\]{max-width:calc(100vw - 2 * var(--sn-space-4))}.sn\:min-w-0{min-width:0}.sn\:shrink-0{flex-shrink:0}.sn\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:cursor-pointer{cursor:pointer}.sn\:flex-col{flex-direction:column}.sn\:flex-wrap{flex-wrap:wrap}.sn\:items-center{align-items:center}.sn\:items-start{align-items:flex-start}.sn\:justify-center{justify-content:center}.sn\:justify-end{justify-content:flex-end}.sn\:gap-1{gap:var(--sn-space-1)}.sn\:gap-2{gap:calc(var(--sn-space-1) * 2)}.sn\:gap-4{gap:calc(var(--sn-space-1) * 4)}.sn\:gap-6{gap:calc(var(--sn-space-1) * 6)}.sn\:gap-10{gap:calc(var(--sn-space-1) * 10)}.sn\:overflow-hidden{overflow:hidden}.sn\:rounded-full{border-radius:var(--sn-radius-full)}.sn\:rounded-lg{border-radius:var(--sn-radius-lg)}.sn\:rounded-md{border-radius:var(--sn-radius-md)}.sn\:border{border-style:var(--tw-border-style);border-width:1px}.sn\:border-default{border-color:var(--sn-color-border-default)}.sn\:border-transparent{border-color:#0000}.sn\:bg-canvas{background-color:var(--sn-color-bg-canvas)}.sn\:bg-danger{background-color:var(--sn-color-bg-danger)}.sn\:bg-overlay{background-color:var(--sn-color-bg-overlay)}.sn\:bg-primary{background-color:var(--sn-color-bg-primary)}.sn\:bg-subtle{background-color:var(--sn-color-bg-subtle)}.sn\:bg-surface{background-color:var(--sn-color-bg-surface)}.sn\:bg-transparent{background-color:#0000}.sn\:object-cover{object-fit:cover}.sn\:p-4{padding:calc(var(--sn-space-1) * 4)}.sn\:p-5{padding:calc(var(--sn-space-1) * 5)}.sn\:p-6{padding:calc(var(--sn-space-1) * 6)}.sn\:px-2{padding-inline:calc(var(--sn-space-1) * 2)}.sn\:px-3{padding-inline:calc(var(--sn-space-1) * 3)}.sn\:px-4{padding-inline:calc(var(--sn-space-1) * 4)}.sn\:align-middle{vertical-align:middle}.sn\:font-mono{font-family:var(--sn-font-mono)}.sn\:font-sans{font-family:var(--sn-font-sans)}.sn\:text-body{font-size:var(--sn-text-body);line-height:var(--tw-leading,var(--sn-text-body--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-body--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-body--font-weight))}.sn\:text-body-strong{font-size:var(--sn-text-body-strong);line-height:var(--tw-leading,var(--sn-text-body-strong--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-body-strong--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-body-strong--font-weight))}.sn\:text-caption{font-size:var(--sn-text-caption);line-height:var(--tw-leading,var(--sn-text-caption--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-caption--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-caption--font-weight))}.sn\:text-display{font-size:var(--sn-text-display);line-height:var(--tw-leading,var(--sn-text-display--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-display--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-display--font-weight))}.sn\:text-label{font-size:var(--sn-text-label);line-height:var(--tw-leading,var(--sn-text-label--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-label--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-label--font-weight))}.sn\:text-title{font-size:var(--sn-text-title);line-height:var(--tw-leading,var(--sn-text-title--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-title--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-title--font-weight))}.sn\:whitespace-nowrap{white-space:nowrap}.sn\:text-danger{color:var(--sn-color-text-danger)}.sn\:text-default{color:var(--sn-color-text-default)}.sn\:text-muted{color:var(--sn-color-text-muted)}.sn\:text-on-danger{color:var(--sn-color-text-on-danger)}.sn\:text-on-primary{color:var(--sn-color-text-on-primary)}.sn\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.sn\:transition-\[opacity\,scale\]{transition-property:opacity,scale;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:duration-\(--sn-duration-fast\){--tw-duration:var(--sn-duration-fast);transition-duration:var(--sn-duration-fast)}.sn\:duration-\(--sn-duration-normal\){--tw-duration:var(--sn-duration-normal);transition-duration:var(--sn-duration-normal)}.sn\:ease-standard{--tw-ease:var(--sn-easing-standard);transition-timing-function:var(--sn-easing-standard)}.sn\:outline-none{--tw-outline-style:none;outline-style:none}.sn\:select-none{-webkit-user-select:none;user-select:none}.sn\:placeholder\:text-muted::placeholder{color:var(--sn-color-text-muted)}@media (hover:hover){.sn\:hover\:not-data-disabled\:border-strong:hover:not([data-disabled]){border-color:var(--sn-color-border-strong)}.sn\:hover\:not-data-disabled\:bg-primary-hover:hover:not([data-disabled]){background-color:var(--sn-color-bg-primary-hover)}.sn\:hover\:not-data-disabled\:bg-subtle:hover:not([data-disabled]){background-color:var(--sn-color-bg-subtle)}}.sn\:focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.sn\:focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.sn\:focus-visible\:outline-focus:focus-visible{outline-color:var(--sn-color-border-focus)}.sn\:aria-invalid\:border-danger[aria-invalid=true]{border-color:var(--sn-color-border-danger)}@media (hover:hover){.sn\:hover\:aria-invalid\:border-danger:hover[aria-invalid=true]{border-color:var(--sn-color-border-danger)}}.sn\:data-disabled\:cursor-not-allowed[data-disabled]{cursor:not-allowed}.sn\:data-disabled\:opacity-\(--sn-opacity-disabled\)[data-disabled]{opacity:var(--sn-opacity-disabled)}.sn\:data-ending-style\:scale-98[data-ending-style]{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x) var(--tw-scale-y)}.sn\:data-ending-style\:opacity-0[data-ending-style]{opacity:0}.sn\:data-invalid\:border-danger[data-invalid]{border-color:var(--sn-color-border-danger)}.sn\:data-starting-style\:scale-98[data-starting-style]{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x) var(--tw-scale-y)}.sn\:data-starting-style\:opacity-0[data-starting-style]{opacity:0}@media (prefers-reduced-motion:reduce){.sn\:motion-reduce\:transition-none{transition-property:none}}}:root{--sn-space-0:0px;--sn-space-1:4px;--sn-space-2:8px;--sn-space-3:12px;--sn-space-4:16px;--sn-space-5:20px;--sn-space-6:24px;--sn-space-7:28px;--sn-space-8:32px;--sn-space-10:40px;--sn-space-12:48px;--sn-space-16:64px;--sn-radius-sm:2px;--sn-radius-md:4px;--sn-radius-lg:6px;--sn-radius-full:9999px;--sn-stroke-default:1px;--sn-stroke-focus:2px;--sn-duration-fast:.12s;--sn-duration-normal:.2s;--sn-easing-standard:cubic-bezier(.2, 0, 0, 1);--sn-opacity-disabled:.45;--sn-font-sans:"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;--sn-font-mono:"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--sn-text-display:32px;--sn-text-display--line-height:40px;--sn-text-display--font-weight:600;--sn-text-display--letter-spacing:-.02em;--sn-text-title:20px;--sn-text-title--line-height:28px;--sn-text-title--font-weight:600;--sn-text-title--letter-spacing:-.01em;--sn-text-body:14px;--sn-text-body--line-height:20px;--sn-text-body--font-weight:400;--sn-text-body--letter-spacing:0em;--sn-text-body-strong:14px;--sn-text-body-strong--line-height:20px;--sn-text-body-strong--font-weight:500;--sn-text-body-strong--letter-spacing:0em;--sn-text-label:13px;--sn-text-label--line-height:16px;--sn-text-label--font-weight:500;--sn-text-label--letter-spacing:0em;--sn-text-caption:12px;--sn-text-caption--line-height:16px;--sn-text-caption--font-weight:400;--sn-text-caption--letter-spacing:0em;--sn-text-mono:14px;--sn-text-mono--line-height:20px;--sn-text-mono--font-weight:400;--sn-text-mono--letter-spacing:0em;--sn-text-mono-caption:12px;--sn-text-mono-caption--line-height:16px;--sn-text-mono-caption--font-weight:400;--sn-text-mono-caption--letter-spacing:0em}:root,[data-theme=light]{color-scheme:light;--sn-color-bg-canvas:#f4f6f8;--sn-color-bg-surface:#fff;--sn-color-bg-subtle:#e6eaee;--sn-color-bg-primary:#2340d0;--sn-color-bg-primary-hover:#1b33ae;--sn-color-bg-danger:#c8312b;--sn-color-bg-overlay:#0e121680;--sn-color-text-default:#0e1216;--sn-color-text-muted:#5b6672;--sn-color-text-on-primary:#fff;--sn-color-text-on-danger:#fff;--sn-color-text-danger:#c8312b;--sn-color-border-default:#d5dbe1;--sn-color-border-strong:#8d99a6;--sn-color-border-focus:#2340d0;--sn-color-border-danger:#c8312b}[data-theme=dark]{color-scheme:dark;--sn-color-bg-canvas:#0e1216;--sn-color-bg-surface:#161b21;--sn-color-bg-subtle:#1e252d;--sn-color-bg-primary:#6e86ff;--sn-color-bg-primary-hover:#8c9fff;--sn-color-bg-danger:#f06a5f;--sn-color-bg-overlay:#0e121680;--sn-color-text-default:#e6eaee;--sn-color-text-muted:#8d99a6;--sn-color-text-on-primary:#0e1216;--sn-color-text-on-danger:#0e1216;--sn-color-text-danger:#f06a5f;--sn-color-border-default:#2a323b;--sn-color-border-strong:#5b6672;--sn-color-border-focus:#6e86ff;--sn-color-border-danger:#f06a5f}}
2
+ @property --tw-border-spacing-x{syntax:"<length>";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:"<length>";inherits:false;initial-value:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@layer sonic{/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
3
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-duration:initial;--tw-ease:initial;--tw-outline-style:solid;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme;@layer utilities{.sn\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.sn\:absolute{position:absolute}.sn\:fixed{position:fixed}.sn\:relative{position:relative}.sn\:inset-0{inset:0}.sn\:top-1\/2{top:50%}.sn\:right-4{right:calc(var(--sn-space-1) * 4)}.sn\:bottom-4{bottom:calc(var(--sn-space-1) * 4)}.sn\:bottom-\[-1px\]{bottom:-1px}.sn\:left-0{left:0}.sn\:left-1\/2{left:50%}.sn\:z-50{z-index:50}.sn\:m-0{margin:0}.sn\:my-1{margin-block:var(--sn-space-1)}.sn\:-mt-2{margin-top:calc(var(--sn-space-1) * -2)}.sn\:-mt-3{margin-top:calc(var(--sn-space-1) * -3)}.sn\:mt-2{margin-top:calc(var(--sn-space-1) * 2)}.sn\:mb-0{margin-bottom:0}.sn\:ml-1{margin-left:var(--sn-space-1)}.sn\:box-border{box-sizing:border-box}.sn\:block{display:block}.sn\:flex{display:flex}.sn\:hidden{display:none}.sn\:inline-block{display:inline-block}.sn\:inline-flex{display:inline-flex}.sn\:size-2{width:calc(var(--sn-space-1) * 2);height:calc(var(--sn-space-1) * 2)}.sn\:size-3{width:calc(var(--sn-space-1) * 3);height:calc(var(--sn-space-1) * 3)}.sn\:size-4{width:calc(var(--sn-space-1) * 4);height:calc(var(--sn-space-1) * 4)}.sn\:size-6{width:calc(var(--sn-space-1) * 6);height:calc(var(--sn-space-1) * 6)}.sn\:size-7{width:calc(var(--sn-space-1) * 7);height:calc(var(--sn-space-1) * 7)}.sn\:size-8{width:calc(var(--sn-space-1) * 8);height:calc(var(--sn-space-1) * 8)}.sn\:size-10{width:calc(var(--sn-space-1) * 10);height:calc(var(--sn-space-1) * 10)}.sn\:size-12{width:calc(var(--sn-space-1) * 12);height:calc(var(--sn-space-1) * 12)}.sn\:size-24{width:calc(var(--sn-space-1) * 24);height:calc(var(--sn-space-1) * 24)}.sn\:size-full{width:100%;height:100%}.sn\:h-\(--accordion-panel-height\){height:var(--accordion-panel-height)}.sn\:h-0\.5{height:calc(var(--sn-space-1) * .5)}.sn\:h-1{height:var(--sn-space-1)}.sn\:h-3{height:calc(var(--sn-space-1) * 3)}.sn\:h-4{height:calc(var(--sn-space-1) * 4)}.sn\:h-5{height:calc(var(--sn-space-1) * 5)}.sn\:h-6{height:calc(var(--sn-space-1) * 6)}.sn\:h-7{height:calc(var(--sn-space-1) * 7)}.sn\:h-8{height:calc(var(--sn-space-1) * 8)}.sn\:h-10{height:calc(var(--sn-space-1) * 10)}.sn\:h-16{height:calc(var(--sn-space-1) * 16)}.sn\:h-full{height:100%}.sn\:h-px{height:1px}.sn\:max-h-\(--available-height\){max-height:var(--available-height)}.sn\:min-h-20{min-height:calc(var(--sn-space-1) * 20)}.sn\:w-\(--active-tab-width\){width:var(--active-tab-width)}.sn\:w-6{width:calc(var(--sn-space-1) * 6)}.sn\:w-7{width:calc(var(--sn-space-1) * 7)}.sn\:w-24{width:calc(var(--sn-space-1) * 24)}.sn\:w-80{width:calc(var(--sn-space-1) * 80)}.sn\:w-90{width:calc(var(--sn-space-1) * 90)}.sn\:w-110{width:calc(var(--sn-space-1) * 110)}.sn\:w-full{width:100%}.sn\:w-px{width:1px}.sn\:max-w-\[calc\(100vw-2\*var\(--sn-space-4\)\)\]{max-width:calc(100vw - 2 * var(--sn-space-4))}.sn\:min-w-\(--anchor-width\){min-width:var(--anchor-width)}.sn\:min-w-0{min-width:0}.sn\:min-w-48{min-width:calc(var(--sn-space-1) * 48)}.sn\:flex-1{flex:1}.sn\:shrink-0{flex-shrink:0}.sn\:border-separate{border-collapse:separate}.sn\:border-spacing-0{--tw-border-spacing-x:0px;--tw-border-spacing-y:0px;border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y)}.sn\:origin-\(--transform-origin\){transform-origin:var(--transform-origin)}.sn\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:translate-x-\(--active-tab-left\){--tw-translate-x:var(--active-tab-left);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:animate-\[sn-pulse_var\(--sn-duration-loop\)_ease-in-out_infinite\]{animation:sn-pulse var(--sn-duration-loop) ease-in-out infinite}.sn\:animate-\[sn-spin_var\(--sn-duration-loop\)_linear_infinite\]{animation:sn-spin var(--sn-duration-loop) linear infinite}.sn\:cursor-default{cursor:default}.sn\:cursor-not-allowed{cursor:not-allowed}.sn\:cursor-pointer{cursor:pointer}.sn\:resize-y{resize:vertical}.sn\:list-none{list-style-type:none}.sn\:flex-col{flex-direction:column}.sn\:flex-col-reverse{flex-direction:column-reverse}.sn\:flex-wrap{flex-wrap:wrap}.sn\:items-center{align-items:center}.sn\:items-start{align-items:flex-start}.sn\:justify-between{justify-content:space-between}.sn\:justify-center{justify-content:center}.sn\:justify-end{justify-content:flex-end}.sn\:gap-1{gap:var(--sn-space-1)}.sn\:gap-2{gap:calc(var(--sn-space-1) * 2)}.sn\:gap-3{gap:calc(var(--sn-space-1) * 3)}.sn\:gap-4{gap:calc(var(--sn-space-1) * 4)}.sn\:gap-6{gap:calc(var(--sn-space-1) * 6)}.sn\:gap-10{gap:calc(var(--sn-space-1) * 10)}.sn\:self-stretch{align-self:stretch}.sn\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.sn\:overflow-hidden{overflow:hidden}.sn\:overflow-x-auto{overflow-x:auto}.sn\:overflow-y-auto{overflow-y:auto}.sn\:rounded-full{border-radius:var(--sn-radius-full)}.sn\:rounded-lg{border-radius:var(--sn-radius-lg)}.sn\:rounded-md{border-radius:var(--sn-radius-md)}.sn\:rounded-sm{border-radius:var(--sn-radius-sm)}.sn\:border{border-style:var(--tw-border-style);border-width:1px}.sn\:border-0{border-style:var(--tw-border-style);border-width:0}.sn\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.sn\:border-dashed{--tw-border-style:dashed;border-style:dashed}.sn\:border-danger{border-color:var(--sn-color-border-danger)}.sn\:border-default{border-color:var(--sn-color-border-default)}.sn\:border-strong{border-color:var(--sn-color-border-strong)}.sn\:border-transparent{border-color:#0000}.sn\:bg-\(--sn-color-border-default\){background-color:var(--sn-color-border-default)}.sn\:bg-\(--sn-color-text-on-primary\){background-color:var(--sn-color-text-on-primary)}.sn\:bg-canvas{background-color:var(--sn-color-bg-canvas)}.sn\:bg-danger{background-color:var(--sn-color-bg-danger)}.sn\:bg-danger-subtle{background-color:var(--sn-color-bg-danger-subtle)}.sn\:bg-inverse{background-color:var(--sn-color-bg-inverse)}.sn\:bg-overlay{background-color:var(--sn-color-bg-overlay)}.sn\:bg-primary{background-color:var(--sn-color-bg-primary)}.sn\:bg-subtle{background-color:var(--sn-color-bg-subtle)}.sn\:bg-success{background-color:var(--sn-color-bg-success)}.sn\:bg-success-subtle{background-color:var(--sn-color-bg-success-subtle)}.sn\:bg-surface{background-color:var(--sn-color-bg-surface)}.sn\:bg-transparent{background-color:#0000}.sn\:bg-warning{background-color:var(--sn-color-bg-warning)}.sn\:bg-warning-subtle{background-color:var(--sn-color-bg-warning-subtle)}.sn\:object-cover{object-fit:cover}.sn\:p-0{padding:0}.sn\:p-1{padding:var(--sn-space-1)}.sn\:p-3{padding:calc(var(--sn-space-1) * 3)}.sn\:p-4{padding:calc(var(--sn-space-1) * 4)}.sn\:p-5{padding:calc(var(--sn-space-1) * 5)}.sn\:p-6{padding:calc(var(--sn-space-1) * 6)}.sn\:p-px{padding:1px}.sn\:px-0{padding-inline:0}.sn\:px-2{padding-inline:calc(var(--sn-space-1) * 2)}.sn\:px-3{padding-inline:calc(var(--sn-space-1) * 3)}.sn\:px-4{padding-inline:calc(var(--sn-space-1) * 4)}.sn\:px-6{padding-inline:calc(var(--sn-space-1) * 6)}.sn\:py-0{padding-block:0}.sn\:py-1{padding-block:var(--sn-space-1)}.sn\:py-2{padding-block:calc(var(--sn-space-1) * 2)}.sn\:py-3{padding-block:calc(var(--sn-space-1) * 3)}.sn\:py-6{padding-block:calc(var(--sn-space-1) * 6)}.sn\:py-12{padding-block:calc(var(--sn-space-1) * 12)}.sn\:pt-1{padding-top:var(--sn-space-1)}.sn\:pb-4{padding-bottom:calc(var(--sn-space-1) * 4)}.sn\:text-center{text-align:center}.sn\:text-left{text-align:left}.sn\:text-right{text-align:right}.sn\:align-middle{vertical-align:middle}.sn\:align-text-bottom{vertical-align:text-bottom}.sn\:font-mono{font-family:var(--sn-font-mono)}.sn\:font-sans{font-family:var(--sn-font-sans)}.sn\:text-body{font-size:var(--sn-text-body);line-height:var(--tw-leading,var(--sn-text-body--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-body--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-body--font-weight))}.sn\:text-body-strong{font-size:var(--sn-text-body-strong);line-height:var(--tw-leading,var(--sn-text-body-strong--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-body-strong--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-body-strong--font-weight))}.sn\:text-caption{font-size:var(--sn-text-caption);line-height:var(--tw-leading,var(--sn-text-caption--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-caption--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-caption--font-weight))}.sn\:text-display{font-size:var(--sn-text-display);line-height:var(--tw-leading,var(--sn-text-display--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-display--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-display--font-weight))}.sn\:text-label{font-size:var(--sn-text-label);line-height:var(--tw-leading,var(--sn-text-label--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-label--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-label--font-weight))}.sn\:text-title{font-size:var(--sn-text-title);line-height:var(--tw-leading,var(--sn-text-title--line-height));letter-spacing:var(--tw-tracking,var(--sn-text-title--letter-spacing));font-weight:var(--tw-font-weight,var(--sn-text-title--font-weight))}.sn\:whitespace-nowrap{white-space:nowrap}.sn\:text-danger{color:var(--sn-color-text-danger)}.sn\:text-default{color:var(--sn-color-text-default)}.sn\:text-inverse{color:var(--sn-color-text-inverse)}.sn\:text-muted{color:var(--sn-color-text-muted)}.sn\:text-on-danger{color:var(--sn-color-text-on-danger)}.sn\:text-on-primary{color:var(--sn-color-text-on-primary)}.sn\:text-on-success{color:var(--sn-color-text-on-success)}.sn\:text-on-warning{color:var(--sn-color-text-on-warning)}.sn\:text-success{color:var(--sn-color-text-success)}.sn\:text-warning{color:var(--sn-color-text-warning)}.sn\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.sn\:underline{text-decoration-line:underline}.sn\:underline-offset-2{text-underline-offset:2px}.sn\:opacity-\(--sn-opacity-disabled\){opacity:var(--sn-opacity-disabled)}.sn\:transition-\[height\]{transition-property:height;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-\[opacity\,scale\]{transition-property:opacity,scale;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-\[opacity\,translate\]{transition-property:opacity,translate;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-\[translate\,width\]{transition-property:translate,width;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.sn\:duration-\(--sn-duration-fast\){--tw-duration:var(--sn-duration-fast);transition-duration:var(--sn-duration-fast)}.sn\:duration-\(--sn-duration-normal\){--tw-duration:var(--sn-duration-normal);transition-duration:var(--sn-duration-normal)}.sn\:ease-standard{--tw-ease:var(--sn-easing-standard);transition-timing-function:var(--sn-easing-standard)}.sn\:outline-none{--tw-outline-style:none;outline-style:none}.sn\:select-none{-webkit-user-select:none;user-select:none}.sn\:group-aria-invalid\:text-danger:is(:where(.sn\:group)[aria-invalid=true] *),.sn\:group-data-invalid\:text-danger:is(:where(.sn\:group)[data-invalid] *){color:var(--sn-color-text-danger)}.sn\:group-data-panel-open\:rotate-180:is(:where(.sn\:group)[data-panel-open] *),.sn\:group-data-popup-open\:rotate-180:is(:where(.sn\:group)[data-popup-open] *){rotate:180deg}.sn\:group-data-selected\:border-transparent:is(:where(.sn\:group)[data-selected] *){border-color:#0000}.sn\:group-data-selected\:bg-primary:is(:where(.sn\:group)[data-selected] *){background-color:var(--sn-color-bg-primary)}.sn\:placeholder\:text-muted::placeholder{color:var(--sn-color-text-muted)}@media (hover:hover){.sn\:hover\:text-muted:hover{color:var(--sn-color-text-muted)}.sn\:hover\:not-disabled\:bg-subtle:hover:not(:disabled){background-color:var(--sn-color-bg-subtle)}.sn\:hover\:not-data-disabled\:border-strong:hover:not([data-disabled]){border-color:var(--sn-color-border-strong)}.sn\:hover\:not-data-disabled\:bg-primary-hover:hover:not([data-disabled]){background-color:var(--sn-color-bg-primary-hover)}.sn\:hover\:not-data-disabled\:bg-subtle:hover:not([data-disabled]){background-color:var(--sn-color-bg-subtle)}.sn\:hover\:not-data-disabled\:text-default:hover:not([data-disabled]){color:var(--sn-color-text-default)}}.sn\:focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.sn\:focus-visible\:-outline-offset-2:focus-visible{outline-offset:calc(2px * -1)}.sn\:focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.sn\:focus-visible\:outline-focus:focus-visible{outline-color:var(--sn-color-border-focus)}.sn\:disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.sn\:disabled\:opacity-\(--sn-opacity-disabled\):disabled{opacity:var(--sn-opacity-disabled)}.sn\:aria-invalid\:border-danger[aria-invalid=true]{border-color:var(--sn-color-border-danger)}@media (hover:hover){.sn\:hover\:aria-invalid\:border-danger:hover[aria-invalid=true]{border-color:var(--sn-color-border-danger)}}.sn\:aria-invalid\:focus-visible\:outline-danger[aria-invalid=true]:focus-visible{outline-color:var(--sn-color-border-danger)}.sn\:data-active\:text-default[data-active]{color:var(--sn-color-text-default)}.sn\:data-checked\:translate-x-3[data-checked]{--tw-translate-x:calc(var(--sn-space-1) * 3);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:data-checked\:border-transparent[data-checked]{border-color:#0000}.sn\:data-checked\:bg-\(--sn-color-text-on-primary\)[data-checked]{background-color:var(--sn-color-text-on-primary)}.sn\:data-checked\:bg-primary[data-checked]{background-color:var(--sn-color-bg-primary)}.sn\:data-disabled\:cursor-not-allowed[data-disabled]{cursor:not-allowed}.sn\:data-disabled\:opacity-\(--sn-opacity-disabled\)[data-disabled]{opacity:var(--sn-opacity-disabled)}.sn\:data-disabled\:not-data-loading\:cursor-not-allowed[data-disabled]:not([data-loading]){cursor:not-allowed}.sn\:data-disabled\:not-data-loading\:opacity-\(--sn-opacity-disabled\)[data-disabled]:not([data-loading]){opacity:var(--sn-opacity-disabled)}.sn\:data-dragging\:border-focus[data-dragging]{border-color:var(--sn-color-border-focus)}.sn\:data-dragging\:bg-subtle[data-dragging]{background-color:var(--sn-color-bg-subtle)}.sn\:data-ending-style\:h-0[data-ending-style]{height:0}.sn\:data-ending-style\:translate-y-2[data-ending-style]{--tw-translate-y:calc(var(--sn-space-1) * 2);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:data-ending-style\:scale-98[data-ending-style]{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x) var(--tw-scale-y)}.sn\:data-ending-style\:opacity-0[data-ending-style]{opacity:0}.sn\:data-highlighted\:bg-subtle[data-highlighted]{background-color:var(--sn-color-bg-subtle)}.sn\:data-indeterminate\:border-transparent[data-indeterminate]{border-color:#0000}.sn\:data-indeterminate\:bg-primary[data-indeterminate]{background-color:var(--sn-color-bg-primary)}.sn\:data-invalid\:border-danger[data-invalid]{border-color:var(--sn-color-border-danger)}.sn\:data-invalid\:focus-visible\:outline-danger[data-invalid]:focus-visible{outline-color:var(--sn-color-border-danger)}.sn\:data-limited\:hidden[data-limited]{display:none}.sn\:data-loading\:cursor-progress[data-loading]{cursor:progress}.sn\:data-placeholder\:text-muted[data-placeholder]{color:var(--sn-color-text-muted)}.sn\:data-popup-open\:border-focus[data-popup-open]{border-color:var(--sn-color-border-focus)}.sn\:data-pressed\:border-default[data-pressed]{border-color:var(--sn-color-border-default)}.sn\:data-pressed\:bg-surface[data-pressed]{background-color:var(--sn-color-bg-surface)}.sn\:data-pressed\:text-default[data-pressed]{color:var(--sn-color-text-default)}.sn\:data-starting-style\:h-0[data-starting-style]{height:0}.sn\:data-starting-style\:translate-y-2[data-starting-style]{--tw-translate-y:calc(var(--sn-space-1) * 2);translate:var(--tw-translate-x) var(--tw-translate-y)}.sn\:data-starting-style\:scale-98[data-starting-style]{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x) var(--tw-scale-y)}.sn\:data-starting-style\:opacity-0[data-starting-style]{opacity:0}@media (prefers-reduced-motion:reduce){.sn\:motion-reduce\:animate-none{animation:none}.sn\:motion-reduce\:transition-none{transition-property:none}}.sn\:\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.sn\:\[\&_svg\]\:size-3 svg{width:calc(var(--sn-space-1) * 3);height:calc(var(--sn-space-1) * 3)}.sn\:\[\&_svg\]\:size-4 svg{width:calc(var(--sn-space-1) * 4);height:calc(var(--sn-space-1) * 4)}.sn\:\[\&_svg\]\:size-5 svg{width:calc(var(--sn-space-1) * 5);height:calc(var(--sn-space-1) * 5)}.sn\:\[\&_svg\]\:size-6 svg{width:calc(var(--sn-space-1) * 6);height:calc(var(--sn-space-1) * 6)}.sn\:\[\&_svg\]\:shrink-0 svg{flex-shrink:0}}:root{--sn-space-0:0px;--sn-space-1:4px;--sn-space-2:8px;--sn-space-3:12px;--sn-space-4:16px;--sn-space-5:20px;--sn-space-6:24px;--sn-space-7:28px;--sn-space-8:32px;--sn-space-10:40px;--sn-space-12:48px;--sn-space-16:64px;--sn-radius-sm:2px;--sn-radius-md:4px;--sn-radius-lg:6px;--sn-radius-full:9999px;--sn-stroke-default:1px;--sn-stroke-focus:2px;--sn-duration-fast:.12s;--sn-duration-normal:.2s;--sn-easing-standard:cubic-bezier(.2, 0, 0, 1);--sn-duration-loop:1s;--sn-opacity-disabled:.45;--sn-font-sans:"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;--sn-font-mono:"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--sn-text-display:32px;--sn-text-display--line-height:40px;--sn-text-display--font-weight:600;--sn-text-display--letter-spacing:-.02em;--sn-text-title:20px;--sn-text-title--line-height:28px;--sn-text-title--font-weight:600;--sn-text-title--letter-spacing:-.01em;--sn-text-body:14px;--sn-text-body--line-height:20px;--sn-text-body--font-weight:400;--sn-text-body--letter-spacing:0em;--sn-text-body-strong:14px;--sn-text-body-strong--line-height:20px;--sn-text-body-strong--font-weight:500;--sn-text-body-strong--letter-spacing:0em;--sn-text-label:13px;--sn-text-label--line-height:16px;--sn-text-label--font-weight:500;--sn-text-label--letter-spacing:0em;--sn-text-caption:12px;--sn-text-caption--line-height:16px;--sn-text-caption--font-weight:400;--sn-text-caption--letter-spacing:0em;--sn-text-mono:14px;--sn-text-mono--line-height:20px;--sn-text-mono--font-weight:400;--sn-text-mono--letter-spacing:0em;--sn-text-mono-caption:12px;--sn-text-mono-caption--line-height:16px;--sn-text-mono-caption--font-weight:400;--sn-text-mono-caption--letter-spacing:0em}:root,[data-theme=light]{color-scheme:light;--sn-color-bg-canvas:#f4f6f8;--sn-color-bg-surface:#fff;--sn-color-bg-subtle:#e6eaee;--sn-color-bg-primary:#2340d0;--sn-color-bg-primary-hover:#1b33ae;--sn-color-bg-danger:#c8312b;--sn-color-bg-overlay:#0e121680;--sn-color-text-default:#0e1216;--sn-color-text-muted:#5b6672;--sn-color-text-on-primary:#fff;--sn-color-text-on-danger:#fff;--sn-color-text-danger:#c8312b;--sn-color-border-default:#d5dbe1;--sn-color-border-strong:#8d99a6;--sn-color-border-focus:#2340d0;--sn-color-border-danger:#c8312b;--sn-color-bg-inverse:#0e1216;--sn-color-text-inverse:#fff;--sn-color-bg-success:#16804f;--sn-color-text-on-success:#fff;--sn-color-bg-success-subtle:#eaf7f0;--sn-color-text-success:#0f6640;--sn-color-bg-warning:#e3a43a;--sn-color-text-on-warning:#0e1216;--sn-color-bg-warning-subtle:#fcf5e6;--sn-color-text-warning:#85520a;--sn-color-bg-danger-subtle:#fcedec;--sn-color-border-success:#16804f;--sn-color-border-warning:#a86c12}[data-theme=dark]{color-scheme:dark;--sn-color-bg-canvas:#0e1216;--sn-color-bg-surface:#161b21;--sn-color-bg-subtle:#1e252d;--sn-color-bg-primary:#6e86ff;--sn-color-bg-primary-hover:#8c9fff;--sn-color-bg-danger:#f06a5f;--sn-color-bg-overlay:#0e121680;--sn-color-text-default:#e6eaee;--sn-color-text-muted:#8d99a6;--sn-color-text-on-primary:#0e1216;--sn-color-text-on-danger:#0e1216;--sn-color-text-danger:#f06a5f;--sn-color-border-default:#2a323b;--sn-color-border-strong:#5b6672;--sn-color-border-focus:#6e86ff;--sn-color-border-danger:#f06a5f;--sn-color-bg-inverse:#e6eaee;--sn-color-text-inverse:#0e1216;--sn-color-bg-success:#3db882;--sn-color-text-on-success:#0e1216;--sn-color-bg-success-subtle:#0b2218;--sn-color-text-success:#6bd1a0;--sn-color-bg-warning:#e3a43a;--sn-color-text-on-warning:#0e1216;--sn-color-bg-warning-subtle:#24190a;--sn-color-text-warning:#eec46a;--sn-color-bg-danger-subtle:#2b1311;--sn-color-border-success:#3db882;--sn-color-border-warning:#e3a43a}@keyframes sn-pulse{50%{opacity:.5}}@keyframes sn-spin{to{transform:rotate(360deg)}}}
package/dist/tailwind.css CHANGED
@@ -54,4 +54,19 @@
54
54
  --outline-color-focus: var(--sn-color-border-focus);
55
55
  --border-color-danger: var(--sn-color-border-danger);
56
56
  --outline-color-danger: var(--sn-color-border-danger);
57
+ --background-color-inverse: var(--sn-color-bg-inverse);
58
+ --text-color-inverse: var(--sn-color-text-inverse);
59
+ --background-color-success: var(--sn-color-bg-success);
60
+ --text-color-on-success: var(--sn-color-text-on-success);
61
+ --background-color-success-subtle: var(--sn-color-bg-success-subtle);
62
+ --text-color-success: var(--sn-color-text-success);
63
+ --background-color-warning: var(--sn-color-bg-warning);
64
+ --text-color-on-warning: var(--sn-color-text-on-warning);
65
+ --background-color-warning-subtle: var(--sn-color-bg-warning-subtle);
66
+ --text-color-warning: var(--sn-color-text-warning);
67
+ --background-color-danger-subtle: var(--sn-color-bg-danger-subtle);
68
+ --border-color-success: var(--sn-color-border-success);
69
+ --outline-color-success: var(--sn-color-border-success);
70
+ --border-color-warning: var(--sn-color-border-warning);
71
+ --outline-color-warning: var(--sn-color-border-warning);
57
72
  }
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@xonic0506/sonic-ui",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Figma-first personal design system (Base UI + Tailwind v4, prebuilt CSS)",
5
5
  "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/sonic0506/sonic-design-system.git"
9
+ },
10
+ "homepage": "https://github.com/sonic0506/sonic-design-system#readme",
6
11
  "type": "module",
7
12
  "sideEffects": [
8
13
  "**/*.css"
@@ -32,7 +37,8 @@
32
37
  "typecheck": "tsc --noEmit",
33
38
  "test": "vitest run",
34
39
  "playground": "vite --config playground/vite.config.ts",
35
- "prepublishOnly": "npm run typecheck && npm test && npm run build"
40
+ "prepublishOnly": "npm run typecheck && npm test && npm run check:contrast && npm run build",
41
+ "check:contrast": "node scripts/check-contrast.mjs"
36
42
  },
37
43
  "peerDependencies": {
38
44
  "react": "^18.2.0 || ^19.0.0",
@@ -41,6 +47,7 @@
41
47
  "dependencies": {
42
48
  "@base-ui/react": "^1.9.0",
43
49
  "class-variance-authority": "^0.7.1",
50
+ "lucide-react": "^1.59.0",
44
51
  "tailwind-merge": "^3.7.0"
45
52
  },
46
53
  "devDependencies": {