ultrahand: tema
Construye el tema de un proyecto una vez y hazlo crecer a partir de ahí. El tema es un archivo de tokens de diseño más un breve registro de sus decisiones, mantenido en el proyecto, para que cada diseño y revisión posterior se base en la misma base en lugar de comenzar una nueva apariencia. El formato del archivo está en shared/theme/README.md; las reglas están en shared/theme/rules.md, y cada regla referencia shared/theme/sources.md.
Cada tema mantiene los no negociables (NN-1 a NN-12: niveles, cuadrícula de 8 puntos, ambos esquemas, contraste, una escala tipográfica real y el resto) y toma una decisión nueva en cada eje creativo (CR-1 a CR-10: tono, neutros, voz tipográfica, esquinas, profundidad, densidad…). Las reglas son fijas para que cada tema se sienta bien hecho; los ejes son abiertos para que no haya dos productos con el mismo aspecto. Lee rules.md antes de comenzar.
Los scripts siguientes se encuentran en ${CLAUDE_PLUGIN_ROOT}/shared/theme/.
1. Encontrar lo que existe
Mira antes de preguntar. Para un diseño que existe solo como artefacto de lienzo, enumera los archivos del artefacto y lee design/ desde allí. En el proyecto, busca design/THEME.md, *.tokens.json, tokens/, una configuración de Style Dictionary y el código del tema de la plataforma: propiedades personalizadas de CSS, tailwind.config.*, ThemeData / ColorScheme de Flutter, activos de color de SwiftUI, MaterialTheme de Compose. El resultado determina el modo:
| Encontrado | Modo |
|---|---|
| Un archivo de tema y THEME.md | Evolucionar (paso 4). Nunca regenerarlo. |
| Sin archivo de tema, pero con código con estilo | Extraer (paso 2), luego evolucionar. |
| Nada (un producto nuevo) | Crear (paso 3). |
2. Extraer el tema que el código ya tiene
El objetivo es capturar el aspecto actual, limpiado, no rediseñarlo.
- Ejecuta
node scan.mjs <directorio src>(añade--jsonpara las listas completas). Enumera cada color, valor de espaciado, radio y tamaño de fuente con recuentos y ubicaciones, agrupa colores casi duplicados y marca espaciados fuera de la cuadrícula. Lee también el código del tema de la plataforma: los valores que nombra un objeto de tema son los intencionados, y los valores sin procesar dispersos son la deriva. - Nombra los roles. Para cada grupo de colores, encuentra para qué se usa (fondo de página, texto del cuerpo, botones, bordes, errores) y asígnalo a un rol semántico (README.md enumera los requeridos). Un rol, un valor: cuando dos casi duplicados sirven para un solo rol, conserva el más usado.
- Ajusta a las reglas. Pliega el espaciado en la escala NN-2, los tamaños en una escala tipográfica (NN-6), los radios en una escala corta (NN-7). Corrige fallos de contraste moviéndote a lo largo de los pasos tonales del mismo tono (NN-4). Cada cambio es un cambio visible en el producto, así que enuméralos en una tabla (
13px → 12px, 4 lugares) para que el propietario los apruebe, y mantén cualquier cosa que quiera sin cambios. - Completa los vacíos. La mayoría del código no tiene modo oscuro, ni anillo de enfoque ni roles
on-. Diséñalos en la propia paleta del tema (NN-3, NN-10) en lugar de añadir genéricos. - Inventaria los componentes. Enumera los componentes reutilizables (busca en
components/,ui/,widgets/,views/), sus variantes y dónde está definido cada uno. Observa cualquier trabajo realizado por dos componentes diferentes: es un candidato a fusión (EV-4), no algo que copiar en el tema. - Registra la personalidad que ya tiene. Sitúa el aspecto existente en cada eje creativo y escríbelo en THEME.md. Las elecciones dadas por la marca (tono del logotipo, fuentes con licencia) son
locked; el resto sonopen.
Luego escribe los archivos (paso 5).
3. Crear un tema nuevo
- Personalidad. Pide tres adjetivos y para quién es, además de cualquier cosa fija: colores de marca, logotipo, fuentes, plataforma (las aplicaciones nativas de iOS o Android se apoyan en la fuente y colores del sistema; el tema se mapea sobre ellos [HIG-COLOR] [M3-COMPOSE]).
- Tres direcciones. Propón tres direcciones que difieran en al menos tres ejes creativos, cada una con una razón de una línea vinculada a los adjetivos. Evita el aspecto predeterminado que describe rules.md a menos que el propietario lo quiera. Muéstralas una al lado de la otra (paso 6) y deja que el propietario elija una o las combine.
- Constrúyelo.
- Paleta: para cada color clave (primario, neutro, más error y cualquier acento), una escala tonal de aproximadamente 10 a 13 pasos de oscuro a claro [M3-HCT] [M3-COMPOSE], para que cada rol pueda encontrar un paso que cumpla con el contraste en ambos esquemas.
- Colores semánticos: cada rol requerido, cada uno con su valor oscuro, cada
on-Xdiseñado contraX. - Espacio: la escala NN-2, luego espaciado semántico por función: pasos
insetpara relleno, ygap-related,gap-groupygap-sectionpara que la regla de composición de que los espacios entre grupos sean claramente mayores que los espacios dentro de ellos (SEC-2 en shared/composition/principles.md) esté incorporada. - Tipografía: una escala a partir de la proporción elegida (CR-5), con roles display, headline, title, body, label; body al valor predeterminado de la plataforma (16 en web, 17 pt en iOS; 13–14 solo para una herramienta de escritorio densa, ver NN-6).
- Forma, profundidad, movimiento, enfoque: una escala de radios en el estilo de esquina elegido; niveles de elevación en el método de profundidad elegido; tokens de duración y transición; un anillo de enfoque de 2 píxeles o más.
- Componentes: solo los tokens de componente que un componente necesita para diferir de su rol (EV-2). La mayoría de los componentes no necesitan ninguno.
Comienza cada valor en la versión 1.0.0.
4. Evolucionar un tema existente
Para una solicitud como "añadir un color de advertencia", "necesitamos una tabla más densa", "hacerlo más cálido", o una habilidad de diseño o theme-review que proponga adiciones:
- Lee THEME.md y los tokens primero (EV-1). Respeta las decisiones
locked; si la solicitud necesita cambiar una, dilo y pregunta. - Reutiliza un rol existente si uno encaja (EV-2). Añade un token solo para un vacío real, con un alias a un paso primitivo existente (EV-3).
- Un cambio amplio ("más cálido", "más divertido") mueve un eje creativo
open: desplaza los primitivos, mantén todos los nombres semánticos y vuelve a ejecutar la verificación de contraste. Los nombres se mantienen fieles incluso en un cambio de marca (NN-11). - Retira con
$deprecatednombrando el reemplazo; elimina en una versión posterior (EV-6). - Aumenta la versión y añade una línea de changelog que indique qué cambió y qué pantallas lo necesitaron (EV-5).
5. Escribir y verificar
- Escribe
design/theme.tokens.json(o la ubicación de tokens existente del proyecto) ydesign/THEME.md, siguiendo README.md. example.tokens.json muestra la estructura. - Ejecuta
node check.mjs design/theme.tokens.jsony corrige cada error. Una advertencia necesita una corrección o una razón en THEME.md. - Entrégaselo al código. Para web,
node css.mjs design/theme.tokens.json --out <ruta>/theme.cssgenera propiedades personalizadas de CSS con modo oscuro incorporado. Para otras plataformas, o varias a la vez, recomienda Style Dictionary, que lee este formato y escribe Swift, Android, Compose y Flutter [STYLE-DICT]. Ofrécete a reemplazar los valores sin procesar que encontró el escaneo con tokens; no lo hagas sin preguntar, ya que toca todos los archivos con estilo.
6. Mostrar el tema
Construye una muestra en el lienzo del plugin (shared/canvas/; su README tiene el contrato) para que el propietario vea el tema funcionando, no una lista de códigos hex:
node "${CLAUDE_PLUGIN_ROOT}/shared/theme/css.mjs" design/theme.tokens.json --style --out theme.html
node "${CLAUDE_PLUGIN_ROOT}/shared/canvas/build.mjs" \
--presets "${CLAUDE_PLUGIN_ROOT}/skills/desktop/references/presets.md" \
--head theme.html --screen screen.html --title "<Producto> tema" --out index.html
El screen.html de la muestra usa solo las propiedades personalizadas del tema y muestra: roles de color como texto on-X sobre X con la proporción medida; la escala tipográfica con texto real; la escala de espaciado; niveles de radio y elevación; cada componente inventariado en sus estados; y una pequeña pantalla realista (una lista y un formulario) construida a partir de él. Los alternadores de Claro / Oscuro y texto al 200% del lienzo prueban ambos esquemas y la escala de texto. Si el tema necesita una fuente web, coloca su <link> en el mismo archivo head.
Comparando direcciones (paso 3): emite cada dirección sin --style, con ámbito mediante --selector '[data-state="a"]' (luego b, c), y pégalas en la parte superior del <style> propio de la plantilla de pantalla: el lienzo establece data-state dentro de la pantalla, donde el head de la página no puede alcanzar. Declara los states a, b, c en config.json con los nombres de las direcciones como etiquetas, y el selector de Estado cambia entre ellas.
Publica index.html como un artefacto. Cuando el diseño en sí mismo es un artefacto, republica construido con el tema (--head theme.html) e incluye los dos archivos design/.
7. Presentar
Comparte el enlace del artefacto. En pocas líneas: el modo (creado, extraído o evolucionado), la versión, dónde se sitúa la personalidad en los ejes creativos y por qué, qué está locked y qué está open, cualquier cambio de ajuste que el propietario necesite aprobar, el resultado de la verificación y el siguiente paso: diseñar con él (las habilidades mobile, tablet y desktop lo leen), o auditar el código contra él con theme-review.