anicca-ui 1.0.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +371 -0
  3. package/dist/anicca-ui.css +1 -0
  4. package/dist/anicca-ui.es.js +927 -0
  5. package/dist/anicca-ui.umd.js +1 -0
  6. package/dist/dashboard/components/ActivityFeed/ActivityFeed.d.ts +27 -0
  7. package/dist/dashboard/components/ActivityFeed/index.d.ts +2 -0
  8. package/dist/dashboard/components/Breadcrumb/Breadcrumb.d.ts +25 -0
  9. package/dist/dashboard/components/Breadcrumb/index.d.ts +2 -0
  10. package/dist/dashboard/components/ChartWrapper/ChartWrapper.d.ts +34 -0
  11. package/dist/dashboard/components/ChartWrapper/index.d.ts +2 -0
  12. package/dist/dashboard/components/DataTable/DataTable.d.ts +38 -0
  13. package/dist/dashboard/components/DataTable/index.d.ts +2 -0
  14. package/dist/dashboard/components/Modal/Modal.d.ts +28 -0
  15. package/dist/dashboard/components/Modal/index.d.ts +2 -0
  16. package/dist/dashboard/components/Navbar/Navbar.d.ts +31 -0
  17. package/dist/dashboard/components/Navbar/index.d.ts +2 -0
  18. package/dist/dashboard/components/ProgressCard/ProgressCard.d.ts +39 -0
  19. package/dist/dashboard/components/ProgressCard/index.d.ts +2 -0
  20. package/dist/dashboard/components/Sidebar/Sidebar.d.ts +36 -0
  21. package/dist/dashboard/components/Sidebar/index.d.ts +2 -0
  22. package/dist/dashboard/components/StatCard/StatCard.d.ts +26 -0
  23. package/dist/dashboard/components/StatCard/index.d.ts +2 -0
  24. package/dist/dashboard/components/Tabs/Tabs.d.ts +28 -0
  25. package/dist/dashboard/components/Tabs/index.d.ts +2 -0
  26. package/dist/dashboard/index.d.ts +11 -0
  27. package/dist/date/hooks/useAniccaDate/index.d.ts +2 -0
  28. package/dist/date/hooks/useAniccaDate/useAniccaDate.d.ts +42 -0
  29. package/dist/date/index.d.ts +2 -0
  30. package/dist/date/utils/index.d.ts +82 -0
  31. package/dist/index.d.ts +6 -0
  32. package/dist/theme/AniccaThemeProvider.d.ts +27 -0
  33. package/dist/theme/index.d.ts +5 -0
  34. package/dist/theme/types.d.ts +39 -0
  35. package/dist/utils/functions/index.d.ts +109 -0
  36. package/dist/utils/hooks/useAniccaUtils/index.d.ts +2 -0
  37. package/dist/utils/hooks/useAniccaUtils/useAniccaUtils.d.ts +40 -0
  38. package/dist/utils/index.d.ts +2 -0
  39. package/dist/validation/hooks/useAniccaForm/index.d.ts +2 -0
  40. package/dist/validation/hooks/useAniccaForm/useAniccaForm.d.ts +60 -0
  41. package/dist/validation/index.d.ts +2 -0
  42. package/dist/validation/rules/index.d.ts +73 -0
  43. package/package.json +65 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 aniccaCode
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,371 @@
1
+ # anicca-ui
2
+
3
+ A production-ready React utility library with dashboard components, form validation, date manipulation, and general utilities. Zero external dependencies beyond React.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install anicca-ui
9
+ ```
10
+
11
+ ## Styles
12
+
13
+ Library ships satu stylesheet (Tailwind + custom utilities). Import sekali di entry app:
14
+
15
+ ```ts
16
+ import 'anicca-ui/styles.css'
17
+ ```
18
+
19
+ ## Theming
20
+
21
+ Override design tokens via CSS or React. Default theme bisa di-rebrand tanpa fork.
22
+
23
+ **Cara 1 — CSS variables (global):**
24
+
25
+ ```css
26
+ :root {
27
+ --anicca-primary: #ff00ff;
28
+ --anicca-radius: 0.5rem;
29
+ }
30
+ ```
31
+
32
+ **Cara 2 — React provider (scoped):**
33
+
34
+ ```tsx
35
+ import { AniccaThemeProvider, AniccaStatCard } from 'anicca-ui'
36
+ import 'anicca-ui/styles.css'
37
+
38
+ export default function App() {
39
+ return (
40
+ <AniccaThemeProvider theme={{ primary: '#ff00ff', success: '#00d18c' }}>
41
+ <AniccaStatCard title="Revenue" value="$48,200" trend={12.5} />
42
+ </AniccaThemeProvider>
43
+ )
44
+ }
45
+ ```
46
+
47
+ Token tersedia: `primary`, `primaryFg`, `primarySoft`, `success`, `successBg`, `danger`, `dangerBg`, `warning`, `warningBg`, `info`, `infoBg`, `surface`, `surfaceMuted`, `surfaceOverlay`, `surfaceDark`, `surfaceDark2`, `surfaceDarkFg`, `surfaceDarkFgMuted`, `border`, `borderStrong`, `borderDark`, `text`, `textMuted`, `textSubtle`, `radius`, `radiusSm`, `radiusLg`, `shadowSm`, `shadowMd`, `shadowLg`.
48
+
49
+ ## i18n
50
+
51
+ Komponen yang punya teks UI internal (DataTable, Modal, Sidebar, Navbar, ChartWrapper, ActivityFeed, ProgressCard) menerima prop `labels` untuk override:
52
+
53
+ ```tsx
54
+ <AniccaDataTable
55
+ data={users}
56
+ columns={cols}
57
+ labels={{
58
+ searchPlaceholder: 'Cari...',
59
+ results: 'hasil',
60
+ emptyMessage: 'Data kosong',
61
+ page: 'Halaman',
62
+ of: 'dari',
63
+ previous: '← Sebelumnya',
64
+ next: 'Berikutnya →',
65
+ }}
66
+ />
67
+
68
+ <AniccaModal open={open} onClose={close} title="Konfirmasi" labels={{ close: 'Tutup' }}>
69
+ ...
70
+ </AniccaModal>
71
+ ```
72
+
73
+ ## Modules
74
+
75
+ | Module | Description |
76
+ |--------|-------------|
77
+ | **Dashboard** | Pre-built UI components: StatCard, ChartWrapper, Sidebar, Navbar, Breadcrumb |
78
+ | **Validation** | Form validation with rules engine and `useAniccaForm` hook |
79
+ | **Date** | Date formatting, diffing, relative time, arithmetic — supports Indonesian & English |
80
+ | **Utils** | General utilities: debounce, throttle, slugify, clipboard, deep clone, and more |
81
+
82
+ ---
83
+
84
+ ## Dashboard Components
85
+
86
+ ### AniccaStatCard
87
+
88
+ ```tsx
89
+ import { AniccaStatCard } from 'anicca-ui'
90
+
91
+ function Dashboard() {
92
+ return (
93
+ <AniccaStatCard
94
+ title="Total Revenue"
95
+ value="$48,200"
96
+ trend={12.5}
97
+ trendLabel="vs last month"
98
+ color="#10b981"
99
+ icon={<span>💰</span>}
100
+ />
101
+ )
102
+ }
103
+ ```
104
+
105
+ ### AniccaChartWrapper
106
+
107
+ ```tsx
108
+ import { AniccaChartWrapper } from 'anicca-ui'
109
+
110
+ function Charts() {
111
+ return (
112
+ <AniccaChartWrapper
113
+ title="Monthly Sales"
114
+ subtitle="Last 6 months"
115
+ loading={false}
116
+ empty={false}
117
+ height={400}
118
+ >
119
+ {/* Your chart component here */}
120
+ <div>Chart content</div>
121
+ </AniccaChartWrapper>
122
+ )
123
+ }
124
+ ```
125
+
126
+ ### AniccaSidebar
127
+
128
+ ```tsx
129
+ import { AniccaSidebar } from 'anicca-ui'
130
+
131
+ function Layout() {
132
+ const items = [
133
+ { label: 'Dashboard', href: '/', icon: <span>📊</span> },
134
+ {
135
+ label: 'Products',
136
+ href: '/products',
137
+ icon: <span>📦</span>,
138
+ children: [
139
+ { label: 'All Products', href: '/products/all' },
140
+ { label: 'Add Product', href: '/products/add' },
141
+ ],
142
+ },
143
+ { label: 'Settings', href: '/settings', icon: <span>⚙️</span> },
144
+ ]
145
+
146
+ return (
147
+ <AniccaSidebar
148
+ items={items}
149
+ activePath="/products/all"
150
+ logo={<span>🚀 MyApp</span>}
151
+ collapsed={false}
152
+ onCollapse={(collapsed) => console.log(collapsed)}
153
+ />
154
+ )
155
+ }
156
+ ```
157
+
158
+ ### AniccaNavbar
159
+
160
+ ```tsx
161
+ import { AniccaNavbar } from 'anicca-ui'
162
+
163
+ function Header() {
164
+ return (
165
+ <AniccaNavbar
166
+ title="Admin Panel"
167
+ user={{ name: 'John Doe', role: 'Administrator' }}
168
+ onMenuToggle={() => console.log('toggle menu')}
169
+ actions={<button>🔔</button>}
170
+ />
171
+ )
172
+ }
173
+ ```
174
+
175
+ ### AniccaBreadcrumb
176
+
177
+ ```tsx
178
+ import { AniccaBreadcrumb } from 'anicca-ui'
179
+
180
+ function PageHeader() {
181
+ return (
182
+ <AniccaBreadcrumb
183
+ items={[
184
+ { label: 'Home', href: '/' },
185
+ { label: 'Products', href: '/products' },
186
+ { label: 'Edit Product' },
187
+ ]}
188
+ separator="›"
189
+ />
190
+ )
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Form Validation
197
+
198
+ ```tsx
199
+ import { useAniccaForm, required, email, minLength } from 'anicca-ui'
200
+
201
+ function LoginForm() {
202
+ const { values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting } =
203
+ useAniccaForm({
204
+ initialValues: { email: '', password: '' },
205
+ validationSchema: {
206
+ email: [required(), email()],
207
+ password: [required(), minLength(8)],
208
+ },
209
+ onSubmit: async (values) => {
210
+ await fetch('/api/login', {
211
+ method: 'POST',
212
+ body: JSON.stringify(values),
213
+ })
214
+ },
215
+ })
216
+
217
+ return (
218
+ <form onSubmit={handleSubmit}>
219
+ <input
220
+ value={values.email as string}
221
+ onChange={handleChange('email')}
222
+ onBlur={handleBlur('email')}
223
+ placeholder="Email"
224
+ />
225
+ {touched.email && errors.email && <span>{errors.email}</span>}
226
+
227
+ <input
228
+ type="password"
229
+ value={values.password as string}
230
+ onChange={handleChange('password')}
231
+ onBlur={handleBlur('password')}
232
+ placeholder="Password"
233
+ />
234
+ {touched.password && errors.password && <span>{errors.password}</span>}
235
+
236
+ <button type="submit" disabled={isSubmitting}>
237
+ {isSubmitting ? 'Loading...' : 'Login'}
238
+ </button>
239
+ </form>
240
+ )
241
+ }
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Date Utils
247
+
248
+ ```tsx
249
+ import { useAniccaDate, aniccaFormat, aniccaRelative } from 'anicca-ui'
250
+
251
+ function DateExample() {
252
+ const { date, setDate, format, relative, add, isBefore } = useAniccaDate(new Date())
253
+
254
+ return (
255
+ <div>
256
+ <p>{format('dddd, DD MMMM YYYY', 'id')}</p>
257
+ {/* "Senin, 15 Januari 2024" */}
258
+
259
+ <p>{relative('id')}</p>
260
+ {/* "baru saja" */}
261
+
262
+ <p>{format('DD/MM/YYYY HH:mm', 'en')}</p>
263
+ {/* "15/01/2024 14:30" */}
264
+
265
+ <button onClick={() => setDate(add(7, 'days'))}>
266
+ +7 Days
267
+ </button>
268
+ </div>
269
+ )
270
+ }
271
+
272
+ // Standalone usage
273
+ const formatted = aniccaFormat(new Date(), 'dddd, DD MMMM YYYY', 'id')
274
+ const rel = aniccaRelative('2024-01-01', 'id') // "X bulan lalu"
275
+ ```
276
+
277
+ ---
278
+
279
+ ## General Utils
280
+
281
+ ```tsx
282
+ import { aniccaDebounce, aniccaTruncate, aniccaCopyToClipboard, useAniccaUtils } from 'anicca-ui'
283
+
284
+ // Standalone
285
+ const debouncedSearch = aniccaDebounce((query: string) => {
286
+ fetch(`/api/search?q=${query}`)
287
+ }, 300)
288
+
289
+ const truncated = aniccaTruncate('This is a very long text', 10)
290
+ // "This is a ..."
291
+
292
+ async function copyLink() {
293
+ const success = await aniccaCopyToClipboard('https://example.com')
294
+ if (success) alert('Copied!')
295
+ }
296
+
297
+ // Hook usage
298
+ function Component() {
299
+ const { slugify, capitalize, groupBy, uniqueBy } = useAniccaUtils()
300
+
301
+ const slug = slugify('Hello World!') // "hello-world"
302
+ const cap = capitalize('hello') // "Hello"
303
+
304
+ return <div>{slug}</div>
305
+ }
306
+ ```
307
+
308
+ ---
309
+
310
+ ## API Reference
311
+
312
+ ### Dashboard Components
313
+
314
+ | Export | Type | Props | Description |
315
+ |--------|------|-------|-------------|
316
+ | `AniccaStatCard` | Component | `title, value, icon?, trend?, trendLabel?, color?, className?` | Stat card with trend indicator |
317
+ | `AniccaChartWrapper` | Component | `title, subtitle?, children, loading?, empty?, emptyMessage?, height?, className?` | Chart container with loading/empty states |
318
+ | `AniccaSidebar` | Component | `items, collapsed?, onCollapse?, logo?, footer?, activePath?, className?` | Collapsible sidebar navigation |
319
+ | `AniccaNavbar` | Component | `title?, logo?, actions?, user?, onMenuToggle?, className?` | Top navigation bar |
320
+ | `AniccaBreadcrumb` | Component | `items, separator?, className?` | Breadcrumb navigation |
321
+
322
+ ### Validation
323
+
324
+ | Export | Type | Params | Returns | Description |
325
+ |--------|------|--------|---------|-------------|
326
+ | `useAniccaForm` | Hook | `{ initialValues, validationSchema?, onSubmit? }` | `{ values, errors, touched, isValid, isSubmitting, handleChange, handleBlur, handleSubmit, reset, setFieldValue, setFieldError }` | Form state management |
327
+ | `required` | Function | `message?` | `ValidationRule` | Required field rule |
328
+ | `email` | Function | `message?` | `ValidationRule` | Email format rule |
329
+ | `minLength` | Function | `min, message?` | `ValidationRule` | Minimum length rule |
330
+ | `maxLength` | Function | `max, message?` | `ValidationRule` | Maximum length rule |
331
+ | `pattern` | Function | `regex, message?` | `ValidationRule` | Regex pattern rule |
332
+ | `min` | Function | `value, message?` | `ValidationRule` | Minimum number rule |
333
+ | `max` | Function | `value, message?` | `ValidationRule` | Maximum number rule |
334
+ | `custom` | Function | `fn, message` | `ValidationRule` | Custom validation rule |
335
+
336
+ ### Date
337
+
338
+ | Export | Type | Params | Returns | Description |
339
+ |--------|------|--------|---------|-------------|
340
+ | `useAniccaDate` | Hook | `initialDate?` | `{ date, setDate, format, diff, relative, add, startOf, endOf, isValid, isBefore, isAfter }` | Date manipulation hook |
341
+ | `aniccaFormat` | Function | `date, format, locale?` | `string` | Format date with tokens |
342
+ | `aniccaDiff` | Function | `date1, date2, unit` | `number` | Absolute difference between dates |
343
+ | `aniccaRelative` | Function | `date, locale?` | `string` | Relative time string |
344
+ | `aniccaStartOf` | Function | `date, unit` | `Date` | Start of time unit |
345
+ | `aniccaEndOf` | Function | `date, unit` | `Date` | End of time unit |
346
+ | `aniccaAdd` | Function | `date, amount, unit` | `Date` | Add/subtract time |
347
+ | `aniccaIsValid` | Function | `date` | `boolean` | Check if valid date |
348
+ | `aniccaIsBefore` | Function | `date1, date2` | `boolean` | Check if before |
349
+ | `aniccaIsAfter` | Function | `date1, date2` | `boolean` | Check if after |
350
+
351
+ ### Utils
352
+
353
+ | Export | Type | Params | Returns | Description |
354
+ |--------|------|--------|---------|-------------|
355
+ | `useAniccaUtils` | Hook | — | `{ debounce, throttle, truncate, copyToClipboard, slugify, capitalize, deepClone, flattenObject, groupBy, uniqueBy }` | All utils as hook |
356
+ | `aniccaDebounce` | Function | `fn, delay` | `(...args) => void` | Debounce a function |
357
+ | `aniccaThrottle` | Function | `fn, limit` | `(...args) => void` | Throttle a function |
358
+ | `aniccaTruncate` | Function | `str, length, suffix?` | `string` | Truncate string |
359
+ | `aniccaCopyToClipboard` | Function | `text` | `Promise<boolean>` | Copy to clipboard |
360
+ | `aniccaSlugify` | Function | `str` | `string` | String to slug |
361
+ | `aniccaCapitalize` | Function | `str` | `string` | Capitalize first letter |
362
+ | `aniccaDeepClone` | Function | `obj` | `T` | Deep clone object |
363
+ | `aniccaFlattenObject` | Function | `obj, prefix?` | `Record<string, unknown>` | Flatten nested object |
364
+ | `aniccaGroupBy` | Function | `array, key` | `Record<string, T[]>` | Group array by key |
365
+ | `aniccaUniqueBy` | Function | `array, key` | `T[]` | Deduplicate by key |
366
+
367
+ ---
368
+
369
+ ## License
370
+
371
+ MIT — aniccaCode
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-0{bottom:0}.left-\[18px\]{left:18px}.top-0{top:0}.top-\[48px\]{top:48px}.z-\[1000\]{z-index:1000}.z-\[100\]{z-index:100}.z-\[1\]{z-index:1}.m-0{margin:0}.mx-1{margin-left:.25rem;margin-right:.25rem}.-mb-px{margin-bottom:-1px}.-ml-\[6px\]{margin-left:-6px}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-5{margin-bottom:1.25rem}.mb-\[2px\]{margin-bottom:2px}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-\[0\.2rem\]{margin-top:.2rem}.mt-\[0\.3rem\]{margin-top:.3rem}.mt-\[0\.4rem\]{margin-top:.4rem}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.hidden{display:none}.h-14{height:3.5rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[22px\]{height:22px}.h-\[38px\]{height:38px}.h-\[68px\]{height:68px}.h-\[7px\]{height:7px}.h-full{height:100%}.h-screen{height:100vh}.max-h-0{max-height:0px}.max-h-\[500px\]{max-height:500px}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0px}.min-h-\[72px\]{min-height:72px}.w-14{width:3.5rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\[1\.5px\]{width:1.5px}.w-\[200px\]{width:200px}.w-\[22px\]{width:22px}.w-\[260px\]{width:260px}.w-\[38px\]{width:38px}.w-\[72px\]{width:72px}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-\[480px\]{max-width:480px}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.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)}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-\[0\.35rem\]{gap:.35rem}.gap-\[0\.4rem\]{gap:.4rem}.gap-\[0\.85rem\]{gap:.85rem}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-\[20px\]{border-radius:20px}.rounded-a{border-radius:var(--anicca-radius)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-\[1\.5px\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-a-border{border-color:var(--anicca-border)}.border-a-border-dark{border-color:var(--anicca-border-dark)}.border-a-surface{border-color:var(--anicca-surface)}.border-b-a-primary{border-bottom-color:var(--anicca-primary)}.border-b-transparent{border-bottom-color:transparent}.bg-a-danger-bg{background-color:var(--anicca-danger-bg)}.bg-a-info-bg{background-color:var(--anicca-info-bg)}.bg-a-primary-soft{background-color:var(--anicca-primary-soft)}.bg-a-success-bg{background-color:var(--anicca-success-bg)}.bg-a-surface{background-color:var(--anicca-surface)}.bg-a-surface-muted{background-color:var(--anicca-surface-muted)}.bg-transparent{background-color:transparent}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-a-border{--tw-gradient-from: var(--anicca-border) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-a-surface{--tw-gradient-from: var(--anicca-surface) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-a-surface-dark{--tw-gradient-from: var(--anicca-surface-dark) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-a-surface-dark-2{--tw-gradient-to: var(--anicca-surface-dark-2) var(--tw-gradient-to-position)}.to-a-surface-muted{--tw-gradient-to: var(--anicca-surface-muted) var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.stroke-\[1\.2\]{stroke-width:1.2}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-7{padding-left:1.75rem;padding-right:1.75rem}.px-\[0\.55rem\]{padding-left:.55rem;padding-right:.55rem}.px-\[0\.6rem\]{padding-left:.6rem;padding-right:.6rem}.px-\[0\.7rem\]{padding-left:.7rem;padding-right:.7rem}.px-\[0\.85rem\]{padding-left:.85rem;padding-right:.85rem}.px-\[1\.1rem\]{padding-left:1.1rem;padding-right:1.1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-\[0\.2rem\]{padding-top:.2rem;padding-bottom:.2rem}.py-\[0\.3rem\]{padding-top:.3rem;padding-bottom:.3rem}.py-\[0\.4rem\]{padding-top:.4rem;padding-bottom:.4rem}.py-\[0\.65rem\]{padding-top:.65rem;padding-bottom:.65rem}.py-\[0\.6rem\]{padding-top:.6rem;padding-bottom:.6rem}.py-\[0\.7rem\]{padding-top:.7rem;padding-bottom:.7rem}.py-\[0\.85rem\]{padding-top:.85rem;padding-bottom:.85rem}.pl-11{padding-left:2.75rem}.pl-2{padding-left:.5rem}.pl-\[0\.4rem\]{padding-left:.4rem}.pr-\[0\.6rem\]{padding-right:.6rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.align-middle{vertical-align:middle}.font-\[inherit\]{font-family:inherit}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[0\.55rem\]{font-size:.55rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.68rem\]{font-size:.68rem}.text-\[0\.78rem\]{font-size:.78rem}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.82rem\]{font-size:.82rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[0\.9rem\]{font-size:.9rem}.text-\[1\.05rem\]{font-size:1.05rem}.text-\[1\.1rem\]{font-size:1.1rem}.text-\[1\.2rem\]{font-size:1.2rem}.text-\[2rem\]{font-size:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.leading-\[1\.1\]{line-height:1.1}.leading-relaxed{line-height:1.625}.tracking-\[-0\.01em\]{letter-spacing:-.01em}.tracking-\[0\.05em\]{letter-spacing:.05em}.tracking-\[0\.06em\]{letter-spacing:.06em}.tracking-tight{letter-spacing:-.025em}.text-a-danger{color:var(--anicca-danger)}.text-a-info{color:var(--anicca-info)}.text-a-primary{color:var(--anicca-primary)}.text-a-primary-fg{color:var(--anicca-primary-fg)}.text-a-success{color:var(--anicca-success)}.text-a-surface-dark-fg{color:var(--anicca-surface-dark-fg)}.text-a-surface-dark-fg-muted{color:var(--anicca-surface-dark-fg-muted)}.text-a-text{color:var(--anicca-text)}.text-a-text-muted{color:var(--anicca-text-muted)}.text-a-text-subtle{color:var(--anicca-text-subtle)}.no-underline{text-decoration-line:none}.opacity-100{opacity:1}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-80{opacity:.8}.shadow-a-lg{--tw-shadow: var(--anicca-shadow-lg);--tw-shadow-colored: var(--anicca-shadow-lg);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-a-sm{--tw-shadow: var(--anicca-shadow-sm);--tw-shadow-colored: var(--anicca-shadow-sm);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-\[12px\]{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-\[4px\]{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[max-height\]{transition-property:max-height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-\[250ms\]{transition-duration:.25s}.duration-\[350ms\]{transition-duration:.35s}.ease-\[cubic-bezier\(0\.4\,0\,0\.2\,1\)\],.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.anicca-shimmer{background:linear-gradient(90deg,var(--anicca-surface-muted) 0%,var(--anicca-border) 20%,var(--anicca-surface-muted) 40%,var(--anicca-surface-muted) 100%);background-size:300% 100%;animation:anicca-shimmer 1.8s ease-in-out infinite}.anicca-empty-bg{background:repeating-linear-gradient(-45deg,transparent,transparent 8px,var(--anicca-primary-soft) 8px,var(--anicca-primary-soft) 16px)}.anicca-fade-in{animation:anicca-fade-in .2s ease}.anicca-slide-up{animation:anicca-slide-up .25s cubic-bezier(.4,0,.2,1)}@keyframes anicca-shimmer{0%{background-position:100% 0}to{background-position:-100% 0}}@keyframes anicca-fade-in{0%{opacity:0}to{opacity:1}}@keyframes anicca-slide-up{0%{opacity:0;transform:translateY(16px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.placeholder\:text-a-text-subtle::-moz-placeholder{color:var(--anicca-text-subtle)}.placeholder\:text-a-text-subtle::placeholder{color:var(--anicca-text-subtle)}.first\:ml-0:first-child{margin-left:0}.last\:border-b-0:last-child{border-bottom-width:0px}.last\:pb-0:last-child{padding-bottom:0}.focus-within\:border-a-primary:focus-within{border-color:var(--anicca-primary)}.focus-within\:shadow-\[0_0_0_3px_var\(--anicca-primary-soft\)\]:focus-within{--tw-shadow: 0 0 0 3px var(--anicca-primary-soft);--tw-shadow-colored: 0 0 0 3px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:-translate-y-1:hover{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-a-border:hover{background-color:var(--anicca-border)}.hover\:bg-a-primary-soft:hover{background-color:var(--anicca-primary-soft)}.hover\:bg-a-surface-dark-2:hover{background-color:var(--anicca-surface-dark-2)}.hover\:bg-a-surface-muted:hover{background-color:var(--anicca-surface-muted)}.hover\:text-a-primary:hover{color:var(--anicca-primary)}.hover\:text-a-surface-dark-fg:hover{color:var(--anicca-surface-dark-fg)}.hover\:text-a-text:hover{color:var(--anicca-text)}.hover\:shadow-a-md:hover{--tw-shadow: var(--anicca-shadow-md);--tw-shadow-colored: var(--anicca-shadow-md);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:enabled\:border-a-primary:enabled:hover{border-color:var(--anicca-primary)}.hover\:enabled\:text-a-primary:enabled:hover{color:var(--anicca-primary)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.group\/item:hover .group-hover\/item\:scale-110,.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:\[\&\>td\]\:bg-a-surface-muted>td:hover{background-color:var(--anicca-surface-muted)}