supafast-ui · sub-skill: TOKENS
Todo vive en apps/performancetv/src/index.css. Tailwind v4 CSS-first: tokens crudos en
:root, mapeados a utilidades en @theme inline. No hay tailwind.config.js.
Imports (orden importa)
@import "tailwindcss";
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "@fontsource-variable/geist";
@custom-variant dark (&:is(.dark *));
Paleta semántica (oklch, monocromo)
Defínela en :root y mapéala en @theme inline como --color-<nombre>. Nunca uses el oklch
crudo en componentes; usa la utilidad (bg-background, text-muted-foreground, etc.).
:root {
--background: oklch(1 0 0); --foreground: oklch(0.205 0 0);
--card: oklch(1 0 0); --card-foreground: oklch(0.205 0 0);
--popover: oklch(1 0 0); --popover-foreground: oklch(0.205 0 0);
--primary: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0); --secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0); --muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0); --accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--chart-series: oklch(0.59 0.23 17);
--border: oklch(0.922 0 0); --input: oklch(0.922 0 0); --ring: oklch(0.708 0 0);
}
Mapeo (resumen): cada token anterior → --color-foo: var(--foo) dentro de @theme inline.
Escala de radios (clave del look)
--app-radius-xs: 0.125rem; --app-radius-sm: 0.25rem; --app-radius-md: 0.375rem;
--app-radius-lg: 0.5rem; --app-radius-xl: 0.75rem; --app-radius-2xl: 1rem;
--radius-control: var(--app-radius-md); /* inputs/selects compactos */
--radius-surface: var(--app-radius-xl); /* cards/superficies */
--radius-panel: var(--app-radius-2xl); /* paneles/diálogos */
Uso en clases: controles rounded-lg, badges pill rounded-4xl, paneles rounded-2xl.
Acentos (hex, solo estados semánticos)
Grises neutral-50…900 + acentos puntuales. Úsalos para estados (éxito/alerta/error/info),
nunca como color de marca decorativo:
red-{50,300,400,600} amber-{50,600} emerald-{50,600,700}
blue-{50,500,600} rose-{50,600}
Tipografía
- Fuente:
Geist(variable) sans,Geist Monopara mono.html { font-family:'Geist' }. - Base
font-size: 15px(no 16). Escala:text-xs .75 / sm .875 / base 1 / lg 1.125 / xl / 2xl 1.5 / 3xl 1.875rem. - Pesos:
normal 400 / medium 500 / semibold 600 / bold 700. Por defecto medium/semibold. - Tracking: títulos a veces
tracking-tight(-.025em).
Base layer
@layer base {
* { @apply border-border outline-ring/50; }
html { font-family: 'Geist', sans-serif; }
body { @apply bg-background text-foreground; }
}
Reglas
- Añadir un token nuevo = (1) declararlo en
:root, (2) exponerlo en@theme inline. - Dark mode vía
.dark *con@custom-variant dark; declara overrides en.dark { … }si hacen falta. - Nunca hardcodees oklch/hex en TSX si existe el token equivalente.