@nlace/ui-kit
v2.4.0
Published
NLACE Design System — fuente única de tokens (W3C DTCG + Style Dictionary), CSS vars, Tailwind v4/v3, objeto JS/TS y 14 componentes React
Downloads
403
Maintainers
Readme
NLACE Design System
Sistema de diseño oficial de NLACE — tokens, componentes React y preset de Tailwind CSS para todos los productos de la empresa.
¿Qué es esto?
@nlace/ui-kit es el paquete que centraliza la identidad visual de NLACE: colores, tipografía, espaciado, motion, y componentes React. Es la fuente de verdad compartida entre todos los proyectos de la empresa — desde productos internos hasta sitios de marketing.
Lo que incluye este repositorio:
| Directorio / archivo | Qué hay |
|---|---|
| tokens/ | Fuente única de los tokens en formato W3C Design Tokens (DTCG). Editás acá. |
| build/ | Config de Style Dictionary que genera todos los formatos desde tokens/ |
| src/tokens/tailwind-v4.css | (generado) Tokens como @theme para Tailwind v4 |
| src/tokens/tokens.css | (generado) Variables CSS puras (sin Tailwind) — agnóstico de framework |
| src/tokens/tokens.mjs · .cjs · .d.ts | (generado) Tokens como objeto JS/TS tipado |
| src/tokens/tokens.json | (generado) Tokens como mapa JSON resuelto (cualquier lenguaje) |
| src/tailwind-preset.js | (generado) Preset para Tailwind v3 |
| src/tokens/fonts.css | @font-face de Inter + Space Grotesk (woff2 variables en src/fonts/) — import '@nlace/ui-kit/fonts' |
| colors_and_type.css | (generado) CSS canónico: variables, @font-face y selectores base |
| src/components/ | Componentes React: Button, Card, Badge, Input, Alert, Loaders, NlaceLogo, Tabs, Switch, Tooltip, Modal, Dropdown, Table, Charts, MeshGradient |
| assets/nlace-black.svg | Wordmark oscuro (fondos claros) |
| assets/nlace-white.svg | Wordmark claro (fondos oscuros) |
| assets/photos/ | 14 fotografías oficiales del equipo |
| assets/imagery/ | 130 imágenes AI para secciones de producto |
| fonts/ | Inter y Space Grotesk como fuentes variables TTF |
| DESIGN.md | Referencia completa para agentes de IA y diseñadores |
| preview/ | Páginas HTML del design system (colores, tipo, componentes) |
| templates/ | Plantillas de documento del sistema: deck, email, one-pager, plantillas sociales, propuesta, reel |
Los archivos marcados (generado) salen de
tokens/. No los edites a mano — corrénpm run tokens:build. Ver Fuente única de tokens.
Instalación
npm install @nlace/ui-kit
# o
pnpm add @nlace/ui-kitUso
Tailwind v4 (Next.js 15+ / Vite)
En tu CSS global (app/globals.css o equivalente):
@import "tailwindcss";
@import "@nlace/ui-kit/tailwind-v4";
/* Necesario para que Tailwind v4 escanee clases de los componentes del kit */
@source "../node_modules/@nlace/ui-kit/dist";El
@import "tailwindcss"debe ir primero.
Clases disponibles:
<!-- Colores -->
<div class="bg-nl-primary text-white">...</div>
<div class="bg-nl-bg text-nl-text">...</div>
<span class="text-nl-accent">...</span>
<div class="border border-nl-border-soft">...</div>
<!-- Radios -->
<button class="rounded-pill">CTA</button>
<div class="rounded-card">Card</div>
<input class="rounded-input">
<!-- Sombras -->
<div class="shadow-card hover:shadow-hover">...</div>
<!-- Gradientes -->
<section class="bg-nl-hero">Hero</section>
<span class="bg-nl-brand bg-clip-text text-transparent">Gradient text</span>
<!-- Animaciones -->
<div class="animate-fade-up">...</div>
<div class="animate-shimmer">Skeleton</div>
<!-- Tipografía -->
<h1 class="font-display">Titular</h1>
<p class="font-body">Texto</p>
<!-- Motion -->
<div class="transition-all duration-ui ease-nl hover:-translate-y-1">...</div>Tailwind v3
// tailwind.config.js
module.exports = {
presets: [require('@nlace/ui-kit/preset')],
content: ['./src/**/*.{js,jsx,ts,tsx}'],
}CSS Variables puras (cualquier framework)
Las variables --nl-* son CSS nativo, así que funcionan igual en Astro, Vue, Svelte, Angular, HTML plano o React — sin runtime ni build especial:
/* Variables y selectores base (NO incluye @font-face) */
@import '@nlace/ui-kit/tokens';
/* Fuentes de marca self-hosted (woff2 variables) — sin esto el navegador
cae a la sans del sistema */
@import '@nlace/ui-kit/fonts';<!-- Mismo markup en .astro, .vue, .svelte o .html -->
<button style="background: var(--nl-primary); border-radius: var(--nl-radius-pill)">
Empezar
</button>
<section style="background: var(--nl-grad-hero)">Hero</section>O copia el bloque de variables directamente desde colors_and_type.css.
Tokens como objeto JS/TS
Para leer los valores desde código (theming dinámico, charts, RN, Tailwind config custom):
import tokens, { cssVars } from '@nlace/ui-kit/tokens-js'
tokens.color.primary // '#5869f7'
tokens.gradient.hero // 'linear-gradient(135deg, #5869f7 0%, …)'
tokens.font.display // ['Space Grotesk', 'system-ui', 'sans-serif']
cssVars['--nl-primary'] // '#5869f7' (mapa nombre-CSS → valor)Disponible como ESM (import), CommonJS (require) y tipos TypeScript. Para
consumidores no-JS hay también un mapa plano en @nlace/ui-kit/tokens.json.
Componentes React
import {
Button, Card, Badge, Input, Alert, Spinner, Skeleton, NlaceLogo,
Tabs, Switch, Tooltip, Modal, Dropdown, Table,
BarChart, LineChart, AreaChart, PieChart, DonutChart,
MeshGradient,
} from '@nlace/ui-kit'
function App() {
return (
<Card>
<NlaceLogo variant="dark" height={32} />
<Badge variant="primary">Nuevo</Badge>
<Badge variant="success">Activo</Badge>
<Input
label="Correo electrónico"
placeholder="[email protected]"
/>
<Input
label="RUT"
error="Formato inválido"
/>
<Alert variant="success" title="Listo">
Cambios guardados correctamente.
</Alert>
<div style={{ display: 'flex', gap: 8 }}>
<Button variant="primary">Empezar</Button>
<Button variant="secondary">Cancelar</Button>
<Button variant="danger">Eliminar</Button>
</div>
<Spinner size="md" />
<Skeleton style={{ width: 200, height: 20 }} />
</Card>
)
}API de componentes
Button
<Button
variant="primary" // 'primary' | 'accent' | 'secondary' | 'success' | 'outlineLight' | 'danger'
size="md" // 'sm' | 'md' | 'lg'
disabled={false}
>
Guardar
</Button>Card
<Card
accent={false} // true → fondo primario sólido
hover={true} // false → sin lift en hover
padding="p-6" // clase de padding Tailwind
>
Contenido
</Card>Badge
<Badge variant="primary">
{/* 'primary' | 'accent' | 'success' | 'danger' | 'neutral'
'solidPrimary' | 'solidAccent' | 'solidDark' */}
v1.5.0
</Badge>Input
<Input
label="Campo"
placeholder="..."
error="Mensaje de error" // activa estado error
success // activa estado success
hint="Texto de ayuda"
/>Alert
<Alert
variant="info" // 'info' | 'success' | 'warning' | 'error'
title="Aviso"
>
El proceso tardará unos minutos.
</Alert>Spinner / Skeleton
<Spinner size="md" /> // 'sm' | 'md' | 'lg'
<Skeleton style={{ width: 200, height: 20 }} />NlaceLogo
<NlaceLogo variant="dark" height={32} /> // fondos claros
<NlaceLogo variant="light" height={32} /> // fondos oscuros
<NlaceAvatar size={40} />Tabs
<Tabs
items={[{ id: 'a', label: 'Resumen' }, { id: 'b', label: 'Detalle', badge: 3 }]}
variant="underline" // 'underline' | 'pill'
defaultValue="a" // o controlado con value + onChange
>
{(active) => <div>{active}</div>}
</Tabs>Switch
<Switch
label="Notificaciones"
description="Recibe alertas por correo"
size="md" // 'sm' | 'md'
defaultChecked // o controlado con checked + onChange
/>Tooltip
<Tooltip label="Copiar enlace" placement="top"> {/* 'top' | 'bottom' | 'left' | 'right' */}
<Button>Compartir</Button>
</Tooltip>Modal
<Modal
open={open}
onClose={() => setOpen(false)}
title="Confirmar"
size="md" // 'sm' | 'md' | 'lg'
footer={<><Button variant="secondary">Cancelar</Button><Button>Guardar</Button></>}
>
¿Seguro que quieres continuar?
</Modal>Dropdown
<Dropdown
trigger={<Button variant="secondary">Acciones ▾</Button>}
align="left" // 'left' | 'right'
items={[
{ id: 'edit', label: 'Editar', shortcut: '⌘E' },
{ divider: true },
{ id: 'del', label: 'Eliminar', danger: true },
]}
onSelect={(id) => {}}
/>Table
<Table
columns={[
{ key: 'name', header: 'Empresa' },
{ key: 'mrr', header: 'MRR', align: 'right' },
{ key: 'state', header: 'Estado', render: (r) => <Badge>{r.state}</Badge> },
]}
rows={rows}
rowKey="id"
dense={false}
/>Charts — gráficos SVG sin dependencias, con la paleta de marca
<BarChart labels={['Ene','Feb','Mar']} series={[{ name: 'MRR', values: [18, 26, 31] }]} />
<LineChart labels={['S1','S2','S3']} series={[{ name: 'Activos', values: [120, 180, 240] }]} />
<AreaChart labels={['Ene','Feb']} series={[{ name: 'Procesos', values: [3, 12] }]} />
<PieChart data={[{ label: 'Auto', value: 46 }, { label: 'Soporte', value: 28 }]} />
<DonutChart centerValue="74%" centerLabel="adopción" data={[{ label: 'Activo', value: 74 }]} />
// NL_CHART_PALETTE exporta el orden de colores de series.MeshGradient — fondo animado WebGL con la paleta de marca (sin dependencias)
// Colócalo como capa de fondo detrás del contenido.
<div style={{ position: 'relative' }}>
<MeshGradient style={{ position: 'absolute', inset: 0, zIndex: 0 }} />
<div style={{ position: 'relative', zIndex: 1 }}>…contenido…</div>
</div>
// Props: speed=10, intensity=2, grain=0.75,
// colors=[primary, accent, pink, magenta, deep], highlight=accent-warm.
// Fallback a color sólido si no hay WebGL; seguro bajo React StrictMode.Plantillas de documento
El directorio templates/ contiene plantillas HTML del sistema, listas para usar en presentaciones, correos y piezas de marketing — todas con tokens, tipografía y fotografía de NLACE:
| Plantilla | Formato | Descripción |
|---|---|---|
| deck-nlace/ | 16:9 | Presentación con portada, separadores, grid, timeline, datos y cierre |
| propuesta/ | A4 multipágina | Propuesta comercial: contexto, alcance, entregables, inversión |
| one-pager/ | A4 | Hoja única de producto/empresa con hero, métricas y CTA |
| email/ | 600px responsive | Email HTML en tablas, seguro para clientes de correo |
| plantillas-sociales/ | feed/retrato/story/wide | 6 variantes × 4 formatos para redes |
| reel/ | 9:16 | Reel animado en loop, temas claro/azul/gradiente |
Cada plantilla carga el sistema vía ds-base.js (tokens + _ds_bundle.js) y se edita dentro de Claude Design.
Fuente única de tokens
Desde la v2.3.0 los tokens tienen una sola fuente de verdad: los JSON de
tokens/ en formato W3C Design Tokens (DTCG).
Desde ahí, Style Dictionary genera todos los
formatos de consumo. Esto elimina el desfase de marca que aparecía al mantener los
mismos colores a mano en varios archivos.
tokens/*.json ──► build/build-tokens.mjs (Style Dictionary) ──► artefactos
(W3C DTCG) ├─ src/tokens/tokens.css → @nlace/ui-kit/tokens
├─ src/tokens/tailwind-v4.css → @nlace/ui-kit/tailwind-v4
├─ src/tailwind-preset.js → @nlace/ui-kit/preset
├─ src/tokens/tokens.mjs/.cjs → @nlace/ui-kit/tokens-js
├─ src/tokens/tokens.json → @nlace/ui-kit/tokens.json
└─ colors_and_type.css (canónico del repo)Cómo cambiar un token
# 1. Editá el valor en tokens/*.json (p. ej. color.primary en tokens/color.json)
# 2. Regenerá todos los formatos:
npm run tokens:build
# 3. Commiteá tokens/ + los archivos generados juntos.npm run build corre tokens:build antes de empaquetar, y prepublishOnly
corre build, así que un npm publish nunca sale con tokens desincronizados.
La generación es determinista: regenerar sin cambios produce bytes idénticos.
Detalles del pipeline y la arquitectura por capas: tokens/README.md.
⚠️ No edites los archivos generados a mano. Llevan un banner de aviso y tu cambio se pierde en el próximo
tokens:build. La fuente es siempretokens/.
Tokens de diseño
Paleta canónica
| Token | Hex | Uso |
|---|---|---|
| --nl-primary | #5869f7 | Acción principal, links, foco |
| --nl-accent | #fc624b | CTA secundario, highlights |
| --nl-pink | #f76dee | Gradientes hero, acento |
| --nl-magenta | #b717af | Gradient stop, badge PRO |
| --nl-success | #42cf8a | Estados positivos |
| --nl-danger | #fc624b | Error, destructivo |
| --nl-bg | #efefef | Canvas (nunca blanco puro) |
| --nl-text | #0f1011 | Texto principal |
Tipografía
- Display: Space Grotesk (titulares, 500–700)
- Body/UI: Inter (todo lo demás, 400–700)
- Mono: JetBrains Mono / SF Mono / Fira Code
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">Gradientes
--nl-grad-hero: linear-gradient(135deg, #5869f7 0%, #b717af 60%, #f76dee 100%);
--nl-grad-brand: linear-gradient(90deg, #5869f7 0%, #fc624b 100%);
--nl-grad-primary: linear-gradient(135deg, #5869f7 0%, #2d3bc4 100%);
--nl-grad-accent: linear-gradient(135deg, #fc624b 0%, #f76dee 100%);Assets
Logos
Los SVGs están embebidos inline en DESIGN.md y disponibles vía URL directa:
https://raw.githubusercontent.com/NLACE-COM/ui-kit/main/assets/nlace-black.svg
https://raw.githubusercontent.com/NLACE-COM/ui-kit/main/assets/nlace-white.svgFotografías del equipo
14 fotos disponibles en assets/photos/. Base URL:
https://raw.githubusercontent.com/NLACE-COM/ui-kit/main/assets/photos/{filename}Archivos: portrait-smile.jpg · portrait-duo.jpg · portrait-speaking.jpg · team-group-laptop.jpg · team-meeting-01/02/03.jpg · team-portrait-01/02.jpg · collab-laptop.jpg · hands-laptop-dark.jpg · hands-laptop-light.jpg · hands-notes.jpg · hands-writing.jpg
Imágenes AI
130 imágenes en assets/imagery/ai-01.png → ai-130.png (dos dígitos hasta ai-99.png, tres desde ai-100.png). Base URL:
https://raw.githubusercontent.com/NLACE-COM/ui-kit/main/assets/imagery/ai-{NN}.pngCatálogo con descripción individual e índice temático: assets/imagery/CATALOG.md.
Guía de estilo y plantilla de prompt para generar imágenes nuevas del set: DESIGN.md § Imágenes AI.
Para agentes de IA
Si eres un agente de IA trabajando con este design system, lee DESIGN.md. Contiene todos los tokens, reglas, ejemplos de código HTML/JSX y markup SVG de los logos — todo inline, sin necesidad de leer otros archivos.
Figma
Diseño canónico: NLACE Design SystemfileKey: hboE6NgrEkFXgC9B0M5B18 · nodeId: 2:1677
Precedencia: Figma > DESIGN.md > código
Productos que usan este kit
- NLACE AI Studio — producto AI principal
- nlace.com — sitio de marketing
- NLACE Docs — documentación
- Herramientas verticales: Agrointegral, Evo, Forge, Cotizador, Firmas, Board as a Service, etc.
Licencia
Apache-2.0 © NLACE
