Sistema de diseño centralizado para el ecosistema de aplicaciones de CEICOL. Construido sobre Material UI v5+, este paquete provee una integración "Plug & Play" con los tokens de marca, tipografía, escala de espaciado, paleta de color semántica y variantes de componentes de CEICOL.
- React >= 18 (desarrollado y probado con React 19)
- @mui/material >= 5 (desarrollado y probado con MUI 9)
- @emotion/react
- @emotion/styled
Se distribuye a través de Git usando tags de versión inmutables: cada tag entrega siempre el mismo código compilado.
npm install git+https://github.com/ceicol/theme-ceicol.git#v0.37.0Para actualizar, cambia el tag por la versión deseada (ver el badge de arriba o la pestaña Tags del repositorio):
npm install git+https://github.com/ceicol/theme-ceicol.git#v0.37.0npm install @mui/material @emotion/react @emotion/styledEl sistema no instala fuentes por NPM; se cargan vía Google Fonts para garantizar consistencia entre proyectos. Incluir en el <head>:
<linkrel="preconnect" href="https://fonts.googleapis.com" /><linkrel="preconnect" href="https://fonts.gstatic.com" crossorigin/><linkhref="https://fonts.googleapis.com/css2?family=Big+Shoulders+Display:wght@600;700;800&family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap"
rel="stylesheet"
/>Sin este paso, el tema no se verá correctamente.
Envuelve la aplicación con ThemeProvider y CssBaseline:
import{ThemeProvider,CssBaseline}from'@mui/material';import{AppTheme}from'theme-ceicol';constApp=()=>(<ThemeProvidertheme={AppTheme}><CssBaseline/><TuAplicacion/></ThemeProvider>);Los colores son accesibles vía color="..." en componentes o palette.nombre en sx.
| Nombre semántico | Rol | Propiedades |
|---|---|---|
primary | Azul de marca | .main.light.dark.bg |
secondary / accent | Turquesa — acción y datos | .main.light.bg |
tech | Cian/sky — dataviz, glows y detalles en modo oscuro | .main.light.dark.bg |
success | Verde — éxito | .main.light.bg |
warning | Ámbar — advertencia | .main.light.bg |
error | Rojo — error / destructivo | .main.light.bg |
info | Azul informativo | .main.light.bg |
contrast | Fondo de énfasis (footer, secciones oscuras) | .main.light |
surface | Superficies para temas oscuros de producto | .brand (#0a2530) .slate (#0f172a) .deep (#020617) |
<Buttoncolor="primary">Continuar</Button><Boxsx={{bgcolor: 'accent.bg',color: 'accent.main'}}>Contenido</Box>Tres familias, cada una con rol exclusivo: Big Shoulders Display (títulos), Inter (cuerpo e interfaz), JetBrains Mono (valores técnicos). Se usan con las variantes estándar de MUI.
| Variante | Familia | @375 → @1440 | Uso |
|---|---|---|---|
h1 | Big Shoulders | 40 → 72 | Título de pantalla / hero |
h2 | Big Shoulders | 32 → 38 | Título de sección |
h3 | Big Shoulders | 26 → 30 | Subtítulo |
h4 | Big Shoulders | 20 → 24 | Subtítulo de sección |
h5 | Big Shoulders | 16 → 18 | Título compacto: panel, collapse, tarjeta |
h6 | Big Shoulders | 16 fijo | El más pequeño en display |
body1 | Inter | 16 fijo | Texto de cuerpo |
body2 | Inter | 18 fijo | Lectura destacada |
overline | Inter | 14 fijo | Etiqueta de categoría (uppercase) |
caption | Inter | 14 fijo | Texto de apoyo (labels, fechas) |
La rampa son seis niveles, no cuatro. h5 y h6 no son huecos de MUI que
CEICOL deje sin usar: llenan un salto medido. La razón entre escalones era
regular en 1.24 y saltaba a 1.63 entre h3 y h4, y h4 medía lo mismo
que body2 — el encabezado más pequeño y el cuerpo grande se distinguían solo
por familia y peso.
subtitle1 y subtitle2 no existen en este theme: están fuera de variant=
y TypeScript los rechaza. Usa body1 y caption.
El nivel de encabezado no sale del tamaño.variant elige el aspecto y
component el elemento: variant="h4" sin component pinta un <h4> esté
donde esté en el documento. Pasa el nivel que le toque por su posición:
<Typographyvariant="h4"component="h2">Título de la sección</Typography><Typographyvariant="h1">Territorio, datos y decisiones</Typography><Typographyvariant="body1">Textodecuerpo.</Typography><Typographyvariant="overline">Servicios</Typography>| Token | Tamaño | Para qué |
|---|---|---|
xs | 12 px | Suelo del texto corrido. Captions, metadatos, cualquier cosa que se lea como frase. |
xxs | 10,4 px | Mínimo absoluto, solo microetiqueta: una o dos palabras, mayúsculas, con letter-spacing. |
xxxs | 8,8 px | Deprecado, se retira en 1.0. Migrar a xxs. |
xxxs se va porque 8,8 px no se lee, y porque el sistema lo estaba autorizando
sin querer: su comentario en la fuente decía «~9px» y el espécimen de la
documentación lo pintaba con una frase completa, igual que body. Un producto
lo aplicó a 366 elementos y ninguna comprobación protestó — el verificador
confirma que el valor salga de la escala, no que la escala tenga sentido.
Ese es el criterio general: si un tamaño no se puede enseñar con su uso real, no debería estar publicado.
import{spacingConstants,borderRadius}from'theme-ceicol';Espaciado (spacingConstants):xxs 4px · xtight 6px · xs 8px · xsm 12px · sm 16px · md 24px · lg 40px · xl 80px · xxl 140px
Bordes (borderRadius):xs 4px · sm 6px · md 12px · lg 18px · xl 24px · xxl 54px · round 50% · pill 9999px
<Boxsx={{p: spacingConstants.md,borderRadius: borderRadius.lg}}/>También accesibles desde el tema: theme.customSpacing, theme.customShape.
import{shadows,glassEffect}from'theme-ceicol';Sombras (shadows):sm · md · lg · premium · glow (halo turquesa) · glowTech (glow cian brillante)
Glassmorphism: para superficies translúcidas que se adaptan al tema usa los roles --cei-bg-glass* o el primitivo .cei-glass (ver la sección Temas). El helper JS glassEffect (estático) se mantiene para casos legacy.
<Boxsx={{ ...glassEffect,boxShadow: shadows.premium}}/>Movimiento rápido y directo, acorde a la personalidad de la marca.
import{transitionStyles}from'theme-ceicol';transitionStyles.fast— 150ms. Hovers y microinteracciones.transitionStyles.normal— 250ms. Cambios de estado.transitionStyles.slow— 300ms. Reveals y transiciones mayores.
<Boxsx={{transition: transitionStyles.fast,'&:hover': {transform: 'translateY(-2px)'}}}/>| Variante | Uso |
|---|---|
cei-primary | Acción principal (azul de marca) |
cei-secondary | Acción secundaria (fondo claro con borde) |
cei-ghost | Acción terciaria / cancelar (solo texto) |
cei-destructive | Acciones irreversibles (rojo) |
cei-large | CTA de hero o de sección |
<Buttonvariant="cei-primary">Enviar consulta</Button><Buttonvariant="cei-ghost">Cancelar</Button><Buttonvariant="cei-large">Comenzar ahora</Button>Para facilitar la migración de productos que consumen theme-gaia, el tema también reexpone el vocabulario genérico de Gaia con los valores de CEICOL, de modo que baste cambiar el import:
- Claves de paleta:
tertiary,cta,green,brown,link. - Variantes de botón:
gaia-cta-contained,gaia-cta-outlined,gaia-icon-glass,gaia-icon-outline. - Botones de mapa de región:
gaia-amazonia,gaia-panamazonia,gaia-macroterritorio(círculo con gradiente + etiqueta flotante), recoloreados a la gama CEICOL con tres tonos distinguibles (turquesa / azul / ámbar). - Variantes tipográficas:
h1xxlBold,bodyxlRegular, y el resto de la escala de Gaia.
Estas claves están marcadas como deprecadas; los proyectos nuevos deben usar la API principal de CEICOL.
Las claves de paleta son alias literales: mismo hexadecimal, dígito a dígito, así que el canje no mueve el píxel.
| Deprecado | CEICOL | Nota |
|---|---|---|
cta · green · link | primary | green.button es primary.dark |
tertiary · brown | contrast | brown.light es --cei-fg-muted, que sí voltea con el tema |
Las variantes de botón no son alias: es un componente por otro, y el relleno, el radio o la sombra pueden diferir. Se comparan en pantalla.
| Deprecado | CEICOL |
|---|---|
gaia-cta-contained | cei-primary |
gaia-cta-outlined | cei-secondary |
gaia-icon-glass | cei-icon-glass |
gaia-icon-outline | cei-icon-outline |
gaia-amazonia · gaia-panamazonia · gaia-macroterritorio | sin equivalente — ver abajo |
Las variantes tipográficas tampoco son un renombrado: la escala compat cruza tamaño y peso en un solo nombre, y la API de CEICOL separa los dos ejes. El escalón sale de variant; el peso, de sx:
// antes // ahora<Typographyvariant="h3Medium"><Typographyvariant="h4"sx={{fontWeight: 500}}>Equivalencia por familia y tamaño: display 64/52/40 → h1, 36/32 → h2, 28/24 → h3, 18 → h4; cuerpo 24/18 → body2, 16 → body1, 14 → caption. Cada nombre compat lleva su equivalente en el @deprecated de sus tipos.
MUI declara trece slots de tipografía y CEICOL define nueve. Los cuatro que faltan no son huecos que rellenar: la escala de CEICOL es una jerarquía de cuatro niveles de encabezado, a propósito.
Pero al estar declarados por MUI se pueden escribir, y entonces devuelven los valores de Material Design en la tipografía de cuerpo — encabezados en Inter:
| Hoy devuelve | Usa en su lugar | |
|---|---|---|
h5 | Inter 400 · 24 px | h4 |
h6 | Inter 500 · 20 px | h4 |
subtitle1 | Inter 400 · 16 px | body1 — es casi idéntico, solo cambia el interlineado |
subtitle2 | Inter 500 · 14 px | caption |
Se desactivarán en 1.0 con h5: false en el augment de tipos, para que TypeScript los rechace en vez de dejarlos filtrar Material.
Y si tu producto repite el mismo estilo de texto muchas veces —un título de tarjeta, la cabecera de un panel—, eso no es un nivel que le falte al sistema: es un componente tuyo. Encapsúlalo una vez con la variante que corresponda más el peso que necesites, en vez de repetir el sx.
El @deprecated de los tipos solo lo marca el editor donde hay acceso a propiedad —theme.palette.cta.main, theme.typography.h3Medium—. En las formas de cadena, que son la mayoría de los usos, no avisa nada:
<Typographyvariant="h3Medium"> // sin aviso
<Typographycolor="cta"> // sin aviso
sx={{color: "cta.main"}} // sin aviso
sx={{typography: "h3Medium"}} // sin avisoEs una limitación de TypeScript, no del tema: ahí el valor es un literal dentro de una unión de cadenas, no una referencia a un símbolo. Para cazar esas formas, añade estas reglas al ESLint del producto:
// eslint.config.jsconstCOMPAT_TIPO="h1xxlBold|h1xlBold|h1lgBold|h1Bold|h2xxlSemibold|h2xxlMedium|h2lgMedium|h2Bold|h3xxlSemibold|h3xlRegular|h3xlSemibold|h3xlMedium|h3lgSemibold|h3Medium|bodyxxlRegular|bodyxxlRegularSpacing|bodyxxlSemiboldSpacing|bodyxlBoldSpacing|bodyxlSemibold|bodyxlMedium|bodyxlMediumSpacing|bodyxlRegular|bodylgMedium|bodylgRegular|bodyRegular|bodyRegularSpacing|bodyMedium";"no-restricted-syntax": ["error",{selector: `Literal[value=/^(${COMPAT_TIPO})$/]`,message: "theme-ceicol: tipografía compat deprecada. Se retira en 1.0."},{selector: "Literal[value=/^gaia-(cta-contained|cta-outlined|icon-glass|icon-outline|amazonia|panamazonia|macroterritorio)$/]",message: "theme-ceicol: variante de botón deprecada."},{selector: "JSXAttribute[name.name=/^(color|bgcolor)$/] Literal[value=/^(cta|green|brown|link|tertiary)$/]",message: "theme-ceicol: clave de paleta deprecada."},{selector: "Literal[value=/^(cta|green|brown|link|tertiary)\\.(main|light|dark|button|glass|contrastText)$/]",message: "theme-ceicol: clave de paleta deprecada."},],Buscar el literal entrecomillado en cualquier posición y no solo en el atributo es deliberado: en un producto real conviven variant="h3Medium", variant={"h3Medium"} y sx={{ typography: "h3Medium" }}, y un patrón que solo mire el atributo deja fuera un 22 % de los usos.
gaia-amazonia, gaia-panamazonia y gaia-macroterritoriose retiran sin sustituto en el sistema: un distintivo de territorio es del dominio de un visor geográfico, no de la marca.
Sus degradados eran los tokens del sistema escritos a mano, así que un producto que los necesite se construye el componente con ellos:
// turquesa → accent · azul → primary · ámbar → warning
background: `radial-gradient(54.15% 54.15% at 46% 46%, var(--cei-${tono}-light) 76.92%, var(--cei-${tono}) 100%)`Sobre los tokens crudos (--cei-*), el sistema expone una capa semántica de roles (theme-ceicol/semantic.css). Los componentes consumen roles (el fondo de página, el texto de cuerpo, un borde…) en vez de colores concretos, y un tema no es más que una reasignación de esos roles. Cambiar de tema no toca ningún componente.
@import'theme-ceicol/tokens.css'; /* 1. tokens crudos (valores de marca) */@import'theme-ceicol/semantic.css'; /* 2. roles: mapa claro + bloque [data-theme="dark"] */Activar el tema oscuro con un atributo en <html>:
document.documentElement.setAttribute('data-theme','dark');// o 'light'Para evitar el parpadeo (FOUC), fija el atributo con un script inline en el <head> antes de pintar, leyendo localStorage y/o prefers-color-scheme.
Roles disponibles (úsalos en los componentes en lugar de los tokens crudos):
| Rol | Uso | ¿Voltea? |
|---|---|---|
--cei-bg | Fondo de página | sí |
--cei-bg-raised | Tarjetas, superficies elevadas | sí |
--cei-bg-sunken | Secciones alternadas | sí |
--cei-bg-inverse | Banners / secciones oscuras | no (estable) |
--cei-bg-footer | Footer | sí |
--cei-fg | Texto de cuerpo | sí |
--cei-fg-strong | Títulos / máximo énfasis | sí |
--cei-fg-muted | Texto secundario | sí |
--cei-fg-on-inverse · --cei-fg-on-brand | Texto sobre superficie oscura / sobre marca | estable |
--cei-line · --cei-line-strong | Bordes | sí |
--cei-brand · --cei-brand-hover | Color de marca interactivo | sí |
--cei-elevation-1 · -2 · -3 | Sombras por nivel | sí |
--cei-scrim-soft · --cei-scrim · --cei-scrim-strong · --cei-scrim-heavy | Velos sobre imagen, mapa o detrás de un modal | sí |
Un velo oscurece lo que hay detrás para que el texto encima se lea. Hay cuatro peldaños y voltean con el tema:
| Rol | Para qué |
|---|---|
--cei-scrim-soft | Insinúa separación: hover sobre una tarjeta con imagen |
--cei-scrim | Uso general sobre imagen o mapa |
--cei-scrim-strong | Detrás de un modal o panel |
--cei-scrim-heavy | Texto largo sobre fotografía a sangre; visor a pantalla completa |
.mi-portada__velo { background:var(--cei-scrim-heavy); }En Tailwind son bg-scrim-soft, bg-scrim, bg-scrim-strong y bg-scrim-heavy. Para el extremo transparente de un degradado no hay token ni hace falta: transparent.
Por qué existen. Los tokens se publican como hex, así que rgba(var(--cei-…), .55) no es válido y copiar el valor era la única salida. Medido sobre los cuatro productos Gaia: 242 literales rgba(), 173 de ellos negro o blanco con alfa, y 60 valores de opacidad distintos —con 0.3, 0.30 y .25 escritos de tres formas para el mismo número—. rgba(0,0,0,0.6) aparecía en los cuatro. El sistema hacía lo mismo: .cei-modal__overlay llevaba rgba(15, 23, 42, 0.55), que es el token slate a mano.
Los peldaños salen de los picos reales de uso, y scrim-strong en claro reproduce exacto el velo histórico del modal.
Si el velo lleva tinte de marca o de territorio, eso es del producto, no del sistema — mismo criterio que retiró gaia-amazonia. Pero derívalo de un rol en vez de mezclarlo a mano, así sigue volteando:
background:color-mix(in srgb,var(--cei-brand) 40%, transparent);El hermano del velo. Un velo oscurece todo el fondo; una sombra de texto separa solo las letras, y a veces quieres lo segundo para no apagar la fotografía.
| Rol | Para qué |
|---|---|
--cei-text-shadow-subtle | Texto de interfaz sobre una superficie con ruido |
--cei-text-shadow-media | Texto encima de fotografía o mapa, donde el fondo no se controla |
.portada__titular { text-shadow:var(--cei-text-shadow-media); }Los valores salen de lo que ya estaba a mano, y el reparto explica por qué hacían falta: 0 1px 4px rgba(0,0,0,0.2) era idéntico en Geovisor, Fichas y DMS, el mismo valor inventado tres veces. Un resplandor de mucho difuminado sobre un hero sigue siendo composición del producto — constrúyelo con color-mix sobre un rol.
Vidrio (superficies translúcidas) adaptable:--cei-bg-glass-soft (55%) · --cei-bg-glass (72%) · --cei-bg-glass-strong (85%). Se tiñen del color de superficie del tema activo; también disponible como primitivo .cei-glass.
.panel { background:var(--cei-bg-raised); color:var(--cei-fg); border:1px solid var(--cei-line); }
.flotante { background:var(--cei-bg-glass); backdrop-filter:blur(12px); }Los tonos de marca, acento y estado (
--cei-primary,--cei-accent,--cei-success…) se mantienen estables entre temas; solo voltean superficies, texto, bordes y elevación.
El tema oscuro de MUI usa la misma fuente de verdad: la paleta de AppTheme referencia los roles (background, text, divider apuntan a var(--cei-bg), var(--cei-fg), var(--cei-line)…), con fallback al valor claro. No hay una paleta dark duplicada en JS. Para habilitarlo:
import'theme-ceicol/semantic.css';// 1. carga los roles (claro + oscuro)import{ThemeProvider,CssBaseline}from'@mui/material';import{AppTheme}from'theme-ceicol';<ThemeProvidertheme={AppTheme}><CssBaseline/>{/* aplica background/text desde los roles */}<App/></ThemeProvider>// 2. alternar tema (mismo atributo que el resto del sistema)document.documentElement.setAttribute('data-theme','dark');// o 'light'Los componentes MUI que usan background.*, text.* y divider voltean solos al cambiar data-theme, porque leen las variables CSS vivas. Si no cargas semantic.css, el tema funciona igual en claro (usa los fallbacks). Nota: los overrides de componentes con color de superficie fijo pueden requerir referenciar roles para un dark 100% pulido.
Los mismos tokens (misma fuente de verdad que el tema MUI) están disponibles fuera de React.
Importa la hoja de custom properties y usa las variables --cei-*:
@import'theme-ceicol/tokens.css';
.boton {
background:var(--cei-primary);
color:var(--cei-text-white);
padding:var(--cei-space-sm) var(--cei-space-md);
border-radius:var(--cei-radius-md);
font-family:var(--cei-font-body);
transition:var(--cei-transition-fast);
}
.titulo { font-family:var(--cei-font-display); color:var(--cei-text-heading); }Variables disponibles: colores (--cei-primary, --cei-accent, --cei-tech, --cei-success, --cei-warning, --cei-error, --cei-info, --cei-contrast, --cei-text-*, --cei-background-*, --cei-border-*), superficies dark (--cei-surface-brand, --cei-surface-slate, --cei-surface-deep), tamaños de fuente (--cei-font-size-hero, -h1…-h3, -body, -body-lg, -small, -xs, -xxs, -xxxs), espaciado (--cei-space-xxs 4 · -xtight 6 · -xs 8 · -xsm 12 · -sm 16 · -md 24 · -lg 40 · -xl 80 · -xxl 140), radios (--cei-radius-xs 4 · -sm 6 · -md 12 · -lg 18 · -xl 24 · -xxl 54 · -round · -pill), sombras (--cei-shadow-*, incluye --cei-shadow-glow y --cei-shadow-glow-tech), transiciones (--cei-transition-*) y fuentes (--cei-font-*). No olvides cargar las fuentes vía Google Fonts (ver arriba).
Para soporte de tema oscuro, importa además
theme-ceicol/semantic.cssy consume los roles (--cei-bg,--cei-fg,--cei-line,--cei-bg-glass*…) en lugar de los tokens crudos. Ver la sección Temas.
Usa el preset generado desde los tokens — sin mapear nada a mano:
// tailwind.config.jsmodule.exports={presets: [require('theme-ceicol/tailwind')],content: ['./src/**/*.{astro,html,js,jsx,ts,tsx}'],};Con eso tienes bg-primary, text-fg, p-md, rounded-lg, shadow-premium, etc. Los colores de marca/estado son concretos (soportan opacidad: bg-primary/50); los roles (bg, bg-raised, fg, line, elevation-*…) usan var(--cei-*) y voltean con el tema (requiere cargar semantic.css + data-theme).
Alternativa manual: import { brandColors } from 'theme-ceicol/tokens' y mapea tú mismo.
VS Code autocompleta variables CSS presentes en el workspace. Para que sugiera los --cei-* del paquete, usa una extensión de variables CSS (p. ej. CSS Variable Autocomplete) apuntándola a los archivos ya publicados:
Para Tailwind, la extensión oficial Tailwind CSS IntelliSense autocompleta las clases del preset automáticamente.
El paquete también expone los tokens en el formato W3C Design Tokens (DTCG) en theme-ceicol/tokens.json, generado desde la misma fuente. Es un artefacto estándar, ideal como fuente de verdad para herramientas de diseño y agentes de IA: primitivos con $type/$value, roles semánticos con alias ({color.background.default}) y el valor de tema oscuro en $extensions.
importtokensfrom'theme-ceicol/tokens.json'with{type: 'json'};// tokens.color.primary.main.$value → "#007298"// tokens.semantic.bg.$value → "{color.background.default}" (dark en $extensions)Primitivos de componentes para proyectos CSS puro / Astro, alimentados por los tokens. Los productos React+MUI usan las variantes/estilos equivalentes del tema; estas clases son el espejo para no-MUI.
<!-- requiere tokens.css primero; semantic.css habilita temas claro/oscuro --><linkrel="stylesheet" href="theme-ceicol/tokens.css" /><linkrel="stylesheet" href="theme-ceicol/semantic.css" /><linkrel="stylesheet" href="theme-ceicol/components.css" />O en un .css/.astro:
@import'theme-ceicol/tokens.css';
@import'theme-ceicol/semantic.css';
@import'theme-ceicol/components.css';<buttonclass="cei-btn cei-btn--primary">Enviar</button><buttonclass="cei-btn cei-btn--secondary">Cancelar</button><buttonclass="cei-btn cei-btn--ghost">Terciario</button><buttonclass="cei-btn cei-btn--destructive">Eliminar</button><buttonclass="cei-btn cei-btn--primary cei-btn--large">CTA grande</button><buttonclass="cei-icon-btn" aria-label="Buscar"><svg>…</svg></button><aclass="cei-link" href="#">Ver más</a>Variantes: --primary, --secondary, --ghost, --destructive; tamaños: --large, --sm.
<h1class="cei-h1">Título de pantalla</h1><h2class="cei-h2">Título de sección</h2><pclass="cei-body">Texto de cuerpo.</p><spanclass="cei-overline">Categoría</span>Utilidades: cei-h1…cei-h4, cei-body, cei-body-lg, cei-small, cei-overline.
<divclass="cei-card cei-card--hover">Contenido</div><!-- Superficie translúcida adaptable (claro/oscuro) --><divclass="cei-glass">Panel flotante</div><spanclass="cei-badge">Nuevo</span><spanclass="cei-badge cei-badge--success">Activo</span><divclass="cei-alert cei-alert--error">Algo salió mal.</div>Badge: --accent, --success, --warning, --error, --neutral. Alert: --success, --warning, --error, --info. cei-card y cei-glass se adaptan al tema si semantic.css está cargado.
<labelclass="cei-field"><spanclass="cei-field__label">Correo</span><inputclass="cei-input" type="email" placeholder="name@ceicol.com" /><spanclass="cei-field__help">No lo compartimos.</span></label><textareaclass="cei-textarea"></textarea><selectclass="cei-select"><option>Opción</option></select><labelclass="cei-check"><inputtype="checkbox" /> Acepto</label><labelclass="cei-check"><inputtype="radio" name="g" /> Opción A</label><labelclass="cei-switch"><inputtype="checkbox" /><spanclass="cei-switch__track"></span></label>Estado de error en input: cei-input cei-input--error + cei-field__error.
<divclass="cei-skeleton cei-skeleton--text"></div><divclass="cei-avatar">MR</div><divclass="cei-empty"><divclass="cei-empty__icon">◎</div><divclass="cei-empty__title">Sin resultados</div><pclass="cei-empty__text">Ajusta los filtros e intenta de nuevo.</p></div>Avatar: --sm, --lg. Skeleton: --text, --circle.
<!-- Modal (apertura/cierre por JS del consumidor) --><divclass="cei-modal__overlay"><divclass="cei-modal"><h3class="cei-modal__title">Confirmar</h3><divclass="cei-modal__body">¿Continuar?</div><divclass="cei-modal__actions"><buttonclass="cei-btn cei-btn--ghost">Cancelar</button><buttonclass="cei-btn cei-btn--primary">Aceptar</button></div></div></div><divclass="cei-toast-container"><divclass="cei-toast cei-toast--success">Guardado</div></div><divclass="cei-tabs"><buttonclass="cei-tab cei-tab--active">Uno</button><buttonclass="cei-tab">Dos</button></div><navclass="cei-breadcrumb"><ahref="#">Inicio</a><spanclass="cei-breadcrumb__sep">/</span><spanclass="cei-breadcrumb__current">Actual</span></nav><divclass="cei-pagination"><buttonclass="cei-page cei-page--active">1</button><buttonclass="cei-page">2</button></div><divclass="cei-accordion"><buttonclass="cei-accordion__header">Pregunta</button><divclass="cei-accordion__panel">Respuesta.</div></div><divclass="cei-stepper"><spanclass="cei-step cei-step--done"><spanclass="cei-step__num">1</span></span><spanclass="cei-step__line"></span><spanclass="cei-step cei-step--active"><spanclass="cei-step__num">2</span></span></div><tableclass="cei-table"><thead><tr><th>Nombre</th><th>Estado</th></tr></thead><tbody><tr><td>Item</td><td>Activo</td></tr></tbody></table>Toast: --success, --warning, --error, --info. Tabs/paginación: estado activo con --active. Stepper: --active, --done.
npm run release # patch
npm run release -- minor # o majorEl script sube la versión en package.json, actualiza el comando de instalación de este README, compila y publica un tag vX.Y.Z con el dist incluido, dejando main sin artefactos de build.
Antes de publicar, mueve los cambios de [Unreleased] a la nueva versión en el CHANGELOG.
- CHANGELOG.md — qué cambió en cada versión.
- CONTRIBUTING.md — cómo contribuir, "Definition of Done", Conventional Commits, política de versionado (SemVer) y de deprecación.
- Cambios en
src/tokens/,src/theme.tsysrc/semantic.cssrequieren revisión de un CODEOWNER.
Los cambios no se reflejan tras actualizar: verifica que el tag en el comando de instalación apunte a la versión deseada y limpia la caché de dependencias Git del proyecto consumidor (borra node_modules y el lockfile, reinstala).
El tema se ve sin las fuentes correctas: confirma que el bloque de Google Fonts está en el <head>.