@suribef/suri-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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sergio Uribe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,329 @@
1
+ # SuriUI
2
+
3
+ React component library built with TypeScript, CSS Modules, and
4
+ zero runtime dependencies.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/@suribef/suri-ui)](https://www.npmjs.com/package/@suribef/suri-ui)
7
+ [![CI](https://github.com/Suribef/suri-ui/actions/workflows/test.yml/badge.svg)](https://github.com/Suribef/suri-ui/actions)
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @suribef/suri-ui
15
+ ```
16
+
17
+ **Peer dependencies** — install if not already present:
18
+
19
+ ```bash
20
+ npm install react react-dom
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Setup
26
+
27
+ Import the design tokens once at your app's entry point:
28
+
29
+ ```ts
30
+ // main.tsx or App.tsx
31
+ import '@suribef/suri-ui/dist/suri-ui.css'
32
+ ```
33
+
34
+ This registers the CSS custom properties (colors, spacing, radius,
35
+ typography) that all components depend on. Without this import,
36
+ components render without styles.
37
+
38
+ ---
39
+
40
+ ## Components
41
+
42
+ ### Button
43
+
44
+ ```tsx
45
+ import { Button } from '@suribef/suri-ui'
46
+
47
+ <Button variant="primary" size="md" onClick={handleClick}>
48
+ Save changes
49
+ </Button>
50
+
51
+ <Button loading>Saving...</Button>
52
+
53
+ <Button variant="danger" disabled>Delete</Button>
54
+ ```
55
+
56
+ | Prop | Type | Default | Description |
57
+ |------|------|---------|-------------|
58
+ | variant | `primary \| secondary \| ghost \| danger` | `primary` | Visual style |
59
+ | size | `sm \| md \| lg` | `md` | Height and padding scale |
60
+ | loading | `boolean` | `false` | Shows spinner, blocks clicks, keeps focus |
61
+ | disabled | `boolean` | `false` | Native disabled, removes from tab order |
62
+ | fullWidth | `boolean` | `false` | 100% container width |
63
+ | leftIcon | `ReactNode` | — | Icon before label |
64
+ | rightIcon | `ReactNode` | — | Icon after label |
65
+
66
+ > **Accessibility note:** `loading` uses `aria-disabled` (not native
67
+ > `disabled`) so the button stays focusable while the operation runs.
68
+ > Screen readers announce "busy" to communicate the active state.
69
+
70
+ ---
71
+
72
+ ### Badge
73
+
74
+ ```tsx
75
+ import { Badge } from '@suribef/suri-ui'
76
+
77
+ <Badge variant="success">Active</Badge>
78
+
79
+ {/* Dot mode — aria-label required */}
80
+ <Badge dot variant="danger" aria-label="3 unread notifications" />
81
+ ```
82
+
83
+ | Prop | Type | Default | Description |
84
+ |------|------|---------|-------------|
85
+ | variant | `default \| success \| warning \| danger \| info` | `default` | Semantic color |
86
+ | size | `sm \| md` | `md` | Height scale |
87
+ | dot | `boolean` | `false` | Visual indicator mode, no text rendered |
88
+
89
+ > **Accessibility note:** Dot mode without `aria-label` logs a
90
+ > development warning. The label is required for screen reader users.
91
+
92
+ ---
93
+
94
+ ### Spinner
95
+
96
+ ```tsx
97
+ import { Spinner } from '@suribef/suri-ui'
98
+
99
+ <Spinner />
100
+ <Spinner size="lg" label="Loading dashboard..." />
101
+
102
+ {/* For critical operations that need immediate announcement */}
103
+ <Spinner aria-live="assertive" label="Processing payment..." />
104
+ ```
105
+
106
+ | Prop | Type | Default | Description |
107
+ |------|------|---------|-------------|
108
+ | size | `sm \| md \| lg` | `md` | Visual size |
109
+ | label | `string` | `Cargando...` | Screen reader text |
110
+ | aria-live | `polite \| assertive` | `polite` | Announcement urgency |
111
+
112
+ ---
113
+
114
+ ### Input
115
+
116
+ ```tsx
117
+ import { Input } from '@suribef/suri-ui'
118
+
119
+ <Input
120
+ label="Email"
121
+ placeholder="you@example.com"
122
+ helperText="We'll never share your email"
123
+ />
124
+
125
+ <Input
126
+ label="Email"
127
+ value={email}
128
+ error={errors.email}
129
+ onChange={e => setEmail(e.target.value)}
130
+ required
131
+ />
132
+ ```
133
+
134
+ | Prop | Type | Default | Description |
135
+ |------|------|---------|-------------|
136
+ | label | `string` | — | Visible label, auto-associated via `useId()` |
137
+ | helperText | `string` | — | Hint text below the input |
138
+ | error | `string` | — | Error message, replaces helperText |
139
+ | fullWidth | `boolean` | `false` | 100% container width |
140
+
141
+ Extends all native `<input>` props. Compatible with React Hook Form
142
+ and other form libraries via `forwardRef`.
143
+
144
+ ---
145
+
146
+ ### Textarea
147
+
148
+ ```tsx
149
+ import { Textarea } from '@suribef/suri-ui'
150
+
151
+ <Textarea label="Message" rows={4} />
152
+
153
+ <Textarea
154
+ label="Notes"
155
+ autoResize
156
+ placeholder="Grows as you type..."
157
+ />
158
+ ```
159
+
160
+ | Prop | Type | Default | Description |
161
+ |------|------|---------|-------------|
162
+ | label | `string` | — | Visible label |
163
+ | helperText | `string` | — | Hint text |
164
+ | error | `string` | — | Error message |
165
+ | rows | `number` | `3` | Initial visible lines |
166
+ | resize | `none \| vertical \| horizontal \| both` | `vertical` | Resize handle |
167
+ | autoResize | `boolean` | `false` | Grows with content via scrollHeight |
168
+
169
+ ---
170
+
171
+ ### Select
172
+
173
+ ```tsx
174
+ import { Select } from '@suribef/suri-ui'
175
+ import type { SelectItem } from '@suribef/suri-ui'
176
+
177
+ const options: SelectItem[] = [
178
+ { value: 'mx', label: 'Mexico' },
179
+ { value: 'us', label: 'United States' },
180
+ { value: 'ca', label: 'Canada', disabled: true }
181
+ ]
182
+
183
+ <Select
184
+ label="Country"
185
+ options={options}
186
+ placeholder="Select a country"
187
+ />
188
+ ```
189
+
190
+ Grouped options:
191
+
192
+ ```tsx
193
+ const grouped: SelectItem[] = [
194
+ {
195
+ group: 'North America',
196
+ options: [
197
+ { value: 'mx', label: 'Mexico' },
198
+ { value: 'us', label: 'United States' }
199
+ ]
200
+ },
201
+ {
202
+ group: 'Europe',
203
+ options: [{ value: 'es', label: 'Spain' }]
204
+ }
205
+ ]
206
+ ```
207
+
208
+ > **Implementation note:** Select uses the native `<select>` element
209
+ > with a CSS reset and custom chevron. This gives mobile users the
210
+ > native picker (optimal UX on iOS/Android) and guaranteed keyboard
211
+ > accessibility. A fully custom listbox is planned for v2.0.
212
+
213
+ ---
214
+
215
+ ### Card
216
+
217
+ ```tsx
218
+ import { Card } from '@suribef/suri-ui'
219
+
220
+ <Card>
221
+ <Card.Header divided>
222
+ <strong>Card title</strong>
223
+ </Card.Header>
224
+ <Card.Body>Content goes here.</Card.Body>
225
+ <Card.Footer divided>
226
+ <Button size="sm">Action</Button>
227
+ </Card.Footer>
228
+ </Card>
229
+
230
+ {/* Semantic element */}
231
+ <Card as="article" shadow="md">
232
+ <Card.Body>Blog post content</Card.Body>
233
+ </Card>
234
+ ```
235
+
236
+ | Prop | Type | Default | Description |
237
+ |------|------|---------|-------------|
238
+ | as | `div \| article \| section \| main` | `div` | Semantic element |
239
+ | shadow | `none \| sm \| md \| lg` | `sm` | Elevation level |
240
+ | bordered | `boolean` | `true` | Border visibility |
241
+ | fullWidth | `boolean` | `false` | 100% container width |
242
+
243
+ > **Layout note:** Card has no padding — subcomponents (Header, Body,
244
+ > Footer) own their padding. This allows full-bleed images and colored
245
+ > headers without consumer overrides.
246
+
247
+ ---
248
+
249
+ ### Stack
250
+
251
+ ```tsx
252
+ import { Stack } from '@suribef/suri-ui'
253
+
254
+ {/* Vertical stack */}
255
+ <Stack gap={4}>
256
+ <Input label="First name" />
257
+ <Input label="Last name" />
258
+ <Button>Submit</Button>
259
+ </Stack>
260
+
261
+ {/* Horizontal with alignment */}
262
+ <Stack direction="row" align="center" justify="between">
263
+ <span>Label</span>
264
+ <Button size="sm">Action</Button>
265
+ </Stack>
266
+ ```
267
+
268
+ | Prop | Type | Default | Description |
269
+ |------|------|---------|-------------|
270
+ | as | `div \| ul \| ol \| nav \| section \| main` | `div` | Semantic element |
271
+ | direction | `row \| column \| row-reverse \| column-reverse` | `column` | Flex direction |
272
+ | gap | `1–12` | `4` | Spacing scale token |
273
+ | align | `start \| center \| end \| stretch \| baseline` | — | align-items |
274
+ | justify | `start \| center \| end \| between \| around \| evenly` | — | justify-content |
275
+
276
+ ---
277
+
278
+ ### Divider
279
+
280
+ ```tsx
281
+ import { Divider } from '@suribef/suri-ui'
282
+
283
+ {/* Semantic — screen readers announce "separator" */}
284
+ <Divider />
285
+
286
+ {/* Decorative — invisible to assistive technology */}
287
+ <Divider decorative />
288
+
289
+ {/* Vertical — for toolbars and navbars */}
290
+ <Divider orientation="vertical" />
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Theming
296
+
297
+ Override any token in your CSS to customize globally:
298
+
299
+ ```css
300
+ :root {
301
+ --sui-color-primary: #0070f3;
302
+ --sui-color-primary-hover: #0060df;
303
+ --sui-radius-md: 4px;
304
+ }
305
+ ```
306
+
307
+ Full token list in
308
+ [src/tokens/index.css](./src/tokens/index.css).
309
+
310
+ ---
311
+
312
+ ## Contributing
313
+
314
+ ```bash
315
+ git clone https://github.com/Suribef/suri-ui
316
+ npm install
317
+ npm test # 118 tests
318
+ npm run storybook # Component explorer on localhost:6006
319
+ npm run build # Verify dist output
320
+ ```
321
+
322
+ Architecture decisions are documented in
323
+ [docs/decisions/](./docs/decisions/).
324
+
325
+ ---
326
+
327
+ ## License
328
+
329
+ MIT © [Sergio Uribe](https://github.com/Suribef)
@@ -0,0 +1,10 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
3
+ variant?: 'default' | 'success' | 'warning' | 'danger' | 'info';
4
+ size?: 'sm' | 'md';
5
+ dot?: boolean;
6
+ }
7
+ export declare function Badge({ variant, size, dot, children, className, ...props }: BadgeProps): import("react").JSX.Element;
8
+ export declare namespace Badge {
9
+ var displayName: string;
10
+ }
@@ -0,0 +1,2 @@
1
+ export { Badge } from './Badge';
2
+ export type { BadgeProps } from './Badge';
@@ -0,0 +1,10 @@
1
+ import { ButtonHTMLAttributes, ReactNode } from 'react';
2
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
+ variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
4
+ size?: 'sm' | 'md' | 'lg';
5
+ loading?: boolean;
6
+ leftIcon?: ReactNode;
7
+ rightIcon?: ReactNode;
8
+ fullWidth?: boolean;
9
+ }
10
+ export declare const Button: import('react').ForwardRefExoticComponent<ButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,2 @@
1
+ export { Button } from './Button';
2
+ export type { ButtonProps } from './Button';
@@ -0,0 +1,34 @@
1
+ import { forwardRef, HTMLAttributes } from 'react';
2
+ type CardElement = 'div' | 'article' | 'section' | 'main';
3
+ export interface CardProps extends HTMLAttributes<HTMLElement> {
4
+ as?: CardElement;
5
+ shadow?: 'none' | 'sm' | 'md' | 'lg';
6
+ bordered?: boolean;
7
+ fullWidth?: boolean;
8
+ }
9
+ type CardType = ReturnType<typeof forwardRef<HTMLElement, CardProps>> & {
10
+ Header: typeof CardHeader;
11
+ Body: typeof CardBody;
12
+ Footer: typeof CardFooter;
13
+ };
14
+ export interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {
15
+ divided?: boolean;
16
+ }
17
+ export declare function CardHeader({ divided, className, children, ...props }: CardHeaderProps): import("react").JSX.Element;
18
+ export declare namespace CardHeader {
19
+ var displayName: string;
20
+ }
21
+ export type CardBodyProps = HTMLAttributes<HTMLDivElement>;
22
+ export declare function CardBody({ className, children, ...props }: CardBodyProps): import("react").JSX.Element;
23
+ export declare namespace CardBody {
24
+ var displayName: string;
25
+ }
26
+ export interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
27
+ divided?: boolean;
28
+ }
29
+ export declare function CardFooter({ divided, className, children, ...props }: CardFooterProps): import("react").JSX.Element;
30
+ export declare namespace CardFooter {
31
+ var displayName: string;
32
+ }
33
+ export declare const Card: CardType;
34
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Card, CardHeader, CardBody, CardFooter } from './Card';
2
+ export type { CardProps, CardHeaderProps, CardBodyProps, CardFooterProps } from './Card';
@@ -0,0 +1,10 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface DividerProps extends HTMLAttributes<HTMLElement> {
3
+ decorative?: boolean;
4
+ orientation?: 'horizontal' | 'vertical';
5
+ label?: string;
6
+ }
7
+ export declare function Divider({ decorative, orientation, label, className, ...props }: DividerProps): import("react").JSX.Element;
8
+ export declare namespace Divider {
9
+ var displayName: string;
10
+ }
@@ -0,0 +1,2 @@
1
+ export { Divider } from './Divider';
2
+ export type { DividerProps } from './Divider';
@@ -0,0 +1,8 @@
1
+ import { InputHTMLAttributes } from 'react';
2
+ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
3
+ label?: string;
4
+ helperText?: string;
5
+ error?: string;
6
+ fullWidth?: boolean;
7
+ }
8
+ export declare const Input: import('react').ForwardRefExoticComponent<InputProps & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { Input } from './Input';
2
+ export type { InputProps } from './Input';
@@ -0,0 +1,20 @@
1
+ import { SelectHTMLAttributes } from 'react';
2
+ export type SelectOption = {
3
+ value: string;
4
+ label: string;
5
+ disabled?: boolean;
6
+ };
7
+ export type SelectOptionGroup = {
8
+ group: string;
9
+ options: SelectOption[];
10
+ };
11
+ export type SelectItem = SelectOption | SelectOptionGroup;
12
+ export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'children'> {
13
+ options: SelectItem[];
14
+ label?: string;
15
+ placeholder?: string;
16
+ helperText?: string;
17
+ error?: string;
18
+ fullWidth?: boolean;
19
+ }
20
+ export declare const Select: import('react').ForwardRefExoticComponent<SelectProps & import('react').RefAttributes<HTMLSelectElement>>;
@@ -0,0 +1,2 @@
1
+ export { Select } from './Select';
2
+ export type { SelectProps, SelectItem, SelectOption, SelectOptionGroup } from './Select';
@@ -0,0 +1,10 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {
3
+ size?: 'sm' | 'md' | 'lg';
4
+ label?: string;
5
+ 'aria-live'?: 'polite' | 'assertive';
6
+ }
7
+ export declare function Spinner({ size, label, 'aria-live': ariaLive, className, ...props }: SpinnerProps): import("react").JSX.Element;
8
+ export declare namespace Spinner {
9
+ var displayName: string;
10
+ }
@@ -0,0 +1,2 @@
1
+ export { Spinner } from './Spinner';
2
+ export type { SpinnerProps } from './Spinner';
@@ -0,0 +1,15 @@
1
+ import { HTMLAttributes } from 'react';
2
+ type StackElement = 'div' | 'ul' | 'ol' | 'nav' | 'section' | 'main';
3
+ type GapScale = 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
4
+ export interface StackProps extends HTMLAttributes<HTMLElement> {
5
+ as?: StackElement;
6
+ direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
7
+ gap?: GapScale;
8
+ align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';
9
+ justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
10
+ wrap?: boolean;
11
+ fullWidth?: boolean;
12
+ fullHeight?: boolean;
13
+ }
14
+ export declare const Stack: import('react').ForwardRefExoticComponent<StackProps & import('react').RefAttributes<HTMLElement>>;
15
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Stack } from './Stack';
2
+ export type { StackProps } from './Stack';
@@ -0,0 +1,10 @@
1
+ import { TextareaHTMLAttributes } from 'react';
2
+ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ label?: string;
4
+ helperText?: string;
5
+ error?: string;
6
+ fullWidth?: boolean;
7
+ resize?: 'none' | 'vertical' | 'horizontal' | 'both';
8
+ autoResize?: boolean;
9
+ }
10
+ export declare const Textarea: import('react').ForwardRefExoticComponent<TextareaProps & import('react').RefAttributes<HTMLTextAreaElement>>;
@@ -0,0 +1,2 @@
1
+ export { Textarea } from './Textarea';
2
+ export type { TextareaProps } from './Textarea';
@@ -0,0 +1,19 @@
1
+ export { Button } from './components/Button';
2
+ export type { ButtonProps } from './components/Button';
3
+ export { Badge } from './components/Badge';
4
+ export type { BadgeProps } from './components/Badge';
5
+ export { Spinner } from './components/Spinner';
6
+ export type { SpinnerProps } from './components/Spinner';
7
+ export { Input } from './components/Input';
8
+ export type { InputProps } from './components/Input';
9
+ export { Card, CardHeader, CardBody, CardFooter } from './components/Card';
10
+ export type { CardProps, CardHeaderProps, CardBodyProps, CardFooterProps } from './components/Card';
11
+ export { Stack } from './components/Stack';
12
+ export type { StackProps } from './components/Stack';
13
+ export { Divider } from './components/Divider';
14
+ export type { DividerProps } from './components/Divider';
15
+ export { Textarea } from './components/Textarea';
16
+ export type { TextareaProps } from './components/Textarea';
17
+ export { useCombinedRef } from './utils/useCombinedRef';
18
+ export { Select } from './components/Select';
19
+ export type { SelectProps, SelectItem, SelectOption, SelectOptionGroup } from './components/Select';
@@ -0,0 +1,6 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);let t=require("react");function n(...e){return e.filter(Boolean).join(` `)}var r={button:`_button_1cyfq_1`,primary:`_primary_1cyfq_27`,secondary:`_secondary_1cyfq_28`,ghost:`_ghost_1cyfq_29`,danger:`_danger_1cyfq_30`,sm:`_sm_1cyfq_37`,md:`_md_1cyfq_38`,lg:`_lg_1cyfq_39`,fullWidth:`_fullWidth_1cyfq_41`,loading:`_loading_1cyfq_42`,spinner:`_spinner_1cyfq_44`,spin:`_spin_1cyfq_44`,icon:`_icon_1cyfq_56`},i=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),a=e((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===O?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=k.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(A.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){N||(N=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return P[e]||(P[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0)if(o)if(j(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`);else f(p);if(A.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,L[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ let props = %s;
3
+ <%s {...props} />
4
+ React keys must be passed directly to JSX without using spread:
5
+ let props = %s;
6
+ <%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),o=e(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=i():t.exports=a()}))(),s=(0,t.forwardRef)(({variant:e=`primary`,size:t=`md`,loading:i=!1,leftIcon:a,rightIcon:s,fullWidth:c=!1,disabled:l,children:u,className:d,onClick:f,tabIndex:p,...m},h)=>(0,o.jsxs)(`button`,{ref:h,className:n(r.button,r[e],r[t],c&&r.fullWidth,i&&r.loading,d),disabled:l,"aria-disabled":i||void 0,"aria-busy":i||void 0,tabIndex:i?-1:p,"data-fullwidth":c||void 0,"data-loading":i||void 0,onClick:e=>{if(i){e.preventDefault();return}f?.(e)},...m,children:[i&&(0,o.jsx)(`span`,{className:r.spinner,"aria-hidden":`true`}),!i&&a&&(0,o.jsx)(`span`,{className:r.icon,children:a}),(0,o.jsx)(`span`,{children:u}),!i&&s&&(0,o.jsx)(`span`,{className:r.icon,children:s})]}));s.displayName=`Button`;var c={badge:`_badge_1di7z_1`,sm:`_sm_1di7z_13`,md:`_md_1di7z_14`,dot:`_dot_1di7z_17`,default:`_default_1di7z_26`,success:`_success_1di7z_27`,warning:`_warning_1di7z_28`,danger:`_danger_1di7z_29`,info:`_info_1di7z_30`};function l({variant:e=`default`,size:t=`md`,dot:r=!1,children:i,className:a,...s}){return process.env.NODE_ENV!==`production`&&r&&!s[`aria-label`]&&console.warn(`[SuriUI Badge] El modo dot requiere aria-label para accesibilidad. Ejemplo: <Badge dot aria-label="3 notificaciones" />`),(0,o.jsx)(`span`,{className:n(c.badge,c[e],c[t],r&&c.dot,a),"data-dot":r||void 0,...s,children:!r&&i})}l.displayName=`Badge`;var u={spinner:`_spinner_b9met_1`,sm:`_sm_b9met_10`,md:`_md_b9met_11`,lg:`_lg_b9met_12`,svg:`_svg_b9met_15`,spin:`_spin_b9met_1`,track:`_track_b9met_22`,head:`_head_b9met_28`};function d({size:e=`md`,label:t=`Cargando...`,"aria-live":r=`polite`,className:i,...a}){return(0,o.jsxs)(`span`,{role:`status`,"aria-live":r,className:n(u.spinner,u[e],i),...a,children:[(0,o.jsxs)(`svg`,{className:u.svg,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`,focusable:`false`,children:[(0,o.jsx)(`circle`,{className:u.track,cx:`12`,cy:`12`,r:`10`,strokeWidth:`3`}),(0,o.jsx)(`path`,{className:u.head,d:`M12 2a10 10 0 0 1 10 10`,strokeWidth:`3`,strokeLinecap:`round`})]}),(0,o.jsx)(`span`,{className:`sui-sr-only`,children:t})]})}d.displayName=`Spinner`;var f={wrapper:`_wrapper_1cd3d_1`,fullWidth:`_fullWidth_1cd3d_7`,label:`_label_1cd3d_12`,required:`_required_1cd3d_20`,input:`_input_1cd3d_25`,inputError:`_inputError_1cd3d_51`,disabled:`_disabled_1cd3d_68`,description:`_description_1cd3d_74`,descriptionHelper:`_descriptionHelper_1cd3d_80`,descriptionError:`_descriptionError_1cd3d_84`},p=(0,t.forwardRef)(({label:e,helperText:r,error:i,fullWidth:a=!1,disabled:s,required:c,id:l,className:u,...d},p)=>{let m=(0,t.useId)(),h=l??m,g=`${h}-description`,_=i||r||void 0;return(0,o.jsxs)(`div`,{className:n(f.wrapper,a&&f.fullWidth,s&&f.disabled),"data-fullwidth":a||void 0,"data-error":!!i||void 0,"data-disabled":s||void 0,children:[e&&(0,o.jsxs)(`label`,{htmlFor:h,className:f.label,children:[e,c&&(0,o.jsxs)(`span`,{"aria-hidden":`true`,className:f.required,children:[` `,`*`]})]}),(0,o.jsx)(`input`,{ref:p,id:h,className:n(f.input,i&&f.inputError,u),disabled:s,required:c,"aria-required":c||void 0,"aria-invalid":!!i||void 0,"aria-describedby":g,...d}),(0,o.jsx)(`span`,{id:g,className:n(f.description,i?f.descriptionError:f.descriptionHelper),"aria-live":`polite`,"aria-atomic":`true`,children:_})]})});p.displayName=`Input`;var m={card:`_card_l6w6d_4`,bordered:`_bordered_l6w6d_15`,fullWidth:`_fullWidth_l6w6d_19`,"shadow-sm":`_shadow-sm_l6w6d_24`,"shadow-md":`_shadow-md_l6w6d_25`,"shadow-lg":`_shadow-lg_l6w6d_26`,header:`_header_l6w6d_29`,headerDivided:`_headerDivided_l6w6d_33`,body:`_body_l6w6d_37`,footer:`_footer_l6w6d_41`,footerDivided:`_footerDivided_l6w6d_45`},h=(0,t.forwardRef)(({as:e=`div`,shadow:t=`sm`,bordered:r=!0,fullWidth:i=!1,className:a,children:s,...c},l)=>(0,o.jsx)(e,{ref:l,className:n(m.card,t!==`none`&&m[`shadow-${t}`],r&&m.bordered,i&&m.fullWidth,a),"data-shadow":t,"data-bordered":r||void 0,"data-fullwidth":i||void 0,...c,children:s}));h.displayName=`Card`;function g({divided:e=!1,className:t,children:r,...i}){return(0,o.jsx)(`div`,{className:n(m.header,e&&m.headerDivided,t),"data-divided":e||void 0,...i,children:r})}g.displayName=`Card.Header`;function _({className:e,children:t,...r}){return(0,o.jsx)(`div`,{className:n(m.body,e),...r,children:t})}_.displayName=`Card.Body`;function v({divided:e=!1,className:t,children:r,...i}){return(0,o.jsx)(`div`,{className:n(m.footer,e&&m.footerDivided,t),"data-divided":e||void 0,...i,children:r})}v.displayName=`Card.Footer`;var y=h;y.Header=g,y.Body=_,y.Footer=v;var b={stack:`_stack_2ervp_1`,"direction-column":`_direction-column_2ervp_8`,"direction-row":`_direction-row_2ervp_9`,"direction-row-reverse":`_direction-row-reverse_2ervp_10`,"direction-column-reverse":`_direction-column-reverse_2ervp_11`,"align-start":`_align-start_2ervp_14`,"align-center":`_align-center_2ervp_15`,"align-end":`_align-end_2ervp_16`,"align-stretch":`_align-stretch_2ervp_17`,"align-baseline":`_align-baseline_2ervp_18`,"justify-start":`_justify-start_2ervp_21`,"justify-center":`_justify-center_2ervp_22`,"justify-end":`_justify-end_2ervp_23`,"justify-between":`_justify-between_2ervp_24`,"justify-around":`_justify-around_2ervp_25`,"justify-evenly":`_justify-evenly_2ervp_26`,wrap:`_wrap_2ervp_29`,fullWidth:`_fullWidth_2ervp_30`,fullHeight:`_fullHeight_2ervp_31`},x=(0,t.forwardRef)(({as:e=`div`,direction:t=`column`,gap:r=4,align:i,justify:a,wrap:s=!1,fullWidth:c=!1,fullHeight:l=!1,className:u,style:d,children:f,...p},m)=>{let h=e,g=`var(--sui-space-${r})`;return(0,o.jsx)(h,{ref:m,className:n(b.stack,b[`direction-${t}`],i&&b[`align-${i}`],a&&b[`justify-${a}`],s&&b.wrap,c&&b.fullWidth,l&&b.fullHeight,u),style:{"--sui-stack-gap":g,...d},"data-direction":t,"data-fullwidth":c||void 0,"data-fullheight":l||void 0,...p,children:f})});x.displayName=`Stack`;var S={divider:`_divider_a98c6_1`,horizontal:`_horizontal_a98c6_7`,vertical:`_vertical_a98c6_13`};function C({decorative:e=!1,orientation:t=`horizontal`,label:r,className:i,...a}){let s=t===`vertical`;return e?(0,o.jsx)(`div`,{"aria-hidden":`true`,className:n(S.divider,s?S.vertical:S.horizontal,i),"data-orientation":t,"data-decorative":`true`,...a}):(0,o.jsx)(`hr`,{role:s?`separator`:void 0,"aria-orientation":s?`vertical`:void 0,"aria-label":r,className:n(S.divider,s?S.vertical:S.horizontal,i),"data-orientation":t,...a})}C.displayName=`Divider`;function w(...e){return(0,t.useCallback)(t=>{e.forEach(e=>{e&&(typeof e==`function`?e(t):e.current=t)})},e)}var T={wrapper:`_wrapper_48l1v_1`,fullWidth:`_fullWidth_48l1v_7`,label:`_label_48l1v_10`,required:`_required_48l1v_18`,textarea:`_textarea_48l1v_21`,"resize-none":`_resize-none_48l1v_47`,"resize-vertical":`_resize-vertical_48l1v_48`,"resize-horizontal":`_resize-horizontal_48l1v_49`,"resize-both":`_resize-both_48l1v_50`,autoResize:`_autoResize_48l1v_54`,textareaError:`_textareaError_48l1v_60`,disabled:`_disabled_48l1v_77`,description:`_description_48l1v_83`,descriptionHelper:`_descriptionHelper_48l1v_91`,descriptionError:`_descriptionError_48l1v_92`},E=(0,t.forwardRef)(({label:e,helperText:r,error:i,fullWidth:a=!1,resize:s=`vertical`,autoResize:c=!1,disabled:l,required:u,id:d,rows:f=3,value:p,className:m,onChange:h,...g},_)=>{let v=(0,t.useId)(),y=d??v,b=`${y}-description`,x=i||r||void 0,S=(0,t.useRef)(null),C=w(S,_);return(0,t.useEffect)(()=>{if(!c||!S.current)return;let e=S.current;e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`},[c,p]),(0,o.jsxs)(`div`,{className:n(T.wrapper,a&&T.fullWidth,l&&T.disabled),"data-fullwidth":a||void 0,"data-error":!!i||void 0,"data-disabled":l||void 0,children:[e&&(0,o.jsxs)(`label`,{htmlFor:y,className:T.label,children:[e,u&&(0,o.jsxs)(`span`,{"aria-hidden":`true`,className:T.required,children:[` `,`*`]})]}),(0,o.jsx)(`textarea`,{ref:C,id:y,rows:f,value:p,className:n(T.textarea,T[`resize-${s}`],c&&T.autoResize,i&&T.textareaError,m),disabled:l,required:u,"aria-required":u||void 0,"aria-invalid":!!i||void 0,"aria-describedby":b,onChange:h,...g}),(0,o.jsx)(`span`,{id:b,className:n(T.description,i?T.descriptionError:T.descriptionHelper),"aria-live":`polite`,"aria-atomic":`true`,children:x})]})});E.displayName=`Textarea`;var D={wrapper:`_wrapper_1ny9q_1`,fullWidth:`_fullWidth_1ny9q_7`,label:`_label_1ny9q_10`,required:`_required_1ny9q_18`,selectWrapper:`_selectWrapper_1ny9q_21`,select:`_select_1ny9q_21`,selectError:`_selectError_1ny9q_57`,disabled:`_disabled_1ny9q_74`,description:`_description_1ny9q_80`,descriptionHelper:`_descriptionHelper_1ny9q_88`,descriptionError:`_descriptionError_1ny9q_89`};function O(e){return`group`in e}var k=(0,t.forwardRef)(({options:e,label:r,placeholder:i,helperText:a,error:s,fullWidth:c=!1,disabled:l,required:u,id:d,className:f,...p},m)=>{let h=(0,t.useId)(),g=d??h,_=`${g}-description`,v=s||a||void 0;return(0,o.jsxs)(`div`,{className:n(D.wrapper,c&&D.fullWidth,l&&D.disabled),"data-fullwidth":c||void 0,"data-error":!!s||void 0,"data-disabled":l||void 0,children:[r&&(0,o.jsxs)(`label`,{htmlFor:g,className:D.label,children:[r,u&&(0,o.jsxs)(`span`,{"aria-hidden":`true`,className:D.required,children:[` `,`*`]})]}),(0,o.jsx)(`div`,{className:D.selectWrapper,children:(0,o.jsxs)(`select`,{ref:m,id:g,className:n(D.select,s&&D.selectError,f),disabled:l,required:u,"aria-required":u||void 0,"aria-invalid":!!s||void 0,"aria-describedby":_,...p,children:[i&&(0,o.jsx)(`option`,{value:``,disabled:!0,hidden:!0,children:i}),e.map(e=>O(e)?(0,o.jsx)(`optgroup`,{label:e.group,children:e.options.map(e=>(0,o.jsx)(`option`,{value:e.value,disabled:e.disabled,children:e.label},e.value))},e.group):(0,o.jsx)(`option`,{value:e.value,disabled:e.disabled,children:e.label},e.value))]})}),(0,o.jsx)(`span`,{id:_,className:n(D.description,s?D.descriptionError:D.descriptionHelper),"aria-live":`polite`,"aria-atomic":`true`,children:v})]})});k.displayName=`Select`,exports.Badge=l,exports.Button=s,exports.Card=y,exports.CardBody=_,exports.CardFooter=v,exports.CardHeader=g,exports.Divider=C,exports.Input=p,exports.Select=k,exports.Spinner=d,exports.Stack=x,exports.Textarea=E,exports.useCombinedRef=w;
@@ -0,0 +1,2 @@
1
+ :root{--sui-color-primary:#6366f1;--sui-color-primary-hover:#4f46e5;--sui-color-primary-foreground:#fff;--sui-color-secondary:#f4f4f5;--sui-color-secondary-hover:#e4e4e7;--sui-color-secondary-foreground:#18181b;--sui-color-danger:#ef4444;--sui-color-danger-hover:#dc2626;--sui-color-danger-foreground:#fff;--sui-color-ghost-hover:#0000000f;--sui-font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--sui-font-size-sm:.875rem;--sui-font-size-md:1rem;--sui-font-size-lg:1.125rem;--sui-font-weight-medium:500;--sui-space-2:.5rem;--sui-space-3:.75rem;--sui-space-4:1rem;--sui-space-6:1.5rem;--sui-radius-md:8px;--sui-radius-lg:12px;--sui-radius-full:9999px;--sui-transition-fast:.12s ease;--sui-color-success:#dcfce7;--sui-color-success-foreground:#166534;--sui-color-warning:#fef9c3;--sui-color-warning-foreground:#854d0e;--sui-color-info:#dbeafe;--sui-color-info-foreground:#1e40af;--sui-color-border:#d1d5db;--sui-color-border-focus:var(--sui-color-primary);--sui-color-border-error:var(--sui-color-danger);--sui-color-input-bg:#fff;--sui-color-input-bg-disabled:#f9fafb;--sui-color-text-primary:#111827;--sui-color-text-secondary:#6b7280;--sui-color-text-placeholder:#9ca3af;--sui-color-text-error:var(--sui-color-danger);--sui-color-text-disabled:#9ca3af;--sui-focus-ring:0 0 0 3px #6366f140;--sui-space-5:1.25rem;--sui-space-8:2rem;--sui-space-10:2.5rem;--sui-space-12:3rem;--sui-color-divider:#e5e7eb;--sui-shadow-sm:0 1px 3px #00000014, 0 1px 2px #0000000a;--sui-shadow-md:0 4px 6px #00000012, 0 2px 4px #0000000d;--sui-shadow-lg:0 10px 15px #00000014, 0 4px 6px #0000000a;--sui-color-card-bg:#fff;--sui-color-card-border:#e5e7eb;--sui-textarea-min-height:80px;--sui-textarea-max-height:400px;--sui-select-chevron-size:16px}.sui-sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._button_1cyfq_1{justify-content:center;align-items:center;gap:var(--sui-space-2);font-family:var(--sui-font-sans);font-weight:var(--sui-font-weight-medium);border-radius:var(--sui-radius-md);cursor:pointer;transition:background-color var(--sui-transition-fast), opacity var(--sui-transition-fast), transform var(--sui-transition-fast);white-space:nowrap;-webkit-user-select:none;user-select:none;border:none;display:inline-flex}._button_1cyfq_1:disabled,._button_1cyfq_1[aria-disabled=true]{opacity:.5;cursor:not-allowed}._button_1cyfq_1:active:not(:disabled):not([aria-disabled=true]){transform:scale(.98)}._primary_1cyfq_27{background-color:var(--sui-color-primary);color:var(--sui-color-primary-foreground)}._secondary_1cyfq_28{background-color:var(--sui-color-secondary);color:var(--sui-color-secondary-foreground)}._ghost_1cyfq_29{color:var(--sui-color-secondary-foreground);background-color:#0000}._danger_1cyfq_30{background-color:var(--sui-color-danger);color:var(--sui-color-danger-foreground)}._primary_1cyfq_27:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-primary-hover)}._secondary_1cyfq_28:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-secondary-hover)}._ghost_1cyfq_29:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-ghost-hover)}._danger_1cyfq_30:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--sui-color-danger-hover)}._sm_1cyfq_37{height:32px;padding:0 var(--sui-space-3);font-size:var(--sui-font-size-sm)}._md_1cyfq_38{height:40px;padding:0 var(--sui-space-4);font-size:var(--sui-font-size-md)}._lg_1cyfq_39{height:48px;padding:0 var(--sui-space-6);font-size:var(--sui-font-size-lg)}._fullWidth_1cyfq_41{width:100%}._loading_1cyfq_42{cursor:wait}._spinner_1cyfq_44{border:2px solid;border-top-color:#0000;border-radius:50%;flex-shrink:0;width:14px;height:14px;animation:.6s linear infinite _spin_1cyfq_44;display:inline-block}@keyframes _spin_1cyfq_44{to{transform:rotate(360deg)}}._icon_1cyfq_56{flex-shrink:0;align-items:center;display:inline-flex}._badge_1di7z_1{font-family:var(--sui-font-sans);font-weight:var(--sui-font-weight-medium);border-radius:var(--sui-radius-full);white-space:nowrap;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}._sm_1di7z_13{height:20px;padding:0 var(--sui-space-2);font-size:.75rem}._md_1di7z_14{height:24px;padding:0 var(--sui-space-3);font-size:var(--sui-font-size-sm)}._dot_1di7z_17{border-radius:50%;flex-shrink:0;padding:0}._dot_1di7z_17._sm_1di7z_13{width:6px;height:6px}._dot_1di7z_17._md_1di7z_14{width:8px;height:8px}._default_1di7z_26{background-color:var(--sui-color-secondary);color:var(--sui-color-secondary-foreground)}._success_1di7z_27{background-color:var(--sui-color-success);color:var(--sui-color-success-foreground)}._warning_1di7z_28{background-color:var(--sui-color-warning);color:var(--sui-color-warning-foreground)}._danger_1di7z_29{background-color:var(--sui-color-danger);color:var(--sui-color-danger-foreground)}._info_1di7z_30{background-color:var(--sui-color-info);color:var(--sui-color-info-foreground)}._spinner_b9met_1{color:var(--sui-color-primary);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}._sm_b9met_10{width:16px;height:16px}._md_b9met_11{width:24px;height:24px}._lg_b9met_12{width:40px;height:40px}._svg_b9met_15{width:100%;height:100%;animation:.75s linear infinite _spin_b9met_1}._track_b9met_22{stroke:currentColor;opacity:.2}._head_b9met_28{stroke:currentColor}@keyframes _spin_b9met_1{to{transform:rotate(360deg)}}._wrapper_1cd3d_1{gap:var(--sui-space-2);flex-direction:column;display:inline-flex}._fullWidth_1cd3d_7{width:100%}._label_1cd3d_12{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text-primary);cursor:pointer}._required_1cd3d_20{color:var(--sui-color-text-error)}._input_1cd3d_25{width:100%;height:40px;padding:0 var(--sui-space-3);font-family:var(--sui-font-sans);font-size:var(--sui-font-size-md);color:var(--sui-color-text-primary);background-color:var(--sui-color-input-bg);border:1.5px solid var(--sui-color-border);border-radius:var(--sui-radius-md);transition:border-color var(--sui-transition-fast), box-shadow var(--sui-transition-fast);box-sizing:border-box;outline:none}._input_1cd3d_25::placeholder{color:var(--sui-color-text-placeholder)}._input_1cd3d_25:focus{border-color:var(--sui-color-border-focus);box-shadow:var(--sui-focus-ring)}._inputError_1cd3d_51{border-color:var(--sui-color-border-error)}._inputError_1cd3d_51:focus{border-color:var(--sui-color-border-error);box-shadow:0 0 0 3px #ef444433}._input_1cd3d_25:disabled{background-color:var(--sui-color-input-bg-disabled);color:var(--sui-color-text-disabled);cursor:not-allowed;opacity:1}._wrapper_1cd3d_1._disabled_1cd3d_68 ._label_1cd3d_12{color:var(--sui-color-text-disabled);cursor:not-allowed}._description_1cd3d_74{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);line-height:1.4}._descriptionHelper_1cd3d_80{color:var(--sui-color-text-secondary)}._descriptionError_1cd3d_84{color:var(--sui-color-text-error)}._description_1cd3d_74:empty{display:none}._card_l6w6d_4{background-color:var(--sui-color-card-bg);border-radius:var(--sui-radius-lg);box-sizing:border-box;position:relative;overflow:hidden}._bordered_l6w6d_15{border:1px solid var(--sui-color-card-border)}._fullWidth_l6w6d_19{width:100%}._shadow-sm_l6w6d_24{box-shadow:var(--sui-shadow-sm)}._shadow-md_l6w6d_25{box-shadow:var(--sui-shadow-md)}._shadow-lg_l6w6d_26{box-shadow:var(--sui-shadow-lg)}._header_l6w6d_29{padding:var(--sui-space-4) var(--sui-space-4) var(--sui-space-3)}._headerDivided_l6w6d_33{border-bottom:1px solid var(--sui-color-card-border)}._body_l6w6d_37{padding:var(--sui-space-4)}._footer_l6w6d_41{padding:var(--sui-space-3) var(--sui-space-4) var(--sui-space-4)}._footerDivided_l6w6d_45{border-top:1px solid var(--sui-color-card-border)}._stack_2ervp_1{gap:var(--sui-stack-gap,var(--sui-space-4));box-sizing:border-box;display:flex}._direction-column_2ervp_8{flex-direction:column}._direction-row_2ervp_9{flex-direction:row}._direction-row-reverse_2ervp_10{flex-direction:row-reverse}._direction-column-reverse_2ervp_11{flex-direction:column-reverse}._align-start_2ervp_14{align-items:flex-start}._align-center_2ervp_15{align-items:center}._align-end_2ervp_16{align-items:flex-end}._align-stretch_2ervp_17{align-items:stretch}._align-baseline_2ervp_18{align-items:baseline}._justify-start_2ervp_21{justify-content:flex-start}._justify-center_2ervp_22{justify-content:center}._justify-end_2ervp_23{justify-content:flex-end}._justify-between_2ervp_24{justify-content:space-between}._justify-around_2ervp_25{justify-content:space-around}._justify-evenly_2ervp_26{justify-content:space-evenly}._wrap_2ervp_29{flex-wrap:wrap}._fullWidth_2ervp_30{width:100%}._fullHeight_2ervp_31{height:100%}._divider_a98c6_1{background-color:var(--sui-color-divider);border:none;flex-shrink:0}._horizontal_a98c6_7{width:100%;height:1px;margin:0}._vertical_a98c6_13{align-self:stretch;width:1px;height:100%}._wrapper_48l1v_1{gap:var(--sui-space-2);flex-direction:column;display:inline-flex}._fullWidth_48l1v_7{width:100%}._label_48l1v_10{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text-primary);cursor:pointer}._required_48l1v_18{color:var(--sui-color-text-error)}._textarea_48l1v_21{width:100%;min-height:var(--sui-textarea-min-height);max-height:var(--sui-textarea-max-height);padding:var(--sui-space-3);font-family:var(--sui-font-sans);font-size:var(--sui-font-size-md);color:var(--sui-color-text-primary);background-color:var(--sui-color-input-bg);border:1.5px solid var(--sui-color-border);border-radius:var(--sui-radius-md);transition:border-color var(--sui-transition-fast), box-shadow var(--sui-transition-fast);box-sizing:border-box;outline:none;line-height:1.5}._textarea_48l1v_21::placeholder{color:var(--sui-color-text-placeholder)}._textarea_48l1v_21:focus{border-color:var(--sui-color-border-focus);box-shadow:var(--sui-focus-ring)}._resize-none_48l1v_47{resize:none}._resize-vertical_48l1v_48{resize:vertical}._resize-horizontal_48l1v_49{resize:horizontal}._resize-both_48l1v_50{resize:both}._autoResize_48l1v_54{resize:none;overflow:hidden}._textareaError_48l1v_60{border-color:var(--sui-color-border-error)}._textareaError_48l1v_60:focus{border-color:var(--sui-color-border-error);box-shadow:0 0 0 3px #ef444433}._textarea_48l1v_21:disabled{background-color:var(--sui-color-input-bg-disabled);color:var(--sui-color-text-disabled);cursor:not-allowed;opacity:1}._wrapper_48l1v_1._disabled_48l1v_77 ._label_48l1v_10{color:var(--sui-color-text-disabled);cursor:not-allowed}._description_48l1v_83{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);line-height:1.4}._description_48l1v_83:empty{display:none}._descriptionHelper_48l1v_91{color:var(--sui-color-text-secondary)}._descriptionError_48l1v_92{color:var(--sui-color-text-error)}._wrapper_1ny9q_1{gap:var(--sui-space-2);flex-direction:column;display:inline-flex}._fullWidth_1ny9q_7{width:100%}._label_1ny9q_10{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text-primary);cursor:pointer}._required_1ny9q_18{color:var(--sui-color-text-error)}._selectWrapper_1ny9q_21{display:flex;position:relative}._select_1ny9q_21{width:100%;height:40px;padding:0 var(--sui-space-8) 0 var(--sui-space-3);font-family:var(--sui-font-sans);font-size:var(--sui-font-size-md);color:var(--sui-color-text-primary);background-color:var(--sui-color-input-bg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--sui-space-3) center;background-size:var(--sui-select-chevron-size);border:1.5px solid var(--sui-color-border);border-radius:var(--sui-radius-md);cursor:pointer;appearance:none;transition:border-color var(--sui-transition-fast), box-shadow var(--sui-transition-fast);box-sizing:border-box;outline:none}._select_1ny9q_21:focus{border-color:var(--sui-color-border-focus);box-shadow:var(--sui-focus-ring)}._selectError_1ny9q_57{border-color:var(--sui-color-border-error)}._selectError_1ny9q_57:focus{border-color:var(--sui-color-border-error);box-shadow:0 0 0 3px #ef444433}._select_1ny9q_21:disabled{background-color:var(--sui-color-input-bg-disabled);color:var(--sui-color-text-disabled);cursor:not-allowed;opacity:1}._wrapper_1ny9q_1._disabled_1ny9q_74 ._label_1ny9q_10{color:var(--sui-color-text-disabled);cursor:not-allowed}._description_1ny9q_80{font-family:var(--sui-font-sans);font-size:var(--sui-font-size-sm);line-height:1.4}._description_1ny9q_80:empty{display:none}._descriptionHelper_1ny9q_88{color:var(--sui-color-text-secondary)}._descriptionError_1ny9q_89{color:var(--sui-color-text-error)}
2
+ /*$vite$:1*/