@ishtar-sink/vega 0.0.0-stage → 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.
Files changed (55) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +99 -2
  3. package/dist/autocomplete/autocomplete.d.ts +37 -0
  4. package/dist/badge/badge.d.ts +8 -0
  5. package/dist/brand-logo/brand-logo.d.ts +9 -0
  6. package/dist/button/button.d.ts +11 -0
  7. package/dist/calendar/calendar.d.ts +28 -0
  8. package/dist/card/card.d.ts +9 -0
  9. package/dist/checkbox/checkbox.d.ts +6 -0
  10. package/dist/color-field/color-field.d.ts +20 -0
  11. package/dist/color-field/color-picker.d.ts +42 -0
  12. package/dist/color-field/color.d.ts +11 -0
  13. package/dist/confirm-dialog/confirm-dialog.d.ts +15 -0
  14. package/dist/date-field/date-field.d.ts +38 -0
  15. package/dist/date-time-field/date-time-field.d.ts +33 -0
  16. package/dist/dialog/dialog.d.ts +21 -0
  17. package/dist/empty-state/empty-state.d.ts +10 -0
  18. package/dist/error-state/error-state.d.ts +12 -0
  19. package/dist/form-layout/form-layout.d.ts +17 -0
  20. package/dist/icon-button/icon-button.d.ts +10 -0
  21. package/dist/icons/index.d.ts +2 -0
  22. package/dist/icons/view-icons.d.ts +17 -0
  23. package/dist/index.d.ts +75 -0
  24. package/dist/index.js +2917 -0
  25. package/dist/item-swatch/item-swatch.d.ts +10 -0
  26. package/dist/item-swatch/palette.d.ts +6 -0
  27. package/dist/loading-state/loading-state.d.ts +13 -0
  28. package/dist/menu-button/menu-button.d.ts +26 -0
  29. package/dist/money-field/money-field.d.ts +13 -0
  30. package/dist/money-field/money-mask.d.ts +6 -0
  31. package/dist/page-header/page-header.d.ts +20 -0
  32. package/dist/period-field/period-field.d.ts +47 -0
  33. package/dist/period-field/period.d.ts +31 -0
  34. package/dist/progress-bar/progress-bar.d.ts +10 -0
  35. package/dist/segmented-field/segmented-field.d.ts +24 -0
  36. package/dist/select-field/select-field.d.ts +24 -0
  37. package/dist/style.css +2 -0
  38. package/dist/tabs/tabs.d.ts +19 -0
  39. package/dist/tag-field/tag-field.d.ts +20 -0
  40. package/dist/text-field/text-field.d.ts +10 -0
  41. package/dist/theme/contrast.d.ts +16 -0
  42. package/dist/theme/index.d.ts +5 -0
  43. package/dist/theme/theme.d.ts +15 -0
  44. package/dist/theme/tokens.d.ts +138 -0
  45. package/dist/time-field/parse-time.d.ts +4 -0
  46. package/dist/time-field/time-field.d.ts +20 -0
  47. package/dist/toast/toast.d.ts +11 -0
  48. package/dist/tokens.css +166 -0
  49. package/dist/toolbar/toolbar.d.ts +16 -0
  50. package/dist/view-switcher/view-switcher.d.ts +19 -0
  51. package/fonts/OFL-Inter.txt +92 -0
  52. package/fonts/OFL-Outfit.txt +93 -0
  53. package/fonts/inter-variable.woff2 +0 -0
  54. package/fonts/outfit-variable.ttf +0 -0
  55. package/package.json +65 -4
@@ -0,0 +1,10 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ import { ItemPalette } from './palette';
3
+ export interface ItemSwatchProps extends ComponentPropsWithRef<'span'> {
4
+ /** Id do item (não vai para o DOM): o mesmo id sempre gera o mesmo par de cores. */
5
+ id: string;
6
+ /** Pares de cor [início, fim] do gradiente; sem ela, usa a paleta padrão do tema. */
7
+ palette?: ItemPalette;
8
+ }
9
+ /** Quadrado em gradiente que identifica um item sem imagem própria; decorativo. */
10
+ export declare function ItemSwatch({ id, palette, className, style, children, ...rest }: ItemSwatchProps): import('react').JSX.Element;
@@ -0,0 +1,6 @@
1
+ /** Pares de cor do gradiente de um item, do início ao fim. */
2
+ export type ItemPalette = ReadonlyArray<readonly [string, string]>;
3
+ /** Paleta padrão: as variáveis --item-palette-N-from/to do tema, sem cor literal; segue o tema e pode ser sobrescrita por CSS. */
4
+ export declare const DEFAULT_ITEM_PALETTE: ItemPalette;
5
+ /** Mesmo id, mesmo par, sem estado guardado; paleta vazia usa a padrão. */
6
+ export declare function pairFor(id: string, palette?: ItemPalette): readonly [string, string];
@@ -0,0 +1,13 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface SkeletonProps extends ComponentPropsWithRef<'div'> {
3
+ /** Quantidade de linhas do esqueleto. */
4
+ rows?: number;
5
+ }
6
+ export declare function Skeleton({ rows, className, style, ...rest }: SkeletonProps): import('react').JSX.Element;
7
+ export interface LoadingStateProps extends ComponentPropsWithRef<'div'> {
8
+ /** Texto lido por leitores de tela enquanto carrega. */
9
+ label?: string;
10
+ /** Quantidade de linhas do esqueleto. */
11
+ rows?: number;
12
+ }
13
+ export declare function LoadingState({ label, rows, className, style, ...rest }: LoadingStateProps): import('react').JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { ComponentPropsWithRef, ReactNode } from 'react';
2
+ export interface MenuItem {
3
+ id: string;
4
+ label: string;
5
+ icon?: ReactNode;
6
+ tone?: 'danger';
7
+ href?: string;
8
+ onSelect?: () => void;
9
+ }
10
+ export interface MenuButtonProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
11
+ /** Nome acessível do botão. Sem ele, o botão é nomeado pelo próprio conteúdo visível. */
12
+ label?: string;
13
+ /** Rótulo do menu aberto. Padrão: `label`. */
14
+ menuLabel?: string;
15
+ /** Conteúdo visível do botão. */
16
+ trigger: ReactNode;
17
+ /** Itens do menu, na ordem. */
18
+ items: readonly MenuItem[];
19
+ /** Posição do menu em relação ao botão. Padrão: `bottom-end`. */
20
+ placement?: 'bottom-end' | 'right-end';
21
+ /** Classe extra do menu aberto, para quem precisa de um visual próprio (ex.: menu da conta). */
22
+ menuClassName?: string;
23
+ /** Classe do botão. */
24
+ triggerClassName?: string;
25
+ }
26
+ export declare function MenuButton({ label, menuLabel, trigger, items, placement, className, menuClassName, triggerClassName, style, ref, ...rest }: MenuButtonProps): import('react').JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { TextFieldProps } from '../text-field/text-field';
2
+ export interface MoneyFieldProps extends Omit<TextFieldProps, 'value' | 'defaultValue' | 'onChange' | 'type' | 'inputMode'> {
3
+ /** Valor em centavos inteiros; `null` quando vazio. */
4
+ valueCents: number | null;
5
+ /** Recebe os centavos inteiros a cada digitação, ou `null` quando vazio. */
6
+ onChange: (cents: number | null) => void;
7
+ /** Locale dos separadores e do símbolo, no formato BCP 47. Padrão: `pt-BR`. */
8
+ locale?: string;
9
+ /** Moeda ISO 4217. Padrão: `BRL`. */
10
+ currency?: string;
11
+ }
12
+ /** Campo de moeda: mostra o valor formatado ao digitar e entrega sempre centavos inteiros. */
13
+ export declare function MoneyField({ valueCents, onChange, locale, currency, onBlur, className, ...rest }: MoneyFieldProps): import('react').JSX.Element;
@@ -0,0 +1,6 @@
1
+ /** Formata o texto digitado, sem completar os decimais. */
2
+ export declare function maskMoneyInput(text: string, locale: string, currency: string): string;
3
+ /** Centavos inteiros do texto, ou `null` se vazio ou fora do inteiro seguro. */
4
+ export declare function parseMoneyInput(text: string, locale: string, currency: string): number | null;
5
+ /** Valor em centavos formatado com duas casas no locale e na moeda. */
6
+ export declare function formatCents(cents: number, locale: string, currency: string): string;
@@ -0,0 +1,20 @@
1
+ import { ComponentPropsWithRef, ReactNode, Ref } from 'react';
2
+ export interface PageHeaderProps extends Omit<ComponentPropsWithRef<'header'>, 'title'> {
3
+ /** Texto do título (`h1`). */
4
+ title: string;
5
+ /** Texto curto acima do título. */
6
+ eyebrow?: string;
7
+ /** Texto de apoio abaixo do título; some no estado compacto. */
8
+ subtitle?: string;
9
+ /** Ações alinhadas ao fim do cabeçalho. */
10
+ actions?: ReactNode;
11
+ /** "Voltar" acima do eyebrow e do título. */
12
+ back?: ReactNode;
13
+ /** Preso sob a barra superior: mostra o fundo de desfoque. */
14
+ stuck?: boolean;
15
+ /** Título menor e sem subtítulo, depois de rolar a página. */
16
+ compact?: boolean;
17
+ /** Ref do `h1`, para levar o foco ao título ao trocar de página. */
18
+ headingRef?: Ref<HTMLHeadingElement>;
19
+ }
20
+ export declare function PageHeader({ title, eyebrow, subtitle, actions, back, stuck, compact, headingRef, className, ...rest }: PageHeaderProps): import('react').JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ import { PeriodPreset, PeriodValue } from './period';
3
+ export interface PeriodFieldLabels {
4
+ /** Nome do popover. */
5
+ title: string;
6
+ /** Título da área do intervalo personalizado e texto do gatilho sem datas. */
7
+ custom: string;
8
+ /** Botão que aplica o intervalo personalizado. */
9
+ apply: string;
10
+ /** Instrução quando nenhum dia foi escolhido. */
11
+ firstDay: string;
12
+ /** Sufixo depois do primeiro dia, pedindo o último. */
13
+ lastDay: string;
14
+ /** Erro ao aplicar sem o primeiro dia. */
15
+ firstDayError: string;
16
+ /** Nome do botão do mês anterior. */
17
+ previous: string;
18
+ /** Nome do botão do próximo mês. */
19
+ next: string;
20
+ /** Sufixo do dia atual no nome acessível. */
21
+ todayMarker: string;
22
+ }
23
+ export interface PeriodFieldProps extends Omit<ComponentPropsWithRef<'button'>, 'onChange' | 'value' | 'defaultValue' | 'children' | 'name' | 'type'> {
24
+ /** Rótulo do campo. */
25
+ label?: string;
26
+ /** `false` deixa o rótulo só para leitores de tela. Padrão: `true`. */
27
+ labelVisible?: boolean;
28
+ /** Período atual: o `id` de um preset ou `custom` com `from` e `to`. */
29
+ value: PeriodValue;
30
+ /** Chamado com o período escolhido. */
31
+ onChange: (value: PeriodValue) => void;
32
+ /** Períodos oferecidos, definidos por quem usa o componente. */
33
+ presets: readonly PeriodPreset[];
34
+ /** Mostra a área de intervalo personalizado. Padrão: `true`. */
35
+ allowCustom?: boolean;
36
+ /** Onde o popover se ancora: alinhado à direita na barra, centrado no formulário. */
37
+ placement: 'toolbar' | 'form';
38
+ /** Dia atual (`YYYY-MM-DD`); padrão: a data do navegador, lida só quando a prop falta. */
39
+ today?: string;
40
+ /** Locale das datas. Padrão: `pt-BR`. */
41
+ locale?: string;
42
+ /** Textos do campo; o que faltar usa o padrão em pt-br, qualquer que seja o `locale`. */
43
+ labels?: Partial<PeriodFieldLabels>;
44
+ /** Com `name`, o campo envia `name`, `<name>From` e `<name>To` em um formulário. */
45
+ name?: string;
46
+ }
47
+ export declare function PeriodField({ label, labelVisible, value, onChange, presets, allowCustom, placement, today: todayProp, locale, labels, name, className, style, ref, ...rest }: PeriodFieldProps): import('react').JSX.Element;
@@ -0,0 +1,31 @@
1
+ /** Intervalo de datas `YYYY-MM-DD`, com as duas pontas incluídas. */
2
+ export interface PeriodRange {
3
+ from: string;
4
+ to: string;
5
+ }
6
+ /**
7
+ * Regra de um período. Um inteiro `n` é uma janela de dias a partir de hoje: positivo vai de
8
+ * hoje até hoje + n, negativo de hoje + n até hoje e zero é só hoje. Uma função recebe o dia
9
+ * atual (`YYYY-MM-DD`) e devolve o intervalo, ou `null` para "sem limite".
10
+ */
11
+ export type PeriodRule = number | ((today: string) => PeriodRange | null);
12
+ /** Período oferecido pelo `PeriodField`, definido por quem usa o componente. */
13
+ export interface PeriodPreset {
14
+ /** Identificador estável; é o `preset` guardado no `PeriodValue`. */
15
+ id: string;
16
+ /** Texto do botão e do gatilho. */
17
+ label: string;
18
+ /** Como o período vira um intervalo a partir de hoje. */
19
+ range: PeriodRule;
20
+ }
21
+ /** Valor do `PeriodField`: o `id` de um `PeriodPreset` ou `custom` com `from` e `to`. */
22
+ export interface PeriodValue {
23
+ preset: string;
24
+ from?: string;
25
+ to?: string;
26
+ }
27
+ /**
28
+ * Intervalo de um período a partir de hoje (`YYYY-MM-DD`). Devolve `null` quando o preset não
29
+ * está em `presets` ou quando a regra não limita o período.
30
+ */
31
+ export declare function resolvePeriod(value: PeriodValue, today: string, presets?: readonly PeriodPreset[]): PeriodRange | null;
@@ -0,0 +1,10 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface ProgressBarProps extends ComponentPropsWithRef<'div'> {
3
+ /** Nome acessível da barra (não é exibido). */
4
+ label: string;
5
+ /** Valor atual, limitado entre 0 e `max`. */
6
+ value: number;
7
+ /** Valor que representa 100%. */
8
+ max?: number;
9
+ }
10
+ export declare function ProgressBar({ label, value, max, className, style, ...rest }: ProgressBarProps): import('react').JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface SegmentedOption {
3
+ value: string;
4
+ label: string;
5
+ }
6
+ export interface SegmentedFieldProps extends Omit<ComponentPropsWithRef<'fieldset'>, 'onChange' | 'onBlur' | 'children'> {
7
+ /** Rótulo visível do grupo (a legenda do `<fieldset>`). */
8
+ label: string;
9
+ /** Opções exibidas como segmentos. */
10
+ options: readonly SegmentedOption[];
11
+ /** Valor da opção escolhida. */
12
+ value: string;
13
+ /** Chamada com o valor da opção escolhida. */
14
+ onChange: (value: string) => void;
15
+ /** Chamada quando um segmento perde o foco. */
16
+ onBlur?: () => void;
17
+ /** Nome dos rádios; sem ele, um nome gerado agrupa as opções. */
18
+ name?: string;
19
+ /** Mensagem de erro; aparece com `role="alert"` ligada ao grupo. */
20
+ error?: string;
21
+ /** Texto de ajuda abaixo do grupo. */
22
+ help?: string;
23
+ }
24
+ export declare function SegmentedField({ label, options, value, onChange, onBlur, name, error, help, className, style, 'aria-describedby': describedByProp, ...rest }: SegmentedFieldProps): import('react').JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface SelectOption {
3
+ value: string;
4
+ label: string;
5
+ }
6
+ export interface SelectFieldProps extends Omit<ComponentPropsWithRef<'button'>, 'value' | 'onChange' | 'onBlur' | 'children' | 'type'> {
7
+ /** Rótulo visível do campo. */
8
+ label: string;
9
+ /** Texto de ajuda abaixo do campo. */
10
+ help?: string;
11
+ /** Mensagem de erro; aparece com `role="alert"` e marca o campo como inválido. */
12
+ error?: string;
13
+ /** Opções da lista. */
14
+ options: readonly SelectOption[];
15
+ /** Valor da opção escolhida. */
16
+ value: string;
17
+ /** Chamada com o valor da opção escolhida. */
18
+ onChange: (value: string) => void;
19
+ /** Chamada quando o gatilho perde o foco com a lista fechada. */
20
+ onBlur?: () => void;
21
+ /** Texto mostrado quando nenhuma opção corresponde ao valor. */
22
+ placeholder?: string;
23
+ }
24
+ export declare function SelectField({ label, help, error, id, className, style, options, value, onChange, onBlur, placeholder, disabled, name, ref, 'aria-describedby': describedByProp, 'aria-invalid': ariaInvalid, ...rest }: SelectFieldProps): import('react').JSX.Element;
package/dist/style.css ADDED
@@ -0,0 +1,2 @@
1
+ ._root_1nm00_1{justify-content:center;align-items:center;gap:calc(var(--space) * 2);min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 4);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);font-weight:var(--font-weight-semibold);cursor:pointer;transition:background var(--motion-fast) var(--motion-ease-standard), color var(--motion-fast) var(--motion-ease-standard);display:inline-flex}._root_1nm00_1:hover:not(:disabled){background:var(--surface-hover)}._root_1nm00_1:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 2)}._root_1nm00_1:disabled{background:var(--surface-muted);color:var(--text-muted);cursor:not-allowed}._primary_1nm00_36{border-color:var(--primary);background:var(--primary);color:var(--primary-on)}._primary_1nm00_36:hover:not(:disabled){background:var(--primary-hover)}._primary_1nm00_36:disabled,._secondary_1nm00_50{border-color:var(--border-strong)}._ghost_1nm00_54{box-shadow:none;color:var(--primary);background:0 0;border-color:#0000}._ghost_1nm00_54:hover:not(:disabled){background:var(--primary-soft)}._ghost_1nm00_54:disabled{background:0 0}._muted_1nm00_69{box-shadow:none;color:var(--text-muted);background:0 0;border-color:#0000}._muted_1nm00_69:hover:not(:disabled){color:var(--primary);background:0 0}._muted_1nm00_69._tinted_1nm00_81{color:color-mix(in srgb, var(--button-tint) 60%, transparent)}._muted_1nm00_69._tinted_1nm00_81:hover:not(:disabled){color:var(--button-tint)}._muted_1nm00_69[aria-pressed=true]{color:var(--success)}._muted_1nm00_69:disabled{background:0 0}._success_1nm00_97{background:var(--success-soft);box-shadow:none;color:var(--success);border-color:#0000}._success_1nm00_97:hover:not(:disabled){background:color-mix(in srgb, var(--success) 22%, var(--success-soft))}._success_1nm00_97[aria-pressed=true]{background:var(--success);color:var(--surface)}._success_1nm00_97[aria-pressed=true]:hover:not(:disabled){background:color-mix(in srgb, var(--success) 85%, var(--text))}._spinner_1nm00_118{width:calc(var(--space) * 4);height:calc(var(--space) * 4);border:calc(var(--space) / 2) solid currentColor;border-radius:var(--radius-pill);animation:_button-spin_1nm00_1 var(--motion-slow) var(--motion-ease-linear) infinite;border-right-color:#0000;flex:none}@keyframes _button-spin_1nm00_1{to{transform:rotate(360deg)}}._root_1nm00_1[aria-busy=true]{cursor:progress}._primary_1nm00_36[aria-busy=true]{border-color:var(--primary);background:var(--primary);color:var(--primary-on)}._root_kpb9b_1{width:calc(var(--space) * 10);height:calc(var(--space) * 10);border:calc(var(--space) / 4) solid transparent;border-radius:var(--radius-pill);color:var(--text-muted);cursor:pointer;transition:background var(--motion-fast) var(--motion-ease-standard), color var(--motion-fast) var(--motion-ease-standard);background:0 0;place-items:center;padding:0;display:inline-grid}._root_kpb9b_1:hover:not(:disabled){background:var(--primary-soft);color:var(--primary)}._root_kpb9b_1:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 2)}._root_kpb9b_1:disabled{color:var(--text-muted);cursor:not-allowed}._secondary_kpb9b_32{border-color:var(--border-strong);background:var(--surface);box-shadow:var(--shadow-sm)}._ghost_kpb9b_38{border-color:#0000}._icon_kpb9b_42{place-items:center;display:inline-grid}._root_1whtz_1{display:inline-flex;position:relative}._trigger_1whtz_6{align-items:center;gap:calc(var(--space) * 2);min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 4);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);font-weight:var(--font-weight-semibold);cursor:pointer;display:inline-flex}._trigger_1whtz_6:hover{background:var(--surface-hover)}._trigger_1whtz_6:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 2)}._menu_1whtz_32{z-index:var(--z-popover);min-width:calc(var(--space) * 44);padding:var(--space);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-lg);flex-direction:column;display:flex;position:absolute}._bottom_1whtz_45{top:calc(100% + var(--space));right:0}._alignStart_1whtz_50{left:0;right:auto}._right_1whtz_55{bottom:0;left:calc(100% + var(--space) * 2)}._item_1whtz_60{align-items:center;gap:calc(var(--space) * 3);width:100%;min-height:calc(var(--space) * 10);padding:0 calc(var(--space) * 3);border-radius:var(--radius-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);text-align:left;cursor:pointer;background:0 0;border:0;text-decoration:none;display:flex}._item_1whtz_60:hover,._item_1whtz_60:focus-visible{background:var(--surface-hover);outline:none}._item_1whtz_60:focus-visible{box-shadow:inset 0 0 0 calc(var(--space) / 2) var(--primary)}._danger_1whtz_88{color:var(--danger)}._icon_1whtz_92{display:inline-flex}._root_o7yxy_1{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_o7yxy_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._control_o7yxy_17{box-sizing:border-box;width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-base);transition:border-color var(--motion-fast) var(--motion-ease-standard)}._control_o7yxy_17:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._control_o7yxy_17[aria-invalid=true]{border-color:var(--danger)}._help_o7yxy_41{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_o7yxy_47{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._control_o7yxy_17[type=number]{appearance:textfield}._control_o7yxy_17[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}._control_o7yxy_17[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}._root_17ncm_1{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_17ncm_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._wrap_17ncm_17{position:relative}._control_17ncm_21{box-sizing:border-box;justify-content:space-between;align-items:center;gap:calc(var(--space) * 2);text-align:left;cursor:pointer;width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-base);transition:border-color var(--motion-fast) var(--motion-ease-standard);display:flex}._control_17ncm_21:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._control_17ncm_21[aria-invalid=true]{border-color:var(--danger)}._help_17ncm_51{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_17ncm_57{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._control_17ncm_21:disabled{background:var(--surface-muted);color:var(--text-muted);cursor:not-allowed}._placeholder_17ncm_72{color:var(--text-muted)}._chevron_17ncm_76{color:var(--text-muted);transition:transform var(--motion-fast) var(--motion-ease-standard);display:inline-flex}._chevronOpen_17ncm_82{transform:rotate(180deg)}._list_17ncm_86{top:calc(100% + var(--space));z-index:var(--z-dropdown);box-sizing:border-box;min-width:100%;max-height:calc(var(--space) * 70);padding:var(--space);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-lg);margin:0;list-style:none;position:absolute;left:0;overflow-y:auto}._list_17ncm_86:focus{outline:none}._above_17ncm_108{top:auto;bottom:calc(100% + var(--space))}._option_17ncm_113{padding:calc(var(--space) * 2) calc(var(--space) * 3);border-radius:var(--radius-sm);color:var(--text);font-size:var(--font-size-base);cursor:pointer}._option_17ncm_113[aria-selected=true]{font-weight:var(--font-weight-semibold);color:var(--primary)}._active_17ncm_126{background:var(--primary-soft)}._root_114y1_1{align-items:center;gap:calc(var(--space) * 2);display:flex}._control_114y1_7{width:calc(var(--space) * 5);height:calc(var(--space) * 5);accent-color:var(--primary);cursor:pointer;margin:0}._control_114y1_7:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 2)}._label_114y1_20{font-family:var(--font-body);font-size:var(--font-size-base);color:var(--text);cursor:pointer}._root_161y9_1{gap:var(--space);border:0;flex-direction:column;min-width:0;margin:0;padding:0;display:flex}._legend_161y9_11{margin-bottom:var(--space);font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted);padding:0}._group_161y9_22{box-sizing:border-box;align-self:flex-start;gap:var(--space);max-width:100%;padding:var(--space);border:calc(var(--space) / 4) solid var(--border);border-radius:var(--radius-md);background:var(--surface-muted);display:inline-flex}._segment_161y9_34{display:inline-flex;position:relative}._input_161y9_39{opacity:0;cursor:pointer;width:100%;height:100%;margin:0;position:absolute;inset:0}._text_161y9_49{min-height:calc(var(--space) * 8);padding:0 calc(var(--space) * 4);border-radius:var(--radius-sm);color:var(--text-muted);font-size:var(--font-size-md);font-weight:var(--font-weight-semibold);transition:background var(--motion-fast) var(--motion-ease-standard), color var(--motion-fast) var(--motion-ease-standard);align-items:center;display:inline-flex}._input_161y9_39:checked+._text_161y9_49{background:var(--surface);box-shadow:var(--shadow-sm);color:var(--primary)}._input_161y9_39:focus-visible+._text_161y9_49{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._help_161y9_74{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_161y9_80{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._root_1m3wp_2{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_1m3wp_9{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._wrap_1m3wp_18{position:relative}._control_1m3wp_22{box-sizing:border-box;width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 9) calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-base);transition:border-color var(--motion-fast) var(--motion-ease-standard)}._control_1m3wp_22::placeholder{color:var(--text-muted)}._control_1m3wp_22:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._control_1m3wp_22[aria-invalid=true]{border-color:var(--danger)}._control_1m3wp_22:disabled{background:var(--surface-muted);color:var(--text-muted);cursor:not-allowed}._chevron_1m3wp_57{top:50%;right:calc(var(--space) * 3);color:var(--text-muted);pointer-events:none;display:inline-flex;position:absolute;transform:translateY(-50%)}._help_1m3wp_67{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_1m3wp_73{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._popup_1m3wp_82{top:calc(100% + var(--space));z-index:var(--z-dropdown);box-sizing:border-box;border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);min-width:100%;box-shadow:var(--shadow-lg);position:absolute;left:0}._above_1m3wp_95{top:auto;bottom:calc(100% + var(--space))}._list_1m3wp_100{max-height:calc(var(--space) * 70);padding:var(--space);margin:0;list-style:none;overflow-y:auto}._empty_1m3wp_108{padding:calc(var(--space) * 2) calc(var(--space) * 3);color:var(--text-muted);font-size:var(--font-size-md);margin:0}._option_1m3wp_115{align-items:center;gap:var(--s2);padding:calc(var(--space) * 2) calc(var(--space) * 3);border-radius:var(--radius-sm);color:var(--text);font-size:var(--font-size-md);cursor:pointer;display:flex}._option_1m3wp_115[aria-selected=true]{font-weight:var(--font-weight-semibold);color:var(--primary)}._active_1m3wp_131{background:var(--primary-soft)}._check_1m3wp_135{color:var(--primary);margin-left:auto;display:inline-flex}._pills_1m3wp_141{gap:var(--s1);margin:var(--s2) 0 0;flex-wrap:wrap;padding:0;list-style:none;display:flex}._pill_1m3wp_141{align-items:center;gap:var(--space);padding:calc(var(--space) / 2) calc(var(--space) * 2) calc(var(--space) / 2) calc(var(--space) * 3);border-radius:var(--radius-pill);background:var(--primary-soft);color:var(--primary);font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);display:inline-flex}._remove_1m3wp_163{width:calc(var(--space) * 5);height:calc(var(--space) * 5);border-radius:var(--radius-pill);color:inherit;cursor:pointer;background:0 0;border:0;place-items:center;padding:0;display:inline-grid}._remove_1m3wp_163:hover{background:var(--surface-hover)}._remove_1m3wp_163:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._remove_1m3wp_163:disabled{cursor:not-allowed}._root_gtcmb_1{gap:var(--s1);flex-direction:column;min-width:0;display:flex}._label_gtcmb_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._control_gtcmb_17{box-sizing:border-box;width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-base)}._control_gtcmb_17:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._control_gtcmb_17[aria-invalid=true]{border-color:var(--danger)}._pills_gtcmb_42{gap:var(--s1);margin:var(--s2) 0 0;flex-wrap:wrap;padding:0;list-style:none;display:flex}._pill_gtcmb_42{align-items:center;gap:var(--space);padding:calc(var(--space) / 2) calc(var(--space) * 2) calc(var(--space) / 2) calc(var(--space) * 3);border-radius:var(--radius-pill);background:var(--primary-soft);color:var(--primary);font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);display:inline-flex}._remove_gtcmb_64{width:calc(var(--space) * 5);height:calc(var(--space) * 5);border-radius:var(--radius-pill);color:inherit;cursor:pointer;background:0 0;border:0;place-items:center;padding:0;display:inline-grid}._remove_gtcmb_64:hover{background:var(--surface-hover)}._remove_gtcmb_64:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._help_gtcmb_86{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_gtcmb_92{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._root_5gwtb_1{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_5gwtb_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._trigger_5gwtb_17{align-items:center;gap:calc(var(--space) * 2);box-sizing:border-box;width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);cursor:pointer;display:flex}._trigger_5gwtb_17:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._trigger_5gwtb_17[aria-invalid=true]{border-color:var(--danger)}._swatch_5gwtb_44{width:calc(var(--space) * 5);height:calc(var(--space) * 5);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-pill)}._hexText_5gwtb_51{font-variant-numeric:tabular-nums}._dialog_5gwtb_55{max-width:calc(100vw - calc(var(--space) * 8));padding:calc(var(--space) * 5);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-lg);color:var(--text)}._dialog_5gwtb_55::backdrop{background:color-mix(in srgb, var(--text) 40%, transparent)}._title_5gwtb_69{margin:0 0 calc(var(--space) * 4);font-family:var(--font-display);font-size:var(--font-size-lg)}._picker_5gwtb_75{gap:calc(var(--space) * 5);flex-wrap:wrap;display:flex}._wheelWrap_5gwtb_81{width:calc(var(--space) * 55);height:calc(var(--space) * 55);max-width:100%;position:relative}._wheel_5gwtb_81{border-radius:var(--radius-pill);cursor:crosshair;touch-action:none;width:100%;height:100%;display:block}._wheel_5gwtb_81:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) * .75)}._marker_5gwtb_102{width:calc(var(--space) * 4);height:calc(var(--space) * 4);border:calc(var(--space) / 2) solid var(--surface);border-radius:var(--radius-pill);box-shadow:var(--shadow-md);pointer-events:none;position:absolute;transform:translate(-50%,-50%)}._controls_5gwtb_113{gap:calc(var(--space) * 3);min-width:calc(var(--space) * 48);flex-direction:column;flex:1;display:flex}._preview_5gwtb_121{height:calc(var(--space) * 10);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md)}._numberLabel_5gwtb_127{gap:var(--space);color:var(--text-muted);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);flex-direction:column;display:flex}._range_5gwtb_136{width:100%;accent-color:var(--primary)}._input_5gwtb_141{box-sizing:border-box;width:100%;min-height:calc(var(--space) * 9);padding:var(--space) calc(var(--space) * 2);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);font-variant-numeric:tabular-nums;appearance:textfield}._input_5gwtb_141::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}._input_5gwtb_141::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}._input_5gwtb_141:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._input_5gwtb_141[aria-invalid=true]{border-color:var(--danger)}._group_5gwtb_172{gap:calc(var(--space) * 2);border:0;grid-template-columns:repeat(3,minmax(0,1fr));margin:0;padding:0;display:grid}._group_5gwtb_172 legend{padding:0 0 var(--space);color:var(--text-muted);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);grid-column:1/-1}._buttons_5gwtb_189{justify-content:flex-end;gap:calc(var(--space) * 2);margin-top:calc(var(--space) * 5);display:flex}._help_5gwtb_196{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_5gwtb_202{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._root_7069v_1{gap:calc(var(--space) * 2);width:calc(var(--space) * 72);flex-direction:column;max-width:100%;display:flex}._head_7069v_9{justify-content:space-between;align-items:center;display:flex}._title_7069v_15{color:var(--text);font-family:var(--font-display);font-size:var(--font-size-base);font-weight:var(--font-weight-bold)}._title_7069v_15:first-letter{text-transform:uppercase}._grid_7069v_27{gap:calc(var(--space) / 2);grid-template-columns:repeat(7,minmax(0,1fr));display:grid}._dow_7069v_33{padding:var(--space) 0;color:var(--text-muted);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);text-align:center;text-transform:uppercase}._day_7069v_42{aspect-ratio:1;border:calc(var(--space) / 4) solid transparent;border-radius:var(--radius-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);font-variant-numeric:tabular-nums;cursor:pointer;transition:background var(--motion-fast) var(--motion-ease-standard);background:0 0;place-items:center;padding:0;display:grid}._day_7069v_42:hover{background:var(--surface-hover)}._day_7069v_42:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._outside_7069v_67{color:color-mix(in srgb, var(--text-muted) 55%, transparent)}._today_7069v_71{border-color:var(--primary)}._inRange_7069v_75{background:var(--primary-soft);border-radius:0}._edge_7069v_80,._edge_7069v_80:hover{background:var(--primary);color:var(--primary-on);opacity:1}._row_7069v_87{display:contents}._root_1fogs_1{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_1fogs_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._hidden_1fogs_17{width:calc(var(--space) / 4);height:calc(var(--space) / 4);clip-path:inset(50%);white-space:nowrap;position:absolute;overflow:hidden}._wrap_1fogs_26{position:relative}._control_1fogs_30{box-sizing:border-box;align-items:center;gap:calc(var(--space) * 2);width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-base);text-align:left;cursor:pointer;display:flex}._control_1fogs_30:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._control_1fogs_30[aria-invalid=true]{border-color:var(--danger)}._control_1fogs_30:disabled{background:var(--surface-muted);cursor:not-allowed}._value_1fogs_63{color:var(--text);font-variant-numeric:tabular-nums}._placeholder_1fogs_68{color:var(--text-muted)}._popover_1fogs_72{top:calc(100% + var(--space) * 2);z-index:var(--z-dropdown);gap:calc(var(--space) * 2);padding:calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-lg);flex-direction:column;display:flex;position:absolute;left:0}._actions_1fogs_87{justify-content:space-between;display:flex}._help_1fogs_92{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_1fogs_98{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._root_ntomw_1{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_ntomw_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._hidden_ntomw_17{width:calc(var(--space) / 4);height:calc(var(--space) / 4);clip-path:inset(50%);white-space:nowrap;position:absolute;overflow:hidden}._wrap_ntomw_26{position:relative}._icon_ntomw_30{top:50%;left:calc(var(--space) * 3);color:var(--text-muted);pointer-events:none;display:inline-flex;position:absolute;transform:translateY(-50%)}._control_ntomw_40{box-sizing:border-box;width:100%;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3) calc(var(--space) * 2) calc(var(--space) * 9);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-base);font-variant-numeric:tabular-nums}._control_ntomw_40:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._control_ntomw_40[aria-invalid=true]{border-color:var(--danger)}._help_ntomw_65{font-size:var(--font-size-sm);color:var(--text-muted);margin:0}._error_ntomw_71{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}._root_2fjcj_1{border:0;min-width:0;margin:0;padding:0}._legend_2fjcj_8{margin-bottom:var(--space);font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted);padding:0}._row_2fjcj_19{grid-template-columns:minmax(0, 1fr) calc(var(--space) * 28);gap:calc(var(--space) * 2);align-items:start;display:grid}._help_2fjcj_26{margin:var(--space) 0 0;font-size:var(--font-size-sm);color:var(--text-muted)}._root_lfjll_1{gap:var(--space);flex-direction:column;min-width:0;display:flex}._label_lfjll_8{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted)}._srOnly_lfjll_17{width:calc(var(--space) / 4);height:calc(var(--space) / 4);margin:calc(var(--space) / -4);clip-path:inset(50%);white-space:nowrap;border:0;padding:0;position:absolute;overflow:hidden}._wrap_lfjll_29{position:relative}._control_lfjll_33{align-items:center;gap:calc(var(--space) * 2);box-sizing:border-box;min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-sm);color:var(--text);font-family:var(--font-body);font-size:var(--font-size-md);font-variant-numeric:tabular-nums;cursor:pointer;display:inline-flex}._control_lfjll_33:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / 4)}._popover_lfjll_56{z-index:var(--z-popover);box-sizing:border-box;gap:calc(var(--space) * 4);padding:calc(var(--space) * 3);border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);box-shadow:var(--shadow-lg);display:flex;position:fixed;top:0;left:0;overflow-y:auto}._presets_lfjll_72{gap:var(--space);min-width:calc(var(--space) * 36);flex-direction:column;display:flex}._preset_lfjll_72{color:var(--text);justify-content:flex-start}._preset_lfjll_72[aria-pressed=true]{background:var(--primary-soft);color:var(--primary)}._custom_lfjll_89{gap:calc(var(--space) * 2);flex-direction:column;display:flex}._customTitle_lfjll_95{font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) / 4);text-transform:uppercase;color:var(--text-muted);margin:0}._summary_lfjll_105{color:var(--text-muted);font-size:var(--font-size-sm);font-variant-numeric:tabular-nums;margin:0}._error_lfjll_112{padding:var(--space) calc(var(--space) * 2);border-radius:var(--radius-sm);background:var(--danger-soft);color:var(--danger);font-size:var(--font-size-sm);margin:0}@media (width<=560px){._popover_lfjll_56{max-width:calc(100vw - calc(var(--space) * 4));flex-direction:column}}._root_13auc_2{font-variant-numeric:tabular-nums}._root_1v7mn_1{padding:calc(var(--space) * 5);border:calc(var(--space) / 4) solid var(--border);border-radius:var(--radius-lg);background:var(--elevation-1);box-shadow:var(--shadow-md);color:var(--text);font-family:var(--font-body)}._primary_1v7mn_11{border-color:var(--primary);background:var(--primary-soft)}._accent_1v7mn_16{border-color:var(--accent);background:var(--accent-soft)}._success_1v7mn_21{border-color:var(--success);background:var(--success-soft)}._warning_1v7mn_26{border-color:var(--warning);background:var(--warning-soft)}._danger_1v7mn_31{border-color:var(--danger);background:var(--danger-soft)}._info_1v7mn_36{border-color:var(--info);background:var(--info-soft)}._root_rjx3r_1{justify-content:space-between;align-items:flex-end;gap:calc(var(--space) * 4);margin-bottom:calc(var(--space) * 5);transition:margin-bottom var(--motion-fast) var(--motion-ease-standard);flex-wrap:wrap;display:flex}._titleBlock_rjx3r_11{min-width:0}._back_rjx3r_15{margin-bottom:var(--s3)}._stuck_rjx3r_19{position:relative}._compact_rjx3r_23 ._pageHeading_rjx3r_23{font-size:var(--font-size-xl);letter-spacing:calc(var(--space) * -.15)}._compact_rjx3r_23{margin-bottom:calc(var(--space) * 3)}._compact_rjx3r_23 ._back_rjx3r_15{margin-bottom:var(--s1)}._eyebrow_rjx3r_36{color:var(--text-muted);font-family:var(--font-display);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);letter-spacing:calc(var(--space) * .35);text-transform:uppercase;margin:0}._pageHeading_rjx3r_23{color:var(--text);font-family:var(--font-display);font-size:var(--font-size-xxxl);font-weight:var(--font-weight-extrabold);letter-spacing:calc(var(--space) * -.3);line-height:var(--line-height-tight);transition:font-size var(--motion-base) var(--motion-ease-standard);margin:0}._pageHeading_rjx3r_23:focus{outline:none}._subtitle_rjx3r_61{margin:var(--space) 0 0;max-width:62ch;color:var(--text-muted);font-family:var(--font-body);font-size:var(--font-size-md)}._actions_rjx3r_69{gap:calc(var(--space) * 2);flex-wrap:wrap;display:flex}@media (width<=720px){._pageHeading_rjx3r_23{font-size:var(--font-size-xxl)}}@media (width<=480px){._actions_rjx3r_69>*{flex:auto}}._root_1akxr_1{align-items:flex-end;gap:calc(var(--space) * 3);margin-bottom:calc(var(--space) * 4);flex-wrap:wrap;display:flex}._search_1akxr_9{flex:1 1 calc(var(--space) * 45);min-width:0}._filters_1akxr_14{align-items:flex-end;gap:calc(var(--space) * 3);flex-wrap:wrap;display:flex}._trailing_1akxr_21{align-items:flex-end;display:flex}._list_jx4ch_1{gap:var(--space);margin-bottom:calc(var(--space) * 4);border-bottom:calc(var(--space) / 4) solid var(--border);flex-wrap:wrap;display:flex}._tab_jx4ch_9{margin-bottom:calc(var(--space) / -4);padding:calc(var(--space) * 2) calc(var(--space) * 4);border:0;border-bottom:calc(var(--space) / 2) solid transparent;color:var(--text-muted);font-family:var(--font-body);font-size:var(--font-size-md);font-weight:var(--font-weight-semibold);cursor:pointer;transition:color var(--motion-fast) var(--motion-ease-standard);background:0 0}._tab_jx4ch_9:hover{color:var(--text)}._tab_jx4ch_9[aria-selected=true]{border-bottom-color:var(--primary);color:var(--primary)}._tab_jx4ch_9:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / -2)}._panel_jx4ch_37{color:var(--text)}._root_1336w_1{border:calc(var(--space) / 4) solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface);flex:none;width:fit-content;display:inline-flex;overflow:hidden}._option_1336w_12{min-width:calc(var(--space) * 11);min-height:calc(var(--space) * 10);padding:calc(var(--space) * 2) calc(var(--space) * 3);color:var(--text-muted);font-family:var(--font-body);font-size:var(--font-size-md);font-weight:var(--font-weight-semibold);cursor:pointer;transition:background var(--motion-fast) var(--motion-ease-standard);background:0 0;border:0;place-items:center;display:inline-grid}._option_1336w_12 svg{display:block}._option_1336w_12:hover{background:var(--surface-hover)}._option_1336w_12[aria-pressed=true]{background:var(--primary-soft);color:var(--primary)}._option_1336w_12:focus-visible{outline:calc(var(--space) / 2) solid var(--primary);outline-offset:calc(var(--space) / -2)}._grid_11vah_2{gap:var(--s4);box-sizing:border-box;width:100%;max-width:calc(var(--space) * 220);padding:var(--s5);border:calc(var(--space) / 4) solid var(--border);border-radius:var(--radius-lg);background:var(--elevation-1);box-shadow:var(--shadow-md);grid-template-columns:repeat(2,minmax(0,1fr));margin-inline:auto;display:grid}._grid_11vah_2>[data-span=full]{grid-column:1/-1}._actions_11vah_21{justify-content:flex-end;gap:var(--s2);margin-top:var(--s2);padding-top:var(--s4);border-top:calc(var(--space) / 4) solid var(--border);display:flex}@media (width<=640px){._grid_11vah_2{grid-template-columns:minmax(0,1fr)}}._root_1n0kf_2{max-width:min(calc(var(--space) * 120), calc(100vw - var(--s8)));border:calc(var(--space) / 4) solid var(--border);border-radius:var(--radius-lg);background:var(--elevation-3);box-shadow:var(--shadow-lg);color:var(--text);font-family:var(--font-body);padding:0}._wide_1n0kf_13{max-width:min(calc(var(--space) * 140), calc(100vw - var(--s8)))}._root_1n0kf_2::backdrop{background:color-mix(in srgb, var(--bg) 70%, transparent)}._inner_1n0kf_21{padding:var(--s6)}._title_1n0kf_25{margin:0 0 var(--s2);font-family:var(--font-display);font-size:var(--font-size-xl);font-weight:var(--font-weight-bold);letter-spacing:-.02em}._body_1n0kf_33{color:var(--text)}._actions_1n0kf_37{justify-content:flex-end;gap:var(--s2);margin-top:var(--s4);flex-wrap:wrap;display:flex}._description_1ftx2_1{color:var(--text-muted);font-size:var(--font-size-md);line-height:var(--line-height-relaxed);margin:0}._region_1l4ou_1{right:calc(var(--space) * 4);bottom:calc(var(--space) * 4);left:calc(var(--space) * 4);z-index:var(--z-toast);align-items:flex-end;gap:calc(var(--space) * 2);pointer-events:none;flex-direction:column;display:flex;position:fixed}._root_1l4ou_14{max-width:calc(var(--space) * 105);padding:calc(var(--space) * 3) calc(var(--space) * 4);border-radius:var(--radius-md);box-shadow:var(--shadow-md);font-family:var(--font-body);font-size:var(--font-size-md);pointer-events:auto;align-items:flex-start;gap:var(--s2);display:flex}._icon_1l4ou_27{flex:none}._srOnly_1l4ou_31{width:calc(var(--space) / 4);height:calc(var(--space) / 4);margin:calc(var(--space) / -4);clip-path:inset(50%);white-space:nowrap;border:0;padding:0;position:absolute;overflow:hidden}._info_1l4ou_43{background:var(--info-soft);color:var(--info)}._success_1l4ou_48{background:var(--success-soft);color:var(--success)}._warning_1l4ou_53{background:var(--warning-soft);color:var(--warning)}._danger_1l4ou_58{background:var(--danger-soft);color:var(--danger)}._root_13abh_1{padding:calc(var(--space) * 10) calc(var(--space) * 4);border:calc(var(--space) / 4) dashed var(--border-strong);border-radius:var(--radius-lg);color:var(--text-muted);font-family:var(--font-body);text-align:center}._title_13abh_10{margin:0 0 var(--space);color:var(--text);font-family:var(--font-display);font-size:var(--font-size-lg);font-weight:var(--font-weight-bold)}._description_13abh_18{max-width:62ch;font-size:var(--font-size-md);line-height:var(--line-height-relaxed);margin:0 auto}._action_13abh_25{margin-top:calc(var(--space) * 4)}._root_1hr22_1{display:block}._skeleton_1hr22_5{gap:calc(var(--space) * 2);display:grid}._row_1hr22_10{height:calc(var(--space) * 14);border-radius:var(--radius-md);background:var(--surface-hover);display:block}._visuallyHidden_1hr22_17{width:calc(var(--space) / 4);height:calc(var(--space) / 4);margin:calc(var(--space) / -4);clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;padding:0;position:absolute;overflow:hidden}._root_gqjnf_1{padding:calc(var(--space) * 8) calc(var(--space) * 4);border-radius:var(--radius-lg);background:var(--danger-soft);color:var(--danger);font-family:var(--font-body);text-align:center}._title_gqjnf_10{margin:0 0 var(--space);font-family:var(--font-display);font-size:var(--font-size-lg);font-weight:var(--font-weight-bold)}._description_gqjnf_17{max-width:62ch;font-size:var(--font-size-md);line-height:var(--line-height-relaxed);margin:0 auto}._action_gqjnf_24{margin-top:calc(var(--space) * 4)}._root_1ikd9_1{height:calc(var(--space) * 2);border-radius:var(--radius-pill);background:var(--surface-hover);overflow:hidden}._fill_1ikd9_8{border-radius:var(--radius-pill);background:var(--primary);height:100%;transition:width var(--motion-slow) var(--motion-ease-standard);display:block}._root_1tkha_1{align-items:center;gap:var(--s2);padding:0 var(--s2);display:flex}._mark_1tkha_8{width:calc(var(--space) * 8.5);height:calc(var(--space) * 8.5);border-radius:var(--radius-sm);background:var(--brand-gradient);box-shadow:var(--shadow-md);color:var(--primary-on);flex:none;place-items:center;display:grid}._name_1tkha_20{font-family:var(--font-display);font-size:var(--font-size-xl);font-weight:var(--font-weight-extrabold);letter-spacing:calc(var(--space) * -.2);background:var(--brand-gradient);color:#0000;-webkit-background-clip:text;background-clip:text}._root_1fzd7_1{padding:calc(var(--space) * .25) var(--s2);border-radius:var(--radius-pill);font-family:var(--font-body);font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);white-space:nowrap;display:inline-block}._neutral_1fzd7_11{background:var(--surface-muted);color:var(--text-muted)}._primary_1fzd7_16{background:var(--primary-soft);color:var(--primary)}._accent_1fzd7_21{background:var(--accent-soft);color:var(--accent)}._success_1fzd7_26{background:var(--success-soft);color:var(--success)}._warning_1fzd7_31{background:var(--warning-soft);color:var(--warning)}._danger_1fzd7_36{background:var(--danger-soft);color:var(--danger)}._info_1fzd7_41{background:var(--info-soft);color:var(--info)}._root_1slwb_1{width:calc(var(--space) * 10);height:calc(var(--space) * 10);border-radius:var(--radius-md);color:var(--primary-on);font-family:var(--font-display);font-size:var(--font-size-md);font-weight:var(--font-weight-bold);place-items:center;display:inline-grid}
2
+ /*$vite$:1*/
@@ -0,0 +1,19 @@
1
+ import { ComponentPropsWithRef, ReactNode } from 'react';
2
+ export interface TabItem {
3
+ id: string;
4
+ label: string;
5
+ panel: ReactNode;
6
+ }
7
+ export interface TabsProps extends Omit<ComponentPropsWithRef<'div'>, 'onChange' | 'defaultValue'> {
8
+ /** Nome acessível da lista de abas. */
9
+ label: string;
10
+ /** Abas e seus painéis. */
11
+ tabs: readonly TabItem[];
12
+ /** Aba ativa (controlado). */
13
+ value?: string;
14
+ /** Aba ativa inicial (não controlado). Padrão: a primeira. */
15
+ defaultValue?: string;
16
+ /** Chamado com o `id` da aba escolhida. */
17
+ onChange?: (id: string) => void;
18
+ }
19
+ export declare function Tabs({ label, tabs, value, defaultValue, onChange, ...rest }: TabsProps): import('react').JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface TagFieldProps extends Omit<ComponentPropsWithRef<'input'>, 'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'type'> {
3
+ /** Rótulo visível do campo. */
4
+ label: string;
5
+ /** Etiquetas adicionadas. */
6
+ value: readonly string[];
7
+ /** Chamada com a lista nova ao adicionar ou remover uma etiqueta. */
8
+ onChange: (value: string[]) => void;
9
+ /** Chamada quando o campo perde o foco, depois de confirmar o texto pendente. */
10
+ onBlur?: () => void;
11
+ /** Nome da lista de etiquetas; padrão `{label} adicionadas`. */
12
+ listLabel?: string;
13
+ /** Nome do "×" de cada etiqueta; padrão `Remover {etiqueta}`. */
14
+ removeLabel?: (tag: string) => string;
15
+ /** Texto de ajuda abaixo do campo. */
16
+ help?: string;
17
+ /** Mensagem de erro; aparece com `role="alert"` e marca o campo como inválido. */
18
+ error?: string;
19
+ }
20
+ export declare function TagField({ label, value, onChange, onBlur, listLabel, removeLabel, help, error, id, className, style, ref, 'aria-describedby': describedByProp, 'aria-invalid': ariaInvalid, ...rest }: TagFieldProps): import('react').JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface TextFieldProps extends ComponentPropsWithRef<'input'> {
3
+ /** Rótulo visível do campo. */
4
+ label: string;
5
+ /** Texto de ajuda abaixo do campo. */
6
+ help?: string;
7
+ /** Mensagem de erro; aparece com `role="alert"` e marca o campo como inválido. */
8
+ error?: string;
9
+ }
10
+ export declare function TextField({ label, help, error, id, className, style, 'aria-describedby': describedByProp, 'aria-invalid': ariaInvalid, ...rest }: TextFieldProps): import('react').JSX.Element;
@@ -0,0 +1,16 @@
1
+ import { Theme, ThemeName, ThemeTokens } from './theme';
2
+ export interface ContrastRequirement {
3
+ foreground: keyof ThemeTokens;
4
+ background: keyof ThemeTokens;
5
+ minimum: number;
6
+ }
7
+ export interface ContrastViolation extends ContrastRequirement {
8
+ theme: ThemeName;
9
+ ratio: number;
10
+ }
11
+ /** Razão de contraste do WCAG 2, de 1 a 21, para cores `#RGB` ou `#RRGGBB`. */
12
+ export declare function contrastRatio(foreground: string, background: string): number;
13
+ /** Pares de token que precisam de contraste: 4,5:1 para texto e 3:1 só para `textFaint`. */
14
+ export declare const CONTRAST_REQUIREMENTS: readonly ContrastRequirement[];
15
+ /** Aplica CONTRAST_REQUIREMENTS aos dois modos de um tema e devolve cada par abaixo do mínimo. */
16
+ export declare function checkThemeContrast(theme: Theme): ContrastViolation[];
@@ -0,0 +1,5 @@
1
+ export { light, dark, radii, space, spacing, fontSizes, fontWeights, lineHeights, zIndices, motion, gradients, fonts, breakpoints, itemPalette, } from './tokens';
2
+ export { defineTheme, ishtarSinkTheme } from './theme';
3
+ export type { Theme, ThemeName, ThemeTokens } from './theme';
4
+ export { contrastRatio, checkThemeContrast, CONTRAST_REQUIREMENTS } from './contrast';
5
+ export type { ContrastRequirement, ContrastViolation } from './contrast';
@@ -0,0 +1,15 @@
1
+ import { light } from './tokens';
2
+ /** Tokens de um tema: todas as chaves do tema claro do Ishtar Sink, com valor de cor ou sombra. */
3
+ export type ThemeTokens = {
4
+ [K in keyof typeof light]: string;
5
+ };
6
+ /** Tema completo: os dois modos são obrigatórios e cada um tem todos os tokens. */
7
+ export interface Theme {
8
+ light: ThemeTokens;
9
+ dark: ThemeTokens;
10
+ }
11
+ export type ThemeName = keyof Theme;
12
+ /** Identidade em tempo de execução; o tipo recusa um tema incompleto na compilação ([project/theme-02]). */
13
+ export declare function defineTheme(theme: Theme): Theme;
14
+ /** Tema padrão do ecossistema; o claro é o padrão. */
15
+ export declare const ishtarSinkTheme: Theme;
@@ -0,0 +1,138 @@
1
+ export declare const light: {
2
+ readonly bg: "#F3F0FA";
3
+ readonly bgElevated: "#FAF8FE";
4
+ readonly surface: "#FFFFFF";
5
+ readonly surfaceMuted: "#EAE5F6";
6
+ readonly surfaceHover: "#E1DAF2";
7
+ readonly border: "#D9D1EC";
8
+ readonly borderStrong: "#BFB3DD";
9
+ readonly elevation1: "#FFFFFF";
10
+ readonly elevation2: "#FFFFFF";
11
+ readonly elevation3: "#FFFFFF";
12
+ readonly primary: "#6D28D9";
13
+ readonly primaryHover: "#5B21B6";
14
+ readonly primaryBright: "#A855F7";
15
+ readonly primarySoft: "#EBE0FD";
16
+ readonly primaryOn: "#FFFFFF";
17
+ readonly accent: "#0E7490";
18
+ readonly accentFill: "#06B6D4";
19
+ readonly accentBright: "#22D3EE";
20
+ readonly accentSoft: "#D8F1F6";
21
+ readonly text: "#1A1230";
22
+ readonly textMuted: "#4F4469";
23
+ readonly textFaint: "#8B84A3";
24
+ readonly success: "#047857";
25
+ readonly successSoft: "#D9F3E7";
26
+ readonly warning: "#92400E";
27
+ readonly warningSoft: "#FCEFCF";
28
+ readonly danger: "#BE123C";
29
+ readonly dangerSoft: "#FDE2E9";
30
+ readonly info: "#0369A1";
31
+ readonly infoSoft: "#DAEEFB";
32
+ readonly shadowSm: "0 1px 2px rgba(42, 24, 96, 0.08)";
33
+ readonly shadowMd: "0 4px 12px rgba(42, 24, 96, 0.10), 0 1px 3px rgba(42, 24, 96, 0.06)";
34
+ readonly shadowLg: "0 18px 44px rgba(42, 24, 96, 0.20), 0 4px 12px rgba(42, 24, 96, 0.08)";
35
+ };
36
+ export declare const dark: {
37
+ readonly bg: "#0B0816";
38
+ readonly bgElevated: "#110B21";
39
+ readonly surface: "#181028";
40
+ readonly surfaceMuted: "#130D22";
41
+ readonly surfaceHover: "#241A3D";
42
+ readonly border: "#2F2250";
43
+ readonly borderStrong: "#45337A";
44
+ readonly elevation1: "#181028";
45
+ readonly elevation2: "#201638";
46
+ readonly elevation3: "#2A1D4A";
47
+ readonly primary: "#A78BFA";
48
+ readonly primaryHover: "#C4B5FD";
49
+ readonly primaryBright: "#C084FC";
50
+ readonly primarySoft: "#2B1D52";
51
+ readonly primaryOn: "#12082B";
52
+ readonly accent: "#22D3EE";
53
+ readonly accentFill: "#06B6D4";
54
+ readonly accentBright: "#67E8F9";
55
+ readonly accentSoft: "#0F3342";
56
+ readonly text: "#F5F1FF";
57
+ readonly textMuted: "#B1A5CF";
58
+ readonly textFaint: "#7A6C9E";
59
+ readonly success: "#34D399";
60
+ readonly successSoft: "#0E2E27";
61
+ readonly warning: "#FBBF24";
62
+ readonly warningSoft: "#33260B";
63
+ readonly danger: "#FB7185";
64
+ readonly dangerSoft: "#3A1222";
65
+ readonly info: "#38BDF8";
66
+ readonly infoSoft: "#0C2C42";
67
+ readonly shadowSm: "0 1px 2px rgba(0, 0, 0, 0.45)";
68
+ readonly shadowMd: "0 6px 16px rgba(0, 0, 0, 0.50), 0 0 0 1px rgba(167, 139, 250, 0.08)";
69
+ readonly shadowLg: "0 22px 52px rgba(0, 0, 0, 0.65), 0 0 0 1px rgba(167, 139, 250, 0.14)";
70
+ };
71
+ export declare const radii: {
72
+ readonly sm: 8;
73
+ readonly md: 12;
74
+ readonly lg: 18;
75
+ readonly xl: 26;
76
+ readonly pill: 999;
77
+ };
78
+ /** Grade de 4px. */
79
+ export declare const space: (n: number) => number;
80
+ export declare const fontSizes: {
81
+ readonly xs: 12;
82
+ readonly sm: 13;
83
+ readonly md: 14;
84
+ readonly base: 16;
85
+ readonly lg: 18;
86
+ readonly xl: 21;
87
+ readonly xxl: 30;
88
+ readonly xxxl: 36;
89
+ };
90
+ /** Pesos de fonte usados pelos componentes. */
91
+ export declare const fontWeights: {
92
+ readonly semibold: 600;
93
+ readonly bold: 700;
94
+ readonly extrabold: 800;
95
+ };
96
+ /** Alturas de linha usadas pelos componentes. */
97
+ export declare const lineHeights: {
98
+ readonly tight: 1.1;
99
+ readonly relaxed: 1.6;
100
+ };
101
+ /** Camadas de empilhamento de dropdown, popover e toast. */
102
+ export declare const zIndices: {
103
+ readonly dropdown: 40;
104
+ readonly popover: 45;
105
+ readonly toast: 200;
106
+ };
107
+ /** Escala de espaçamento do protótipo (`--s1` a `--s10`), em múltiplos de 4 px. */
108
+ export declare const spacing: {
109
+ readonly unit: 4;
110
+ readonly steps: readonly [1, 2, 3, 4, 5, 6, 8, 10];
111
+ };
112
+ export declare const motion: {
113
+ readonly fast: 120;
114
+ readonly base: 200;
115
+ readonly slow: 320;
116
+ readonly ease: {
117
+ readonly standard: "cubic-bezier(0.4, 0, 0.2, 1)";
118
+ readonly enter: "cubic-bezier(0, 0, 0.2, 1)";
119
+ readonly exit: "cubic-bezier(0.4, 0, 1, 1)";
120
+ readonly linear: "linear";
121
+ };
122
+ };
123
+ export declare const gradients: {
124
+ readonly brand: readonly ["#7C3AED", "#06B6D4"];
125
+ readonly deep: readonly ["#6D28D9", "#7C3AED"];
126
+ readonly calm: readonly ["#F3EBFF", "#E0F7FB"];
127
+ };
128
+ export declare const fonts: {
129
+ readonly display: "'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif";
130
+ readonly body: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif";
131
+ };
132
+ export declare const breakpoints: {
133
+ readonly md: 720;
134
+ readonly sm: 480;
135
+ readonly min: 360;
136
+ };
137
+ /** Pares de cor dos itens sem imagem própria (mesmos valores de artPalettes do Atria); o ItemSwatch usa o par pelo hash do id. */
138
+ export declare const itemPalette: readonly [readonly ["#7C3AED", "#06B6D4"], readonly ["#A855F7", "#22D3EE"], readonly ["#6366F1", "#2DD4BF"], readonly ["#8B5CF6", "#38BDF8"], readonly ["#4C1D95", "#0E7490"], readonly ["#9333EA", "#67E8F9"], readonly ["#5B21B6", "#14B8A6"], readonly ["#C084FC", "#0891B2"], readonly ["#7E22CE", "#06B6D4"], readonly ["#6D28D9", "#5EEAD4"]];
@@ -0,0 +1,4 @@
1
+ /** Normaliza "930", "9:30", "09:30" ou "9" para "HH:mm" em 24 h; `null` para vazio. */
2
+ export declare function parseTime(text: string): string | null;
3
+ /** Insere o ":" enquanto se digita. */
4
+ export declare function maskTime(text: string): string;
@@ -0,0 +1,20 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export interface TimeFieldProps extends Omit<ComponentPropsWithRef<'input'>, 'onChange' | 'onBlur' | 'value' | 'defaultValue' | 'type'> {
3
+ /** Rótulo visível do campo. */
4
+ label: string;
5
+ /** Hora no formato `HH:mm`, ou `''` quando vazia. */
6
+ value: string;
7
+ /** Chamado com a hora normalizada (`HH:mm` ou `''`) quando o campo perde o foco com valor novo. */
8
+ onChange: (value: string) => void;
9
+ /** Chamado quando o campo perde o foco, depois da normalização. */
10
+ onBlur?: () => void;
11
+ /** Texto de exemplo do campo vazio. */
12
+ placeholder?: string;
13
+ /** Esconde o rótulo visualmente, mantendo-o para leitores de tela. */
14
+ hideLabel?: boolean;
15
+ /** Texto de ajuda abaixo do campo. */
16
+ help?: string;
17
+ /** Mensagem de erro; aparece com `role="alert"` e marca o campo como inválido. */
18
+ error?: string;
19
+ }
20
+ export declare function TimeField({ label, value, onChange, onBlur, placeholder, hideLabel, help, error, id, className, style, ...rest }: TimeFieldProps): import('react').JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export type ToastTone = 'info' | 'success' | 'warning' | 'danger';
3
+ /** Região fixa que anuncia os avisos com `aria-live="polite"`. */
4
+ export declare function ToastRegion({ className, ...rest }: ComponentPropsWithRef<'div'>): import('react').JSX.Element;
5
+ export interface ToastProps extends ComponentPropsWithRef<'div'> {
6
+ /** Tom do aviso. Padrão: `info`. */
7
+ tone?: ToastTone;
8
+ /** Nome do tom lido por leitor de tela. Padrão em pt-br por tom. */
9
+ toneLabel?: string;
10
+ }
11
+ export declare function Toast({ tone, toneLabel, className, children, ...rest }: ToastProps): import('react').JSX.Element;