@imansi/tailwind
v0.1.2
Published
Capa visual fundacional del ecosistema Imansi: design tokens, temas y estilos base construidos sobre Tailwind CSS.
Downloads
512
Maintainers
Readme
@imansi/tailwind
Capa visual fundacional del ecosistema Imansi. Design tokens, temas y estilos base construidos sobre Tailwind CSS v4.
Tabla de contenidos
- ¿Qué es Imansi Tailwind?
- ¿Qué problema resuelve?
- Instalación
- Uso
- Temas
- Light / Dark / System
- Design Tokens
- Anatomía del paquete
- Desarrollo local
- Arquitectura
- Roadmap
- Licencia
- Soporte
¿Qué es Imansi Tailwind?
@imansi/tailwind es el primer paquete del ecosistema Imansi y su capa visual fundacional. No contiene componentes, lógica de negocio ni utilidades de aplicación.
Su única responsabilidad es definir cómo se ve una interfaz Imansi:
- Colores semánticos
- Tipografía (familias + escala)
- Espaciado
- Border radius
- Sombras
- Transiciones y animaciones
- Z-index coherentes
- 6 temas visuales listos para usar
- Modo claro, oscuro y detección del sistema operativo
Todo esto se implementa sobre Tailwind CSS v4 mediante la directiva @theme, sin tailwind.config.js ni JavaScript de configuración.
¿Qué problema resuelve?
En un ecosistema con múltiples paquetes (@imansi/ui, imansi-auth-react, @imansi/templates-dashboard), cada uno necesita compartir la misma identidad visual. Sin una capa fundacional:
- Cada paquete reinventaría sus colores, tamaños y espaciados.
- Cambiar el primario implicaría tocar decenas de archivos.
- Los temas y modos serían inconsistentes entre paquetes.
@imansi/tailwind centraliza esa capa en un solo lugar. Los componentes consumen tokens semánticos (bg-primary, text-muted-foreground) que nunca cambian de nombre, pero cuyos valores se adaptan automáticamente al tema y modo activos.
Cambiar la identidad visual completa de una app Imansi se reduce a cambiar un atributo en <html>.
Instalación
npm install @imansi/tailwindRequiere Tailwind CSS v4 y el plugin oficial para Vite (o PostCSS) como dependencias pares:
npm install -D tailwindcss @tailwindcss/viteConfigurar Vite
En vite.config.js:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [react(), tailwindcss()],
})Configurar PostCSS (alternativa sin Vite)
Si usás otro bundler, agregá @tailwindcss/postcss:
npm install -D tailwindcss @tailwindcss/postcssY creá postcss.config.js:
export default {
plugins: {
'@tailwindcss/postcss': {},
},
}Uso
1. Importar los estilos
En el archivo CSS principal de tu aplicación (src/index.css):
@import "tailwindcss";
@import "@imansi/tailwind/styles.css";
/* Dile a Tailwind dónde escanear clases */
@source "./**/*.jsx";
@source "./**/*.js";
@source "./**/*.tsx";
@source "./**/*.ts";Nota:
@sourcedebe estar en tu app, no en el paquete. Cada app consumidora escanea sus propios archivos.
2. Configurar tema y modo
En el <html> de tu index.html:
<html lang="es" data-theme="modern" data-mode="dark">O dinámicamente desde JavaScript:
document.documentElement.dataset.theme = 'modern'; // minimal | modern | compact | warm | red | yellow
document.documentElement.dataset.mode = 'light'; // light | dark | system3. Usar tokens en tus componentes
export function Button({ children }) {
return (
<button className="bg-primary text-primary-foreground px-4 py-2 rounded-md font-medium transition-colors hover:opacity-90">
{children}
</button>
);
}Ese componente funcionará igual en los 6 temas y los 3 modos sin una sola línea condicional.
4. Detección automática del sistema (opcional)
Si querés que data-mode="system" responda a cambios en vivo del sistema operativo:
const mq = window.matchMedia('(prefers-color-scheme: dark)');
function resolveSystemMode() {
return mq.matches ? 'dark' : 'light';
}
function applyMode(mode) {
document.documentElement.dataset.mode =
mode === 'system' ? resolveSystemMode() : mode;
}
// Aplicar al cargar
applyMode('system');
// Escuchar cambios del sistema
mq.addEventListener('change', () => {
if (document.documentElement.dataset.mode !== 'light' &&
document.documentElement.dataset.mode !== 'dark') {
// Solo si el usuario tenía "system" seleccionado
}
});Temas
El paquete incluye 6 temas, cada uno con identidad visual propia. Todos comparten la misma API de tokens; solo cambian sus valores.
minimal
Inspirado en interfaces editoriales y SaaS minimalistas.
- Paleta monocroma (blanco, negro, grises)
- Sin color de marca visible
- Radios contenidos (4–8px)
- Sombras planas (solo borde de 1px)
- Sensación limpia y premium
Ideal para: productos que priorizan claridad y elegancia.
modern
Inspirado en SaaS contemporáneo.
- Paleta índigo/violeta vibrante
- Radios generosos (14–24px)
- Sombras con tinte violeta
- Alto contraste entre superficies
Ideal para: aplicaciones que quieren transmitir modernidad.
compact
Inspirado en dashboards administrativos.
- Paleta verde esmeralda
- Radios casi nulos (1–4px)
- Sombras planas con borde marcado
- Espaciado más denso (
--spacing: 3px) - Tipografía ligeramente más pequeña
Ideal para: paneles con mucha información, tablas y vistas densas.
warm
Inspirado en diseño editorial y revistas.
- Tipografía serif (Georgia)
- Paleta cálida (crema, terracota, ámbar)
- Radios medianos (6–20px)
- Sombras con tinte marrón
Ideal para: blogs, portfolios, productos con carácter editorial.
red
Rojo intenso y pasional. Bold, energético.
- Paleta roja vibrante (
oklch(0.55 0.24 27)) - Radios moderados (4–16px)
- Sombras con tinte rojo
- Alto contraste y presencia fuerte
Ideal para: apps de urgencia, alertas, monitoreo en tiempo real, o branding agresivo.
yellow
Amarillo/ámbar brillante. Soleado, cálido, energético.
- Paleta ámbar/mostaza (
oklch(0.78 0.17 80)) - Contraste automático: texto oscuro sobre primary
- Radios suaves (6–18px)
- Sombras con tinte amarillo
Ideal para: apps creativas, educativas, o branding vibrante.
Light / Dark / System
Cada tema soporta los 3 modos. Se controlan con el atributo data-mode en <html>.
| Modo | data-mode | Comportamiento |
|------|-------------|----------------|
| Light | "light" | Fuerza colores claros |
| Dark | "dark" | Fuerza colores oscuros |
| System | "system" | Detecta prefers-color-scheme (implementado por la app) |
Por qué system se implementa en la app y no en el paquete:
El paquete es CSS puro. La detección de prefers-color-scheme requiere JavaScript y es una decisión del consumidor (¿cambio automático? ¿con botón? ¿persistencia en localStorage?). Por eso el paquete solo provee los estilos para light y dark, y expone system como una convención.
Cuando un usuario quiere modo sistema, la app resuelve prefers-color-scheme y escribe data-mode="light" o "dark" según corresponda. Un snippet listo está arriba en Uso → punto 4.
Design Tokens
Colores semánticos
Todos los componentes deben usar estos nombres, nunca colores crudos (blue-500, gray-900):
| Token | Uso típico |
|---|---|
| background | Fondo de la app |
| foreground | Texto principal |
| card / card-foreground | Superficies elevadas |
| popover / popover-foreground | Overlays, dropdowns |
| primary / primary-foreground | Acciones principales |
| secondary / secondary-foreground | Acciones secundarias |
| muted / muted-foreground | Texto de apoyo, fondos sutiles |
| accent / accent-foreground | Elementos destacados |
| destructive / destructive-foreground | Errores, acciones peligrosas |
| success / success-foreground | Confirmaciones |
| warning / warning-foreground | Advertencias |
| info / info-foreground | Información |
| border | Bordes estándar |
| input | Fondo de campos de formulario |
| ring | Anillo de foco |
| overlay | Capa de modales |
Uso en Tailwind:
<div className="bg-background text-foreground border border-border">
<p className="text-muted-foreground">Texto secundario</p>
</div>Tipografía
Escala definida en tokens.css:
| Clase | Uso | Tamaño | Peso |
|---|---|---|---|
| text-display | Héroe, landing | 3.5rem | 700 |
| text-h1 | H1 | 2.5rem | 700 |
| text-h2 | H2 | 1.875rem | 600 |
| text-h3 | H3 | 1.5rem | 600 |
| text-h4 | H4 | 1.25rem | 600 |
| text-body | Texto principal | 1rem | 400 |
| text-small | Texto secundario | 0.875rem | 400 |
| text-caption | Metadatos, etiquetas | 0.75rem | 400 |
Cada nivel incluye tamaño, line-height, font-weight y (en algunos) letter-spacing.
<h1 className="text-h1">Título</h1>
<p className="text-body">Párrafo normal</p>
<span className="text-caption text-muted-foreground">Hace 2 min</span>Familias disponibles:
--font-sans— Sans-serif por defecto (system-ui)--font-serif— Serif (Georgia, Palatino)--font-mono— Monospace (Cascadia, Menlo, Consolas)
Espaciado
Escala basada en --spacing (4px por defecto, 3px en compact). Tailwind genera automáticamente p-1, m-2, gap-4, etc.
Border Radius
| Token | Uso |
|---|---|
| radius-sm | Inputs pequeños, badges |
| radius-md | Botones, inputs |
| radius-lg | Cards |
| radius-xl | Modales, contenedores grandes |
| radius-2xl | Contenedores extra grandes |
| radius-full | Avatares, píldoras |
Cada tema ajusta estos valores según su personalidad.
Sombras
shadow-none, shadow-sm, shadow-md, shadow-lg, shadow-xl, shadow-inner.
Minimal las usa casi invisibles; Modern las usa con tinte violeta.
Transiciones
| Token | Valor |
|---|---|
| --transition-duration-fast | 150ms |
| --transition-duration-normal | 250ms |
| --transition-duration-slow | 350ms |
| --transition-timing | cubic-bezier(0.4, 0, 0.2, 1) |
Animaciones
Utilidades listas para usar:
<div className="animate-fade-in">Aparece con fade</div>
<div className="animate-slide-up">Sube desde abajo</div>
<div className="animate-scale-in">Aparece con escala</div>
<div className="animate-spin-slow">Gira lentamente</div>
<div className="animate-pulse-soft">Pulsa suavemente</div>Animaciones disponibles: fade-in, fade-out, scale-in, scale-out, slide-up, slide-down, slide-left, slide-right, spin-slow, pulse-soft, accordion-down, accordion-up.
Todas respetan prefers-reduced-motion.
Z-Index
Tokens --z-base, --z-dropdown, --z-sticky, --z-fixed, --z-overlay, --z-modal, --z-popover, --z-tooltip, --z-toast para mantener coherencia en capas.
Utilidades .imansi-*
Utilidades propias del paquete, prefijadas para no chocar con Tailwind:
| Utilidad | Qué hace |
|---|---|
| .imansi-sr-only | Oculta visualmente pero accesible para lectores de pantalla |
| .imansi-container | Contenedor centrado con padding responsive |
| .imansi-overlay | Capa de overlay fixed con --color-overlay |
| .imansi-truncate | Trunca texto con ellipsis |
| .imansi-line-clamp-2 | Limita a 2 líneas |
| .imansi-line-clamp-3 | Limita a 3 líneas |
| .imansi-divider | Línea divisoria horizontal |
| .imansi-focus-ring | Anillo de foco consistente |
| .imansi-font-serif | Aplica --font-serif |
| .imansi-font-mono | Aplica --font-mono |
Anatomía del paquete
packages/tailwind/
├── src/
│ ├── tokens.css Design tokens base (colores, tipografía, spacing, radius, sombras)
│ ├── themes.css Overrides por tema y modo (6 temas × 2 modos)
│ ├── base.css Reset mínimo, utilidades .imansi-* y variantes explícitas
│ └── index.css Entry point: importa todo y define @custom-variant
├── package.json
├── README.md
└── LICENSEPor qué esta estructura:
tokens.cssdefine los valores por defecto. Cambiar aquí afecta a todos los temas.themes.csscontiene solo overrides. Añadir un tema nuevo es copiar un bloque y ajustar valores.base.cssaplica el reset y utilidades globales. Va en@layer basepara que las utilidades de Tailwind siempre ganen.index.csses el único archivo que el consumidor importa. Centraliza los@importy las variantes (dark:,theme-minimal:, etc.).
Añadir un tema nuevo es trivial: agrega un bloque [data-theme="nuevo"] y su par [data-theme="nuevo"][data-mode="light"|"dark"] en themes.css. No toques componentes. No toques el resto.
Cascade de CSS
Los estilos siguen este orden de especificidad (de más específico a menos):
[data-theme="x"][data-mode="y"] ← gana siempre
[data-theme="x"]
[data-mode="y"]
@theme (tokens.css) ← fallbackEsto garantiza que minimal + dark gane sobre minimal solo, y que minimal solo gane sobre @theme.
Variantes personalizadas
El paquete expone variantes para usar en tus clases de Tailwind:
@custom-variant dark (&:where([data-mode="dark"], [data-mode="dark"] *));
@custom-variant theme-minimal (&:where([data-theme="minimal"], [data-theme="minimal"] *));
@custom-variant theme-modern (&:where([data-theme="modern"], [data-theme="modern"] *));
@custom-variant theme-compact (&:where([data-theme="compact"], [data-theme="compact"] *));
@custom-variant theme-warm (&:where([data-theme="warm"], [data-theme="warm"] *));
@custom-variant theme-red (&:where([data-theme="red"], [data-theme="red"] *));
@custom-variant theme-yellow (&:where([data-theme="yellow"], [data-theme="yellow"] *));Uso:
<div className="bg-background dark:bg-card theme-modern:rounded-xl">
Contenido
</div>Desarrollo local
Este paquete vive dentro de un monorepo con npm workspaces:
imansi-tailwind/
├── packages/
│ └── tailwind/ ← @imansi/tailwind
├── apps/
│ └── playground/ ← App React + Vite para probar el paquete
└── package.json ← Raíz del workspaceInstalación
Desde la raíz del monorepo:
npm installnpm crea automáticamente un symlink en node_modules/@imansi/tailwind que apunta a packages/tailwind. No hace falta npm link, ni publicar, ni hacer nada manual.
Desarrollo
npm run devEsto arranca el playground en http://localhost:5173. Cualquier cambio en packages/tailwind/src/*.css se refleja al instante en el navegador gracias al HMR de Vite.
Verificar el paquete antes de publicar
cd packages/tailwind
npm run pack:dryMuestra exactamente qué archivos se incluirían en el tarball de npm. Si algo sobra o falta, ajusta el campo files en package.json.
¿Por qué npm workspaces y no otra cosa?
- Sin herramientas externas. No necesitás Lerna, Nx, pnpm o Turborepo.
- Un solo
npm install. Instala y enlaza todo el monorepo. - HMR instantáneo. Los cambios en el paquete se ven en la app sin recompilar.
- Un solo
node_modulesraíz. Menos peso y sin duplicaciones.
Para un proyecto mantenido por una sola persona, es la opción más simple y limpia.
Arquitectura
@imansi/tailwind es la base del ecosistema. Los paquetes superiores lo consumen sin modificarlo.
Tailwind CSS v4
↓
@imansi/tailwind ← Este paquete (tokens + 6 temas + base)
↓
@imansi/ui ← Componentes React (Button, Input, Card...)
↓
@imansi/templates-auth ← Variantes visuales de autenticación
↓
@imansi/templates-dashboard ← Variantes visuales de dashboard
↓
create-imansi-app ← CLI de scaffoldingReglas arquitectónicas:
@imansi/tailwindno depende de ningún otro paquete Imansi. Es la base.- No contiene componentes. Solo tokens, temas y estilos base.
- Los paquetes superiores nunca usan colores crudos (
bg-blue-500). Solo tokens semánticos (bg-primary). - Cambiar la identidad visual de una app Imansi completa se hace cambiando
data-themeydata-modeen<html>. Cero cambios de código.
Roadmap
✅ v0.1.x — Paquete fundacional
- [x] Design tokens semánticos (colores, tipografía, spacing, radius, sombras)
- [x] 6 temas:
minimal,modern,compact,warm,red,yellow - [x] 2 modos +
systemcomo convención:light,dark - [x] Transiciones y animaciones
- [x] Reset base y utilidades
.imansi-* - [x] Contraste automático en
bg-*sintext-* - [x] Variantes
hover:,focus:ydata-state:explícitas - [x] Publicable en npm
⏭️ Próximos pasos
- [ ] Presets de tema adicionales (
ocean,forest,sunset) - [ ] Modo "high-contrast" para accesibilidad
- [ ] Utilidades
imansi-scroll-*para scroll suave y scrollbar custom - [ ] Editor visual de temas (aplicación web interactiva)
🌱 Ecosistema Imansi
- [x]
@imansi/tailwind— Este paquete (tokens + temas + base) - [x]
@imansi/ui— Componentes React accesibles - [x]
imansi-auth-node— Servidor de autenticación (Express + PostgreSQL) - [x]
imansi-auth-react— Hooks de autenticación para React - [x]
imansi-correos-node— 26 plantillas de correo con SMTP - [x]
@imansi/templates— Páginas completas listas para usar - [x]
@imansi/templates-auth— Variantes visuales de autenticación - [x]
@imansi/templates-dashboard— Variantes visuales de dashboard - [x]
create-imansi-app— CLI interactivo para scaffoldear proyectos
🎯 Visión
Un desarrollador puede crear una aplicación completa con:
npx create-imansi-app@latest mi-app
cd mi-app
npm run devY obtener un proyecto con:
- Tailwind +
@imansi/tailwindpreconfigurado - Tema y modo listos (con selector visual)
- Autenticación funcional
- Dashboard base con sidebar
- Componentes UI accesibles
Todo coherente, todo editable, todo basado en el mismo sistema de tokens.
Licencia
MIT © 2026 Imansi
Soporte
- Documentación: docs.imansi.pro
- Issues: github.com/imansi-pro/imansi-tailwind/issues
