# Qué primitiva usar

Antes de escribir markup a mano en una página, revisá esta tabla. Si tu caso
no está, preguntá antes de inventar un patrón nuevo — probablemente ya hay
uno.

| Situación | Usar | No usar |
|---|---|---|
| Lista de registros en mobile (no caben columnas) | `DashboardListRow` (`components/dashboard-page.tsx`) | `<table>` a mano, `<div>` sueltos con bordes |
| Tabla en desktop con columnas que sí caben | `ui/table.tsx` | `<table>` HTML crudo |
| Buscador + filtros + acción de un listado | `DashboardToolbar` (`components/dashboard-page.tsx`) | Reimplementar el flex a mano en cada página |
| Encabezado de página con filtros propios | `DashboardPageIntro` con prop `filters` | Meter los filtros como `children` sueltos |
| Carga de página completa | Composición de `ui/skeleton.tsx` (esqueleto con la forma real del contenido) | `Loader2` centrado de página completa |
| Carga corta dentro de una sección/botón | `Loader2` chico inline | Bloquear toda la pantalla |
| Estado vacío | `DashboardEmptyState` o `ui/empty-state.tsx` | Texto suelto centrado |
| Estado de error de carga | `ui/error-state.tsx` | `alert()`, texto rojo suelto |
| Badge de estado de OT | `ui/badge.tsx` variante `estado` | Clases `.estado-*` de `globals.css` (deprecadas) |
| Avatar / inicial de usuario | `ui/avatar.tsx` | `<span>` con iniciales armado a mano |
| Selects | `ui/select.tsx` | `<select>` nativo |
| Checkbox | `ui/checkbox.tsx` | `<input type="checkbox">` nativo |
| Tabs | `ui/tabs.tsx` | Botones con estado manual simulando tabs |
| Menú contextual (⋮) | `ui/dropdown-menu.tsx` | `<div>` posicionado a mano con `absolute` |
| Separador visual | `ui/separator.tsx` | `<hr>` o `border-t` suelto repetido |
| Panel lateral / modal deslizante | `ui/sheet.tsx` | Drawer hecho a mano con `fixed` + z-index |
| Tooltip | `ui/tooltip.tsx` | `title=""` del HTML nativo |

## Prohibido fuera de `ui/`

Estas clases están permitidas dentro de la implementación de los componentes
en `src/components/ui/` (donde sí se define la escala visual), pero no en
`src/app/` ni en el resto de `src/components/`:

- `rounded-2xl` / `rounded-3xl` sueltos — usar los tamaños que ya exponen los
  componentes (`Card`, `Button`, etc.), no reimplementar el radio a mano.
- `transition-all` — siempre listar las propiedades que transicionan
  (`transition-colors`, `transition-transform`, etc.), nunca todas.
- `shadow-none` sobre `Card` — si no querés sombra, no es una `Card`.
- `font-extrabold` / `font-black` — el peso máximo del sistema es 600/700 vía
  `font-bold`; escribir estas clases no rompe nada (la escala las aplana) pero
  es ruido, señala que alguien está tratando de "gritar" más de lo que el
  sistema permite.
- Colores crudos de Tailwind (`bg-amber-100`, `text-emerald-800`, etc.) —
  usar los tokens semánticos (`bg-warning-soft`, `text-success`, etc.).
- `Loader2` centrado ocupando toda la página — usar un skeleton compuesto.
- `<select>` / `<input>` nativos crudos en `src/app/` — usar los componentes
  de `ui/`.

Si encontrás un caso legítimo que rompe alguna de estas reglas, señalalo en
vez de silenciarlo — puede ser una primitiva que todavía falta.
