@sbkbs/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.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @oficios/ui
2
+
3
+ Biblioteca de componentes UI e tema global para manter o mesmo padrão visual entre projetos (OFICIO.IA, CADASTRO.IA, etc.).
4
+
5
+ ## Conteúdo
6
+
7
+ - **Tema**: variáveis CSS (Material Design 3) light/dark + **Guia de marca SBK** (cores e tipografia Jakarta) em `theme/theme.css` + `ThemeProvider` React.
8
+ - **Componentes**: `Button`, `Card`, `Input`, `Modal`, `Title`, `Subtitle`, `Paragraph`, `Header`, `Footer`.
9
+ - **Paletas de botão**: escolha a cor do botão primary via prop `palette` ou `data-button-palette` no pai (`verde-vibrante`, `grafite-azulado`, etc.).
10
+
11
+ ## Uso em outro projeto
12
+
13
+ ### 1. Instalar no monorepo
14
+
15
+ No `package.json` do app (ex.: frontend), adicione:
16
+
17
+ ```json
18
+ "dependencies": {
19
+ "@oficios/ui": "*"
20
+ }
21
+ ```
22
+
23
+ Rode `npm install` na raiz do monorepo.
24
+
25
+ ### 2. Tema (variáveis CSS)
26
+
27
+ Os componentes usam variáveis CSS (`--md-surface`, `--primary-color`, etc.). O consumidor pode:
28
+
29
+ - Usar o tema da lib: `import '@oficios/ui/theme.css';` no entry (ex.: `main.tsx`), ou
30
+ - Definir as mesmas variáveis no próprio CSS do projeto (o frontend OFICIO.IA já tem `theme.css` próprio).
31
+
32
+ ### 3. ThemeProvider (opcional)
33
+
34
+ Para light/dark com toggle e persistência em `localStorage`:
35
+
36
+ ```tsx
37
+ import { ThemeProvider } from '@oficios/ui';
38
+
39
+ root.render(
40
+ <ThemeProvider defaultTheme="light">
41
+ <App />
42
+ </ThemeProvider>
43
+ );
44
+ ```
45
+
46
+ ### 4. Componentes
47
+
48
+ ```tsx
49
+ import { Button, Card, Input, Modal, Title, Subtitle, Paragraph, Header, Footer } from '@oficios/ui';
50
+
51
+ <Button variant="primary" size="md" palette="verde-vibrante">Salvar</Button>
52
+ <Card variant="elevated" padding="lg" hoverable>...</Card>
53
+ <Input label="E-mail" size="md" />
54
+ <Modal isOpen={open} onClose={() => setOpen(false)} title="Título">...</Modal>
55
+ <Title size="2xl" weight="bold">Título</Title>
56
+ <Subtitle size="md" muted>Subtítulo</Subtitle>
57
+ <Paragraph size="md">Texto.</Paragraph>
58
+
59
+ <Header
60
+ logoSrc="/logo.png"
61
+ logoDarkSrc="/logo-dark.png"
62
+ title="OFÍCIO.IA"
63
+ subtitle="Subtítulo"
64
+ onLogoClick={() => navigate('/home')}
65
+ rightContent={<>
66
+ <LanguageSelector />
67
+ <ThemeToggle />
68
+ <UserMenu />
69
+ </>}
70
+ />
71
+ <Footer poweredByText="Powered by" logoSrc="/logo.png" logoFallbackText="SBK" />
72
+ ```
73
+
74
+ ### Guia de marca (tema)
75
+
76
+ Cores disponíveis como variáveis CSS: `--brand-verde-vibrante`, `--brand-grafite-azulado`, `--brand-verde-profundo`, `--brand-azul-acinzentado`, `--brand-cinza-medio`, `--brand-cinza-escuro`, `--brand-off-white`, e paleta "O Criador" (`--brand-azul-intenso`, `--brand-verde-lima`, etc.). Tipografia: `--font-primary` / `--font-heading` = Plus Jakarta Sans (Google Fonts).
77
+
78
+ Paletas de botão (prop `palette` ou `data-button-palette` no pai): `verde-vibrante` | `verde-profundo` | `grafite-azulado` | `azul-acinzentado` | `cinza-medio` | `cinza-escuro` | `off-white`.
79
+
80
+ ## Compartilhar com outro projeto
81
+
82
+ - **Mesmo monorepo:** adicione o app em `workspaces` e use `"@oficios/ui": "*"` nas dependências; depois `npm install` na raiz.
83
+ - **Outro repositório:** use dependência por Git (`"@oficios/ui": "git+https://..."`) ou publique em um registry npm e instale com `npm install @oficios/ui`.
84
+
85
+ Guia completo: [docs/COMPARTILHAR_LIB_UI.md](../docs/COMPARTILHAR_LIB_UI.md).
86
+
87
+ ## Desenvolvimento
88
+
89
+ - **Build**: `npm run build -w @oficios/ui` (na raiz) ou `npm run build` dentro de `ui`.
90
+ - **Watch**: `npm run dev -w @oficios/ui` para rebuild ao editar.
91
+
92
+ ## Estrutura
93
+
94
+ ```
95
+ ui/
96
+ src/
97
+ index.ts
98
+ theme/
99
+ theme.css
100
+ ThemeProvider.tsx
101
+ components/
102
+ Button/
103
+ Card/
104
+ Input/
105
+ Modal/
106
+ Title/
107
+ Subtitle/
108
+ Paragraph/
109
+ Header/
110
+ Footer/
111
+ dist/
112
+ ```
@@ -0,0 +1,16 @@
1
+ import type React from 'react';
2
+ import './Button.css';
3
+ /** Paletas do guia de marca (só afeta variant primary). Use para escolher o modelo de cor do botão. */
4
+ export type ButtonPalette = 'verde-vibrante' | 'verde-profundo' | 'grafite-azulado' | 'azul-acinzentado' | 'cinza-medio' | 'cinza-escuro' | 'off-white';
5
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
+ children: React.ReactNode;
7
+ fullWidth?: boolean;
8
+ isLoading?: boolean;
9
+ leftIcon?: React.ReactNode;
10
+ /** Paleta de cor do guia de marca (aplica-se ao primary). Ignorado em outros variants. */
11
+ palette?: ButtonPalette;
12
+ rightIcon?: React.ReactNode;
13
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
14
+ variant?: 'primary' | 'secondary' | 'success' | 'error' | 'warning' | 'info' | 'neutral' | 'ghost';
15
+ }
16
+ export declare const Button: React.FC<ButtonProps>;
@@ -0,0 +1,9 @@
1
+ import type React from 'react';
2
+ import './Card.css';
3
+ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ children: React.ReactNode;
5
+ hoverable?: boolean;
6
+ padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
7
+ variant?: 'default' | 'elevated' | 'outlined' | 'flat';
8
+ }
9
+ export declare const Card: React.FC<CardProps>;
@@ -0,0 +1,15 @@
1
+ import type React from 'react';
2
+ import './Footer.css';
3
+ export interface FooterProps {
4
+ /** Classe CSS adicional */
5
+ className?: string;
6
+ /** Texto alternativo do logo */
7
+ logoAlt?: string;
8
+ /** Texto exibido se a imagem do logo falhar (ex.: "SBK") */
9
+ logoFallbackText?: string;
10
+ /** URL da imagem do logo */
11
+ logoSrc?: string;
12
+ /** Texto antes do logo (ex.: "Powered by") */
13
+ poweredByText?: string;
14
+ }
15
+ export declare const Footer: React.FC<FooterProps>;
@@ -0,0 +1,24 @@
1
+ import type React from 'react';
2
+ import type { Theme } from '../../theme/ThemeProvider';
3
+ import './Header.css';
4
+ export interface HeaderProps {
5
+ /** Classe CSS adicional */
6
+ className?: string;
7
+ /** Texto alternativo do logo */
8
+ logoAlt?: string;
9
+ /** URL da imagem do logo (tema escuro). Se não informado, usa logoSrc. */
10
+ logoDarkSrc?: string;
11
+ /** URL da imagem do logo (tema claro) */
12
+ logoSrc?: string;
13
+ /** Callback ao clicar na área do logo/título */
14
+ onLogoClick?: () => void;
15
+ /** Conteúdo da área direita (ex.: seletor de idioma, toggle tema, menu usuário) */
16
+ rightContent?: React.ReactNode;
17
+ /** Subtítulo abaixo do título */
18
+ subtitle?: React.ReactNode;
19
+ /** Tema opcional para escolher o logo correto sem depender do ThemeProvider do UI */
20
+ theme?: Theme;
21
+ /** Título exibido ao lado do logo (ex.: "OFÍCIO.IA") */
22
+ title?: React.ReactNode;
23
+ }
24
+ export declare const Header: React.FC<HeaderProps>;
@@ -0,0 +1,12 @@
1
+ import type React from 'react';
2
+ import './Input.css';
3
+ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
4
+ error?: string;
5
+ fullWidth?: boolean;
6
+ helperText?: string;
7
+ label?: string;
8
+ leftIcon?: React.ReactNode;
9
+ rightIcon?: React.ReactNode;
10
+ size?: 'sm' | 'md' | 'lg';
11
+ }
12
+ export declare const Input: React.FC<InputProps>;
@@ -0,0 +1,14 @@
1
+ import type React from 'react';
2
+ import './Modal.css';
3
+ export interface ModalProps {
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ closeOnOverlayClick?: boolean;
7
+ isOpen: boolean;
8
+ onClose: () => void;
9
+ showCloseButton?: boolean;
10
+ size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
11
+ subtitle?: string;
12
+ title?: string | React.ReactNode;
13
+ }
14
+ export declare const Modal: React.FC<ModalProps>;
@@ -0,0 +1,11 @@
1
+ import type React from 'react';
2
+ import './Paragraph.css';
3
+ export interface ParagraphProps extends React.HTMLAttributes<HTMLParagraphElement> {
4
+ align?: 'left' | 'center' | 'right' | 'justify';
5
+ as?: 'p' | 'span' | 'div';
6
+ children: React.ReactNode;
7
+ muted?: boolean;
8
+ size?: 'xs' | 'sm' | 'md' | 'lg';
9
+ weight?: 'light' | 'normal' | 'medium';
10
+ }
11
+ export declare const Paragraph: React.FC<ParagraphProps>;
@@ -0,0 +1,11 @@
1
+ import type React from 'react';
2
+ import './Subtitle.css';
3
+ export interface SubtitleProps extends React.HTMLAttributes<HTMLParagraphElement> {
4
+ align?: 'left' | 'center' | 'right';
5
+ as?: 'p' | 'span' | 'div';
6
+ children: React.ReactNode;
7
+ muted?: boolean;
8
+ size?: 'xs' | 'sm' | 'md' | 'lg';
9
+ weight?: 'normal' | 'medium' | 'semibold';
10
+ }
11
+ export declare const Subtitle: React.FC<SubtitleProps>;
@@ -0,0 +1,11 @@
1
+ import type React from 'react';
2
+ import './Title.css';
3
+ export interface TitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
4
+ align?: 'left' | 'center' | 'right';
5
+ as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
6
+ children: React.ReactNode;
7
+ gradient?: boolean;
8
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';
9
+ weight?: 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold';
10
+ }
11
+ export declare const Title: React.FC<TitleProps>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @oficios/ui
3
+ * Biblioteca de componentes UI e tema para manter padrão visual entre projetos.
4
+ *
5
+ * Uso no projeto consumidor:
6
+ * 1. Importar o CSS do tema uma vez (ex.: no main.tsx):
7
+ * import '@oficios/ui/theme.css';
8
+ * ou import '@oficios/ui/styles.css' (tema + estilos dos componentes).
9
+ * 2. Envolver a app com ThemeProvider (opcional, para light/dark):
10
+ * import { ThemeProvider } from '@oficios/ui';
11
+ * 3. Usar os componentes:
12
+ * import { Button, Card } from '@oficios/ui';
13
+ * O tema (variáveis CSS) deve ser carregado pelo consumidor (ex.: frontend já tem theme.css).
14
+ */
15
+ import './tailwind.css';
16
+ import './theme/theme.css';
17
+ export { Button, type ButtonPalette, type ButtonProps, } from './components/Button/Button';
18
+ export { Card, type CardProps } from './components/Card/Card';
19
+ export { Footer, type FooterProps } from './components/Footer/Footer';
20
+ export { Header, type HeaderProps } from './components/Header/Header';
21
+ export { Input, type InputProps } from './components/Input/Input';
22
+ export { Modal, type ModalProps } from './components/Modal/Modal';
23
+ export { Paragraph, type ParagraphProps, } from './components/Paragraph/Paragraph';
24
+ export { Subtitle, type SubtitleProps } from './components/Subtitle/Subtitle';
25
+ export { Title, type TitleProps } from './components/Title/Title';
26
+ export { type Theme, ThemeProvider, useTheme, } from './theme/ThemeProvider';
@@ -0,0 +1 @@
1
+ @import"https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400;1,500&display=swap";@import"https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&display=swap";*,: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}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.flex-shrink{flex-shrink:1}.transform{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))}.flex-wrap{flex-wrap:wrap}.border{border-width:1px}.outline{outline-style:solid}.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)}.invert{--tw-invert: invert(100%);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-filter{-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{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{--brand-verde-vibrante: #01b2aa;--brand-verde-profundo: #1f3a3a;--brand-grafite-azulado: #0f2f3a;--brand-azul-acinzentado: #5f7b8d;--brand-cinza-medio: #4b4b4b;--brand-cinza-escuro: #24262d;--brand-off-white: #ffffff;--brand-neutral-75: rgba(255, 255, 255, .75);--brand-branco: #ffffff;--brand-preto: #000000;--brand-cinza: #989495;--brand-azul-lavanda: #777dac;--brand-azul-intenso: #132c3b;--brand-cinza-azulado: #b4c2c7;--brand-verde-lima: #cffe40;--brand-off-white-criador: #e4e4e4;--brand-azul-escuro: #071a5c}:root{--font-primary: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-secondary: "Plus Jakarta Sans", var(--font-primary);--font-heading: var(--font-primary);--font-body: var(--font-primary)}html{font-family:var(--font-body);font-size:1rem}:root{--primary-color: var(--brand-verde-vibrante);--primary-color-dark: var(--brand-verde-profundo);--primary-color-light: color-mix( in srgb, var(--brand-verde-vibrante) 84%, white );--primary-color-hover: var(--brand-verde-profundo);--md-primary: var(--brand-verde-vibrante);--md-on-primary: #ffffff;--md-primary-container: color-mix( in srgb, var(--brand-verde-vibrante) 18%, white );--md-on-primary-container: var(--brand-grafite-azulado);--secondary-color: var(--brand-grafite-azulado);--color-primary: var(--primary-color);--color-on-primary: var(--md-on-primary);--color-secondary: var(--secondary-color);--color-on-secondary: var(--md-on-secondary);--color-surface: var(--md-surface);--color-on-surface: var(--md-on-surface);--color-contrast: var(--brand-verde-lima);--md-secondary: var(--brand-grafite-azulado);--md-on-secondary: #ffffff;--md-outline: var(--brand-azul-acinzentado);--md-outline-variant: color-mix( in srgb, var(--brand-azul-acinzentado) 35%, white );--success-color: #22c55e;--success-color-light: #4ade80;--error-color: #ef4444;--error-color-light: #f87171;--md-error: #ba1a1a;--md-on-error: #ffffff;--warning-color: #f59e0b;--warning-color-light: #fbbe24;--info-color: #3b82f6;--info-color-light: #60a5fa;--neutral-color: var(--brand-cinza-medio);--neutral-color-light: var(--brand-azul-acinzentado);--secondary-color-light: var(--brand-azul-acinzentado);--bg-hover: color-mix(in srgb, var(--brand-grafite-azulado) 8%, white);--bg-active: color-mix(in srgb, var(--brand-grafite-azulado) 14%, white);--md-on-surface: var(--brand-grafite-azulado);--accent-color: var(--primary-color);--accent-color-hover: var(--primary-color-hover);--bg-primary: var(--brand-neutral-75);--bg-secondary: #ffffff;--bg-tertiary: color-mix(in srgb, var(--brand-azul-acinzentado) 14%, white);--md-surface: #ffffff;--md-surface-container: var(--brand-neutral-75);--md-surface-container-high: color-mix( in srgb, var(--brand-azul-acinzentado) 14%, white );--border-color-hover: color-mix( in srgb, var(--brand-grafite-azulado) 32%, white );--bg-card: #ffffff;--bg-card-hover: color-mix(in srgb, var(--brand-azul-acinzentado) 8%, white);--bg-card-border: color-mix( in srgb, var(--brand-azul-acinzentado) 28%, white );--text-primary: var(--brand-grafite-azulado);--text-secondary: var(--brand-cinza-escuro);--text-tertiary: var(--brand-cinza-medio);--text-muted: var(--brand-cinza-medio);--text-on-primary: #ffffff;--border-color: color-mix(in srgb, var(--brand-azul-acinzentado) 30%, white);--border-color-focus: color-mix( in srgb, var(--brand-verde-vibrante) 52%, transparent );--shadow-xs: 0 .0625rem .125rem rgba(0, 0, 0, .05);--shadow-sm: 0 .125rem .25rem rgba(0, 0, 0, .08);--shadow-md: 0 .25rem .75rem rgba(0, 0, 0, .1);--shadow-lg: 0 .5rem 1.5rem rgba(0, 0, 0, .12);--font-size-xs: .75rem;--font-size-sm: .875rem;--font-size-base: 1rem;--font-size-md: 1.125rem;--font-size-lg: 1.25rem;--font-size-xl: 1.5rem;--font-weight-normal: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--line-height-normal: 1.5;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: .75rem;--spacing-lg: 1rem;--spacing-xl: 1.5rem;--spacing-2xl: 2rem;--border-radius-sm: .375rem;--border-radius-md: .5rem;--border-radius-lg: .75rem;--border-width-thin: .0625rem;--transition-base: .3s ease;--transition-all: all var(--transition-base);--transition-colors: color var(--transition-base), background-color var(--transition-base), border-color var(--transition-base);--z-index-dropdown: 1000;--z-index-modal-backdrop: 1040;--z-index-modal: 1050;--border-radius-2xl: 1.25rem;--shadow-2xl: 0 1.25rem 3.75rem rgba(0, 0, 0, .2);--font-size-2xl: 1.75rem;--font-size-3xl: 2rem;--font-size-4xl: 2.5rem;--font-weight-light: 300;--line-height-tight: 1.2;--line-height-relaxed: 1.6;--line-height-loose: 1.8;--md-on-surface-variant: #44474e;--spacing-3xl: 2.5rem}[data-theme=dark],.theme-dark{--bg-primary: #0f141a;--bg-secondary: #161b22;--bg-card: #161b22;--bg-card-hover: #1e2630;--bg-card-border: #2f3a46;--md-surface: #161b22;--md-on-surface: #e6e8eb;--md-on-surface-variant: #c2c7cf;--md-outline-variant: #44474e;--md-primary: var(--brand-verde-vibrante);--md-on-primary: #062126;--primary-color: var(--brand-verde-vibrante);--primary-color-light: color-mix( in srgb, var(--brand-verde-vibrante) 85%, white );--primary-color-hover: var(--brand-verde-profundo);--secondary-color: var(--brand-azul-acinzentado);--color-primary: var(--primary-color);--color-on-primary: var(--md-on-primary);--color-secondary: var(--secondary-color);--color-on-secondary: var(--md-on-secondary);--color-surface: var(--md-surface);--color-on-surface: var(--md-on-surface);--color-contrast: var(--brand-off-white);--text-primary: #e6e8eb;--text-secondary: #d1d5db;--text-muted: #9ca3af;--border-color: #2f3a46;--shadow-sm: 0 .125rem .25rem 0 rgba(0, 0, 0, .4);--shadow-md: 0 .25rem .5rem 0 rgba(0, 0, 0, .5);--shadow-lg: 0 .5rem 1rem 0 rgba(0, 0, 0, .6)}[data-button-palette=verde-vibrante],.btn--palette-verde-vibrante.btn--primary,[data-button-palette=verde-vibrante] .btn--primary{--md-primary: var(--brand-verde-vibrante);--primary-color-hover: var(--brand-verde-profundo)}[data-button-palette=verde-profundo],.btn--palette-verde-profundo.btn--primary,[data-button-palette=verde-profundo] .btn--primary{--md-primary: var(--brand-verde-profundo);--primary-color-hover: var(--brand-grafite-azulado)}[data-button-palette=grafite-azulado],.btn--palette-grafite-azulado.btn--primary,[data-button-palette=grafite-azulado] .btn--primary{--md-primary: var(--brand-grafite-azulado);--primary-color-hover: var(--brand-cinza-escuro)}[data-button-palette=azul-acinzentado],.btn--palette-azul-acinzentado.btn--primary,[data-button-palette=azul-acinzentado] .btn--primary{--md-primary: var(--brand-azul-acinzentado);--primary-color-hover: var(--brand-grafite-azulado)}[data-button-palette=cinza-medio],.btn--palette-cinza-medio.btn--primary,[data-button-palette=cinza-medio] .btn--primary{--md-primary: var(--brand-cinza-medio);--primary-color-hover: var(--brand-cinza-escuro)}[data-button-palette=cinza-escuro],.btn--palette-cinza-escuro.btn--primary,[data-button-palette=cinza-escuro] .btn--primary{--md-primary: var(--brand-cinza-escuro);--primary-color-hover: var(--brand-preto)}[data-button-palette=off-white],.btn--palette-off-white.btn--primary,[data-button-palette=off-white] .btn--primary{--md-primary: var(--brand-off-white);--md-on-primary: var(--brand-grafite-azulado);--primary-color-hover: var(--brand-branco)}.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap;gap:var(--spacing-sm);font-family:inherit;font-weight:var(--font-weight-semibold);cursor:pointer;border:var(--border-width-thin) solid transparent;border-radius:var(--border-radius-md);transition:var(--transition-all)}.btn:focus-visible{outline:2px solid var(--md-primary);outline-offset:2px}.btn:disabled{pointer-events:none;cursor:not-allowed;opacity:.6}.btn--xs{min-height:1.75rem;padding:var(--spacing-xs) var(--spacing-sm);font-size:var(--font-size-xs)}.btn--sm{min-height:2rem;padding:var(--spacing-sm) var(--spacing-md);font-size:var(--font-size-sm)}.btn--md{min-height:2.5rem;padding:var(--spacing-md) var(--spacing-lg);font-size:var(--font-size-base)}.btn--lg{min-height:3rem;padding:var(--spacing-lg) var(--spacing-xl);font-size:var(--font-size-lg)}.btn--xl{min-height:3.5rem;padding:var(--spacing-xl) var(--spacing-2xl);font-size:var(--font-size-xl)}.btn--primary{color:var(--md-on-primary);background:var(--md-primary);box-shadow:var(--shadow-sm)}.btn--primary:hover:not(:disabled){background:var(--primary-color-hover);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--secondary{color:var(--md-on-secondary);background:var(--md-secondary);box-shadow:var(--shadow-sm)}.btn--secondary:hover:not(:disabled){background:var(--secondary-color-light);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--success{color:#fff;background:var(--success-color);box-shadow:var(--shadow-sm)}.btn--success:hover:not(:disabled){background:var(--success-color-light);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--error{color:var(--md-on-error);background:var(--md-error);box-shadow:var(--shadow-sm)}.btn--error:hover:not(:disabled){background:var(--error-color-light);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--warning{color:#fff;background:var(--warning-color);box-shadow:var(--shadow-sm)}.btn--warning:hover:not(:disabled){background:var(--warning-color-light);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--info{color:#fff;background:var(--info-color);box-shadow:var(--shadow-sm)}.btn--info:hover:not(:disabled){background:var(--info-color-light);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--neutral{color:#fff;background:var(--neutral-color);box-shadow:var(--shadow-sm)}.btn--neutral:hover:not(:disabled){background:var(--neutral-color-light);box-shadow:var(--shadow-md);transform:translateY(-.125rem)}.btn--ghost{color:var(--md-on-surface);background:transparent;border-color:var(--md-outline-variant)}.btn--ghost:hover:not(:disabled){color:var(--md-primary);background:var(--bg-hover);border-color:var(--border-color-hover)}.btn--full-width{width:100%}.btn__spinner{position:absolute;display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;animation:btn-spin .9s linear infinite}@keyframes btn-spin{to{transform:rotate(360deg)}}.btn__icon{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center}.btn__icon--left{margin-right:var(--spacing-xs)}.btn__icon--right{margin-left:var(--spacing-xs)}.btn__content{display:inline-flex;align-items:center;justify-content:center}.btn--loading .btn__content{opacity:0}.card{position:relative;overflow:hidden;background:var(--md-surface);border-radius:var(--border-radius-lg);transition:var(--transition-all)}.card--default{background:var(--md-surface);border:var(--border-width-thin) solid var(--md-outline-variant);box-shadow:var(--shadow-sm)}.card--elevated{background:var(--md-surface);border:var(--border-width-thin) solid var(--md-outline-variant);box-shadow:var(--shadow-lg)}.card--outlined{background:transparent;border:var(--border-width-thin) solid var(--md-outline-variant);box-shadow:none}.card--flat{background:var(--md-surface);border:none;box-shadow:none}.card--padding-none{padding:0}.card--padding-sm{padding:var(--spacing-md)}.card--padding-md{padding:var(--spacing-lg)}.card--padding-lg{padding:var(--spacing-xl)}.card--padding-xl{padding:var(--spacing-2xl)}.card--hoverable:hover{box-shadow:var(--shadow-md)}.app-footer{position:relative;z-index:1;display:flex;flex-shrink:0;align-items:center;justify-content:center;width:100%;max-height:5vh;padding:var(--spacing-lg) var(--spacing-2xl);background:var(--bg-secondary);border-top:1px solid var(--border-color)}.app-footer-powered{display:flex;gap:var(--spacing-md);align-items:center}.app-footer-powered-text{font-size:.95rem;font-weight:var(--font-weight-normal);color:var(--text-secondary)}.app-footer-logo-wrap{display:flex;align-items:center}.app-footer-logo{width:auto;height:1.5rem;-o-object-fit:contain;object-fit:contain}[data-theme=dark] .app-footer-logo{filter:brightness(0) invert(1)}[data-theme=light] .app-footer-logo{filter:brightness(0)}.app-footer-logo-fallback{display:flex;align-items:center;font-family:Orbitron,sans-serif;font-size:1rem;font-weight:700;color:var(--md-primary);letter-spacing:.1em}.app-header{position:fixed;top:0;right:0;left:0;z-index:1000;width:100%;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);transition:background .3s cubic-bezier(.4,0,.2,1)}.app-header-top-bar{width:100%;height:.125rem;background:var(--md-primary)}.app-header-content{display:flex;align-items:center;justify-content:space-between;padding:.5rem 1.5rem;box-shadow:var(--shadow-sm);transition:background .3s cubic-bezier(.4,0,.2,1),border-color .3s cubic-bezier(.4,0,.2,1)}[data-theme=light] .app-header-content,[data-theme=dark] .app-header-content{color:var(--md-on-surface);background:color-mix(in srgb,var(--md-surface) 18%,transparent);border-bottom:1px solid color-mix(in srgb,var(--md-outline-variant) 30%,transparent)}.app-header.scrolled .app-header-content{background:color-mix(in srgb,var(--md-surface) 14%,transparent);border-bottom-color:color-mix(in srgb,var(--md-outline-variant) 22%,transparent)}.app-header-left{display:flex;gap:.75rem;align-items:center;cursor:pointer;transition:opacity .2s ease}.app-header-left:hover{opacity:.8}.app-header-logo{display:flex;flex-shrink:0;align-items:center;justify-content:center;width:4rem;height:4rem}.app-header-logo img{width:100%;height:100%;-o-object-fit:contain;object-fit:contain}.logo-icon-fallback{display:none;width:100%;height:100%}.app-header-title{display:flex;flex-direction:column;gap:.25rem}.app-header-title h1{display:inline-flex;align-items:baseline;margin:0;font-family:Orbitron,sans-serif;font-size:1.375rem;font-weight:700;line-height:1.2;color:var(--md-on-surface);letter-spacing:.05em}.app-header-title-highlight{color:var(--md-primary)}.app-header-title p{margin:0;font-size:.8125rem;font-weight:400;color:var(--md-on-surface-variant)}.app-header-right{display:flex;flex-shrink:0;gap:.75rem;align-items:center}@media(max-width:768px){.app-header-content{flex-direction:column;gap:.75rem;padding:.75rem 1rem}.app-header-right{flex-wrap:wrap;justify-content:space-between;width:100%}.app-header-title h1{font-size:1.25rem}.app-header-title p{font-size:.75rem}}.input-wrapper{display:flex;flex-direction:column;gap:var(--spacing-xs)}.input-wrapper--full-width{width:100%}.input-label{font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);color:var(--md-on-surface)}.input-container{position:relative;display:flex;width:100%;align-items:center}.input-container .input-icon--left{left:var(--spacing-md)}.input-container .input-icon--right{right:var(--spacing-md)}.input{width:100%;font-family:inherit;font-size:inherit;color:var(--md-on-surface);outline:none;background:var(--md-surface);border:var(--border-width-thin) solid var(--md-outline-variant);border-radius:var(--border-radius-md);transition:var(--transition-all)}.input::-moz-placeholder{color:var(--md-on-surface-variant);opacity:.7}.input::placeholder{color:var(--md-on-surface-variant);opacity:.7}.input:hover:not(:disabled):not(:focus){border-color:var(--border-color-hover)}.input:focus{border-color:var(--border-color-focus);box-shadow:0 0 0 .1875rem #2f5d8c26}.input:disabled{cursor:not-allowed;background:var(--md-surface-container-high);opacity:.6}.input--sm{min-height:2rem;padding:var(--spacing-sm) var(--spacing-md);font-size:var(--font-size-sm)}.input--md{min-height:2.5rem;padding:var(--spacing-md) var(--spacing-lg);font-size:var(--font-size-base)}.input--lg{min-height:3rem;padding:var(--spacing-lg) var(--spacing-xl);font-size:var(--font-size-lg)}.input--has-left-icon{padding-left:2.5rem}.input--has-right-icon{padding-right:2.5rem}.input-icon{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;color:var(--md-on-surface-variant);pointer-events:none}.input-container:focus-within .input-icon{color:var(--md-primary)}.input-icon svg{width:1.125rem;height:1.125rem}.input--error{border-color:var(--md-error)}.input--error:focus{border-color:var(--md-error);box-shadow:0 0 0 .1875rem #ba1a1a33}.input-error{display:block;margin-top:var(--spacing-xs);font-size:var(--font-size-xs);color:var(--md-error)}.input-helper{display:block;margin-top:var(--spacing-xs);font-size:var(--font-size-xs);color:var(--md-on-surface-variant)}.modal-overlay{position:fixed;inset:0;z-index:var(--z-index-modal-backdrop);display:flex;align-items:center;justify-content:center;min-height:100dvh;padding:var(--spacing-lg);overflow-y:auto;background:#00000080;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);animation:modal-fade-in var(--transition-base)}@keyframes modal-fade-in{0%{opacity:0}to{opacity:1}}.modal{position:relative;z-index:var(--z-index-modal);display:flex;width:100%;flex-direction:column;max-width:100%;max-height:90vh;margin:auto;overflow:hidden;background:var(--md-surface);border:var(--border-width-thin) solid var(--md-outline-variant);border-radius:var(--border-radius-2xl);box-shadow:var(--shadow-2xl);animation:modal-slide-up var(--transition-base)}@keyframes modal-slide-up{0%{transform:translateY(1.25rem);opacity:0}to{transform:translateY(0);opacity:1}}.modal--sm{max-width:25rem}.modal--md{max-width:31.25rem}.modal--lg{max-width:43.75rem}.modal--xl{max-width:56.25rem}.modal--full{max-width:90vw;max-height:90vh}.modal-header{display:flex;flex-shrink:0;gap:var(--spacing-lg);align-items:flex-start;justify-content:space-between;padding:var(--spacing-2xl);border-bottom:var(--border-width-thin) solid var(--md-outline-variant)}.modal-header-content{flex:1}.modal-title{margin:0 0 var(--spacing-xs) 0;font-size:var(--font-size-2xl);font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);color:var(--md-on-surface)}.modal-subtitle{margin:0;font-size:var(--font-size-base);line-height:var(--line-height-normal);color:var(--md-on-surface-variant)}.modal-close{display:flex;flex-shrink:0;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;color:var(--md-on-surface);cursor:pointer;background:var(--md-surface-container-high);border:none;border-radius:var(--border-radius-md);transition:var(--transition-all)}.modal-close:hover{color:var(--md-error);background:color-mix(in srgb,var(--md-error) 15%,var(--md-surface))}.modal-close svg{width:1.25rem;height:1.25rem}.modal-content{display:flex;flex:1;flex-direction:column;min-height:0;padding:var(--spacing-2xl);overflow-x:hidden;overflow-y:auto}.modal:not(:has(.modal-header)) .modal-content{padding-top:var(--spacing-2xl)}.paragraph{margin:0;line-height:var(--line-height-relaxed);color:var(--text-primary);transition:var(--transition-colors)}.paragraph--xs{font-size:var(--font-size-xs);line-height:var(--line-height-normal)}.paragraph--sm{font-size:var(--font-size-sm);line-height:var(--line-height-normal)}.paragraph--md{font-size:var(--font-size-base);line-height:var(--line-height-relaxed)}.paragraph--lg{font-size:var(--font-size-lg);line-height:var(--line-height-loose)}.paragraph--light{font-weight:var(--font-weight-light)}.paragraph--normal{font-weight:var(--font-weight-normal)}.paragraph--medium{font-weight:var(--font-weight-medium)}.paragraph--align-left{text-align:left}.paragraph--align-center{text-align:center}.paragraph--align-right{text-align:right}.paragraph--align-justify{text-align:justify}.paragraph--muted{color:var(--text-muted)}.subtitle{margin:0;line-height:var(--line-height-normal);color:var(--text-secondary);transition:var(--transition-colors)}.subtitle--xs{font-size:var(--font-size-xs)}.subtitle--sm{font-size:var(--font-size-sm)}.subtitle--md{font-size:var(--font-size-base)}.subtitle--lg{font-size:var(--font-size-lg)}.subtitle--normal{font-weight:var(--font-weight-normal)}.subtitle--medium{font-weight:var(--font-weight-medium)}.subtitle--semibold{font-weight:var(--font-weight-semibold)}.subtitle--align-left{text-align:left}.subtitle--align-center{text-align:center}.subtitle--align-right{text-align:right}.subtitle--muted{color:var(--text-muted);opacity:.8}.title{margin:0;line-height:var(--line-height-tight);color:var(--text-primary);transition:var(--transition-colors)}.title--xs{font-size:var(--font-size-sm)}.title--sm{font-size:var(--font-size-base)}.title--md{font-size:var(--font-size-lg)}.title--lg{font-size:var(--font-size-xl)}.title--xl{font-size:var(--font-size-2xl)}.title--2xl{font-size:var(--font-size-3xl)}.title--3xl{font-size:var(--font-size-4xl)}.title--4xl{font-size:3rem}.title--light{font-weight:var(--font-weight-light)}.title--normal{font-weight:var(--font-weight-normal)}.title--medium{font-weight:var(--font-weight-medium)}.title--semibold{font-weight:var(--font-weight-semibold)}.title--bold{font-weight:var(--font-weight-bold)}.title--extrabold{font-weight:800}.title--align-left{text-align:left}.title--align-center{text-align:center}.title--align-right{text-align:right}.title--gradient{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,var(--text-primary) 0%,var(--primary-color) 50%,var(--secondary-color) 100%);-webkit-background-clip:text;background-clip:text}[data-theme=dark] .title--gradient{background:linear-gradient(135deg,#ffffff 0%,var(--primary-color-light) 50%,var(--secondary-color) 100%);-webkit-background-clip:text;background-clip:text}
@@ -0,0 +1,343 @@
1
+ import { jsxs as m, jsx as e } from "react/jsx-runtime";
2
+ import { useState as y, useEffect as C, useContext as k, createContext as E } from "react";
3
+ const M = ({
4
+ variant: a = "primary",
5
+ size: t = "md",
6
+ fullWidth: n = !1,
7
+ isLoading: s = !1,
8
+ leftIcon: r,
9
+ rightIcon: l,
10
+ children: o,
11
+ className: d = "",
12
+ disabled: h,
13
+ palette: p,
14
+ ...i
15
+ }) => {
16
+ const c = `btn--${a}`, b = `btn--${t}`, f = n ? "btn--full-width" : "", g = s ? "btn--loading" : "", $ = p && a === "primary" ? `btn--palette-${p}` : "", v = `btn ${c} ${b} ${f} ${g} ${$} ${d}`.trim();
17
+ return /* @__PURE__ */ m(
18
+ "button",
19
+ {
20
+ className: v,
21
+ disabled: h || s,
22
+ ...i,
23
+ children: [
24
+ s && /* @__PURE__ */ e("span", { "aria-hidden": "true", className: "btn__spinner", children: /* @__PURE__ */ m(
25
+ "svg",
26
+ {
27
+ fill: "none",
28
+ stroke: "currentColor",
29
+ strokeWidth: "2",
30
+ viewBox: "0 0 24 24",
31
+ children: [
32
+ /* @__PURE__ */ e("circle", { cx: "12", cy: "12", r: "10", strokeOpacity: "0.25" }),
33
+ /* @__PURE__ */ e("path", { d: "M12 2 A10 10 0 0 1 22 12", strokeLinecap: "round" })
34
+ ]
35
+ }
36
+ ) }),
37
+ !s && r && /* @__PURE__ */ e("span", { className: "btn__icon btn__icon--left", children: r }),
38
+ /* @__PURE__ */ e("span", { className: "btn__content", children: o }),
39
+ !s && l && /* @__PURE__ */ e("span", { className: "btn__icon btn__icon--right", children: l })
40
+ ]
41
+ }
42
+ );
43
+ }, S = ({
44
+ variant: a = "default",
45
+ padding: t = "md",
46
+ hoverable: n = !1,
47
+ children: s,
48
+ className: r = "",
49
+ ...l
50
+ }) => {
51
+ const o = "card", d = `card--${a}`, h = `card--padding-${t}`, i = `${o} ${d} ${h} ${n ? "card--hoverable" : ""} ${r}`.trim();
52
+ return /* @__PURE__ */ e("div", { className: i, ...l, children: s });
53
+ }, T = ({
54
+ poweredByText: a = "Powered by",
55
+ logoSrc: t,
56
+ logoAlt: n = "Logo",
57
+ logoFallbackText: s,
58
+ className: r = ""
59
+ }) => /* @__PURE__ */ e("footer", { className: `app-footer ${r}`.trim(), children: /* @__PURE__ */ m("div", { className: "app-footer-powered", children: [
60
+ a && /* @__PURE__ */ e("span", { className: "app-footer-powered-text", children: a }),
61
+ (t || s) && /* @__PURE__ */ m("div", { className: "app-footer-logo-wrap", children: [
62
+ t && /* @__PURE__ */ e(
63
+ "img",
64
+ {
65
+ alt: n,
66
+ className: "app-footer-logo",
67
+ onError: (l) => {
68
+ l.target.style.display = "none";
69
+ const o = l.target.nextElementSibling;
70
+ o && (o.style.display = "flex");
71
+ },
72
+ src: t
73
+ }
74
+ ),
75
+ s && /* @__PURE__ */ e(
76
+ "span",
77
+ {
78
+ className: "app-footer-logo-fallback",
79
+ style: { display: t ? "none" : "flex" },
80
+ children: s
81
+ }
82
+ )
83
+ ] })
84
+ ] }) }), N = () => typeof document > "u" ? "light" : document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light", P = ({
85
+ logoSrc: a,
86
+ logoDarkSrc: t,
87
+ logoAlt: n = "Logo",
88
+ title: s,
89
+ subtitle: r,
90
+ theme: l,
91
+ onLogoClick: o,
92
+ rightContent: d,
93
+ className: h = ""
94
+ }) => {
95
+ const [p, i] = y(!1), [u, c] = y(
96
+ () => l ?? N()
97
+ ), b = u === "dark" && t ? t : a;
98
+ C(() => {
99
+ const $ = () => i(window.scrollY > 10);
100
+ return window.addEventListener("scroll", $, { passive: !0 }), () => window.removeEventListener("scroll", $);
101
+ }, []), C(() => {
102
+ if (l) {
103
+ c(l);
104
+ return;
105
+ }
106
+ const $ = () => c(N());
107
+ if ($(), typeof MutationObserver > "u")
108
+ return;
109
+ const v = new MutationObserver($);
110
+ return v.observe(document.documentElement, {
111
+ attributes: !0,
112
+ attributeFilter: ["data-theme"]
113
+ }), () => v.disconnect();
114
+ }, [l]);
115
+ const f = () => o?.(), g = ($) => {
116
+ $.key === "Enter" && o?.();
117
+ };
118
+ return /* @__PURE__ */ m(
119
+ "header",
120
+ {
121
+ className: `app-header ${p ? "scrolled" : ""} ${h}`.trim(),
122
+ children: [
123
+ /* @__PURE__ */ e("div", { className: "app-header-top-bar" }),
124
+ /* @__PURE__ */ m("div", { className: "app-header-content", children: [
125
+ /* @__PURE__ */ m(
126
+ "div",
127
+ {
128
+ className: "app-header-left",
129
+ onClick: o ? f : void 0,
130
+ onKeyDown: o ? g : void 0,
131
+ role: o ? "button" : void 0,
132
+ tabIndex: o ? 0 : void 0,
133
+ children: [
134
+ b && /* @__PURE__ */ m("div", { className: "app-header-logo", children: [
135
+ /* @__PURE__ */ e(
136
+ "img",
137
+ {
138
+ alt: n,
139
+ onError: ($) => {
140
+ $.target.style.display = "none";
141
+ const v = $.target.nextElementSibling;
142
+ v && (v.style.display = "block");
143
+ },
144
+ src: b
145
+ }
146
+ ),
147
+ /* @__PURE__ */ m(
148
+ "svg",
149
+ {
150
+ className: "logo-icon-fallback",
151
+ fill: "none",
152
+ stroke: "currentColor",
153
+ strokeWidth: "2",
154
+ viewBox: "0 0 24 24",
155
+ children: [
156
+ /* @__PURE__ */ e("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
157
+ /* @__PURE__ */ e("path", { d: "M2 17l10 5 10-5M2 12l10 5 10-5" })
158
+ ]
159
+ }
160
+ )
161
+ ] }),
162
+ (s || r) && /* @__PURE__ */ m("div", { className: "app-header-title", children: [
163
+ s && /* @__PURE__ */ e("h1", { children: s }),
164
+ r && /* @__PURE__ */ e("p", { children: r })
165
+ ] })
166
+ ]
167
+ }
168
+ ),
169
+ d && /* @__PURE__ */ e("div", { className: "app-header-right", children: d })
170
+ ] })
171
+ ]
172
+ }
173
+ );
174
+ }, W = ({
175
+ label: a,
176
+ error: t,
177
+ helperText: n,
178
+ leftIcon: s,
179
+ rightIcon: r,
180
+ fullWidth: l = !1,
181
+ size: o = "md",
182
+ className: d = "",
183
+ id: h,
184
+ ...p
185
+ }) => {
186
+ const i = h || `input-${Math.random().toString(36).substring(2, 9)}`, u = !!t, c = "input", b = `input--${o}`, x = `${c} ${b} ${u ? "input--error" : ""} ${l ? "input--full-width" : ""} ${s ? "input--has-left-icon" : ""} ${r ? "input--has-right-icon" : ""} ${d}`.trim();
187
+ return /* @__PURE__ */ m(
188
+ "div",
189
+ {
190
+ className: `input-wrapper ${l ? "input-wrapper--full-width" : ""}`,
191
+ children: [
192
+ a && /* @__PURE__ */ e("label", { className: "input-label", htmlFor: i, children: a }),
193
+ /* @__PURE__ */ m("div", { className: "input-container", children: [
194
+ s && /* @__PURE__ */ e("span", { className: "input-icon input-icon--left", children: s }),
195
+ /* @__PURE__ */ e(
196
+ "input",
197
+ {
198
+ "aria-describedby": t ? `${i}-error` : n ? `${i}-helper` : void 0,
199
+ "aria-invalid": u ? !0 : void 0,
200
+ className: x,
201
+ id: i,
202
+ ...p
203
+ }
204
+ ),
205
+ r && /* @__PURE__ */ e("span", { className: "input-icon input-icon--right", children: r })
206
+ ] }),
207
+ t && /* @__PURE__ */ e("span", { className: "input-error", id: `${i}-error`, role: "alert", children: t }),
208
+ n && !t && /* @__PURE__ */ e("span", { className: "input-helper", id: `${i}-helper`, children: n })
209
+ ]
210
+ }
211
+ );
212
+ }, I = ({
213
+ isOpen: a,
214
+ onClose: t,
215
+ title: n,
216
+ subtitle: s,
217
+ children: r,
218
+ size: l = "md",
219
+ showCloseButton: o = !0,
220
+ closeOnOverlayClick: d = !0,
221
+ className: h = ""
222
+ }) => {
223
+ if (C(() => (a ? document.body.style.overflow = "hidden" : document.body.style.overflow = "", () => {
224
+ document.body.style.overflow = "";
225
+ }), [a]), C(() => {
226
+ const c = (b) => {
227
+ b.key === "Escape" && a && t();
228
+ };
229
+ return a && document.addEventListener("keydown", c), () => document.removeEventListener("keydown", c);
230
+ }, [a, t]), !a)
231
+ return null;
232
+ const p = (c) => {
233
+ d && c.target === c.currentTarget && t();
234
+ }, u = `modal ${`modal--${l}`} ${h}`.trim();
235
+ return /* @__PURE__ */ e(
236
+ "div",
237
+ {
238
+ "aria-labelledby": n ? "modal-title" : void 0,
239
+ "aria-modal": "true",
240
+ className: "modal-overlay",
241
+ onClick: p,
242
+ role: "dialog",
243
+ children: /* @__PURE__ */ m("div", { className: u, children: [
244
+ (n || s || o) && /* @__PURE__ */ m("div", { className: "modal-header", children: [
245
+ (n || s) && /* @__PURE__ */ m("div", { className: "modal-header-content", children: [
246
+ n && /* @__PURE__ */ e("h2", { className: "modal-title", id: "modal-title", children: n }),
247
+ s && /* @__PURE__ */ e("p", { className: "modal-subtitle", children: s })
248
+ ] }),
249
+ o && /* @__PURE__ */ e(
250
+ "button",
251
+ {
252
+ "aria-label": "Fechar modal",
253
+ className: "modal-close",
254
+ onClick: t,
255
+ type: "button",
256
+ children: /* @__PURE__ */ m(
257
+ "svg",
258
+ {
259
+ fill: "none",
260
+ stroke: "currentColor",
261
+ strokeWidth: "2",
262
+ viewBox: "0 0 24 24",
263
+ children: [
264
+ /* @__PURE__ */ e("line", { x1: "18", x2: "6", y1: "6", y2: "18" }),
265
+ /* @__PURE__ */ e("line", { x1: "6", x2: "18", y1: "6", y2: "18" })
266
+ ]
267
+ }
268
+ )
269
+ }
270
+ )
271
+ ] }),
272
+ /* @__PURE__ */ e("div", { className: "modal-content", children: r })
273
+ ] })
274
+ }
275
+ );
276
+ }, R = ({
277
+ as: a = "p",
278
+ size: t = "md",
279
+ weight: n = "normal",
280
+ align: s = "left",
281
+ muted: r = !1,
282
+ children: l,
283
+ className: o = "",
284
+ ...d
285
+ }) => {
286
+ const h = a, p = "paragraph", i = `paragraph--${t}`, u = `paragraph--${n}`, c = `paragraph--align-${s}`, f = `${p} ${i} ${u} ${c} ${r ? "paragraph--muted" : ""} ${o}`.trim();
287
+ return /* @__PURE__ */ e(h, { className: f, ...d, children: l });
288
+ }, A = ({
289
+ as: a = "p",
290
+ size: t = "md",
291
+ weight: n = "normal",
292
+ align: s = "left",
293
+ muted: r = !1,
294
+ children: l,
295
+ className: o = "",
296
+ ...d
297
+ }) => {
298
+ const h = a, p = "subtitle", i = `subtitle--${t}`, u = `subtitle--${n}`, c = `subtitle--align-${s}`, f = `${p} ${i} ${u} ${c} ${r ? "subtitle--muted" : ""} ${o}`.trim();
299
+ return /* @__PURE__ */ e(h, { className: f, ...d, children: l });
300
+ }, j = ({
301
+ as: a = "h1",
302
+ size: t = "2xl",
303
+ weight: n = "bold",
304
+ align: s = "left",
305
+ gradient: r = !1,
306
+ children: l,
307
+ className: o = "",
308
+ ...d
309
+ }) => {
310
+ const h = a, p = "title", i = `title--${t}`, u = `title--${n}`, c = `title--align-${s}`, f = `${p} ${i} ${u} ${c} ${r ? "title--gradient" : ""} ${o}`.trim();
311
+ return /* @__PURE__ */ e(h, { className: f, ...d, children: l });
312
+ }, w = E(void 0), B = () => {
313
+ const a = k(w);
314
+ if (!a)
315
+ throw new Error("useTheme must be used within a ThemeProvider");
316
+ return a;
317
+ }, F = ({
318
+ children: a,
319
+ defaultTheme: t = "light"
320
+ }) => {
321
+ const [n, s] = y(() => typeof window > "u" ? t : window.localStorage.getItem("theme") || t);
322
+ C(() => {
323
+ typeof window > "u" || (window.localStorage.setItem("theme", n), document.documentElement.setAttribute("data-theme", n));
324
+ }, [n]);
325
+ const r = () => {
326
+ s((l) => l === "dark" ? "light" : "dark");
327
+ };
328
+ return /* @__PURE__ */ e(w.Provider, { value: { theme: n, toggleTheme: r }, children: a });
329
+ };
330
+ export {
331
+ M as Button,
332
+ S as Card,
333
+ T as Footer,
334
+ P as Header,
335
+ W as Input,
336
+ I as Modal,
337
+ R as Paragraph,
338
+ A as Subtitle,
339
+ F as ThemeProvider,
340
+ j as Title,
341
+ B as useTheme
342
+ };
343
+ //# sourceMappingURL=oficios-ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oficios-ui.js","sources":["../src/components/Button/Button.tsx","../src/components/Card/Card.tsx","../src/components/Footer/Footer.tsx","../src/components/Header/Header.tsx","../src/components/Input/Input.tsx","../src/components/Modal/Modal.tsx","../src/components/Paragraph/Paragraph.tsx","../src/components/Subtitle/Subtitle.tsx","../src/components/Title/Title.tsx","../src/theme/ThemeProvider.tsx"],"sourcesContent":["import type React from 'react';\nimport './Button.css';\n\n/** Paletas do guia de marca (só afeta variant primary). Use para escolher o modelo de cor do botão. */\nexport type ButtonPalette =\n | 'verde-vibrante'\n | 'verde-profundo'\n | 'grafite-azulado'\n | 'azul-acinzentado'\n | 'cinza-medio'\n | 'cinza-escuro'\n | 'off-white';\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n fullWidth?: boolean;\n isLoading?: boolean;\n leftIcon?: React.ReactNode;\n /** Paleta de cor do guia de marca (aplica-se ao primary). Ignorado em outros variants. */\n palette?: ButtonPalette;\n rightIcon?: React.ReactNode;\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n variant?:\n | 'primary'\n | 'secondary'\n | 'success'\n | 'error'\n | 'warning'\n | 'info'\n | 'neutral'\n | 'ghost';\n}\n\nexport const Button: React.FC<ButtonProps> = ({\n variant = 'primary',\n size = 'md',\n fullWidth = false,\n isLoading = false,\n leftIcon,\n rightIcon,\n children,\n className = '',\n disabled,\n palette,\n ...props\n}) => {\n const baseClass = 'btn';\n const variantClass = `btn--${variant}`;\n const sizeClass = `btn--${size}`;\n const fullWidthClass = fullWidth ? 'btn--full-width' : '';\n const loadingClass = isLoading ? 'btn--loading' : '';\n const paletteClass =\n palette && variant === 'primary' ? `btn--palette-${palette}` : '';\n const combinedClass =\n `${baseClass} ${variantClass} ${sizeClass} ${fullWidthClass} ${loadingClass} ${paletteClass} ${className}`.trim();\n\n return (\n <button\n className={combinedClass}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading && (\n <span aria-hidden=\"true\" className=\"btn__spinner\">\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" strokeOpacity=\"0.25\" />\n <path d=\"M12 2 A10 10 0 0 1 22 12\" strokeLinecap=\"round\" />\n </svg>\n </span>\n )}\n {!isLoading && leftIcon && (\n <span className=\"btn__icon btn__icon--left\">{leftIcon}</span>\n )}\n <span className=\"btn__content\">{children}</span>\n {!isLoading && rightIcon && (\n <span className=\"btn__icon btn__icon--right\">{rightIcon}</span>\n )}\n </button>\n );\n};\n","import type React from 'react';\nimport './Card.css';\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n hoverable?: boolean;\n padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';\n variant?: 'default' | 'elevated' | 'outlined' | 'flat';\n}\n\nexport const Card: React.FC<CardProps> = ({\n variant = 'default',\n padding = 'md',\n hoverable = false,\n children,\n className = '',\n ...props\n}) => {\n const baseClass = 'card';\n const variantClass = `card--${variant}`;\n const paddingClass = `card--padding-${padding}`;\n const hoverableClass = hoverable ? 'card--hoverable' : '';\n const combinedClass =\n `${baseClass} ${variantClass} ${paddingClass} ${hoverableClass} ${className}`.trim();\n\n return (\n <div className={combinedClass} {...props}>\n {children}\n </div>\n );\n};\n","import type React from 'react';\nimport './Footer.css';\n\nexport interface FooterProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** Texto exibido se a imagem do logo falhar (ex.: \"SBK\") */\n logoFallbackText?: string;\n /** URL da imagem do logo */\n logoSrc?: string;\n /** Texto antes do logo (ex.: \"Powered by\") */\n poweredByText?: string;\n}\n\nexport const Footer: React.FC<FooterProps> = ({\n poweredByText = 'Powered by',\n logoSrc,\n logoAlt = 'Logo',\n logoFallbackText,\n className = '',\n}) => {\n return (\n <footer className={`app-footer ${className}`.trim()}>\n <div className=\"app-footer-powered\">\n {poweredByText && (\n <span className=\"app-footer-powered-text\">{poweredByText}</span>\n )}\n {(logoSrc || logoFallbackText) && (\n <div className=\"app-footer-logo-wrap\">\n {logoSrc && (\n <img\n alt={logoAlt}\n className=\"app-footer-logo\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n const next = (e.target as HTMLElement)\n .nextElementSibling as HTMLElement;\n if (next) {\n next.style.display = 'flex';\n }\n }}\n src={logoSrc}\n />\n )}\n {logoFallbackText && (\n <span\n className=\"app-footer-logo-fallback\"\n style={{ display: logoSrc ? 'none' : 'flex' }}\n >\n {logoFallbackText}\n </span>\n )}\n </div>\n )}\n </div>\n </footer>\n );\n};\n","import type React from 'react';\nimport { useEffect, useState } from 'react';\nimport type { Theme } from '../../theme/ThemeProvider';\nimport './Header.css';\n\nexport interface HeaderProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** URL da imagem do logo (tema escuro). Se não informado, usa logoSrc. */\n logoDarkSrc?: string;\n /** URL da imagem do logo (tema claro) */\n logoSrc?: string;\n /** Callback ao clicar na área do logo/título */\n onLogoClick?: () => void;\n /** Conteúdo da área direita (ex.: seletor de idioma, toggle tema, menu usuário) */\n rightContent?: React.ReactNode;\n /** Subtítulo abaixo do título */\n subtitle?: React.ReactNode;\n /** Tema opcional para escolher o logo correto sem depender do ThemeProvider do UI */\n theme?: Theme;\n /** Título exibido ao lado do logo (ex.: \"OFÍCIO.IA\") */\n title?: React.ReactNode;\n}\n\nconst detectTheme = (): Theme => {\n if (typeof document === 'undefined') {\n return 'light';\n }\n\n return document.documentElement.getAttribute('data-theme') === 'dark'\n ? 'dark'\n : 'light';\n};\n\nexport const Header: React.FC<HeaderProps> = ({\n logoSrc,\n logoDarkSrc,\n logoAlt = 'Logo',\n title,\n subtitle,\n theme,\n onLogoClick,\n rightContent,\n className = '',\n}) => {\n const [isScrolled, setIsScrolled] = useState(false);\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(\n () => theme ?? detectTheme()\n );\n\n const logoSrcResolved =\n resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\n\n useEffect(() => {\n const handleScroll = () => setIsScrolled(window.scrollY > 10);\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, []);\n\n useEffect(() => {\n if (theme) {\n setResolvedTheme(theme);\n return;\n }\n\n const syncTheme = () => setResolvedTheme(detectTheme());\n syncTheme();\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(syncTheme);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme'],\n });\n\n return () => observer.disconnect();\n }, [theme]);\n\n const handleClick = () => onLogoClick?.();\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n onLogoClick?.();\n }\n };\n\n return (\n <header\n className={`app-header ${isScrolled ? 'scrolled' : ''} ${className}`.trim()}\n >\n <div className=\"app-header-top-bar\" />\n <div className=\"app-header-content\">\n <div\n className=\"app-header-left\"\n onClick={onLogoClick ? handleClick : undefined}\n onKeyDown={onLogoClick ? handleKeyDown : undefined}\n role={onLogoClick ? 'button' : undefined}\n tabIndex={onLogoClick ? 0 : undefined}\n >\n {logoSrcResolved && (\n <div className=\"app-header-logo\">\n <img\n alt={logoAlt}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n const next = (e.target as HTMLElement)\n .nextElementSibling as HTMLElement;\n if (next) {\n next.style.display = 'block';\n }\n }}\n src={logoSrcResolved}\n />\n <svg\n className=\"logo-icon-fallback\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\" />\n <path d=\"M2 17l10 5 10-5M2 12l10 5 10-5\" />\n </svg>\n </div>\n )}\n {(title || subtitle) && (\n <div className=\"app-header-title\">\n {title && <h1>{title}</h1>}\n {subtitle && <p>{subtitle}</p>}\n </div>\n )}\n </div>\n {rightContent && <div className=\"app-header-right\">{rightContent}</div>}\n </div>\n </header>\n );\n};\n","import type React from 'react';\nimport './Input.css';\n\nexport interface InputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n error?: string;\n fullWidth?: boolean;\n helperText?: string;\n label?: string;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n size?: 'sm' | 'md' | 'lg';\n}\n\nexport const Input: React.FC<InputProps> = ({\n label,\n error,\n helperText,\n leftIcon,\n rightIcon,\n fullWidth = false,\n size = 'md',\n className = '',\n id,\n ...props\n}) => {\n const inputId = id || `input-${Math.random().toString(36).substring(2, 9)}`;\n const hasError = !!error;\n const baseClass = 'input';\n const sizeClass = `input--${size}`;\n const errorClass = hasError ? 'input--error' : '';\n const fullWidthClass = fullWidth ? 'input--full-width' : '';\n const hasLeftIconClass = leftIcon ? 'input--has-left-icon' : '';\n const hasRightIconClass = rightIcon ? 'input--has-right-icon' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${errorClass} ${fullWidthClass} ${hasLeftIconClass} ${hasRightIconClass} ${className}`.trim();\n\n return (\n <div\n className={`input-wrapper ${fullWidth ? 'input-wrapper--full-width' : ''}`}\n >\n {label && (\n <label className=\"input-label\" htmlFor={inputId}>\n {label}\n </label>\n )}\n <div className=\"input-container\">\n {leftIcon && (\n <span className=\"input-icon input-icon--left\">{leftIcon}</span>\n )}\n <input\n aria-describedby={\n error\n ? `${inputId}-error`\n : helperText\n ? `${inputId}-helper`\n : undefined\n }\n aria-invalid={hasError ? true : undefined}\n className={combinedClass}\n id={inputId}\n {...props}\n />\n {rightIcon && (\n <span className=\"input-icon input-icon--right\">{rightIcon}</span>\n )}\n </div>\n {error && (\n <span className=\"input-error\" id={`${inputId}-error`} role=\"alert\">\n {error}\n </span>\n )}\n {helperText && !error && (\n <span className=\"input-helper\" id={`${inputId}-helper`}>\n {helperText}\n </span>\n )}\n </div>\n );\n};\n","import type React from 'react';\nimport { useEffect } from 'react';\nimport './Modal.css';\n\nexport interface ModalProps {\n children: React.ReactNode;\n className?: string;\n closeOnOverlayClick?: boolean;\n isOpen: boolean;\n onClose: () => void;\n showCloseButton?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n subtitle?: string;\n title?: string | React.ReactNode;\n}\n\nexport const Modal: React.FC<ModalProps> = ({\n isOpen,\n onClose,\n title,\n subtitle,\n children,\n size = 'md',\n showCloseButton = true,\n closeOnOverlayClick = true,\n className = '',\n}) => {\n useEffect(() => {\n if (isOpen) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => {\n document.body.style.overflow = '';\n };\n }, [isOpen]);\n\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen) {\n onClose();\n }\n };\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n }\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, onClose]);\n\n if (!isOpen) {\n return null;\n }\n\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (closeOnOverlayClick && e.target === e.currentTarget) {\n onClose();\n }\n };\n\n const sizeClass = `modal--${size}`;\n const combinedClass = `modal ${sizeClass} ${className}`.trim();\n\n return (\n <div\n aria-labelledby={title ? 'modal-title' : undefined}\n aria-modal=\"true\"\n className=\"modal-overlay\"\n onClick={handleOverlayClick}\n role=\"dialog\"\n >\n <div className={combinedClass}>\n {(title || subtitle || showCloseButton) && (\n <div className=\"modal-header\">\n {(title || subtitle) && (\n <div className=\"modal-header-content\">\n {title && (\n <h2 className=\"modal-title\" id=\"modal-title\">\n {title}\n </h2>\n )}\n {subtitle && <p className=\"modal-subtitle\">{subtitle}</p>}\n </div>\n )}\n {showCloseButton && (\n <button\n aria-label=\"Fechar modal\"\n className=\"modal-close\"\n onClick={onClose}\n type=\"button\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <line x1=\"18\" x2=\"6\" y1=\"6\" y2=\"18\" />\n <line x1=\"6\" x2=\"18\" y1=\"6\" y2=\"18\" />\n </svg>\n </button>\n )}\n </div>\n )}\n <div className=\"modal-content\">{children}</div>\n </div>\n </div>\n );\n};\n","import type React from 'react';\nimport './Paragraph.css';\n\nexport interface ParagraphProps\n extends React.HTMLAttributes<HTMLParagraphElement> {\n align?: 'left' | 'center' | 'right' | 'justify';\n as?: 'p' | 'span' | 'div';\n children: React.ReactNode;\n muted?: boolean;\n size?: 'xs' | 'sm' | 'md' | 'lg';\n weight?: 'light' | 'normal' | 'medium';\n}\n\nexport const Paragraph: React.FC<ParagraphProps> = ({\n as = 'p',\n size = 'md',\n weight = 'normal',\n align = 'left',\n muted = false,\n children,\n className = '',\n ...props\n}) => {\n const Component = as;\n const baseClass = 'paragraph';\n const sizeClass = `paragraph--${size}`;\n const weightClass = `paragraph--${weight}`;\n const alignClass = `paragraph--align-${align}`;\n const mutedClass = muted ? 'paragraph--muted' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${weightClass} ${alignClass} ${mutedClass} ${className}`.trim();\n\n return (\n <Component className={combinedClass} {...props}>\n {children}\n </Component>\n );\n};\n","import type React from 'react';\nimport './Subtitle.css';\n\nexport interface SubtitleProps\n extends React.HTMLAttributes<HTMLParagraphElement> {\n align?: 'left' | 'center' | 'right';\n as?: 'p' | 'span' | 'div';\n children: React.ReactNode;\n muted?: boolean;\n size?: 'xs' | 'sm' | 'md' | 'lg';\n weight?: 'normal' | 'medium' | 'semibold';\n}\n\nexport const Subtitle: React.FC<SubtitleProps> = ({\n as = 'p',\n size = 'md',\n weight = 'normal',\n align = 'left',\n muted = false,\n children,\n className = '',\n ...props\n}) => {\n const Component = as;\n const baseClass = 'subtitle';\n const sizeClass = `subtitle--${size}`;\n const weightClass = `subtitle--${weight}`;\n const alignClass = `subtitle--align-${align}`;\n const mutedClass = muted ? 'subtitle--muted' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${weightClass} ${alignClass} ${mutedClass} ${className}`.trim();\n\n return (\n <Component className={combinedClass} {...props}>\n {children}\n </Component>\n );\n};\n","import type React from 'react';\nimport './Title.css';\n\nexport interface TitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n align?: 'left' | 'center' | 'right';\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n children: React.ReactNode;\n gradient?: boolean;\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';\n weight?: 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold';\n}\n\nexport const Title: React.FC<TitleProps> = ({\n as = 'h1',\n size = '2xl',\n weight = 'bold',\n align = 'left',\n gradient = false,\n children,\n className = '',\n ...props\n}) => {\n const Component = as;\n const baseClass = 'title';\n const sizeClass = `title--${size}`;\n const weightClass = `title--${weight}`;\n const alignClass = `title--align-${align}`;\n const gradientClass = gradient ? 'title--gradient' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${weightClass} ${alignClass} ${gradientClass} ${className}`.trim();\n\n return (\n <Component className={combinedClass} {...props}>\n {children}\n </Component>\n );\n};\n","import {\n createContext,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from 'react';\n\nexport type Theme = 'light' | 'dark';\n\ninterface ThemeContextType {\n theme: Theme;\n toggleTheme: () => void;\n}\n\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined);\n\nexport const useTheme = (): ThemeContextType => {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n};\n\ninterface ThemeProviderProps {\n children: ReactNode;\n defaultTheme?: Theme;\n}\n\nexport const ThemeProvider = ({\n children,\n defaultTheme = 'light',\n}: ThemeProviderProps) => {\n const [theme, setTheme] = useState<Theme>(() => {\n if (typeof window === 'undefined') {\n return defaultTheme;\n }\n const saved = window.localStorage.getItem('theme');\n return (saved as Theme) || defaultTheme;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n window.localStorage.setItem('theme', theme);\n document.documentElement.setAttribute('data-theme', theme);\n }, [theme]);\n\n const toggleTheme = (): void => {\n setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'));\n };\n\n return (\n <ThemeContext.Provider value={{ theme, toggleTheme }}>\n {children}\n </ThemeContext.Provider>\n );\n};\n"],"names":["Button","variant","size","fullWidth","isLoading","leftIcon","rightIcon","children","className","disabled","palette","props","variantClass","sizeClass","fullWidthClass","loadingClass","paletteClass","combinedClass","jsxs","jsx","Card","padding","hoverable","baseClass","paddingClass","Footer","poweredByText","logoSrc","logoAlt","logoFallbackText","e","next","detectTheme","Header","logoDarkSrc","title","subtitle","theme","onLogoClick","rightContent","isScrolled","setIsScrolled","useState","resolvedTheme","setResolvedTheme","logoSrcResolved","useEffect","handleScroll","syncTheme","observer","handleClick","handleKeyDown","Input","label","error","helperText","id","inputId","hasError","Modal","isOpen","onClose","showCloseButton","closeOnOverlayClick","handleEscape","handleOverlayClick","Paragraph","as","weight","align","muted","Component","weightClass","alignClass","Subtitle","Title","gradient","ThemeContext","createContext","useTheme","context","useContext","ThemeProvider","defaultTheme","setTheme","toggleTheme","prev"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ (function(c,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],e):(c=typeof globalThis<"u"?globalThis:c||self,e(c.OficiosUI={},c.jsxRuntime,c.React))})(this,(function(c,e,$){"use strict";const w=({variant:t="primary",size:a="md",fullWidth:n=!1,isLoading:s=!1,leftIcon:r,rightIcon:l,children:o,className:h="",disabled:p,palette:m,...d})=>{const i=`btn--${t}`,b=`btn--${a}`,v=n?"btn--full-width":"",g=s?"btn--loading":"",u=m&&t==="primary"?`btn--palette-${m}`:"",C=`btn ${i} ${b} ${v} ${g} ${u} ${h}`.trim();return e.jsxs("button",{className:C,disabled:p||s,...d,children:[s&&e.jsx("span",{"aria-hidden":"true",className:"btn__spinner",children:e.jsxs("svg",{fill:"none",stroke:"currentColor",strokeWidth:"2",viewBox:"0 0 24 24",children:[e.jsx("circle",{cx:"12",cy:"12",r:"10",strokeOpacity:"0.25"}),e.jsx("path",{d:"M12 2 A10 10 0 0 1 22 12",strokeLinecap:"round"})]})}),!s&&r&&e.jsx("span",{className:"btn__icon btn__icon--left",children:r}),e.jsx("span",{className:"btn__content",children:o}),!s&&l&&e.jsx("span",{className:"btn__icon btn__icon--right",children:l})]})},E=({variant:t="default",padding:a="md",hoverable:n=!1,children:s,className:r="",...l})=>{const o="card",h=`card--${t}`,p=`card--padding-${a}`,d=`${o} ${h} ${p} ${n?"card--hoverable":""} ${r}`.trim();return e.jsx("div",{className:d,...l,children:s})},k=({poweredByText:t="Powered by",logoSrc:a,logoAlt:n="Logo",logoFallbackText:s,className:r=""})=>e.jsx("footer",{className:`app-footer ${r}`.trim(),children:e.jsxs("div",{className:"app-footer-powered",children:[t&&e.jsx("span",{className:"app-footer-powered-text",children:t}),(a||s)&&e.jsxs("div",{className:"app-footer-logo-wrap",children:[a&&e.jsx("img",{alt:n,className:"app-footer-logo",onError:l=>{l.target.style.display="none";const o=l.target.nextElementSibling;o&&(o.style.display="flex")},src:a}),s&&e.jsx("span",{className:"app-footer-logo-fallback",style:{display:a?"none":"flex"},children:s})]})]})}),y=()=>typeof document>"u"?"light":document.documentElement.getAttribute("data-theme")==="dark"?"dark":"light",T=({logoSrc:t,logoDarkSrc:a,logoAlt:n="Logo",title:s,subtitle:r,theme:l,onLogoClick:o,rightContent:h,className:p=""})=>{const[m,d]=$.useState(!1),[f,i]=$.useState(()=>l??y()),b=f==="dark"&&a?a:t;$.useEffect(()=>{const u=()=>d(window.scrollY>10);return window.addEventListener("scroll",u,{passive:!0}),()=>window.removeEventListener("scroll",u)},[]),$.useEffect(()=>{if(l){i(l);return}const u=()=>i(y());if(u(),typeof MutationObserver>"u")return;const C=new MutationObserver(u);return C.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>C.disconnect()},[l]);const v=()=>o?.(),g=u=>{u.key==="Enter"&&o?.()};return e.jsxs("header",{className:`app-header ${m?"scrolled":""} ${p}`.trim(),children:[e.jsx("div",{className:"app-header-top-bar"}),e.jsxs("div",{className:"app-header-content",children:[e.jsxs("div",{className:"app-header-left",onClick:o?v:void 0,onKeyDown:o?g:void 0,role:o?"button":void 0,tabIndex:o?0:void 0,children:[b&&e.jsxs("div",{className:"app-header-logo",children:[e.jsx("img",{alt:n,onError:u=>{u.target.style.display="none";const C=u.target.nextElementSibling;C&&(C.style.display="block")},src:b}),e.jsxs("svg",{className:"logo-icon-fallback",fill:"none",stroke:"currentColor",strokeWidth:"2",viewBox:"0 0 24 24",children:[e.jsx("path",{d:"M12 2L2 7l10 5 10-5-10-5z"}),e.jsx("path",{d:"M2 17l10 5 10-5M2 12l10 5 10-5"})]})]}),(s||r)&&e.jsxs("div",{className:"app-header-title",children:[s&&e.jsx("h1",{children:s}),r&&e.jsx("p",{children:r})]})]}),h&&e.jsx("div",{className:"app-header-right",children:h})]})]})},x=({label:t,error:a,helperText:n,leftIcon:s,rightIcon:r,fullWidth:l=!1,size:o="md",className:h="",id:p,...m})=>{const d=p||`input-${Math.random().toString(36).substring(2,9)}`,f=!!a,i="input",b=`input--${o}`,I=`${i} ${b} ${f?"input--error":""} ${l?"input--full-width":""} ${s?"input--has-left-icon":""} ${r?"input--has-right-icon":""} ${h}`.trim();return e.jsxs("div",{className:`input-wrapper ${l?"input-wrapper--full-width":""}`,children:[t&&e.jsx("label",{className:"input-label",htmlFor:d,children:t}),e.jsxs("div",{className:"input-container",children:[s&&e.jsx("span",{className:"input-icon input-icon--left",children:s}),e.jsx("input",{"aria-describedby":a?`${d}-error`:n?`${d}-helper`:void 0,"aria-invalid":f?!0:void 0,className:I,id:d,...m}),r&&e.jsx("span",{className:"input-icon input-icon--right",children:r})]}),a&&e.jsx("span",{className:"input-error",id:`${d}-error`,role:"alert",children:a}),n&&!a&&e.jsx("span",{className:"input-helper",id:`${d}-helper`,children:n})]})},S=({isOpen:t,onClose:a,title:n,subtitle:s,children:r,size:l="md",showCloseButton:o=!0,closeOnOverlayClick:h=!0,className:p=""})=>{if($.useEffect(()=>(t?document.body.style.overflow="hidden":document.body.style.overflow="",()=>{document.body.style.overflow=""}),[t]),$.useEffect(()=>{const i=b=>{b.key==="Escape"&&t&&a()};return t&&document.addEventListener("keydown",i),()=>document.removeEventListener("keydown",i)},[t,a]),!t)return null;const m=i=>{h&&i.target===i.currentTarget&&a()},f=`modal ${`modal--${l}`} ${p}`.trim();return e.jsx("div",{"aria-labelledby":n?"modal-title":void 0,"aria-modal":"true",className:"modal-overlay",onClick:m,role:"dialog",children:e.jsxs("div",{className:f,children:[(n||s||o)&&e.jsxs("div",{className:"modal-header",children:[(n||s)&&e.jsxs("div",{className:"modal-header-content",children:[n&&e.jsx("h2",{className:"modal-title",id:"modal-title",children:n}),s&&e.jsx("p",{className:"modal-subtitle",children:s})]}),o&&e.jsx("button",{"aria-label":"Fechar modal",className:"modal-close",onClick:a,type:"button",children:e.jsxs("svg",{fill:"none",stroke:"currentColor",strokeWidth:"2",viewBox:"0 0 24 24",children:[e.jsx("line",{x1:"18",x2:"6",y1:"6",y2:"18"}),e.jsx("line",{x1:"6",x2:"18",y1:"6",y2:"18"})]})})]}),e.jsx("div",{className:"modal-content",children:r})]})})},_=({as:t="p",size:a="md",weight:n="normal",align:s="left",muted:r=!1,children:l,className:o="",...h})=>{const p=t,m="paragraph",d=`paragraph--${a}`,f=`paragraph--${n}`,i=`paragraph--align-${s}`,v=`${m} ${d} ${f} ${i} ${r?"paragraph--muted":""} ${o}`.trim();return e.jsx(p,{className:v,...h,children:l})},M=({as:t="p",size:a="md",weight:n="normal",align:s="left",muted:r=!1,children:l,className:o="",...h})=>{const p=t,m="subtitle",d=`subtitle--${a}`,f=`subtitle--${n}`,i=`subtitle--align-${s}`,v=`${m} ${d} ${f} ${i} ${r?"subtitle--muted":""} ${o}`.trim();return e.jsx(p,{className:v,...h,children:l})},z=({as:t="h1",size:a="2xl",weight:n="bold",align:s="left",gradient:r=!1,children:l,className:o="",...h})=>{const p=t,m="title",d=`title--${a}`,f=`title--${n}`,i=`title--align-${s}`,v=`${m} ${d} ${f} ${i} ${r?"title--gradient":""} ${o}`.trim();return e.jsx(p,{className:v,...h,children:l})},N=$.createContext(void 0),P=()=>{const t=$.useContext(N);if(!t)throw new Error("useTheme must be used within a ThemeProvider");return t},j=({children:t,defaultTheme:a="light"})=>{const[n,s]=$.useState(()=>typeof window>"u"?a:window.localStorage.getItem("theme")||a);$.useEffect(()=>{typeof window>"u"||(window.localStorage.setItem("theme",n),document.documentElement.setAttribute("data-theme",n))},[n]);const r=()=>{s(l=>l==="dark"?"light":"dark")};return e.jsx(N.Provider,{value:{theme:n,toggleTheme:r},children:t})};c.Button=w,c.Card=E,c.Footer=k,c.Header=T,c.Input=x,c.Modal=S,c.Paragraph=_,c.Subtitle=M,c.ThemeProvider=j,c.Title=z,c.useTheme=P,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
2
+ //# sourceMappingURL=oficios-ui.umd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oficios-ui.umd.cjs","sources":["../src/components/Button/Button.tsx","../src/components/Card/Card.tsx","../src/components/Footer/Footer.tsx","../src/components/Header/Header.tsx","../src/components/Input/Input.tsx","../src/components/Modal/Modal.tsx","../src/components/Paragraph/Paragraph.tsx","../src/components/Subtitle/Subtitle.tsx","../src/components/Title/Title.tsx","../src/theme/ThemeProvider.tsx"],"sourcesContent":["import type React from 'react';\nimport './Button.css';\n\n/** Paletas do guia de marca (só afeta variant primary). Use para escolher o modelo de cor do botão. */\nexport type ButtonPalette =\n | 'verde-vibrante'\n | 'verde-profundo'\n | 'grafite-azulado'\n | 'azul-acinzentado'\n | 'cinza-medio'\n | 'cinza-escuro'\n | 'off-white';\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n fullWidth?: boolean;\n isLoading?: boolean;\n leftIcon?: React.ReactNode;\n /** Paleta de cor do guia de marca (aplica-se ao primary). Ignorado em outros variants. */\n palette?: ButtonPalette;\n rightIcon?: React.ReactNode;\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n variant?:\n | 'primary'\n | 'secondary'\n | 'success'\n | 'error'\n | 'warning'\n | 'info'\n | 'neutral'\n | 'ghost';\n}\n\nexport const Button: React.FC<ButtonProps> = ({\n variant = 'primary',\n size = 'md',\n fullWidth = false,\n isLoading = false,\n leftIcon,\n rightIcon,\n children,\n className = '',\n disabled,\n palette,\n ...props\n}) => {\n const baseClass = 'btn';\n const variantClass = `btn--${variant}`;\n const sizeClass = `btn--${size}`;\n const fullWidthClass = fullWidth ? 'btn--full-width' : '';\n const loadingClass = isLoading ? 'btn--loading' : '';\n const paletteClass =\n palette && variant === 'primary' ? `btn--palette-${palette}` : '';\n const combinedClass =\n `${baseClass} ${variantClass} ${sizeClass} ${fullWidthClass} ${loadingClass} ${paletteClass} ${className}`.trim();\n\n return (\n <button\n className={combinedClass}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading && (\n <span aria-hidden=\"true\" className=\"btn__spinner\">\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" strokeOpacity=\"0.25\" />\n <path d=\"M12 2 A10 10 0 0 1 22 12\" strokeLinecap=\"round\" />\n </svg>\n </span>\n )}\n {!isLoading && leftIcon && (\n <span className=\"btn__icon btn__icon--left\">{leftIcon}</span>\n )}\n <span className=\"btn__content\">{children}</span>\n {!isLoading && rightIcon && (\n <span className=\"btn__icon btn__icon--right\">{rightIcon}</span>\n )}\n </button>\n );\n};\n","import type React from 'react';\nimport './Card.css';\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n hoverable?: boolean;\n padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';\n variant?: 'default' | 'elevated' | 'outlined' | 'flat';\n}\n\nexport const Card: React.FC<CardProps> = ({\n variant = 'default',\n padding = 'md',\n hoverable = false,\n children,\n className = '',\n ...props\n}) => {\n const baseClass = 'card';\n const variantClass = `card--${variant}`;\n const paddingClass = `card--padding-${padding}`;\n const hoverableClass = hoverable ? 'card--hoverable' : '';\n const combinedClass =\n `${baseClass} ${variantClass} ${paddingClass} ${hoverableClass} ${className}`.trim();\n\n return (\n <div className={combinedClass} {...props}>\n {children}\n </div>\n );\n};\n","import type React from 'react';\nimport './Footer.css';\n\nexport interface FooterProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** Texto exibido se a imagem do logo falhar (ex.: \"SBK\") */\n logoFallbackText?: string;\n /** URL da imagem do logo */\n logoSrc?: string;\n /** Texto antes do logo (ex.: \"Powered by\") */\n poweredByText?: string;\n}\n\nexport const Footer: React.FC<FooterProps> = ({\n poweredByText = 'Powered by',\n logoSrc,\n logoAlt = 'Logo',\n logoFallbackText,\n className = '',\n}) => {\n return (\n <footer className={`app-footer ${className}`.trim()}>\n <div className=\"app-footer-powered\">\n {poweredByText && (\n <span className=\"app-footer-powered-text\">{poweredByText}</span>\n )}\n {(logoSrc || logoFallbackText) && (\n <div className=\"app-footer-logo-wrap\">\n {logoSrc && (\n <img\n alt={logoAlt}\n className=\"app-footer-logo\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n const next = (e.target as HTMLElement)\n .nextElementSibling as HTMLElement;\n if (next) {\n next.style.display = 'flex';\n }\n }}\n src={logoSrc}\n />\n )}\n {logoFallbackText && (\n <span\n className=\"app-footer-logo-fallback\"\n style={{ display: logoSrc ? 'none' : 'flex' }}\n >\n {logoFallbackText}\n </span>\n )}\n </div>\n )}\n </div>\n </footer>\n );\n};\n","import type React from 'react';\nimport { useEffect, useState } from 'react';\nimport type { Theme } from '../../theme/ThemeProvider';\nimport './Header.css';\n\nexport interface HeaderProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** URL da imagem do logo (tema escuro). Se não informado, usa logoSrc. */\n logoDarkSrc?: string;\n /** URL da imagem do logo (tema claro) */\n logoSrc?: string;\n /** Callback ao clicar na área do logo/título */\n onLogoClick?: () => void;\n /** Conteúdo da área direita (ex.: seletor de idioma, toggle tema, menu usuário) */\n rightContent?: React.ReactNode;\n /** Subtítulo abaixo do título */\n subtitle?: React.ReactNode;\n /** Tema opcional para escolher o logo correto sem depender do ThemeProvider do UI */\n theme?: Theme;\n /** Título exibido ao lado do logo (ex.: \"OFÍCIO.IA\") */\n title?: React.ReactNode;\n}\n\nconst detectTheme = (): Theme => {\n if (typeof document === 'undefined') {\n return 'light';\n }\n\n return document.documentElement.getAttribute('data-theme') === 'dark'\n ? 'dark'\n : 'light';\n};\n\nexport const Header: React.FC<HeaderProps> = ({\n logoSrc,\n logoDarkSrc,\n logoAlt = 'Logo',\n title,\n subtitle,\n theme,\n onLogoClick,\n rightContent,\n className = '',\n}) => {\n const [isScrolled, setIsScrolled] = useState(false);\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(\n () => theme ?? detectTheme()\n );\n\n const logoSrcResolved =\n resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\n\n useEffect(() => {\n const handleScroll = () => setIsScrolled(window.scrollY > 10);\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, []);\n\n useEffect(() => {\n if (theme) {\n setResolvedTheme(theme);\n return;\n }\n\n const syncTheme = () => setResolvedTheme(detectTheme());\n syncTheme();\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(syncTheme);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme'],\n });\n\n return () => observer.disconnect();\n }, [theme]);\n\n const handleClick = () => onLogoClick?.();\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n onLogoClick?.();\n }\n };\n\n return (\n <header\n className={`app-header ${isScrolled ? 'scrolled' : ''} ${className}`.trim()}\n >\n <div className=\"app-header-top-bar\" />\n <div className=\"app-header-content\">\n <div\n className=\"app-header-left\"\n onClick={onLogoClick ? handleClick : undefined}\n onKeyDown={onLogoClick ? handleKeyDown : undefined}\n role={onLogoClick ? 'button' : undefined}\n tabIndex={onLogoClick ? 0 : undefined}\n >\n {logoSrcResolved && (\n <div className=\"app-header-logo\">\n <img\n alt={logoAlt}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n const next = (e.target as HTMLElement)\n .nextElementSibling as HTMLElement;\n if (next) {\n next.style.display = 'block';\n }\n }}\n src={logoSrcResolved}\n />\n <svg\n className=\"logo-icon-fallback\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\" />\n <path d=\"M2 17l10 5 10-5M2 12l10 5 10-5\" />\n </svg>\n </div>\n )}\n {(title || subtitle) && (\n <div className=\"app-header-title\">\n {title && <h1>{title}</h1>}\n {subtitle && <p>{subtitle}</p>}\n </div>\n )}\n </div>\n {rightContent && <div className=\"app-header-right\">{rightContent}</div>}\n </div>\n </header>\n );\n};\n","import type React from 'react';\nimport './Input.css';\n\nexport interface InputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n error?: string;\n fullWidth?: boolean;\n helperText?: string;\n label?: string;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n size?: 'sm' | 'md' | 'lg';\n}\n\nexport const Input: React.FC<InputProps> = ({\n label,\n error,\n helperText,\n leftIcon,\n rightIcon,\n fullWidth = false,\n size = 'md',\n className = '',\n id,\n ...props\n}) => {\n const inputId = id || `input-${Math.random().toString(36).substring(2, 9)}`;\n const hasError = !!error;\n const baseClass = 'input';\n const sizeClass = `input--${size}`;\n const errorClass = hasError ? 'input--error' : '';\n const fullWidthClass = fullWidth ? 'input--full-width' : '';\n const hasLeftIconClass = leftIcon ? 'input--has-left-icon' : '';\n const hasRightIconClass = rightIcon ? 'input--has-right-icon' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${errorClass} ${fullWidthClass} ${hasLeftIconClass} ${hasRightIconClass} ${className}`.trim();\n\n return (\n <div\n className={`input-wrapper ${fullWidth ? 'input-wrapper--full-width' : ''}`}\n >\n {label && (\n <label className=\"input-label\" htmlFor={inputId}>\n {label}\n </label>\n )}\n <div className=\"input-container\">\n {leftIcon && (\n <span className=\"input-icon input-icon--left\">{leftIcon}</span>\n )}\n <input\n aria-describedby={\n error\n ? `${inputId}-error`\n : helperText\n ? `${inputId}-helper`\n : undefined\n }\n aria-invalid={hasError ? true : undefined}\n className={combinedClass}\n id={inputId}\n {...props}\n />\n {rightIcon && (\n <span className=\"input-icon input-icon--right\">{rightIcon}</span>\n )}\n </div>\n {error && (\n <span className=\"input-error\" id={`${inputId}-error`} role=\"alert\">\n {error}\n </span>\n )}\n {helperText && !error && (\n <span className=\"input-helper\" id={`${inputId}-helper`}>\n {helperText}\n </span>\n )}\n </div>\n );\n};\n","import type React from 'react';\nimport { useEffect } from 'react';\nimport './Modal.css';\n\nexport interface ModalProps {\n children: React.ReactNode;\n className?: string;\n closeOnOverlayClick?: boolean;\n isOpen: boolean;\n onClose: () => void;\n showCloseButton?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n subtitle?: string;\n title?: string | React.ReactNode;\n}\n\nexport const Modal: React.FC<ModalProps> = ({\n isOpen,\n onClose,\n title,\n subtitle,\n children,\n size = 'md',\n showCloseButton = true,\n closeOnOverlayClick = true,\n className = '',\n}) => {\n useEffect(() => {\n if (isOpen) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => {\n document.body.style.overflow = '';\n };\n }, [isOpen]);\n\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen) {\n onClose();\n }\n };\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n }\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, onClose]);\n\n if (!isOpen) {\n return null;\n }\n\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (closeOnOverlayClick && e.target === e.currentTarget) {\n onClose();\n }\n };\n\n const sizeClass = `modal--${size}`;\n const combinedClass = `modal ${sizeClass} ${className}`.trim();\n\n return (\n <div\n aria-labelledby={title ? 'modal-title' : undefined}\n aria-modal=\"true\"\n className=\"modal-overlay\"\n onClick={handleOverlayClick}\n role=\"dialog\"\n >\n <div className={combinedClass}>\n {(title || subtitle || showCloseButton) && (\n <div className=\"modal-header\">\n {(title || subtitle) && (\n <div className=\"modal-header-content\">\n {title && (\n <h2 className=\"modal-title\" id=\"modal-title\">\n {title}\n </h2>\n )}\n {subtitle && <p className=\"modal-subtitle\">{subtitle}</p>}\n </div>\n )}\n {showCloseButton && (\n <button\n aria-label=\"Fechar modal\"\n className=\"modal-close\"\n onClick={onClose}\n type=\"button\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <line x1=\"18\" x2=\"6\" y1=\"6\" y2=\"18\" />\n <line x1=\"6\" x2=\"18\" y1=\"6\" y2=\"18\" />\n </svg>\n </button>\n )}\n </div>\n )}\n <div className=\"modal-content\">{children}</div>\n </div>\n </div>\n );\n};\n","import type React from 'react';\nimport './Paragraph.css';\n\nexport interface ParagraphProps\n extends React.HTMLAttributes<HTMLParagraphElement> {\n align?: 'left' | 'center' | 'right' | 'justify';\n as?: 'p' | 'span' | 'div';\n children: React.ReactNode;\n muted?: boolean;\n size?: 'xs' | 'sm' | 'md' | 'lg';\n weight?: 'light' | 'normal' | 'medium';\n}\n\nexport const Paragraph: React.FC<ParagraphProps> = ({\n as = 'p',\n size = 'md',\n weight = 'normal',\n align = 'left',\n muted = false,\n children,\n className = '',\n ...props\n}) => {\n const Component = as;\n const baseClass = 'paragraph';\n const sizeClass = `paragraph--${size}`;\n const weightClass = `paragraph--${weight}`;\n const alignClass = `paragraph--align-${align}`;\n const mutedClass = muted ? 'paragraph--muted' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${weightClass} ${alignClass} ${mutedClass} ${className}`.trim();\n\n return (\n <Component className={combinedClass} {...props}>\n {children}\n </Component>\n );\n};\n","import type React from 'react';\nimport './Subtitle.css';\n\nexport interface SubtitleProps\n extends React.HTMLAttributes<HTMLParagraphElement> {\n align?: 'left' | 'center' | 'right';\n as?: 'p' | 'span' | 'div';\n children: React.ReactNode;\n muted?: boolean;\n size?: 'xs' | 'sm' | 'md' | 'lg';\n weight?: 'normal' | 'medium' | 'semibold';\n}\n\nexport const Subtitle: React.FC<SubtitleProps> = ({\n as = 'p',\n size = 'md',\n weight = 'normal',\n align = 'left',\n muted = false,\n children,\n className = '',\n ...props\n}) => {\n const Component = as;\n const baseClass = 'subtitle';\n const sizeClass = `subtitle--${size}`;\n const weightClass = `subtitle--${weight}`;\n const alignClass = `subtitle--align-${align}`;\n const mutedClass = muted ? 'subtitle--muted' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${weightClass} ${alignClass} ${mutedClass} ${className}`.trim();\n\n return (\n <Component className={combinedClass} {...props}>\n {children}\n </Component>\n );\n};\n","import type React from 'react';\nimport './Title.css';\n\nexport interface TitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n align?: 'left' | 'center' | 'right';\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n children: React.ReactNode;\n gradient?: boolean;\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';\n weight?: 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold';\n}\n\nexport const Title: React.FC<TitleProps> = ({\n as = 'h1',\n size = '2xl',\n weight = 'bold',\n align = 'left',\n gradient = false,\n children,\n className = '',\n ...props\n}) => {\n const Component = as;\n const baseClass = 'title';\n const sizeClass = `title--${size}`;\n const weightClass = `title--${weight}`;\n const alignClass = `title--align-${align}`;\n const gradientClass = gradient ? 'title--gradient' : '';\n const combinedClass =\n `${baseClass} ${sizeClass} ${weightClass} ${alignClass} ${gradientClass} ${className}`.trim();\n\n return (\n <Component className={combinedClass} {...props}>\n {children}\n </Component>\n );\n};\n","import {\n createContext,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from 'react';\n\nexport type Theme = 'light' | 'dark';\n\ninterface ThemeContextType {\n theme: Theme;\n toggleTheme: () => void;\n}\n\nconst ThemeContext = createContext<ThemeContextType | undefined>(undefined);\n\nexport const useTheme = (): ThemeContextType => {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n};\n\ninterface ThemeProviderProps {\n children: ReactNode;\n defaultTheme?: Theme;\n}\n\nexport const ThemeProvider = ({\n children,\n defaultTheme = 'light',\n}: ThemeProviderProps) => {\n const [theme, setTheme] = useState<Theme>(() => {\n if (typeof window === 'undefined') {\n return defaultTheme;\n }\n const saved = window.localStorage.getItem('theme');\n return (saved as Theme) || defaultTheme;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n window.localStorage.setItem('theme', theme);\n document.documentElement.setAttribute('data-theme', theme);\n }, [theme]);\n\n const toggleTheme = (): void => {\n setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'));\n };\n\n return (\n <ThemeContext.Provider value={{ theme, toggleTheme }}>\n {children}\n </ThemeContext.Provider>\n );\n};\n"],"names":["Button","variant","size","fullWidth","isLoading","leftIcon","rightIcon","children","className","disabled","palette","props","variantClass","sizeClass","fullWidthClass","loadingClass","paletteClass","combinedClass","jsxs","jsx","Card","padding","hoverable","baseClass","paddingClass","Footer","poweredByText","logoSrc","logoAlt","logoFallbackText","e","next","detectTheme","Header","logoDarkSrc","title","subtitle","theme","onLogoClick","rightContent","isScrolled","setIsScrolled","useState","resolvedTheme","setResolvedTheme","logoSrcResolved","useEffect","handleScroll","syncTheme","observer","handleClick","handleKeyDown","Input","label","error","helperText","id","inputId","hasError","Modal","isOpen","onClose","showCloseButton","closeOnOverlayClick","handleEscape","handleOverlayClick","Paragraph","as","weight","align","muted","Component","weightClass","alignClass","Subtitle","Title","gradient","ThemeContext","createContext","useTheme","context","useContext","ThemeProvider","defaultTheme","setTheme","toggleTheme","prev"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from 'react';
2
+ export type Theme = 'light' | 'dark';
3
+ interface ThemeContextType {
4
+ theme: Theme;
5
+ toggleTheme: () => void;
6
+ }
7
+ export declare const useTheme: () => ThemeContextType;
8
+ interface ThemeProviderProps {
9
+ children: ReactNode;
10
+ defaultTheme?: Theme;
11
+ }
12
+ export declare const ThemeProvider: ({ children, defaultTheme, }: ThemeProviderProps) => import("react/jsx-runtime").JSX.Element;
13
+ export {};
package/dist/theme.css ADDED
@@ -0,0 +1,295 @@
1
+ /* ============================================================
2
+ DESIGN SYSTEM - VARIÁVEIS GLOBAIS DE TEMA (@oficios/ui)
3
+ Guia de marca: cores e tipografia SBK
4
+ ============================================================ */
5
+
6
+ @import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400;1,500&display=swap");
7
+
8
+ /* ============================================================
9
+ GUIA DE MARCA - CORES (paleta fixa para referência e paletas)
10
+ ============================================================ */
11
+ :root {
12
+ /* Cores principais do guia */
13
+ --brand-verde-vibrante: #01b2aa;
14
+ --brand-verde-profundo: #1f3a3a;
15
+ --brand-grafite-azulado: #0f2f3a;
16
+ --brand-azul-acinzentado: #5f7b8d;
17
+ --brand-cinza-medio: #4b4b4b;
18
+ --brand-cinza-escuro: #24262d;
19
+ --brand-off-white: #ffffff;
20
+ --brand-neutral-75: rgba(255, 255, 255, 0.75);
21
+ --brand-branco: #ffffff;
22
+
23
+ /* DNA da marca - O Criador */
24
+ --brand-preto: #000000;
25
+ --brand-cinza: #989495;
26
+ --brand-azul-lavanda: #777dac;
27
+ --brand-azul-intenso: #132c3b;
28
+ --brand-cinza-azulado: #b4c2c7;
29
+ --brand-verde-lima: #cffe40;
30
+ --brand-off-white-criador: #e4e4e4;
31
+ --brand-azul-escuro: #071a5c;
32
+ }
33
+
34
+ /* ============================================================
35
+ GUIA DE MARCA - TIPOGRAFIA (O Herói / O Criador)
36
+ Jakarta = headlines fortes; alta legibilidade; estrutura
37
+ ============================================================ */
38
+ :root {
39
+ --font-primary:
40
+ "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
41
+ sans-serif;
42
+ --font-secondary: "Plus Jakarta Sans", var(--font-primary);
43
+ --font-heading: var(--font-primary);
44
+ --font-body: var(--font-primary);
45
+ }
46
+
47
+ html {
48
+ font-family: var(--font-body);
49
+ font-size: 1rem;
50
+ }
51
+
52
+ :root {
53
+ --primary-color: var(--brand-verde-vibrante);
54
+ --primary-color-dark: var(--brand-verde-profundo);
55
+ --primary-color-light: color-mix(
56
+ in srgb,
57
+ var(--brand-verde-vibrante) 84%,
58
+ white
59
+ );
60
+ --primary-color-hover: var(--brand-verde-profundo);
61
+ --md-primary: var(--brand-verde-vibrante);
62
+ --md-on-primary: #ffffff;
63
+ --md-primary-container: color-mix(
64
+ in srgb,
65
+ var(--brand-verde-vibrante) 18%,
66
+ white
67
+ );
68
+ --md-on-primary-container: var(--brand-grafite-azulado);
69
+ --secondary-color: var(--brand-grafite-azulado);
70
+ /* Tokens semânticos para integração com Tailwind */
71
+ --color-primary: var(--primary-color);
72
+ --color-on-primary: var(--md-on-primary);
73
+ --color-secondary: var(--secondary-color);
74
+ --color-on-secondary: var(--md-on-secondary);
75
+ --color-surface: var(--md-surface);
76
+ --color-on-surface: var(--md-on-surface);
77
+ --color-contrast: var(--brand-verde-lima);
78
+
79
+ --md-secondary: var(--brand-grafite-azulado);
80
+ --md-on-secondary: #ffffff;
81
+ --md-outline: var(--brand-azul-acinzentado);
82
+ --md-outline-variant: color-mix(
83
+ in srgb,
84
+ var(--brand-azul-acinzentado) 35%,
85
+ white
86
+ );
87
+ --success-color: #22c55e;
88
+ --success-color-light: #4ade80;
89
+ --error-color: #ef4444;
90
+ --error-color-light: #f87171;
91
+ --md-error: #ba1a1a;
92
+ --md-on-error: #ffffff;
93
+ --warning-color: #f59e0b;
94
+ --warning-color-light: #fbbe24;
95
+ --info-color: #3b82f6;
96
+ --info-color-light: #60a5fa;
97
+ --neutral-color: var(--brand-cinza-medio);
98
+ --neutral-color-light: var(--brand-azul-acinzentado);
99
+ --secondary-color-light: var(--brand-azul-acinzentado);
100
+ --bg-hover: color-mix(in srgb, var(--brand-grafite-azulado) 8%, white);
101
+ --bg-active: color-mix(in srgb, var(--brand-grafite-azulado) 14%, white);
102
+ --md-on-surface: var(--brand-grafite-azulado);
103
+ --accent-color: var(--primary-color);
104
+ --accent-color-hover: var(--primary-color-hover);
105
+ --bg-primary: var(--brand-neutral-75);
106
+ --bg-secondary: #ffffff;
107
+ --bg-tertiary: color-mix(in srgb, var(--brand-azul-acinzentado) 14%, white);
108
+ --md-surface: #ffffff;
109
+ --md-surface-container: var(--brand-neutral-75);
110
+ --md-surface-container-high: color-mix(
111
+ in srgb,
112
+ var(--brand-azul-acinzentado) 14%,
113
+ white
114
+ );
115
+ --border-color-hover: color-mix(
116
+ in srgb,
117
+ var(--brand-grafite-azulado) 32%,
118
+ white
119
+ );
120
+ --bg-card: #ffffff;
121
+ --bg-card-hover: color-mix(in srgb, var(--brand-azul-acinzentado) 8%, white);
122
+ --bg-card-border: color-mix(
123
+ in srgb,
124
+ var(--brand-azul-acinzentado) 28%,
125
+ white
126
+ );
127
+ --text-primary: var(--brand-grafite-azulado);
128
+ --text-secondary: var(--brand-cinza-escuro);
129
+ --text-tertiary: var(--brand-cinza-medio);
130
+ --text-muted: var(--brand-cinza-medio);
131
+ --text-on-primary: #ffffff;
132
+ --border-color: color-mix(in srgb, var(--brand-azul-acinzentado) 30%, white);
133
+ --border-color-focus: color-mix(
134
+ in srgb,
135
+ var(--brand-verde-vibrante) 52%,
136
+ transparent
137
+ );
138
+ --shadow-xs: 0 0.0625rem 0.125rem rgba(0, 0, 0, 0.05);
139
+ --shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.08);
140
+ --shadow-md: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);
141
+ --shadow-lg: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.12);
142
+ --font-size-xs: 0.75rem;
143
+ --font-size-sm: 0.875rem;
144
+ --font-size-base: 1rem;
145
+ --font-size-md: 1.125rem;
146
+ --font-size-lg: 1.25rem;
147
+ --font-size-xl: 1.5rem;
148
+ --font-weight-normal: 400; /* Jakarta regular */
149
+ --font-weight-medium: 500;
150
+ --font-weight-semibold: 600; /* Jakarta seminegrito */
151
+ --font-weight-bold: 700;
152
+ --line-height-normal: 1.5;
153
+ --spacing-xs: 0.25rem;
154
+ --spacing-sm: 0.5rem;
155
+ --spacing-md: 0.75rem;
156
+ --spacing-lg: 1rem;
157
+ --spacing-xl: 1.5rem;
158
+ --spacing-2xl: 2rem;
159
+ --border-radius-sm: 0.375rem;
160
+ --border-radius-md: 0.5rem;
161
+ --border-radius-lg: 0.75rem;
162
+ --border-width-thin: 0.0625rem;
163
+ --transition-base: 0.3s ease;
164
+ --transition-all: all var(--transition-base);
165
+ --transition-colors:
166
+ color var(--transition-base), background-color var(--transition-base),
167
+ border-color var(--transition-base);
168
+ --z-index-dropdown: 1000;
169
+ --z-index-modal-backdrop: 1040;
170
+ --z-index-modal: 1050;
171
+ --border-radius-2xl: 1.25rem;
172
+ --shadow-2xl: 0 1.25rem 3.75rem rgba(0, 0, 0, 0.2);
173
+ --font-size-2xl: 1.75rem;
174
+ --font-size-3xl: 2rem;
175
+ --font-size-4xl: 2.5rem;
176
+ --font-weight-light: 300;
177
+ --line-height-tight: 1.2;
178
+ --line-height-relaxed: 1.6;
179
+ --line-height-loose: 1.8;
180
+ --md-on-surface-variant: #44474e;
181
+ --spacing-3xl: 2.5rem;
182
+ }
183
+
184
+ [data-theme="dark"],
185
+ .theme-dark {
186
+ --bg-primary: #0f141a;
187
+ --bg-secondary: #161b22;
188
+ --bg-card: #161b22;
189
+ --bg-card-hover: #1e2630;
190
+ --bg-card-border: #2f3a46;
191
+ --md-surface: #161b22;
192
+ --md-on-surface: #e6e8eb;
193
+ --md-on-surface-variant: #c2c7cf;
194
+ --md-outline-variant: #44474e;
195
+ --md-primary: var(--brand-verde-vibrante);
196
+ --md-on-primary: #062126;
197
+ --primary-color: var(--brand-verde-vibrante);
198
+ --primary-color-light: color-mix(
199
+ in srgb,
200
+ var(--brand-verde-vibrante) 85%,
201
+ white
202
+ );
203
+ --primary-color-hover: var(--brand-verde-profundo);
204
+ --secondary-color: var(--brand-azul-acinzentado);
205
+ --color-primary: var(--primary-color);
206
+ --color-on-primary: var(--md-on-primary);
207
+ --color-secondary: var(--secondary-color);
208
+ --color-on-secondary: var(--md-on-secondary);
209
+ --color-surface: var(--md-surface);
210
+ --color-on-surface: var(--md-on-surface);
211
+ --color-contrast: var(--brand-off-white);
212
+ --text-primary: #e6e8eb;
213
+ --text-secondary: #d1d5db;
214
+ --text-muted: #9ca3af;
215
+ --border-color: #2f3a46;
216
+ --shadow-sm: 0 0.125rem 0.25rem 0 rgba(0, 0, 0, 0.4);
217
+ --shadow-md: 0 0.25rem 0.5rem 0 rgba(0, 0, 0, 0.5);
218
+ --shadow-lg: 0 0.5rem 1rem 0 rgba(0, 0, 0, 0.6);
219
+ }
220
+
221
+ /* ============================================================
222
+ PALETAS DE BOTÃO (guia de marca)
223
+ Use data-button-palette no pai (ex.: body) ou prop palette no Button.
224
+ ============================================================ */
225
+ [data-button-palette="verde-vibrante"],
226
+ .btn--palette-verde-vibrante.btn--primary {
227
+ --md-primary: var(--brand-verde-vibrante);
228
+ --primary-color-hover: var(--brand-verde-profundo);
229
+ }
230
+ [data-button-palette="verde-vibrante"] .btn--primary {
231
+ --md-primary: var(--brand-verde-vibrante);
232
+ --primary-color-hover: var(--brand-verde-profundo);
233
+ }
234
+
235
+ [data-button-palette="verde-profundo"],
236
+ .btn--palette-verde-profundo.btn--primary {
237
+ --md-primary: var(--brand-verde-profundo);
238
+ --primary-color-hover: var(--brand-grafite-azulado);
239
+ }
240
+ [data-button-palette="verde-profundo"] .btn--primary {
241
+ --md-primary: var(--brand-verde-profundo);
242
+ --primary-color-hover: var(--brand-grafite-azulado);
243
+ }
244
+
245
+ [data-button-palette="grafite-azulado"],
246
+ .btn--palette-grafite-azulado.btn--primary {
247
+ --md-primary: var(--brand-grafite-azulado);
248
+ --primary-color-hover: var(--brand-cinza-escuro);
249
+ }
250
+ [data-button-palette="grafite-azulado"] .btn--primary {
251
+ --md-primary: var(--brand-grafite-azulado);
252
+ --primary-color-hover: var(--brand-cinza-escuro);
253
+ }
254
+
255
+ [data-button-palette="azul-acinzentado"],
256
+ .btn--palette-azul-acinzentado.btn--primary {
257
+ --md-primary: var(--brand-azul-acinzentado);
258
+ --primary-color-hover: var(--brand-grafite-azulado);
259
+ }
260
+ [data-button-palette="azul-acinzentado"] .btn--primary {
261
+ --md-primary: var(--brand-azul-acinzentado);
262
+ --primary-color-hover: var(--brand-grafite-azulado);
263
+ }
264
+
265
+ [data-button-palette="cinza-medio"],
266
+ .btn--palette-cinza-medio.btn--primary {
267
+ --md-primary: var(--brand-cinza-medio);
268
+ --primary-color-hover: var(--brand-cinza-escuro);
269
+ }
270
+ [data-button-palette="cinza-medio"] .btn--primary {
271
+ --md-primary: var(--brand-cinza-medio);
272
+ --primary-color-hover: var(--brand-cinza-escuro);
273
+ }
274
+
275
+ [data-button-palette="cinza-escuro"],
276
+ .btn--palette-cinza-escuro.btn--primary {
277
+ --md-primary: var(--brand-cinza-escuro);
278
+ --primary-color-hover: var(--brand-preto);
279
+ }
280
+ [data-button-palette="cinza-escuro"] .btn--primary {
281
+ --md-primary: var(--brand-cinza-escuro);
282
+ --primary-color-hover: var(--brand-preto);
283
+ }
284
+
285
+ [data-button-palette="off-white"],
286
+ .btn--palette-off-white.btn--primary {
287
+ --md-primary: var(--brand-off-white);
288
+ --md-on-primary: var(--brand-grafite-azulado);
289
+ --primary-color-hover: var(--brand-branco);
290
+ }
291
+ [data-button-palette="off-white"] .btn--primary {
292
+ --md-primary: var(--brand-off-white);
293
+ --md-on-primary: var(--brand-grafite-azulado);
294
+ --primary-color-hover: var(--brand-branco);
295
+ }
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@sbkbs/ui",
3
+ "version": "1.0.0",
4
+ "description": "Biblioteca de componentes UI SBK BS",
5
+ "type": "module",
6
+ "main": "./dist/oficios-ui.umd.cjs",
7
+ "module": "./dist/oficios-ui.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/oficios-ui.js",
13
+ "require": "./dist/oficios-ui.umd.cjs",
14
+ "default": "./dist/oficios-ui.js"
15
+ },
16
+ "./theme.css": "./dist/theme.css",
17
+ "./styles.css": "./dist/oficios-ui.css"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "sideEffects": [
23
+ "**/*.css"
24
+ ],
25
+ "scripts": {
26
+ "clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
27
+ "build": "vite build && tsc -p tsconfig.build.json && node -e \"require('fs').copyFileSync('src/theme/theme.css', 'dist/theme.css')\"",
28
+ "dev": "vite build --watch",
29
+ "prepublishOnly": "npm run clean && npm run build && npm run typecheck",
30
+ "playground": "vite",
31
+ "publish:public": "npm publish --access public",
32
+ "release:patch": "npm version patch && npm run publish:public",
33
+ "typecheck": "tsc --noEmit -p tsconfig.build.json"
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=18.0.0",
37
+ "react-dom": ">=18.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/react": "^18.2.43",
41
+ "@types/react-dom": "^18.2.17",
42
+ "@vitejs/plugin-react": "^4.2.1",
43
+ "autoprefixer": "^10.4.21",
44
+ "postcss": "^8.5.6",
45
+ "react": "^18.2.0",
46
+ "react-dom": "^18.2.0",
47
+ "tailwindcss": "^3.4.17",
48
+ "typescript": "^5.9.3",
49
+ "vite": "^7.3.1"
50
+ },
51
+ "keywords": [
52
+ "oficios",
53
+ "ui",
54
+ "design-system",
55
+ "react",
56
+ "components"
57
+ ],
58
+ "author": "Carlos Augusto",
59
+ "license": "ISC",
60
+ "publishConfig": {
61
+ "access": "public"
62
+ }
63
+ }