+
+
+
+
+
diff --git a/src/componentes/campo/README.md b/src/componentes/campo/README.md
new file mode 100644
index 0000000..6acd0a3
--- /dev/null
+++ b/src/componentes/campo/README.md
@@ -0,0 +1,118 @@
+# EliInput
+
+**Componente base de input do design system**
+
+O EliInput unifica vários tipos de campo (v-text-field, v-textarea, v-select, v-radio-group, v-checkbox) em uma única API consistente. Ele encapsula comportamentos, máscaras e regras comuns (CPF/CNPJ, telefone, CEP, numéricos, formatação de moeda etc.) para manter coerência visual e de lógica em toda a aplicação.
+
+> ⚠️ Nunca use os componentes Vuetify diretamente fora do design system para esses casos.
+> Utilize sempre EliInput para garantir formatação, tipagem e repasse de atributos padronizados.
+
+---
+
+## Visão geral
+
+EliInput foi projetado para:
+
+* Centralizar formatação (máscaras) para tipos de entrada comuns (telefone, CPF/CNPJ, CEP, numéricos).
+* Fornecer uma API única (type) que representa diferentes controles (text, textarea, select, radio, checkbox, etc.).
+* Repassar atributos/props do pai para o componente Vuetify interno (v-bind="$attrs") mantendo inheritAttrs: false.
+* Emitir eventos padronizados: update:modelValue, change, focus, blur.
+
+---
+
+## Principais decisões de implementação
+
+* inheritAttrs: false — o componente controla explicitamente para onde os atributos são passados (v-bind="attrs" no elemento interno).
+* Uso de um computed value que faz emit("update:modelValue", v) e emit("change", v) — assim qualquer v-model no pai funciona como esperado.
+* Normalização de props.options para aceitar objetos { label, value, disabled } ou primitivos ('A', 1).
+* Separação clara entre lógica de formatação (aplicada em onInput) e componentes que não devem ser formatados (ex.: v-select).
+
+---
+
+## Tipagem (TypeScript)
+
+```ts
+type ValorCampo = string | number | boolean | null;
+type Option = { label: string; value: ValorCampo; disabled?: boolean };
+
+type InputVariant = 'outlined' | 'filled' | 'plain' | 'solo' | 'solo-filled' | 'solo-inverted' | 'underlined';
+type Density = 'default' | 'comfortable' | 'compact';
+type TipoNumerico = 'numericoInteiro' | 'numericoDecimal' | 'numericoMoeda' | 'porcentagem';
+
+type InputType =
+ | 'text' | 'password' | 'email' | 'search' | 'url' | 'textarea'
+ | 'radio' | 'checkbox' | 'telefone' | 'cpfCnpj' | 'cep' | 'select'
+ | TipoNumerico;
+```
+
+---
+
+## Props
+
+| Prop | Tipo | Default | Descrição |
+| ---------------- | --------------------------- | --------------- | ------------------------------------------------------ |
+| `modelValue` | `string \| number \| boolean \| (string \| number \| boolean \| null)[]` | `""` | Valor controlado (use com `v-model`). |
+| `type` | `InputType` | `"text"` | Tipo do controle (ver `InputType`). |
+| `label` | `string` | `-` | Rótulo do campo. |
+| `placeholder` | `string` | `-` | Texto exibido quando o campo está vazio. |
+| `disabled` | `boolean` | `false` | Desabilita o campo. |
+| `error` | `boolean` | `false` | Força estado visual de erro. |
+| `errorMessages` | `string \| string[]` | `[]` | Mensagem ou lista de mensagens de erro. |
+| `hint` | `string` | `-` | Texto de ajuda exibido abaixo do campo. |
+| `persistentHint` | `boolean` | `false` | Mantém o hint sempre visível. |
+| `variant` | `InputVariant` | `"outlined"` | Variante visual do Vuetify. |
+| `density` | `Density` | `"comfortable"` | Densidade visual do campo. |
+| `color` | `string` | `"primary"` | Cor do campo quando focado (ou `error`, se aplicável). |
+| `clearable` | `boolean` | `false` | Permite limpar o valor do campo. |
+
+
+## Notas sobre props
+
+* options: aceita arrays como ['Frontend','Backend'] ou { label:'São Paulo', value:'SP' }. O componente normaliza para { label, value, disabled? }.
+* type determina quais comportamentos internos são aplicados. Tipos numéricos e máscara (telefone, cpfCnpj, cep) passam por formatação em onInput.
+* multiple/chips: úteis para type="select". O v-select interno recebe item-title="label" e item-value="value" para compatibilidade com objetos.
+
+---
+
+## Emissões (events)
+
+* update:modelValue — padrão v-model.
+* change — emitido sempre que o valor muda (alinha com update:modelValue).
+* focus — quando o campo interno recebe foco.
+* blur — quando perde o foco.
+* Observação: como value é um computed com getter/setter que emite ambos, v-model e listeners de mudança no pai funcionarão normalmente.
+
+---
+
+## Repasso de atributos e listeners
+
+* O componente define inheritAttrs: false e usa v-bind="attrs" nos componentes internos (v-text-field, v-select, etc.). Isso implica que:
+* Atributos HTML (ex.: type, aria-label, class, style) passados para são aplicados ao componente Vuetify interno apropriado.
+* Listeners (ex.: @click, @keydown) também fazem parte de $attrs e serão repassados para o componente interno — use o EliInput como se estivesse ouvindo eventos diretamente no input.
+
+## Exemplo:
+
+```vue
+
+```
+
+---
+
+## Comportamentos de formatação importantes
+
+* numericoInteiro — remove tudo que não for dígito.
+* numericoDecimal — mantém separador decimal (aplica formatarDecimal).
+* numericoMoeda — formata para moeda conforme util (formatarMoeda).
+* porcentagem — aplica formatação decimal e exibe sufixo `%` automaticamente.
+* telefone — aplica máscara/format formatTelefone.
+* cpfCnpj — aplica formatarCpfCnpj.
+* cep — aplica formatarCep.
+
+**Importante: a formatação ocorre no onInput (campos text-like). O v-select não passa por onInput — ele usa v-model="value" e o computed que emite o update. Se desejar formatação específica para itens do select (por exemplo, mostrar label formatado), trate nos options antes de passar.**
+
+---
+
+## Slot
+
+* O componente não expõe slots customizados diretamente. Ele controla internamente o append para toggle de senha quando type === 'password' && showPasswordToggle (ícone de olho).
+* Se você precisa de slots específicos do v-text-field/v-select, considere estender o componente ou criar uma variação que exponha os slots desejados.
diff --git a/src/componentes/campo/index.ts b/src/componentes/campo/index.ts
new file mode 100644
index 0000000..890a77a
--- /dev/null
+++ b/src/componentes/campo/index.ts
@@ -0,0 +1 @@
+export { default as EliInput } from "./EliInput.vue";
diff --git a/src/componentes/campo/utils/cep.ts b/src/componentes/campo/utils/cep.ts
new file mode 100644
index 0000000..701fd34
--- /dev/null
+++ b/src/componentes/campo/utils/cep.ts
@@ -0,0 +1,9 @@
+import { somenteNumeros } from "./numerico";
+
+export function formatarCep(v: string): string {
+ const d = somenteNumeros(v).slice(0, 8);
+
+ if (d.length <= 5) return d;
+
+ return d.replace(/^(\d{5})(\d{1,3})$/, "$1-$2");
+}
diff --git a/src/componentes/EliEntrada/utils/cpfCnpj.ts b/src/componentes/campo/utils/cpfCnpj.ts
similarity index 100%
rename from src/componentes/EliEntrada/utils/cpfCnpj.ts
rename to src/componentes/campo/utils/cpfCnpj.ts
diff --git a/src/componentes/campo/utils/numerico.ts b/src/componentes/campo/utils/numerico.ts
new file mode 100644
index 0000000..5c2a3a6
--- /dev/null
+++ b/src/componentes/campo/utils/numerico.ts
@@ -0,0 +1,26 @@
+export function somenteNumeros(valor: string) {
+ return valor.replace(/\D+/g, "");
+}
+
+export function formatarDecimal(valor: string) {
+ const limpo = valor.replace(/[^\d,]/g, "");
+ const partes = limpo.split(",");
+ return partes.length > 2 ? partes[0] + "," + partes.slice(1).join("") : limpo;
+}
+
+/**
+ * Formatação para percentual:
+ * - remove '%' caso venha junto (ex: colar "10%")
+ * - mantém apenas dígitos e vírgula (no máximo uma)
+ */
+export function formatarPorcentagem(valor: string) {
+ return formatarDecimal(valor.replace(/%/g, ""));
+}
+
+export function formatarMoeda(valor: string) {
+ const numero = somenteNumeros(valor);
+ if (!numero) return "";
+
+ const inteiro = (parseInt(numero, 10) / 100).toFixed(2);
+ return inteiro.replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, ".");
+}
diff --git a/src/componentes/EliEntrada/utils/telefone.ts b/src/componentes/campo/utils/telefone.ts
similarity index 96%
rename from src/componentes/EliEntrada/utils/telefone.ts
rename to src/componentes/campo/utils/telefone.ts
index dcd7d04..66fbd46 100644
--- a/src/componentes/EliEntrada/utils/telefone.ts
+++ b/src/componentes/campo/utils/telefone.ts
@@ -1,3 +1,5 @@
+// utils/telefone.ts
+
/**
* Remove tudo que não é número
*/
diff --git a/src/componentes/data_hora/EliDataHora.vue b/src/componentes/data_hora/EliDataHora.vue
new file mode 100644
index 0000000..ab6ec70
--- /dev/null
+++ b/src/componentes/data_hora/EliDataHora.vue
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/componentes/data_hora/README.md b/src/componentes/data_hora/README.md
new file mode 100644
index 0000000..693b91a
--- /dev/null
+++ b/src/componentes/data_hora/README.md
@@ -0,0 +1,108 @@
+# EliDataHora
+
+O `EliDataHora` é um componente de **entrada de data e hora** baseado em `v-text-field` (Vuetify), usando o tipo nativo do HTML `datetime-local`.
+
+Ele foi criado para oferecer uma solução **estável e leve** sem depender de componentes experimentais do Vuetify.
+
+## Objetivo
+
+- Permitir o usuário selecionar **data + hora** com UX nativa do navegador.
+- Padronizar a API em português (props/eventos) no Design System.
+
+## API
+
+### Props
+
+| Prop | Tipo | Padrão | Descrição |
+|------|------|--------|-----------|
+| `modelValue` | `string \| null` | `null` | **Sempre em ISO 8601**, aceitando UTC absoluto (`Z`) ou com offset (ex.: `2026-01-09T16:15:00Z`, `2026-01-09T13:15:00-03:00`). O componente converte para horário **local** antes de exibir. |
+| `modo` | `"data" \| "dataHora"` | `"dataHora"` | Define se o campo permite selecionar apenas data (`date`) ou data+hora (`datetime-local`). |
+| `rotulo` | `string` | `"Data e hora"` | Label do campo. |
+| `placeholder` | `string` | `""` | Placeholder do campo. |
+| `desabilitado` | `boolean` | `false` | Desabilita o campo. |
+| `limpavel` | `boolean` | `false` | Habilita botão de limpar (Vuetify `clearable`). |
+| `erro` | `boolean` | `false` | Estado de erro visual. |
+| `mensagensErro` | `string \| string[]` | `[]` | Mensagens de erro. |
+| `dica` | `string` | `""` | Hint/ajuda abaixo do campo. |
+| `dicaPersistente` | `boolean` | `false` | Mantém dica sempre visível. |
+| `densidade` | `CampoDensidade` | `"comfortable"` | Densidade (Vuetify). |
+| `variante` | `CampoVariante` | `"outlined"` | Variante (Vuetify). |
+| `min` | `string \| undefined` | `undefined` | Mínimo permitido em ISO 8601 (offset ou `Z`). |
+| `max` | `string \| undefined` | `undefined` | Máximo permitido em ISO 8601 (offset ou `Z`). |
+
+> Observação: o atributo HTML `datetime-local` **não inclui timezone**.
+> Este componente resolve isso convertendo:
+>
+> - **entrada**: ISO 8601 (UTC/offset) → **exibição** em horário local
+> - **saída**: valor selecionado → ISO 8601 com **offset local**
+
+### Emits
+
+| Evento | Payload | Quando dispara |
+|--------|---------|---------------|
+| `update:modelValue` | `string \| null` | Sempre que o valor muda (padrão do v-model). O payload é ISO 8601 com **offset local**. |
+| `alterar` | `string \| null` | Alias semântico para mudanças de valor (mesmo payload do v-model). |
+| `foco` | `void` | Ao focar o campo. |
+| `desfoco` | `void` | Ao sair do foco. |
+
+### Slots
+
+Este componente não define slots próprios. Você pode usar slots do `v-text-field` via `v-bind="$attrs"` caso precise (ver exemplos abaixo).
+
+## Exemplos
+
+### 1) Uso básico com v-model
+
+```vue
+
+
+
Valor: {{ dataHora }}
+
+
+
+```
+
+### 2) Com limites (min/max) e validação visual
+
+```vue
+
+
+
+```
+
+## Casos de borda / comportamento esperado
+
+- Ao limpar o campo, o componente emite `null` (não string vazia).
+- O navegador pode variar a UI do seletor (isso é esperado do `datetime-local`).
+- `min/max` devem ser strings em ISO 8601 (offset ou `Z`).
+- Em `modo="data"`, o componente emite ISO no **início do dia** (`00:00:00`) no fuso local.
+
+## Acessibilidade
+
+- O `v-text-field` do Vuetify já oferece base de acessibilidade.
+- Sempre prefira passar `rotulo` significativo.
+
+## Decisões de implementação
+
+- Usamos `datetime-local` por ser amplamente suportado e não depender de APIs experimentais.
+- O componente usa `dayjs` para converter entradas UTC/offset para local antes de exibir e para emitir ISO 8601 com offset local.
+- Mantemos o valor como `string | null` para evitar conversões implícitas e permitir que cada projeto decida como persistir (UTC/local).
diff --git a/src/componentes/data_hora/index.ts b/src/componentes/data_hora/index.ts
new file mode 100644
index 0000000..002d336
--- /dev/null
+++ b/src/componentes/data_hora/index.ts
@@ -0,0 +1 @@
+export { default as EliDataHora } from "./EliDataHora.vue";
\ No newline at end of file
diff --git a/src/componentes/ola_mundo/EliOlaMundo.vue b/src/componentes/ola_mundo/EliOlaMundo.vue
index 04a0cec..7289172 100644
--- a/src/componentes/ola_mundo/EliOlaMundo.vue
+++ b/src/componentes/ola_mundo/EliOlaMundo.vue
@@ -11,31 +11,100 @@