create-lexy 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/assets/r/accordion.json +1 -1
  2. package/assets/r/alert-dialog.json +1 -1
  3. package/assets/r/app-accordion.json +1 -1
  4. package/assets/r/app-dialog.json +1 -1
  5. package/assets/r/app-header-bar.json +1 -1
  6. package/assets/r/app-sidebar.json +1 -1
  7. package/assets/r/avatar.json +1 -1
  8. package/assets/r/badge.json +1 -1
  9. package/assets/r/brand-background.json +135 -0
  10. package/assets/r/breadcrumb.json +1 -1
  11. package/assets/r/button-group.json +1 -1
  12. package/assets/r/button.json +1 -1
  13. package/assets/r/calendar.json +1 -1
  14. package/assets/r/card.json +1 -1
  15. package/assets/r/chart.json +1 -1
  16. package/assets/r/checkbox.json +1 -1
  17. package/assets/r/combobox.json +1 -1
  18. package/assets/r/command.json +1 -1
  19. package/assets/r/confirmacion.json +2 -2
  20. package/assets/r/counter-badge.json +1 -1
  21. package/assets/r/crm-app-layout.json +2 -2
  22. package/assets/r/crm-desk.json +2 -2
  23. package/assets/r/crm-detalle-caso.json +2 -2
  24. package/assets/r/date-picker.json +1 -1
  25. package/assets/r/dialog.json +1 -1
  26. package/assets/r/dropdown-menu.json +1 -1
  27. package/assets/r/empty.json +1 -1
  28. package/assets/r/feature-card.json +1 -1
  29. package/assets/r/form.json +1 -1
  30. package/assets/r/header-bar.json +1 -1
  31. package/assets/r/input.json +1 -1
  32. package/assets/r/intake-wizard.json +2 -2
  33. package/assets/r/label.json +1 -1
  34. package/assets/r/login.json +2 -2
  35. package/assets/r/logo.json +1 -1
  36. package/assets/r/menubar.json +1 -1
  37. package/assets/r/navigation-menu.json +1 -1
  38. package/assets/r/pagination.json +1 -1
  39. package/assets/r/popover.json +1 -1
  40. package/assets/r/profile-card.json +1 -1
  41. package/assets/r/progress.json +1 -1
  42. package/assets/r/radio-group.json +1 -1
  43. package/assets/r/registry.json +116 -0
  44. package/assets/r/scroll-area.json +1 -1
  45. package/assets/r/searchbox.json +1 -1
  46. package/assets/r/select.json +1 -1
  47. package/assets/r/separator.json +1 -1
  48. package/assets/r/sheet.json +1 -1
  49. package/assets/r/sidebar.json +2 -2
  50. package/assets/r/skeleton.json +1 -1
  51. package/assets/r/slider.json +1 -1
  52. package/assets/r/snippet.json +1 -1
  53. package/assets/r/spinner.json +1 -1
  54. package/assets/r/status-dot.json +1 -1
  55. package/assets/r/switch.json +1 -1
  56. package/assets/r/table.json +1 -1
  57. package/assets/r/tabs.json +1 -1
  58. package/assets/r/tag.json +1 -1
  59. package/assets/r/textarea.json +1 -1
  60. package/assets/r/toaster.json +1 -1
  61. package/assets/r/tooltip.json +1 -1
  62. package/assets/r/tree.json +1 -1
  63. package/assets/registry-version +1 -1
  64. package/assets/theme/lexy-theme.css +15 -4
  65. package/dist/index.js +2421 -70
  66. package/package.json +16 -5
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Snippet.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Snippet.md",
22
- "content": "# Snippet — guía de uso\n\nFragmento de código. Para mostrar código con copia. El componente vive en tu proyecto: instálalo con `create-lexy add snippet` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Snippet } from \"@/components/base/Snippet\";\n```\n\n## Uso básico\n\n```tsx\n<Snippet />\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Reglas\n\n- Usa Snippet según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Snippet desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
22
+ "content": "# Snippet — guía de uso\n\nFragmento de código. Para mostrar código con copia. El componente vive en tu proyecto: instálalo con `create-lexy add snippet` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara mostrar un comando o fragmento corto que la persona va a copiar: una instalación, un token, una URL. Para bloques largos de código con sintaxis, usa el bloque de código del documento, no un Snippet.\n\n## Composición\n\nUna sola pieza (`Snippet`): texto en mono con botón de copiado incorporado.\n\n## Uso básico\n\n```tsx\n<Snippet />\n```\n\n## Reglas\n\n- Usa Snippet según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Snippet } from \"@/components/base/Snippet\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Snippet desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -20,7 +20,7 @@
20
20
  "path": "components/base/Spinner.md",
21
21
  "type": "registry:file",
22
22
  "target": "components/base/Spinner.md",
23
- "content": "# Spinner — guía de uso\n\nIndicador de carga visual. Usa el icono `Loader2` de Lucide con animación de rotación. El componente vive en tu proyecto: instálalo con `create-lexy add spinner` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Spinner } from \"@/shared/components/base/Spinner\"; // o @/components/base/Spinner\n```\n\n## Uso básico\n\n```tsx\n<Spinner size=\"md\" />\n```\n\n## Tamaños\n\n```tsx\n<div className=\"flex gap-4\">\n <Spinner size=\"sm\" />\n <Spinner size=\"md\" />\n <Spinner size=\"lg\" />\n <Spinner size=\"xl\" />\n</div>\n```\n\n## Colores personalizados\n\n```tsx\n<Spinner className=\"text-destructive\" />\n<Spinner className=\"text-success\" />\n```\n\n## En botón cargando\n\n```tsx\n<button disabled className=\"inline-flex items-center gap-2 opacity-50\">\n <Spinner size=\"sm\" className=\"text-primary-foreground\" />\n Guardando...\n</button>\n```\n\n## Props\n\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `size` | `\"sm\" \\| \"md\" \\| \"lg\" \\| \"xl\"` | `\"md\"` | Tamaño del spinner. |\n| `className` | `string?` | — | Clase adicional. |\n\n## Reglas\n\n- Usa `Spinner` para operaciones de corta duración (menos de 2-3 segundos).\n- Combina con texto descriptivo cuando el contexto no sea obvio.\n- Usa `size=\"sm\"` dentro de botones.\n- Usa `size=\"lg\"` o `\"xl\"` para estados de carga de página completa.\n- No uses `Spinner` si la operación dura más de 5 segundos → considera `Progress`.\n- No uses `Spinner` sin texto si hay múltiples operaciones simultáneas.\n\n## Para IA\n\n1. Identifica si hay una operación en progreso o carga de datos.\n2. Si es una operación corta → usa `Spinner`.\n3. Elige el tamaño según el contexto.\n4. Agrega texto descriptivo si el contexto no es obvio.\n5. Considera `Skeleton` si conoces la estructura del contenido que cargará.\n6. Considera `Progress` si la operación tiene progreso medible.\n"
23
+ "content": "# Spinner — guía de uso\n\nIndicador de carga visual. Usa el icono `Loader2` de Lucide con animación de rotación. El componente vive en tu proyecto: instálalo con `create-lexy add spinner` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara esperas breves e indeterminadas, sobre todo dentro del control que las causó: el botón que guarda, el campo que busca. Si la espera tiene forma conocida (una lista que carga), prefiere `Skeleton`.\n\n## Composición\n\nUna sola pieza (`Spinner`: el icono `Loader2` de Lucide girando) con tamaños. Dentro de un `Button` deshabilitado comunica “trabajando”.\n\n## Uso básico\n\n```tsx\n<Spinner size=\"md\" />\n```\n\n## Tamaños\n\n```tsx\n<div className=\"flex gap-4\">\n <Spinner size=\"sm\" />\n <Spinner size=\"md\" />\n <Spinner size=\"lg\" />\n <Spinner size=\"xl\" />\n</div>\n```\n\n## Colores personalizados\n\n```tsx\n<Spinner className=\"text-destructive\" />\n<Spinner className=\"text-success\" />\n```\n\n## En botón cargando\n\n```tsx\n<button disabled className=\"inline-flex items-center gap-2 opacity-50\">\n <Spinner size=\"sm\" className=\"text-primary-foreground\" />\n Guardando...\n</button>\n```\n\n## Reglas\n\n- Usa `Spinner` para operaciones de corta duración (menos de 2-3 segundos).\n- Combina con texto descriptivo cuando el contexto no sea obvio.\n- Usa `size=\"sm\"` dentro de botones.\n- Usa `size=\"lg\"` o `\"xl\"` para estados de carga de página completa.\n- No uses `Spinner` si la operación dura más de 5 segundos → considera `Progress`.\n- No uses `Spinner` sin texto si hay múltiples operaciones simultáneas.\n\n## Import\n\n```tsx\nimport { Spinner } from \"@/shared/components/base/Spinner\"; // o @/components/base/Spinner\n```\n\n## Props\n\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `size` | `\"sm\" \\| \"md\" \\| \"lg\" \\| \"xl\"` | `\"md\"` | Tamaño del spinner. |\n| `className` | `string?` | — | Clase adicional. |\n\n## Para IA\n\n1. Identifica si hay una operación en progreso o carga de datos.\n2. Si es una operación corta → usa `Spinner`.\n3. Elige el tamaño según el contexto.\n4. Agrega texto descriptivo si el contexto no es obvio.\n5. Considera `Skeleton` si conoces la estructura del contenido que cargará.\n6. Considera `Progress` si la operación tiene progreso medible.\n"
24
24
  }
25
25
  ]
26
26
  }
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/StatusDot.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/StatusDot.md",
22
- "content": "# StatusDot — guía de uso\n\nPunto de estado con color, pensado para acompañar texto (estado de una fila, disponibilidad, conexión). El color **nunca** es la única señal: va con texto o `aria-label`. El componente vive en tu proyecto: instálalo con `create-lexy add status-dot` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { StatusDot } from \"@/components/base/StatusDot\";\n```\n\n## Uso básico\n\n```tsx\n<StatusDot tone=\"success\">Activo</StatusDot>\n<StatusDot tone=\"warning\">Pendiente</StatusDot>\n<StatusDot tone=\"danger\">Vencido</StatusDot>\n```\n\nSi va solo (sin texto visible), agrega `aria-label`:\n\n```tsx\n<StatusDot tone=\"success\" aria-label=\"En línea\" />\n```\n\n## Props\n\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `tone` | `\"gray\" \\| \"brand\" \\| \"success\" \\| \"warning\" \\| \"danger\" \\| \"info\"` | `\"gray\"` | Color del estado. |\n| `size` | `\"sm\" \\| \"md\" \\| \"lg\"` | `\"md\"` | Tamaño del punto. |\n| `children` | `ReactNode` | — | Texto del estado junto al punto. |\n\n## Reglas\n\n- Acompaña el punto con texto (`children`) o, si va solo, con `aria-label`. El color por sí solo no comunica estado (accesibilidad).\n- Usa el `tone` por significado: `success`/`warning`/`danger` para estados; `gray`/`info`/`brand` para neutros.\n- Mantén el texto de estado corto.\n\n## Cuándo NO usar\n\n- **Etiqueta de estado con fondo** (chip) → `Badge`.\n- **Conteo numérico** → `CounterBadge`.\n- **Chip removible / filtro** → `Tag`.\n\n## Para IA\n\n1. Úsalo para señalar el estado de un ítem o fila, casi siempre dentro de una `Table` o lista.\n2. Empareja el color con texto visible; si no hay texto, agrega `aria-label`.\n3. Elige `tone` por significado, no por estética.\n"
22
+ "content": "# StatusDot — guía de uso\n\nPunto de estado con color, pensado para acompañar texto (estado de una fila, disponibilidad, conexión). El color **nunca** es la única señal: va con texto o `aria-label`. El componente vive en tu proyecto: instálalo con `create-lexy add status-dot` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara estado compacto en contexto denso: la columna de estado de una tabla, disponibilidad, conexión. El color nunca va solo — siempre con texto al lado o `aria-label`.\n\n## Composición\n\nUna sola pieza (`StatusDot`) con variantes de color semántico; convive con el texto del estado en la misma celda o línea.\n\n## Uso básico\n\n```tsx\n<StatusDot tone=\"success\">Activo</StatusDot>\n<StatusDot tone=\"warning\">Pendiente</StatusDot>\n<StatusDot tone=\"danger\">Vencido</StatusDot>\n```\n\nSi va solo (sin texto visible), agrega `aria-label`:\n\n```tsx\n<StatusDot tone=\"success\" aria-label=\"En línea\" />\n```\n\n## Reglas\n\n- Acompaña el punto con texto (`children`) o, si va solo, con `aria-label`. El color por sí solo no comunica estado (accesibilidad).\n- Usa el `tone` por significado: `success`/`warning`/`danger` para estados; `gray`/`info`/`brand` para neutros.\n- Mantén el texto de estado corto.\n\n## Cuándo NO usar\n\n- **Etiqueta de estado con fondo** (chip) → `Badge`.\n- **Conteo numérico** → `CounterBadge`.\n- **Chip removible / filtro** → `Tag`.\n\n## Import\n\n```tsx\nimport { StatusDot } from \"@/components/base/StatusDot\";\n```\n\n## Props\n\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `tone` | `\"gray\" \\| \"brand\" \\| \"success\" \\| \"warning\" \\| \"danger\" \\| \"info\"` | `\"gray\"` | Color del estado. |\n| `size` | `\"sm\" \\| \"md\" \\| \"lg\"` | `\"md\"` | Tamaño del punto. |\n| `children` | `ReactNode` | — | Texto del estado junto al punto. |\n\n## Para IA\n\n1. Úsalo para señalar el estado de un ítem o fila, casi siempre dentro de una `Table` o lista.\n2. Empareja el color con texto visible; si no hay texto, agrega `aria-label`.\n3. Elige `tone` por significado, no por estética.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Switch.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Switch.md",
22
- "content": "# Switch — guía de uso\n\nInterruptor de palanca. Para activar/desactivar estados. El componente vive en tu proyecto: instálalo con `create-lexy add switch` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Switch } from \"@/components/base/Switch\";\n```\n\n## Uso básico\n\n```tsx\n<Switch />\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Reglas\n\n- Usa Switch según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Switch desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
22
+ "content": "# Switch — guía de uso\n\nInterruptor de palanca. Para activar/desactivar estados. El componente vive en tu proyecto: instálalo con `create-lexy add switch` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara activar o desactivar algo con efecto inmediato: notificaciones, un modo. Es un interruptor de luz — sin botón Guardar. Si el cambio se confirma después con el formulario, usa `Checkbox`.\n\n## Composición\n\nUna sola pieza (`Switch`) con su `Label` al lado. El estado se lee del propio control, no de un texto que cambia.\n\n## Uso básico\n\n```tsx\n<Switch />\n```\n\n## Reglas\n\n- Usa Switch según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Switch } from \"@/components/base/Switch\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Switch desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Table.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Table.md",
22
- "content": "# Table — guía de uso\n\nTabla de datos para comparar/escanear filas y columnas. Componente compuesto (`TableHeader`, `TableContent`, `TableRow`, `TableCell` — también disponibles como alias `Table.Header`, `Table.Content`, `Table.Row`, `Table.Cell`) basado en CSS grid. El componente vive en tu proyecto: instálalo con `create-lexy add table` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Table } from \"@/components/base/Table\";\n```\n\n## Uso básico\n\n```tsx\n<Table columns=\"2fr 1fr 1fr\">\n <Table.Header>\n <Table.Cell>Cliente</Table.Cell>\n <Table.Cell>Estado</Table.Cell>\n <Table.Cell>Monto</Table.Cell>\n </Table.Header>\n <Table.Content>\n {filas.map((f) => (\n <Table.Row key={f.id} onClick={() => abrir(f.id)}>\n <Table.Cell>{f.cliente}</Table.Cell>\n <Table.Cell><StatusDot tone={f.tone}>{f.estado}</StatusDot></Table.Cell>\n <Table.Cell>{f.monto}</Table.Cell>\n </Table.Row>\n ))}\n </Table.Content>\n</Table>\n```\n\n## Props\n\n### `Table`\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `columns` | `string` | — | `grid-template-columns` (p. ej. `\"2fr 1fr 1fr\"`). Si se omite, columnas iguales automáticas. |\n| `variant` | `\"normal\" \\| \"basic\" \\| \"striped\"` | `\"normal\"` | Con borde/relleno, sin bordes, o filas alternadas. |\n| `stickyHeader` | `boolean` | `false` | Header fijo con scroll vertical (alto máx. ~500px). |\n\n### Subcomponentes\n`TableHeader`, `TableContent`, `TableRow` (acepta `onClick`), `TableCell` — alias: `Table.Header`, `Table.Content`, `Table.Row`, `Table.Cell`. Todos aceptan `className`, esparcen `...props` al nodo raíz y reenvían `ref`. `tableVariants` (CVA) se exporta para extender estilos.\n\n## Reglas\n\n- Las celdas de `Table.Header` y de cada `Table.Row` deben tener el **mismo número** de columnas que `columns`.\n- Usa `columns` con `fr`/anchos para alinear; no metas anchos a mano por celda.\n- Si las filas son clicables (`onClick`), que toda la fila sea el objetivo y el cursor lo indique.\n- Para estado por fila combina con `StatusDot`/`Badge` (texto, no solo color).\n- `stickyHeader` para listas largas; mantén el header escaneable.\n\n## Cuándo NO usar\n\n- **Lista de un solo dato por ítem** → una lista simple, no una tabla.\n- **Tarjetas con jerarquía visual rica** → `Card`/`FeatureCard`.\n- **Pocos pares clave-valor de un registro** → lista de definición (`dl`) o `Card`, no tabla.\n\n## Para IA\n\n1. Usa tabla solo cuando hay varias columnas que se comparan entre filas.\n2. Define `columns` y respeta ese número de `Table.Cell` en header y filas.\n3. Elige `variant` (`striped` ayuda a escanear filas largas; `basic` para tablas embebidas).\n4. Para estados, añade `StatusDot`/`Badge` con texto, no solo color.\n5. Si las filas navegan, usa `onClick` en `Table.Row` y deja claro que es clicable.\n"
22
+ "content": "# Table — guía de uso\n\nTabla de datos para comparar/escanear filas y columnas. Componente compuesto (`TableHeader`, `TableContent`, `TableRow`, `TableCell` — también disponibles como alias `Table.Header`, `Table.Content`, `Table.Row`, `Table.Cell`) basado en CSS grid. El componente vive en tu proyecto: instálalo con `create-lexy add table` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara comparar y escanear filas homogéneas: casos, facturas, personas. Es la pieza central del CRM — densidad cómoda, estado por fila y acciones cerca. Si cada elemento pide narrativa propia (foto, párrafos), una lista de cards cuenta mejor.\n\n## Composición\n\nCompuesto basado en CSS grid: `Table` define las columnas, `TableHeader` la fila de encabezados, `TableContent` el cuerpo y `TableRow`/`TableCell` cada fila y celda (también como alias `Table.Header`, `Table.Row`…). El estado por fila se acompaña con `StatusDot` o `Tag`.\n\n## Uso básico\n\n```tsx\n<Table columns=\"2fr 1fr 1fr\">\n <Table.Header>\n <Table.Cell>Cliente</Table.Cell>\n <Table.Cell>Estado</Table.Cell>\n <Table.Cell>Monto</Table.Cell>\n </Table.Header>\n <Table.Content>\n {filas.map((f) => (\n <Table.Row key={f.id} onClick={() => abrir(f.id)}>\n <Table.Cell>{f.cliente}</Table.Cell>\n <Table.Cell><StatusDot tone={f.tone}>{f.estado}</StatusDot></Table.Cell>\n <Table.Cell>{f.monto}</Table.Cell>\n </Table.Row>\n ))}\n </Table.Content>\n</Table>\n```\n\n## Reglas\n\n- Las celdas de `Table.Header` y de cada `Table.Row` deben tener el **mismo número** de columnas que `columns`.\n- Usa `columns` con `fr`/anchos para alinear; no metas anchos a mano por celda.\n- Si las filas son clicables (`onClick`), que toda la fila sea el objetivo y el cursor lo indique.\n- Para estado por fila combina con `StatusDot`/`Badge` (texto, no solo color).\n- `stickyHeader` para listas largas; mantén el header escaneable.\n\n## Cuándo NO usar\n\n- **Lista de un solo dato por ítem** → una lista simple, no una tabla.\n- **Tarjetas con jerarquía visual rica** → `Card`/`FeatureCard`.\n- **Pocos pares clave-valor de un registro** → lista de definición (`dl`) o `Card`, no tabla.\n\n## Import\n\n```tsx\nimport { Table } from \"@/components/base/Table\";\n```\n\n## Props\n\n### `Table`\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `columns` | `string` | — | `grid-template-columns` (p. ej. `\"2fr 1fr 1fr\"`). Si se omite, columnas iguales automáticas. |\n| `variant` | `\"normal\" \\| \"basic\" \\| \"striped\"` | `\"normal\"` | Con borde/relleno, sin bordes, o filas alternadas. |\n| `stickyHeader` | `boolean` | `false` | Header fijo con scroll vertical (alto máx. ~500px). |\n\n### Subcomponentes\n`TableHeader`, `TableContent`, `TableRow` (acepta `onClick`), `TableCell` — alias: `Table.Header`, `Table.Content`, `Table.Row`, `Table.Cell`. Todos aceptan `className`, esparcen `...props` al nodo raíz y reenvían `ref`. `tableVariants` (CVA) se exporta para extender estilos.\n\n## Para IA\n\n1. Usa tabla solo cuando hay varias columnas que se comparan entre filas.\n2. Define `columns` y respeta ese número de `Table.Cell` en header y filas.\n3. Elige `variant` (`striped` ayuda a escanear filas largas; `basic` para tablas embebidas).\n4. Para estados, añade `StatusDot`/`Badge` con texto, no solo color.\n5. Si las filas navegan, usa `onClick` en `Table.Row` y deja claro que es clicable.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Tabs.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Tabs.md",
22
- "content": "# Tabs — guía de uso\n\nPestañas para alternar entre vistas **del mismo nivel** sin salir de la página (Radix). Progressive disclosure: muestra una categoría a la vez. El componente vive en tu proyecto: instálalo con `create-lexy add tabs` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/base/Tabs\";\n```\n\n## Uso básico\n\n```tsx\n<Tabs defaultValue=\"resumen\">\n <TabsList>\n <TabsTrigger value=\"resumen\">Resumen</TabsTrigger>\n <TabsTrigger value=\"documentos\">Documentos</TabsTrigger>\n <TabsTrigger value=\"actividad\">Actividad</TabsTrigger>\n </TabsList>\n <TabsContent value=\"resumen\">…</TabsContent>\n <TabsContent value=\"documentos\">…</TabsContent>\n <TabsContent value=\"actividad\">…</TabsContent>\n</Tabs>\n```\n\n## Props (esenciales)\n\n| Parte | Prop | Descripción |\n|---|---|---|\n| `Tabs` | `value` / `defaultValue` | Pestaña activa (controlada / inicial). |\n| `Tabs` | `onValueChange` | Cambio de pestaña. |\n| `TabsTrigger` | `value` | **Requerido.** Debe coincidir con un `TabsContent`. |\n| `TabsContent` | `value` | **Requerido.** Empareja con su trigger. |\n\n## Reglas\n\n- Cada `TabsTrigger.value` debe tener su `TabsContent.value` correspondiente.\n- Las pestañas son **pares**: contenido del mismo rango que no necesitas ver junto.\n- Pocas pestañas (idealmente ≤5) con etiquetas cortas y escaneables.\n- No escondas detrás de tabs información crítica o de error que el usuario debe ver siempre.\n\n## Cuándo NO usar\n\n- **Pasos secuenciales de un flujo** → usa un stepper/wizard; las tabs no implican orden.\n- **Navegación entre páginas/rutas** → `NavigationMenu` o enlaces.\n- **Mostrar/ocultar detalle puntual** → `Accordion` o `Dialog`.\n\n## Para IA\n\n1. Confirma que son categorías pares del mismo contexto (no pasos, no rutas).\n2. Mantén ≤5 pestañas con labels en sentence case.\n3. Empareja cada `value` trigger↔content.\n4. No ocultes errores, costos o próximos pasos dentro de una pestaña inactiva.\n"
22
+ "content": "# Tabs — guía de uso\n\nPestañas para alternar entre vistas **del mismo nivel** sin salir de la página (Radix). Progressive disclosure: muestra una categoría a la vez. El componente vive en tu proyecto: instálalo con `create-lexy add tabs` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara alternar entre vistas del mismo nivel sin salir de la página: las pestañas de un detalle (Actividad, Documentos, Notas). Una categoría a la vez, el resto a un click. Si los contenidos son pasos secuenciales, eso es un wizard, no tabs.\n\n## Composición\n\n`Tabs` (estado) contiene `TabsList` con un `TabsTrigger` por pestaña, y un `TabsContent` por panel. Trigger y panel se emparejan por `value`.\n\n## Uso básico\n\n```tsx\n<Tabs defaultValue=\"resumen\">\n <TabsList>\n <TabsTrigger value=\"resumen\">Resumen</TabsTrigger>\n <TabsTrigger value=\"documentos\">Documentos</TabsTrigger>\n <TabsTrigger value=\"actividad\">Actividad</TabsTrigger>\n </TabsList>\n <TabsContent value=\"resumen\">…</TabsContent>\n <TabsContent value=\"documentos\">…</TabsContent>\n <TabsContent value=\"actividad\">…</TabsContent>\n</Tabs>\n```\n\n## Reglas\n\n- Cada `TabsTrigger.value` debe tener su `TabsContent.value` correspondiente.\n- Las pestañas son **pares**: contenido del mismo rango que no necesitas ver junto.\n- Pocas pestañas (idealmente ≤5) con etiquetas cortas y escaneables.\n- No escondas detrás de tabs información crítica o de error que el usuario debe ver siempre.\n\n## Cuándo NO usar\n\n- **Pasos secuenciales de un flujo** → usa un stepper/wizard; las tabs no implican orden.\n- **Navegación entre páginas/rutas** → `NavigationMenu` o enlaces.\n- **Mostrar/ocultar detalle puntual** → `Accordion` o `Dialog`.\n\n## Import\n\n```tsx\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/base/Tabs\";\n```\n\n## Props (esenciales)\n\n| Parte | Prop | Descripción |\n|---|---|---|\n| `Tabs` | `value` / `defaultValue` | Pestaña activa (controlada / inicial). |\n| `Tabs` | `onValueChange` | Cambio de pestaña. |\n| `TabsTrigger` | `value` | **Requerido.** Debe coincidir con un `TabsContent`. |\n| `TabsContent` | `value` | **Requerido.** Empareja con su trigger. |\n\n## Para IA\n\n1. Confirma que son categorías pares del mismo contexto (no pasos, no rutas).\n2. Mantén ≤5 pestañas con labels en sentence case.\n3. Empareja cada `value` trigger↔content.\n4. No ocultes errores, costos o próximos pasos dentro de una pestaña inactiva.\n"
23
23
  }
24
24
  ]
25
25
  }
package/assets/r/tag.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Tag.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Tag.md",
22
- "content": "# Tag — guía de uso\n\nEtiqueta de categoría. Para clasificación. El componente vive en tu proyecto: instálalo con `create-lexy add tag` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Tag } from \"@/components/base/Tag\";\n```\n\n## Uso básico\n\n```tsx\n<Tag />\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Reglas\n\n- Usa Tag según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Tag desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
22
+ "content": "# Tag — guía de uso\n\nEtiqueta de categoría. Para clasificación. El componente vive en tu proyecto: instálalo con `create-lexy add tag` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara clasificar: materia, categoría, etiqueta de un caso. Es taxonomía — si lo que comunicas es un estado del sistema (activo, pendiente), eso es un `Badge`.\n\n## Composición\n\nUna sola pieza (`Tag`) con variantes de color. Convive en filas de tabla y headers de detalle junto a `Badge` y `StatusDot`, cada uno con su papel.\n\n## Uso básico\n\n```tsx\n<Tag />\n```\n\n## Reglas\n\n- Usa Tag según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Tag } from \"@/components/base/Tag\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Tag desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -17,7 +17,7 @@
17
17
  "path": "components/base/Textarea.md",
18
18
  "type": "registry:file",
19
19
  "target": "components/base/Textarea.md",
20
- "content": "# Textarea — guía de uso\n\nCampo de texto multilínea, redimensionable verticalmente (alto mínimo predefinido). Renderiza un `<textarea>` nativo. El componente vive en tu proyecto: instálalo con `create-lexy add textarea` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Textarea } from \"@/components/base/Textarea\";\n```\n\n## Uso básico\n\n```tsx\n<div className=\"grid gap-1.5\">\n <Label htmlFor=\"notas\">Notas del caso</Label>\n <Textarea id=\"notas\" placeholder=\"Resumen de la reunión…\" rows={4} />\n</div>\n```\n\n## Props\n\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `rows` | `number` | — | Alto inicial en líneas. |\n| `aria-invalid` | `boolean` | — | Activa el estilo de error. |\n| `disabled` | `boolean` | `false` | Deshabilita el campo. |\n| ...resto | `textarea` props | — | `value`, `onChange`, `placeholder`, `maxLength`, etc. |\n\n## Reglas\n\n- Asocia siempre un `Label` por `htmlFor`/`id`.\n- Usa `rows` para insinuar la longitud esperada de la respuesta.\n- Si hay límite de caracteres, muéstralo cerca del campo (no solo un `maxLength` silencioso).\n- Marca errores con `aria-invalid` + mensaje de texto.\n\n## Cuándo NO usar\n\n- **Una sola línea** (nombre, email, RUT) → `Input`.\n- **Editor con formato/markdown** → no existe en el registry; documenta la decisión si usas algo a medida.\n\n## Para IA\n\n1. Úsalo solo cuando se espera texto de varias líneas (comentarios, descripciones, notas).\n2. Empareja con `Label`.\n3. Ajusta `rows` a la longitud esperada.\n4. Si hay tope de caracteres, hazlo visible y redacta el error como corregir.\n"
20
+ "content": "# Textarea — guía de uso\n\nCampo de texto multilínea, redimensionable verticalmente (alto mínimo predefinido). Renderiza un `<textarea>` nativo. El componente vive en tu proyecto: instálalo con `create-lexy add textarea` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara texto libre de varias líneas: descripciones, comentarios, relatos. El alto inicial insinúa la extensión esperada. Para respuestas de una línea, `Input`.\n\n## Composición\n\nUna sola pieza (`Textarea`, un `<textarea>` nativo redimensionable en vertical) con `Label` visible; en formularios validados va dentro de `FormControl`.\n\n## Uso básico\n\n```tsx\n<div className=\"grid gap-1.5\">\n <Label htmlFor=\"notas\">Notas del caso</Label>\n <Textarea id=\"notas\" placeholder=\"Resumen de la reunión…\" rows={4} />\n</div>\n```\n\n## Reglas\n\n- Asocia siempre un `Label` por `htmlFor`/`id`.\n- Usa `rows` para insinuar la longitud esperada de la respuesta.\n- Si hay límite de caracteres, muéstralo cerca del campo (no solo un `maxLength` silencioso).\n- Marca errores con `aria-invalid` + mensaje de texto.\n\n## Cuándo NO usar\n\n- **Una sola línea** (nombre, email, RUT) → `Input`.\n- **Editor con formato/markdown** → no existe en el registry; documenta la decisión si usas algo a medida.\n\n## Import\n\n```tsx\nimport { Textarea } from \"@/components/base/Textarea\";\n```\n\n## Props\n\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `rows` | `number` | — | Alto inicial en líneas. |\n| `aria-invalid` | `boolean` | — | Activa el estilo de error. |\n| `disabled` | `boolean` | `false` | Deshabilita el campo. |\n| ...resto | `textarea` props | — | `value`, `onChange`, `placeholder`, `maxLength`, etc. |\n\n## Para IA\n\n1. Úsalo solo cuando se espera texto de varias líneas (comentarios, descripciones, notas).\n2. Empareja con `Label`.\n3. Ajusta `rows` a la longitud esperada.\n4. Si hay tope de caracteres, hazlo visible y redacta el error como corregir.\n"
21
21
  }
22
22
  ]
23
23
  }
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Toaster.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Toaster.md",
22
- "content": "# Toaster — guía de uso\n\nNotificaciones efímeras de la app (sobre **Sonner**, tematizado con tokens Lexy). Se monta **una vez** en el layout raíz y se dispara imperativo con `toast.*` desde cualquier parte. Reemplaza al `Toast` presentacional del sistema antiguo (deprecado). El componente vive en tu proyecto: instálalo con `create-lexy add toaster` y edítalo con libertad.\n\n## Import\n\n```tsx\n// En el layout raíz (una sola vez):\nimport { Toaster } from \"@/components/base/Toaster\";\n\n// Donde dispares notificaciones:\nimport { toast } from \"@/components/base/Toaster\";\n```\n\n## Montaje\n\n```tsx\nfunction App() {\n return (\n <>\n <Rutas />\n <Toaster />\n </>\n );\n}\n```\n\n## Uso básico\n\n```tsx\ntoast(\"Borrador guardado\");\ntoast.success(\"Cambios guardados\");\ntoast.error(\"No pudimos guardar. Intenta de nuevo.\");\ntoast.warning(\"Tu sesión expira en 5 minutos\");\ntoast.info(\"Hay una versión nueva disponible\");\n\n// Con acción y descripción:\ntoast.success(\"Contrato enviado\", {\n description: \"Le avisamos al cliente por correo.\",\n action: { label: \"Ver contrato\", onClick: () => navigate(`/contratos/${id}`) },\n});\n\n// Operación async de una vez:\ntoast.promise(guardar(), {\n loading: \"Guardando…\",\n success: \"Cambios guardados\",\n error: \"No pudimos guardar. Intenta de nuevo.\",\n});\n```\n\n## Tematización\n\nLos tipos colorean con los tokens semánticos del theme vía las CSS vars de Sonner: `success` → `--color-success`, `error` → `--color-destructive`, `warning` → `--color-warning`, `info` → `--color-info`. Cambiar los tokens re-tematiza los toasts sin tocar el componente.\n\n## Posición, duración y cola (criterio por mundo)\n\nDefaults del componente: `position=\"bottom-right\"`, `duration={4000}`, `visibleToasts={3}` — pensados para **CRM** (escritorio denso: la esquina inferior derecha no tapa toolbars ni encabezados, y la cola corta evita ruido en flujos de alta frecuencia).\n\nPara **mundo cliente** (flujos guiados, móvil primero) configura el montaje:\n\n```tsx\n<Toaster position=\"top-center\" duration={6000} visibleToasts={2} />\n```\n\nArriba y centrado entra en el campo visual del flujo paso a paso, y la duración mayor da tiempo de lectura a personas no expertas.\n\n## Props\n\n`Toaster` acepta todas las props de Sonner (`position`, `duration`, `visibleToasts`, `closeButton`, `toastOptions`…); los defaults y el mapeo de tokens viven en el componente y son editables. Exporta también `toast` (la API imperativa completa de Sonner).\n\n## Reglas (UX writing)\n\n- Éxito puntual (guardado, envío) → toast con el **siguiente paso** cuando exista (*\"Contrato enviado\"* + acción *\"Ver contrato\"*).\n- Error en toast solo si es transitorio y re-intentable (*\"No pudimos guardar. Intenta de nuevo.\"*); errores de validación van en el formulario (`FormMessage`), y errores que bloquean la página van en la vista, no en un toast.\n- Mensajes cortos, verbo primero, sin tecnicismos ni códigos de error.\n- No comuniques con color solamente: el texto debe bastar.\n\n## Cuándo NO usar\n\n- **Confirmar antes de actuar** → `AlertDialog`.\n- **Estado persistente de la vista** (vacío, error de carga) → `Empty` o estado en la página.\n- **Errores de campos** → `FormMessage`.\n\n## Para IA\n\n1. Monta `<Toaster />` una vez en el layout raíz; nunca por vista.\n2. Importa `toast` desde el componente local, no desde `sonner` directo (así hereda el tema).\n3. Tras una mutación: éxito → `toast.success` con siguiente paso; fallo re-intentable → `toast.error` con cómo arreglarlo.\n4. En mundo cliente configura `position=\"top-center\" duration={6000}`; en CRM deja los defaults.\n"
22
+ "content": "# Toaster — guía de uso\n\nNotificaciones efímeras de la app (sobre **Sonner**, tematizado con tokens Lexy). Se monta **una vez** en el layout raíz y se dispara imperativo con `toast.*` desde cualquier parte. Reemplaza al `Toast` presentacional del sistema antiguo (deprecado). El componente vive en tu proyecto: instálalo con `create-lexy add toaster` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara confirmar resultados de acciones sin interrumpir: “Guardado”, “Enviado”, un error recuperable. Es efímero — si la persona debe decidir algo, usa `AppDialog`; si el error bloquea el flujo, muéstralo en el lugar del error.\n\n## Composición\n\nDos piezas: `Toaster` se monta una sola vez en el layout raíz, y `toast.*` (success, error, info…) se dispara imperativo desde cualquier parte. Construido sobre Sonner, tematizado con tokens Lexy.\n\n## Montaje\n\n```tsx\nfunction App() {\n return (\n <>\n <Rutas />\n <Toaster />\n </>\n );\n}\n```\n\n## Uso básico\n\n```tsx\ntoast(\"Borrador guardado\");\ntoast.success(\"Cambios guardados\");\ntoast.error(\"No pudimos guardar. Intenta de nuevo.\");\ntoast.warning(\"Tu sesión expira en 5 minutos\");\ntoast.info(\"Hay una versión nueva disponible\");\n\n// Con acción y descripción:\ntoast.success(\"Contrato enviado\", {\n description: \"Le avisamos al cliente por correo.\",\n action: { label: \"Ver contrato\", onClick: () => navigate(`/contratos/${id}`) },\n});\n\n// Operación async de una vez:\ntoast.promise(guardar(), {\n loading: \"Guardando…\",\n success: \"Cambios guardados\",\n error: \"No pudimos guardar. Intenta de nuevo.\",\n});\n```\n\n## Tematización\n\nLos tipos colorean con los tokens semánticos del theme vía las CSS vars de Sonner: `success` → `--color-success`, `error` → `--color-destructive`, `warning` → `--color-warning`, `info` → `--color-info`. Cambiar los tokens re-tematiza los toasts sin tocar el componente.\n\n## Posición, duración y cola (criterio por mundo)\n\nDefaults del componente: `position=\"bottom-right\"`, `duration={4000}`, `visibleToasts={3}` — pensados para **CRM** (escritorio denso: la esquina inferior derecha no tapa toolbars ni encabezados, y la cola corta evita ruido en flujos de alta frecuencia).\n\nPara **mundo cliente** (flujos guiados, móvil primero) configura el montaje:\n\n```tsx\n<Toaster position=\"top-center\" duration={6000} visibleToasts={2} />\n```\n\nArriba y centrado entra en el campo visual del flujo paso a paso, y la duración mayor da tiempo de lectura a personas no expertas.\n\n## Reglas (UX writing)\n\n- Éxito puntual (guardado, envío) → toast con el **siguiente paso** cuando exista (*\"Contrato enviado\"* + acción *\"Ver contrato\"*).\n- Error en toast solo si es transitorio y re-intentable (*\"No pudimos guardar. Intenta de nuevo.\"*); errores de validación van en el formulario (`FormMessage`), y errores que bloquean la página van en la vista, no en un toast.\n- Mensajes cortos, verbo primero, sin tecnicismos ni códigos de error.\n- No comuniques con color solamente: el texto debe bastar.\n\n## Cuándo NO usar\n\n- **Confirmar antes de actuar** → `AlertDialog`.\n- **Estado persistente de la vista** (vacío, error de carga) → `Empty` o estado en la página.\n- **Errores de campos** → `FormMessage`.\n\n## Import\n\n```tsx\n// En el layout raíz (una sola vez):\nimport { Toaster } from \"@/components/base/Toaster\";\n\n// Donde dispares notificaciones:\nimport { toast } from \"@/components/base/Toaster\";\n```\n\n## Props\n\n`Toaster` acepta todas las props de Sonner (`position`, `duration`, `visibleToasts`, `closeButton`, `toastOptions`…); los defaults y el mapeo de tokens viven en el componente y son editables. Exporta también `toast` (la API imperativa completa de Sonner).\n\n## Para IA\n\n1. Monta `<Toaster />` una vez en el layout raíz; nunca por vista.\n2. Importa `toast` desde el componente local, no desde `sonner` directo (así hereda el tema).\n3. Tras una mutación: éxito → `toast.success` con siguiente paso; fallo re-intentable → `toast.error` con cómo arreglarlo.\n4. En mundo cliente configura `position=\"top-center\" duration={6000}`; en CRM deja los defaults.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Tooltip.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Tooltip.md",
22
- "content": "# Tooltip — guía de uso\n\nEtiqueta breve que aparece al pasar el cursor o enfocar (Radix). Para **ayuda complementaria**, nunca para información esencial. El componente vive en tu proyecto: instálalo con `create-lexy add tooltip` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport {\n Tooltip, TooltipTrigger, TooltipContent, TooltipProvider,\n} from \"@/components/base/Tooltip\";\n```\n\n## Uso básico\n\nEnvuelve la app (o la zona) una vez con `TooltipProvider`:\n\n```tsx\n<TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button size=\"icon\" aria-label=\"Archivar\"><Archive /></Button>\n </TooltipTrigger>\n <TooltipContent>Archivar conversación</TooltipContent>\n </Tooltip>\n</TooltipProvider>\n```\n\n## Props (esenciales)\n\n| Parte | Prop | Default | Descripción |\n|---|---|---|---|\n| `TooltipProvider` | `delayDuration` | `700` | Retardo antes de mostrar. |\n| `TooltipTrigger` | `asChild` | — | Usa tu propio elemento como disparador. |\n| `TooltipContent` | `side` | `\"top\"` | Lado: `top`/`right`/`bottom`/`left`. |\n| `TooltipContent` | `sideOffset` | `4` | Separación del trigger. |\n\n## Reglas\n\n- El contenido es **complementario**: la interfaz debe entenderse sin leerlo.\n- En botones solo-icono, el tooltip **no** reemplaza al `aria-label`: pon ambos.\n- Usa `asChild` en el trigger para no anidar botones.\n- Texto corto; no metas párrafos ni acciones dentro del tooltip.\n- Coloca un `TooltipProvider` arriba en el árbol; no anides uno por tooltip.\n\n## Cuándo NO usar\n\n- **Información necesaria para decidir o actuar** → muéstrala en pantalla (texto de ayuda, `Label`, descripción).\n- **Contenido rico o interactivo** (links, botones, formularios) → `Popover`.\n- **Mensajes de error de formulario** → texto bajo el campo con `aria-describedby`.\n\n## Para IA\n\n1. Pregúntate si el dato es prescindible; si es necesario, NO uses tooltip.\n2. Envuelve con un `TooltipProvider` (una vez por zona).\n3. Usa `TooltipTrigger asChild` sobre el control real.\n4. En iconos, mantén `aria-label` además del tooltip.\n5. Si necesitas contenido interactivo, cambia a `Popover`.\n"
22
+ "content": "# Tooltip — guía de uso\n\nEtiqueta breve que aparece al pasar el cursor o enfocar (Radix). Para **ayuda complementaria**, nunca para información esencial. El componente vive en tu proyecto: instálalo con `create-lexy add tooltip` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara ayuda complementaria al pasar el cursor o enfocar: el nombre de un botón solo-icono, una aclaración breve. Nunca para información esencial — en móvil no hay hover, y lo esencial debe estar visible.\n\n## Composición\n\n`TooltipProvider` una vez, arriba en el árbol; por cada caso, `Tooltip` con `TooltipTrigger` (el elemento que lo invoca) y `TooltipContent` (el texto breve).\n\n## Uso básico\n\nEnvuelve la app (o la zona) una vez con `TooltipProvider`:\n\n```tsx\n<TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button size=\"icon\" aria-label=\"Archivar\"><Archive /></Button>\n </TooltipTrigger>\n <TooltipContent>Archivar conversación</TooltipContent>\n </Tooltip>\n</TooltipProvider>\n```\n\n## Reglas\n\n- El contenido es **complementario**: la interfaz debe entenderse sin leerlo.\n- En botones solo-icono, el tooltip **no** reemplaza al `aria-label`: pon ambos.\n- Usa `asChild` en el trigger para no anidar botones.\n- Texto corto; no metas párrafos ni acciones dentro del tooltip.\n- Coloca un `TooltipProvider` arriba en el árbol; no anides uno por tooltip.\n\n## Cuándo NO usar\n\n- **Información necesaria para decidir o actuar** → muéstrala en pantalla (texto de ayuda, `Label`, descripción).\n- **Contenido rico o interactivo** (links, botones, formularios) → `Popover`.\n- **Mensajes de error de formulario** → texto bajo el campo con `aria-describedby`.\n\n## Import\n\n```tsx\nimport {\n Tooltip, TooltipTrigger, TooltipContent, TooltipProvider,\n} from \"@/components/base/Tooltip\";\n```\n\n## Props (esenciales)\n\n| Parte | Prop | Default | Descripción |\n|---|---|---|---|\n| `TooltipProvider` | `delayDuration` | `700` | Retardo antes de mostrar. |\n| `TooltipTrigger` | `asChild` | — | Usa tu propio elemento como disparador. |\n| `TooltipContent` | `side` | `\"top\"` | Lado: `top`/`right`/`bottom`/`left`. |\n| `TooltipContent` | `sideOffset` | `4` | Separación del trigger. |\n\n## Para IA\n\n1. Pregúntate si el dato es prescindible; si es necesario, NO uses tooltip.\n2. Envuelve con un `TooltipProvider` (una vez por zona).\n3. Usa `TooltipTrigger asChild` sobre el control real.\n4. En iconos, mantén `aria-label` además del tooltip.\n5. Si necesitas contenido interactivo, cambia a `Popover`.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -17,7 +17,7 @@
17
17
  "path": "components/base/Tree.md",
18
18
  "type": "registry:file",
19
19
  "target": "components/base/Tree.md",
20
- "content": "# Tree — guía de uso\n\nÁrbol jerárquico. Para navegación en profundidad. El componente vive en tu proyecto: instálalo con `create-lexy add tree` y edítalo con libertad.\n\n## Import\n\n```tsx\nimport { Tree } from \"@/components/base/Tree\";\n```\n\n## Uso básico\n\n```tsx\n<Tree />\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Reglas\n\n- Usa Tree según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Tree desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
20
+ "content": "# Tree — guía de uso\n\nÁrbol jerárquico. Para navegación en profundidad. El componente vive en tu proyecto: instálalo con `create-lexy add tree` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara navegar jerarquías con profundidad real: carpetas, expedientes anidados, estructuras organizacionales. Si la jerarquía tiene un solo nivel de agrupación, un acordeón o una lista con secciones es más simple.\n\n## Composición\n\n`Tree` contiene `TreeItem`s anidables: cada item puede expandirse y contener hijos.\n\n## Uso básico\n\n```tsx\n<Tree />\n```\n\n## Reglas\n\n- Usa Tree según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Tree } from \"@/components/base/Tree\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Tree desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
21
21
  }
22
22
  ]
23
23
  }
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.17
@@ -36,9 +36,9 @@
36
36
  Fluent de origen se anota a la derecha de cada valor. */
37
37
 
38
38
  /* ── Superficies y texto ── */
39
- --color-background: #ffffff; /* Fluent NeutralBackground1 */
39
+ --color-background: #ffffff; /* blanco absoluto */
40
40
  --color-foreground: #242424; /* Fluent NeutralForeground1 */
41
- --color-card: #fafafa; /* Fluent NeutralCardBackground */
41
+ --color-card: #fdfdfe; /* superficie casi blanca, con un matiz frío mínimo */
42
42
  --color-card-foreground: #242424;
43
43
  --color-popover: #ffffff;
44
44
  --color-popover-foreground: #242424;
@@ -57,6 +57,8 @@
57
57
 
58
58
  /* ── Marca ── */
59
59
  --color-brand-navy: #0b013c; /* navy/ink del wordmark Lexy (HeaderBar surface navy) */
60
+ --color-brand-lavender: #9d90fc; /* lavanda de marca (superficies expresivas) */
61
+ --color-brand-indigo-deep: #4429cc; /* índigo profundo de marca (superficies expresivas) */
60
62
 
61
63
  /* ── Bordes y foco ── */
62
64
  --color-border: #d1d1d1; /* Fluent NeutralStroke1 */
@@ -72,7 +74,7 @@
72
74
  --radius-lg: calc(var(--radius) + 0.25rem); /* 8px · superficies grandes */
73
75
 
74
76
  /* ── Sidebar shadcn ── */
75
- --color-sidebar: #ffffff;
77
+ --color-sidebar: #ffffff; /* = background: la navegación comparte superficie con la página */
76
78
  --color-sidebar-foreground: #242424;
77
79
  --color-sidebar-primary: #4648d4;
78
80
  --color-sidebar-primary-foreground: #ffffff;
@@ -168,6 +170,15 @@
168
170
  --spacing-margin-mobile: 1rem; /* 16px · margen lateral en móvil */
169
171
  --spacing-margin-desktop: 3rem; /* 48px · margen lateral en desktop */
170
172
  --spacing-container-max: 80rem; /* 1280px · ancho máximo de contenedor */
173
+
174
+ /* ── Breakpoints ────────────────────────────────────────────────
175
+ Contrato responsive: móvil = <768px (bajo md). Es el mismo umbral que
176
+ MOBILE_BREAKPOINT en registry/components/useIsMobile.ts — si el
177
+ contrato cambia, cambia en ambos lugares. Los valores coinciden con
178
+ los defaults de Tailwind: se declaran para fijar el contrato. */
179
+ --breakpoint-sm: 40rem; /* 640px */
180
+ --breakpoint-md: 48rem; /* 768px · umbral móvil ↔ desktop */
181
+ --breakpoint-lg: 64rem; /* 1024px · umbral columnas master-detail */
171
182
  }
172
183
 
173
184
  @layer utilities {
@@ -189,7 +200,7 @@
189
200
  el entrypoint CSS porque debe ir antes de @import "tailwindcss". */
190
201
  @layer base {
191
202
  :root {
192
- --sidebar-background: 0 0% 100%;
203
+ --sidebar-background: 210 40% 98%;
193
204
  --sidebar-foreground: 0 0% 14%;
194
205
  --sidebar-primary: 239 62% 55%;
195
206
  --sidebar-primary-foreground: 0 0% 100%;