Theme System Contract

Estado: base implementada

Fecha: 2026-05-05

Objetivo

El tema visual de OPS debe poder cambiarse por usuario sin duplicar pantallas ni reescribir componentes. La UI se apoya en tokens CSS y se activa con data-theme en el elemento html.

Temas Iniciales

  • minimal: tema principal, sobrio y desaturado.
  • classic: variante clara mas neutra y corporativa.
  • contrast: variante clara con mayor contraste funcional.
  • dark: variante oscura para uso prolongado.
  • catalyst: variante clara tipo app shell SaaS, con mas separacion de superficies y acento de producto.
  • catalyst-warm: variante clara derivada de catalyst, con base crema, sidebar arena y acento terracota.

El valor antiguo light se normaliza a minimal.

Resolucion

La prioridad de resolucion queda preparada asi:

  1. Preferencia del usuario: app_users.metadata.preferences.theme.
  2. Valor local inmediato en localStorage.ops_theme para evitar parpadeos al arrancar.
  3. Fallback del producto: minimal.

En fases posteriores se podra anadir preferencia por workspace sin cambiar el contrato de componentes.

Tokens

Los componentes deben leer tokens en lugar de colores directos:

  • --c-bg
  • --c-surface
  • --c-surface-alt
  • --c-surface-soft
  • --c-text
  • --c-text-muted
  • --c-border
  • --c-border-strong
  • --c-accent
  • --c-success
  • --c-warning
  • --c-danger
  • --radius-sm
  • --radius-md
  • --radius-lg
  • --button-radius
  • --button-py
  • --button-px
  • --button-font-weight
  • --button-min-height
  • --card-radius
  • --card-padding
  • --table-header-size
  • --table-header-tracking
  • --table-cell-py
  • --table-cell-px
  • --shadow-1
  • --shadow-2

API

GET /api/me/preferences

Devuelve las preferencias normalizadas del usuario autenticado.

PUT /api/me/preferences

Actualiza preferencias permitidas. En esta fase solo acepta:


{ "theme": "minimal" }

Valores validos: minimal, classic, contrast, dark, catalyst, catalyst-warm.

UI

El selector global vive en la barra superior y la pantalla Mi cuenta muestra el mismo control con texto de confirmacion.

Cuando el usuario cambia el tema:

  1. Se aplica inmediatamente a document.documentElement.
  2. Se guarda en localStorage.
  3. Se persiste en app_users.metadata.preferences.theme.

Regla De Implementacion De Temas

Un tema nuevo no se considera completo si solo cambia la paleta.

Cada variante debe revisar tambien:

  • tipografia base (--font-ui, --font-display, --font-mono)
  • jerarquia de titulos, labels y numerica cuando aplique
  • radios y sombras si forman parte del caracter visual del tema
  • contraste de lectura en sidebar, top bar, cards, tablas y modales

Ejemplo practico:

  • catalyst y sus variantes deben incluir ajustes de tipografia y no solo cambio de color, para que el tema tenga identidad visual real.
  • Las variantes deben poder cambiar densidad y forma de botones, tarjetas y tablas mediante tokens, no mediante parches dispersos por pantalla.

Reglas Para Nuevos Componentes

  1. No hardcodear colores funcionales si existe token.
  2. No depender de nombres Tailwind de color para estados finales.
  3. Usar bordes y superficies por token.
  4. Los estados de tarea pueden usar mezcla suave con tokens semanticos.
  5. El tema oscuro no debe requerir CSS especifico por componente salvo excepciones justificadas.