kit v9 · f417275 · base/tokens.css
Tokens del design system
Todo color, tamaño, espacio, radio y tiempo de los sitios del grupo sale de una variable CSS declarada en base/tokens.css. Esta página lista los 47 tokens del archivo real, con su valor en tema claro, su valor en tema oscuro cuando cambia, para qué sirve cada uno y cómo se usa en código. Los swatches son vivos: pintan con la variable, no con el hex.
Regla cero: nunca un hex a mano en un sitio del grupo. Si necesitas un color que el kit no da, el diseño está mal planteado, no el kit.
Cómo cargar los tokens
Los tokens llegan con la hoja base/tokens.css del CDN del grupo, siempre por digest inmutable. La marca se aplica al final con brands/<marca>/tokens.css, que solo re-tiñe el acento. El orden importa: fuentes, tokens base, chrome, componentes, marca.
<link rel=stylesheet href=".../v9/<digest>/fonts/css/ibm-plex-sans.css">
<link rel=stylesheet href=".../v9/<digest>/fonts/css/jetbrains-mono.css">
<link rel=stylesheet href=".../v9/<digest>/base/tokens.css">
<link rel=stylesheet href=".../v9/<digest>/base/chrome.css">
<link rel=stylesheet href=".../v9/<digest>/base/components.css">
<link rel=stylesheet href=".../v9/<digest>/brands/cis/tokens.css">
<script src=".../v9/<digest>/chrome.js" defer></script>Tinta y papel
Cinco neutros forman la base: tres tintas para texto y dos papeles para fondo. En tema claro ambos papeles son blancos y la jerarquía la hacen los bordes; en oscuro los papeles sí se separan.
| Token | Claro | Oscuro | Para qué sirve | Uso |
|---|---|---|---|---|
| --ink | #0e1418 | #f3f1ea | Texto principal, titulares, iconos. | color:var(--ink) |
| --ink-muted | #5b6672 | #a9a69d | Texto secundario: descripciones, metadatos, labels. | color:var(--ink-muted) |
| --ink-soft | #a3acb5 | #6b6863 | Texto terciario: placeholders, pies, notas al margen. | color:var(--ink-soft) |
| --paper | #ffffff | #0a0a0a | Fondo de página. | background:var(--paper) |
| --paper-raised | #ffffff | #111110 | Fondo de superficies elevadas: cards, nav, paneles. | background:var(--paper-raised) |
<div style="border:1px solid var(--line);background:var(--paper-raised)">
<div style="color:var(--ink)">Titular en tinta plena</div>
<div style="color:var(--ink-muted)">Descripción en tinta atenuada</div>
<div style="color:var(--ink-soft)">Nota al pie en tinta suave</div>
</div>OJO · El comentario del archivo de marca menciona un papel crema #f6f5f1, pero el token desplegado declara #ffffff y la marca CIS no lo sobreescribe. Documenta y usa lo que declara el CSS vivo, no el comentario.
Líneas
El separador dominante de la casa es el borde de 1 píxel, no la sombra. Hay dos pesos: la línea normal para casi todo y la línea fuerte para reglas de énfasis, cabeceras de tabla y filetes editoriales.
| Token | Claro | Oscuro | Para qué sirve | Uso |
|---|---|---|---|---|
| --line | #d4d1c9 | #2a2a27 | Borde estándar de cards, tablas, inputs y separadores. | border:1px solid var(--line) |
| --line-strong | #14181c | #eaeae4 | Regla de énfasis: cabecera de tabla, filete de sección, botón ghost. | border-bottom:1px solid var(--line-strong) |
<div style="border-bottom:1px solid var(--line)">Separador estándar</div>
<div style="border-bottom:1px solid var(--line-strong)">Regla de énfasis</div>Acento y marca
El acento es el único color que cambia entre marcas: cada sitio carga brands/<marca>/tokens.css y esa hoja sobreescribe solo --accent y --accent-soft. En CIS el acento es dual por tema: navy en claro, verde claro en oscuro. El resto de la paleta no cambia nunca entre marcas.
| Token | Claro (CIS) | Oscuro (CIS) | Para qué sirve | Uso |
|---|---|---|---|---|
| --accent | #1e3a5f | #7fc598 | Color de marca: links activos, hover de botón, énfasis en titulares, eyebrow. | color:var(--accent) |
| --accent-soft | #e7edf4 | #12261a | Fondo teñido de marca: chips, resaltados suaves, fondos de icono. | background:var(--accent-soft) |
Énfasis en titulares por color, no cursiva
chip teñido<span class=eyebrow>eyebrow con acento</span>
<h2>Énfasis en titulares <em>por color</em>, no cursiva</h2>
<span style="background:var(--accent-soft);color:var(--accent);
border:1px solid var(--accent)">chip teñido</span>NOTA · h1 em, h2 em, h3 em ya vienen mapeados a var(--accent) con font-style:normal desde la base: el énfasis de titular se marca con <em> y el kit pone el color.
Estado
Tres colores semánticos, iguales en claro y oscuro: el kit no los redefine en tema oscuro. El estado siempre va acompañado de texto, nunca es solo color.
| Token | Valor (ambos temas) | Para qué sirve | Uso |
|---|---|---|---|
| --ok | #0b7e59 | Éxito, en línea, verificado. | color:var(--ok) |
| --warn | #b45309 | Advertencia, degradado, pendiente. | color:var(--warn) |
| --err | #9a1b1b | Error, en falla, rechazado. | color:var(--err) |
<span class="badge badge--ok">en línea</span>
<span class="badge badge--warn">degradado</span>
<span class="badge badge--err">en falla</span>
<span class="badge">neutro</span>Superficie inversa
Para bloques oscuros dentro de una página clara (footers editoriales, franjas de cierre) existe una mini paleta propia. Así el bloque no depende del tema: se ve oscuro en claro y apenas más claro que el fondo en oscuro.
| Token | Claro | Oscuro | Para qué sirve | Uso |
|---|---|---|---|---|
| --surface-inverse | #0c1116 | #17171a | Fondo del bloque inverso. | background:var(--surface-inverse) |
| --on-inverse | #c7cdd4 | #d4d0c5 | Texto corriente sobre superficie inversa. | color:var(--on-inverse) |
| --on-inverse-strong | #ffffff | #ffffff (no cambia) | Titulares y énfasis sobre superficie inversa. | color:var(--on-inverse-strong) |
<div style="background:var(--surface-inverse)">
<div style="color:var(--on-inverse-strong)">Bloque inverso</div>
<div style="color:var(--on-inverse)">Texto corriente</div>
</div>Fuentes
Dos familias, self-hosted en /v9/<digest>/fonts/, nunca desde un CDN externo ni Google Fonts (CANON y ADR-021). La sans lleva la voz principal; la mono es la voz secundaria de la casa: eyebrows, labels, cifras, código.
| Token | Valor | Para qué sirve | Uso |
|---|---|---|---|
| --font-sans | "IBM Plex Sans", sans-serif | Todo el texto de interfaz y prosa. | font-family:var(--font-sans) |
| --font-mono | "JetBrains Mono", monospace | Eyebrows, labels uppercase, cifras, código, wordmark. | font-family:var(--font-mono) |
<p style="font-family:var(--font-sans)">IBM Plex Sans lleva la prosa.</p>
<p style="font-family:var(--font-mono)">JetBrains Mono lleva cifras.</p>NOTA · El body de la base ya activa font-feature-settings: "ss01", "ss02", "tnum", "cv11": cifras tabulares y alternates de Plex vienen de fábrica.
Escala tipográfica
Siete pasos con nombre por función, no por tamaño. Los dos titulares son fluidos con clamp(); el resto es fijo. Cada token trae en el archivo su interlineado y tracking recomendados, anotados aquí.
| Token | Valor | Para qué sirve | Uso |
|---|---|---|---|
| --fs-hero | clamp(34px, 5vw, 60px) | Titular hero de portada. Peso 800, lh .98, ls -.035em. | font-size:var(--fs-hero) |
| --fs-section | clamp(28px, 3.6vw, 44px) | Título de sección. lh 1.05, ls -.025em. | font-size:var(--fs-section) |
| --fs-prose | 15px | Prosa larga. lh 1.6, max-width 68ch (clase .prose lo empaqueta). | font-size:var(--fs-prose) |
| --fs-body | 14px | Base de interfaz, ya aplicada al body. lh 1.45. | font-size:var(--fs-body) |
| --fs-small | 13.5px | Links de nav, botones, texto secundario compacto. | font-size:var(--fs-small) |
| --fs-micro | 11.5px | Wordmark, eyebrows. Siempre mono uppercase. | font-size:var(--fs-micro) |
| --fs-mono-label | 10.5px | h4 de footer, base legal, tags de card. Mono UPPERCASE. | font-size:var(--fs-mono-label) |
Prosa larga a 15 píxeles con interlineado 1.6 y ancho máximo de 68 caracteres, empaquetada en la clase .prose del kit.
<h1 style="font-size:var(--fs-hero);font-weight:800;line-height:.98">Hero</h1>
<h2 style="font-size:var(--fs-section);line-height:1.05">Título de sección</h2>
<p class=prose>Prosa larga...</p>
<small style="font-size:var(--fs-small)">Texto small</small>
<span style="font:var(--fs-micro) var(--font-mono);text-transform:uppercase;
letter-spacing:var(--track-eyebrow)">micro · eyebrow</span>Tracking mono
Tres anchos de tracking para la voz mono. A mayor tracking, más pequeño y más ceremonial el texto. Siempre con text-transform:uppercase.
| Token | Valor | Para qué sirve | Uso |
|---|---|---|---|
| --track-eyebrow | .18em | Eyebrows y kickers (la clase .eyebrow lo aplica). | letter-spacing:var(--track-eyebrow) |
| --track-label | .12em | Labels de card, cabeceras de tabla, stats. | letter-spacing:var(--track-label) |
| --track-legal | .1em | Base legal del footer, pies de página. | letter-spacing:var(--track-legal) |
<span class=eyebrow>eyebrow</span> <!-- ya trae --track-eyebrow -->
<span style="letter-spacing:var(--track-label)">label</span>
<span style="letter-spacing:var(--track-legal)">legal</span>Espaciado
Escala de ocho pasos tomada de los sitios vivos. No es geométrica pura: crece de a 4 y luego de a 8. Úsala para padding, margin y gap; un espacio fuera de escala es un olor de maqueta.
--space-1: 8px --space-2: 12px --space-3: 16px --space-4: 24px
--space-5: 32px --space-6: 40px --space-7: 48px --space-8: 56px
.panel { padding: var(--space-4); }
.seccion { margin-bottom: var(--space-7); }
.grid { gap: var(--space-3); }Radios
La geometría de la casa es recta. Las superficies (cards, paneles, modales) van a radio cero; los 6 píxeles son solo para controles (inputs, selects); la píldora es solo para chips de usuario y login. Cualquier otra esquina redondeada es ajena al sistema.
| Token | Valor | Para qué sirve | Uso |
|---|---|---|---|
| --radius | 0 | Superficies: cards, paneles, botones. El cero es decisión, no omisión. | border-radius:var(--radius) |
| --radius-ctl | 6px | SOLO controles de formulario. | border-radius:var(--radius-ctl) |
| --radius-pill | 999px | SOLO pills: chip de usuario, login. | border-radius:var(--radius-pill) |
.card { border-radius: var(--radius); } /* superficie: recta */
.input { border-radius: var(--radius-ctl); } /* control: 6px */
.chip { border-radius: var(--radius-pill); } /* pill: 999px */Sombras y transiciones
Las dos sombras existen como token y valen none a propósito: la jerarquía se construye con bordes y fondos, no con elevación. Referéncialas igual: si el sistema alguna vez introduce sombra, tu código la hereda solo. Las transiciones tienen tres tiempos.
| Token | Valor | Para qué sirve | Uso |
|---|---|---|---|
| --shadow | none | Sombra de superficies. Deliberadamente ninguna. | box-shadow:var(--shadow) |
| --shadow-modal | none | Sombra de modales. Deliberadamente ninguna. | box-shadow:var(--shadow-modal) |
| --t-fast | .12s | Micro interacción: hover de botón y link. | transition:color var(--t-fast) |
| --t-base | .15s | Transición estándar: bordes de card, fondos. | transition:border-color var(--t-base) |
| --t-slow | .2s | Movimientos mayores: paneles, despliegues. | transition:transform var(--t-slow) |
.card {
border: 1px solid var(--line);
box-shadow: var(--shadow); /* none, a propósito */
transition: border-color var(--t-base);
}
.card:hover { border-color: var(--accent); }Layout y grilla
Un contenedor canónico de 1240 píxeles con padding lateral que baja a 20 en móvil (media query a 640px dentro del propio tokens.css). La grilla de referencia es de columnas de 96 con calles de 24. La clase .container del kit ya empaqueta contenedor y padding.
| Token | Valor | Para qué sirve | Uso |
|---|---|---|---|
| --container | 1240px | Ancho máximo del contenido. | max-width:var(--container) |
| --pad-x | 32px (20px si ≤640px) | Padding lateral del contenedor. El kit lo baja solo en móvil. | padding-inline:var(--pad-x) |
| --grid-col | 96px | Ancho de columna de la grilla de referencia. | grid-template-columns:repeat(auto-fill,var(--grid-col)) |
| --grid-gap | 24px | Calle entre columnas. | gap:var(--grid-gap) |
<div class=container> <!-- max-width:var(--container) + padding var(--pad-x) -->
<div style="display:grid;
grid-template-columns:repeat(auto-fill,var(--grid-col));
gap:var(--grid-gap)">...</div>
</div>Tema oscuro
El tema se resuelve en tres capas, todas sobre el elemento <html>:
1 · Automático: si el sistema pide oscuro y no hay override, aplica el bloque @media (prefers-color-scheme: dark) con selector :root:not([data-theme="light"]).
2 · Explícito: :root[data-theme="dark"] fuerza oscuro, data-theme="light" fuerza claro.
3 · Persistencia: chrome.js lee y escribe la clave group-theme en localStorage y estampa el atributo; el bootstrap anti-flash inline en el <head> lo aplica antes de que carguen las hojas.
OJO · Los selectores son de :root: poner data-theme=dark en un div interior NO cambia nada. El tema es por documento, no por bloque; para un bloque oscuro dentro de página clara usa la superficie inversa.
Qué se redefine en oscuro
| Token | Claro | Oscuro |
|---|---|---|
| --ink | #0e1418 | #f3f1ea |
| --ink-muted | #5b6672 | #a9a69d |
| --ink-soft | #a3acb5 | #6b6863 |
| --paper | #ffffff | #0a0a0a |
| --paper-raised | #ffffff | #111110 |
| --line | #d4d1c9 | #2a2a27 |
| --line-strong | #14181c | #eaeae4 |
| --accent (CIS) | #1e3a5f | #7fc598 |
| --accent-soft (CIS) | #e7edf4 | #12261a |
| --surface-inverse | #0c1116 | #17171a |
| --on-inverse | #c7cdd4 | #d4d0c5 |
| color-scheme | light | dark |
NO se redefinen en oscuro: --warn, --err, --ok, --on-inverse-strong, y ningún token de tipografía, espaciado, radio, sombra, transición ni layout. Si tu diseño depende de que un color de estado cambie con el tema, está fuera del sistema.
<!-- bootstrap anti-flash, inline en el head ANTES de los stylesheets -->
<script>
(function(){try{var t=localStorage.getItem("group-theme");
if(t==="dark"||t==="light")document.documentElement.setAttribute("data-theme",t);
}catch(_){}})();
</script>
<!-- el toggle real lo pone chrome.js con [data-theme-toggle] -->
<button class="gr-nav__theme" data-theme-toggle aria-label="Cambiar tema">...</button>Los que NO debes usar
Variables que verás en el código del ecosistema y que no son API pública del sistema:
| Variable | Qué es | Qué hacer |
|---|---|---|
| --cis-* (legacy) | Sistema viejo de CIS: Inter + verdes #0f5f2d. El propio archivo de marca ordena no propagarlo. | Migrar a los tokens v9. No copiar de sitios sin migrar. |
| --cis-accent, --cis-link | Alias de compatibilidad que la marca CIS apunta a var(--accent) para código antiguo. | En código nuevo usa --accent directo. |
| --card-color | Propiedad interna de .card y .feature-card en components.css: parametriza el color de UNA card. | Sobreescríbela solo en el elemento card; nunca la uses como token global. |
| Hex literales | Cualquier #rrggbb escrito a mano en un sitio del grupo. | Prohibido. Todo color sale de un token; el linter del canon lo bloquea. |
| Google Fonts / CDN externo | Cargar Plex o cualquier fuente desde fuera del grupo. | Prohibido (CANON, ADR-021). Las fuentes viven en /v9/<digest>/fonts/. |
/* mal: hex a mano y alias de compatibilidad */
a { color: #1e3a5f; }
a { color: var(--cis-link); }
/* bien: el token del sistema, que además cambia solo con el tema */
a { color: var(--accent); }