sebs7n-ui0.1.0

Tokens

Color, tipografía, radios y sombras. Los valores salen de `tokens/geist.json` y de `theme.css`.

La paleta, los radios y las sombras por defecto de Tailwind están reseteados: bg-blue-50 o shadow-md no compilan. Solo existen los tokens del paquete.

Los valores viven en tokens/geist.json y se compilan a src/styles/colors.css con npm run tokens; un test falla si el CSS quedó desactualizado. Las tablas de esta página se generan de esos mismos archivos.

Fondos: página, superficie y banda

Son tres roles distintos y cada uno tiene su token. Elegir mal se nota sobre todo en oscuro, donde la página es negro puro:

Token Rol Claro Oscuro
bg-background La página. body (ya lo pone el paquete) y la raíz del AppShell. #ffffff #000000
bg-background-100 La superficie: lo que flota sobre la página. Input, Select, Textarea, popup de menú, Popover, Dialog, Sheet, Card, Alert, Toast, barra mobile del shell. #ffffff #0a0a0a
bg-background-200 El fondo sutil / banda: Sidebar, thead/tfoot de Table, Card variant="subtle", EmptyState. #fafafa #0a0a0a

La regla: si el elemento es la página, bg-background; si flota sobre ella, bg-background-100.

Los valores de oscuro son los de vercel.com medidos con getComputedStyle (contact/sales, 2026-09-22): --ds-background-100: hsla(0,0%,4%) = #0a0a0a para las superficies y --ds-background-200: hsla(0,0%,0%) = #000 para la página. background-200 es siempre el tono que no es el de la página: en claro baja a #fafafa, en oscuro no puede bajar de #000 y sube a #0a0a0a. Por eso en oscuro coincide con background-100: Geist tiene dos fondos por tema, no tres.

Color

Diez pasos por familia, de 100 (el más claro en tema claro) a 1000. La convención de Geist: 100–400 son fondos, 500–700 son bordes y elementos, 800–1000 son texto. El contraste de gray-900 sobre cualquier fondo de la misma familia llega a AA.

gray

Paso Claro Oscuro
gray-100 #f2f2f2 #1a1a1a
gray-200 #ebebeb #1f1f1f
gray-300 #e6e6e6 #292929
gray-400 #eaeaea #2e2e2e
gray-500 #c9c9c9 #454545
gray-600 #a8a8a8 #878787
gray-700 #8f8f8f #8f8f8f
gray-800 #7d7d7d #7d7d7d
gray-900 #4d4d4d #a0a0a0
gray-1000 #171717 #ededed

gray-alpha

Paso Claro Oscuro
gray-alpha-100 #0000000d #ffffff12
gray-alpha-200 #00000015 #ffffff17
gray-alpha-300 #0000001a #ffffff21
gray-alpha-400 #00000014 #ffffff24
gray-alpha-500 #00000036 #ffffff3d
gray-alpha-600 #0000003d #ffffff82
gray-alpha-700 #00000070 #ffffff8a
gray-alpha-800 #00000082 #ffffff78
gray-alpha-900 #000000b3 #ffffff9c
gray-alpha-1000 #000000e8 #ffffffeb

blue

Paso Claro Oscuro
blue-100 #f0f7ff #06193a
blue-200 #eaf4ff #022248
blue-300 #e0efff #002f62
blue-400 #cce7ff #003771
blue-500 #97ccff #004287
blue-600 #51aeff #0090ff
blue-700 #0070f7 #0071f6
blue-800 #005edc #005fd8
blue-900 #0064e2 #50a8ff
blue-1000 #002453 #ebf6ff

red

Paso Claro Oscuro
red-100 #ffeef0 #330a11
red-200 #ffe9ea #440d13
red-300 #ffe4e5 #5d0e17
red-400 #ffd8d7 #6f101b
red-500 #ffb5b6 #88151f
red-600 #ff6a6e #f32e40
red-700 #fc0035 #f13242
red-800 #e70022 #e2162a
red-900 #d60020 #ff5e63
red-1000 #46000c #ffeaed

amber

Paso Claro Oscuro
amber-100 #fff6e1 #291800
amber-200 #fff4d4 #331b00
amber-300 #fff1c8 #4f2900
amber-400 #ffdd84 #573200
amber-500 #ffc85e #6c4100
amber-600 #ffaa00 #e99c00
amber-700 #ffb200 #ffb200
amber-800 #ff9900 #ff9900
amber-900 #a64f00 #ff9900
amber-1000 #541c00 #fff3d9

green

Paso Claro Oscuro
green-100 #ecfdec #00250a
green-200 #e5fce7 #003110
green-300 #d3fad1 #003814
green-400 #b9f5bc #004616
green-500 #82eb8d #00661d
green-600 #4ce15e #009431
green-700 #28a948 #00ab3e
green-800 #279141 #009335
green-900 #107d32 #00ca52
green-1000 #00370d #daffe5

teal

Paso Claro Oscuro
teal-100 #dffffb #00211b
teal-200 #ddfef6 #002922
teal-300 #ccf9f1 #003b33
teal-400 #b1f7ec #003f35
teal-500 #52f0db #005f53
teal-600 #00e2c4 #009885
teal-700 #00a694 #00a794
teal-800 #008d7d #008d7d
teal-900 #007a6e #00c9b5
teal-1000 #003d34 #cefff5

purple

Paso Claro Oscuro
purple-100 #f9f0ff #290c33
purple-200 #f9f1ff #341142
purple-300 #f5e8ff #47185e
purple-400 #f1d9ff #541a76
purple-500 #dda9ff #642290
purple-600 #c77dff #9440d5
purple-700 #9f00f4 #9440d5
purple-800 #8400cd #7d2bba
purple-900 #7c00c9 #c472fb
purple-1000 #2e004d #faedff

pink

Paso Claro Oscuro
pink-100 #ffeaf5 #310d1e
pink-200 #ffeaf2 #420c25
pink-300 #ffe0eb #571032
pink-400 #ffd5e1 #5d0c34
pink-500 #fdb3cc #76063f
pink-600 #f97ea7 #b90056
pink-700 #f22782 #f12b82
pink-800 #e4106e #e6006e
pink-900 #c41562 #ff518d
pink-1000 #460523 #ffeaf4

brand no está en la tabla porque no tiene valores fijos: se deriva de las tres variables de la app. Ver Theming.

Tipografía

Las utilidades de Geist. cn() las entiende como tamaño de fuente, así que conviven con text-gray-900.

Utilidad Tamaño Interlineado Peso Tracking
text-heading-72 72px 72px 400 -4.32px
text-heading-64 64px 64px 400 -3.84px
text-heading-56 56px 56px 450 -3.36px
text-heading-48 48px 56px 450 -2.88px
text-heading-40 40px 48px 450 -2.4px
text-heading-32 32px 40px 500 -1.28px
text-heading-24 24px 32px 500 -0.96px
text-heading-20 20px 26px 550 -0.4px
text-heading-16 16px 24px 600 -0.32px
text-heading-14 14px 20px 600 -0.28px
text-button-16 16px 20px 500 0
text-button-14 14px 20px 500 0
text-button-12 12px 16px 500 0
text-label-20 20px 32px 400 0
text-label-18 18px 20px 400 0
text-label-16 16px 20px 400 0
text-label-14 14px 20px 400 0
text-label-13 13px 16px 400 0
text-label-12 12px 16px 400 0
text-label-14-mono 14px 20px 400 0
text-label-13-mono 13px 20px 400 0
text-label-12-mono 12px 16px 400 0
text-copy-24 24px 36px 400 0
text-copy-20 20px 36px 400 0
text-copy-18 18px 28px 400 0
text-copy-16 16px 24px 400 0
text-copy-14 14px 20px 400 0
text-copy-13 13px 18px 400 0
text-copy-14-mono 14px 20px 400 0
text-copy-13-mono 13px 18px 400 0

Los heading llevan el peso corregido ópticamente, no 600 fijo. Un mismo peso no se ve igual a 14px que a 64px: cuanto más grande el cuerpo, más gruesos se leen los trazos, y 600 a 64px sale plomizo. Los números salen de medir vercel.com (computed style, 2026-09-22); los pasos que no aparecían ahí se interpolan en la misma curva.

No lo pises con font-semibold: para eso está el paso de arriba de la escala. Y necesita Geist como fuente variable (rango 100 900); con una estática los pesos intermedios se redondean y la corrección se pierde.

Cuándo usar cada familia:

Familia Para qué
heading-* Títulos. Peso óptico, tracking negativo.
copy-* Párrafos y texto corrido. Interlineado holgado.
label-* Etiquetas, celdas, metadatos. Interlineado ajustado, peso 400.
button-* Texto dentro de controles. Peso 500.
*-mono Código, IDs, importes. Geist Mono.

Radios

Utilidad Valor
rounded-xs 4px
rounded-sm 6px
rounded-md 6px
rounded-lg 12px
rounded-xl 12px
rounded-2xl 16px
rounded-3xl 16px
rounded-4xl 9999px

rounded-md (6px) es el radio del sistema: botones, inputs, ítems de menú. rounded-xl (12px) es el de las tarjetas. rounded-full solo en Badge, en avatares y en Button shape="pill".

Sombras

Utilidad Dónde
shadow-tooltip Tooltip.
shadow-menu DropdownMenu, Select, Combobox, Popover.
shadow-modal Dialog, AlertDialog, Sheet.

Las tres terminan en un anillo de 1px que en oscuro reemplaza al borde. No hay sombras decorativas: una sombra en este sistema significa «esto flota», y solo flotan los tres tipos de superficie de arriba.

Foco y movimiento

Utilidad Dónde
focus-visible:focus-ring Controles: botones, ítems de menú, tabs, toggles. Anillo de 2px en brand-700 con hueco.
focus:focus-border Campos: Input, Textarea, Select, Combobox. Tiñe el borde y agrega un halo.
focus:focus-border-error Lo mismo, en rojo, cuando el campo tiene aria-invalid.
transition-control 150 ms, ease, solo color / fondo / borde / sombra / opacidad.
animate-skeleton El latido del Skeleton.

Todas las animaciones pasan por motion-reduce, además del reset global del paquete.