@imansi/tailwind
Capa visual fundacional del ecosistema Imansi. Design tokens, 6 temas y estilos base construidos sobre Tailwind CSS v4.
¿Qué es?
@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
Todo se implementa sobre Tailwind CSS v4 mediante la directiva @theme, sin tailwind.config.js ni JavaScript de configuración.
El problema que resuelve
En un ecosistema con múltiples paquetes, 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.
@imansi/tailwind centraliza esa capa. 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 se reduce a cambiar un atributo en <html>.
Instalación
npm install @imansi/tailwindInstalá también Tailwind CSS v4 y el plugin de Vite:
npm install -D tailwindcss @tailwindcss/viteConfigurar Vite
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [react(), tailwindcss()],
})Uso
1. Importar los estilos
En tu src/index.css:
@import "tailwindcss";
@import "@imansi/tailwind/styles.css";
@source "./**/*.jsx";
@source "./**/*.js";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';
document.documentElement.dataset.mode = 'light';3. 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 hover:opacity-90">
{children}
</button>
);
}Ese componente funciona igual en los 6 temas y los 2 modos sin una línea condicional.
Los 6 temas
Cada tema tiene 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
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
Ideal para: aplicaciones que quieren transmitir modernidad.
compact
Inspirado en dashboards administrativos.
- Paleta verde esmeralda
- Radios casi nulos (1–4px)
- Espaciado más denso
- Tipografía ligeramente más pequeña
Ideal para: paneles con mucha información.
warm
Inspirado en diseño editorial y revistas.
- Tipografía serif (Georgia)
- Paleta cálida (crema, terracota, ámbar)
- Radios medianos
Ideal para: blogs, portfolios, productos con carácter editorial.
red
Rojo intenso y pasional.
- Paleta roja vibrante
- Radios moderados
- Alto contraste y presencia fuerte
Ideal para: apps de urgencia, alertas, monitoreo en tiempo real.
yellow
Amarillo/ámbar brillante.
- Paleta ámbar/mostaza
- Contraste automático: texto oscuro sobre primary
- Radios suaves
Ideal para: apps creativas, educativas, branding vibrante.
Modos: 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) |
Detección automática del sistema:
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;
}
applyMode('system');
mq.addEventListener('change', () => {
if (document.documentElement.dataset.mode !== 'light' &&
document.documentElement.dataset.mode !== 'dark') {
applyMode('system');
}
});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 |
success / success-foreground | Confirmaciones |
warning / warning-foreground | Advertencias |
info / info-foreground | Información |
border | Bordes estándar |
input | Fondo de campos |
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
| Clase | Tamaño | Peso |
|---|---|---|
text-display | 3.5rem | 700 |
text-h1 | 2.5rem | 700 |
text-h2 | 1.875rem | 600 |
text-h3 | 1.5rem | 600 |
text-h4 | 1.25rem | 600 |
text-body | 1rem | 400 |
text-small | 0.875rem | 400 |
text-caption | 0.75rem | 400 |
Familias: --font-sans, --font-serif, --font-mono
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 |
radius-full | Avatares, píldoras |
Sombras
shadow-none, shadow-sm, shadow-md, shadow-lg, shadow-xl, shadow-inner.
Animaciones
<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>Animaciones: 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.
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>Utilidades .imansi-*
| Utilidad | Qué hace |
|---|---|
.imansi-sr-only | Oculta visualmente pero accesible |
.imansi-container | Contenedor centrado con padding responsive |
.imansi-overlay | Capa de overlay fixed |
.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 |
.imansi-focus-ring | Anillo de foco consistente |
.imansi-font-serif | Aplica --font-serif |
.imansi-font-mono | Aplica --font-mono |
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.
Arquitectura
@imansi/tailwind es la base del ecosistema. Los paquetes superiores lo consumen sin modificarlo.
@imansi/tailwind ← Este paquete
↓
@imansi/ui ← Componentes React
↓
@imansi/templates ← Páginas completas
↓
create-imansi-app ← CLI de scaffoldingReglas arquitectónicas:
- No 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. Solo tokens semánticos.
- Cambiar la identidad visual completa es cambiar
data-themeydata-modeen<html>.
Próximos pasos
- @imansi/ui — Los componentes React
- create-imansi-app — El CLI oficial
- Guía de temas — Cómo usar los 6 temas
