Communitygithub.com

Taste — Ingeniería Inversa del ADN de Diseño de un Sitio Web

Analiza el diseño visual de cualquier sitio web a partir de una URL, capturando datos del DOM y una captura de pantalla mediante un navegador real, y genera un archivo {dominio}.md y {dominio}.json con tokens de diseño prácticos y un análisis detallado de las decisiones de diseño.

¿Qué es Taste — Ingeniería Inversa del ADN de Diseño de un Sitio Web?

Esta habilidad permite extraer y comprender el sistema de diseño de cualquier sitio web. Al recibir una URL, utiliza Playwright MCP para capturar datos del DOM y una captura de pantalla del sitio. Luego, ejecuta un análisis de cuatro pasos que produce dos archivos: un archivo .md legible para humanos (que incluye un 'Design Map' con tokens prácticos como colores, tipografía, espaciado, radios, sombras y cuadrícula, y un 'Taste DNA' con 3-4 principios de diseño basados en compensaciones razonadas) y un archivo .json estructurado y procesable por máquinas. La habilidad está diseñada para rechazar descripciones genéricas ('limpio', 'moderno', 'fácil de usar') en favor de valores concretos (px, hex) y compensaciones de diseño específicas. Es útil para extraer el sistema de diseño de un sitio, estudiar el lenguaje visual de un competidor, portar una estética a un nuevo proyecto o generar guías de diseño para un agente de codificación de IA. Se activa con comandos como `/taste <url>`, 'analiza el diseño de X', 'qué hace que el sitio de X sea bueno', 'extrae tokens de diseño de X', 'dame el ADN de diseño de X', 'construye algo al estilo de X' o 'quiero que mi aplicación se sienta como X'. Soporta exportación dirigida a herramientas como Cursor, Windsurf, Claude Code, GitHub Copilot, Bolt, Antigravity, v0, Figma, Lovable, o simplemente guardar los archivos. El proceso incluye la opción de analizar una sola página o 2-3 páginas enlazadas para identificar patrones del sistema.

Compatible con✓Claude Code~Codex CLI✓Cursor✓Antigravity✓Gemini CLI✓Windsurf
npx skills add senlindesign/taste-skill

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace Taste — Ingeniería Inversa del ADN de Diseño de un Sitio Web?

Esta habilidad convierte una URL en dos archivos:

  • ./{dominio}.md — legible para humanos. Dos secciones:
    • Design Map — tokens prácticos (colores, escala tipográfica, espaciado, radios, sombras, cuadrícula)
    • Taste DNA — 3-4 compensaciones con opinión (Trigger → Decisión → Razón → Evidencia)
  • ./{dominio}.json — estructurado. Mismos datos, procesables por máquina, para herramientas posteriores (Cursor, Windsurf, sistemas de diseño).

El pipeline rechaza descripciones genéricas como "limpio y moderno". Un taste.md finalizado debería leerse como un diseñador senior explicando por qué esta página en particular tomó estas decisiones particulares — y qué alternativas plausibles rechazó.

Cuándo activar

Activa esta habilidad siempre que el usuario quiera estudiar el diseño de un sitio web y capturarlo como guía para trabajos de diseño futuros. Captura todo esto:

  • Formulario explícito de barra: /taste <url>
  • Solicitudes en lenguaje natural: "analiza el diseño de vercel.com", "qué hace que el sitio de Stripe sea tan bueno", "extrae los tokens de diseño de linear.app", "dame el ADN de diseño de are.na"
  • Intención de imitación: "quiero que mi tablero se sienta como Linear", "construye una página de inicio al estilo de ", "porta el diseño de este sitio a mi proyecto"
  • Investigación competitiva: "compara nuestra apariencia con ", "qué convenciones de diseño usa "
  • En cualquier lugar donde el usuario mencione una URL y pregunte sobre sus decisiones de diseño, tipografía, colores, espaciado, filosofía o "sensación"

Si el usuario menciona una URL en relación con cualquier tema visual/de diseño, inclínate a activar — Claude tiende a activar habilidades con poca frecuencia. Ante la duda, úsala. El costo de una invocación de habilidad desperdiciada es pequeño; el costo de generar consejos de diseño genéricos cuando esta habilidad podría haber producido un análisis específico y respaldado por evidencia es grande.

NO actives para: "extraer datos de un sitio web" (usa una habilidad de scraping), "resumir el contenido de " (usa WebFetch), "desplegar este sitio" (no relacionado).

Prerrequisitos

Esta habilidad requiere que el servidor MCP de Playwright (https://playwright.dev/docs/getting-started-mcp) esté instalado y conectado. Verifica con:

claude mcp list | grep playwright

Si ves playwright: ... - ✓ Connected, estás listo. Si no, instálalo:

claude mcp add playwright -s user -- npx -y @playwright/mcp@latest --isolated

Por qué --isolated: cada ejecución de /taste comienza con un estado de navegador nuevo, por lo que las cookies, las sesiones de inicio de sesión y la caché anterior no se filtran en la página analizada. Sin él, ejecutar /taste https://linear.app mientras estás conectado a Linear analizaría el tablero de la aplicación en lugar de la página de marketing pública — superficie incorrecta, gusto incorrecto.

Por qué npx @playwright/mcp@latest (sin el indicador --browser): Playwright descargará y usará su propio Chromium empaquetado (~100 MB, una sola vez). Esto es más portátil que depender del Chrome del sistema del usuario: funciona en máquinas sin Chrome instalado, proporciona una representación consistente entre usuarios y nunca abre una ventana en el perfil del navegador real del usuario.

Después de instalar, el usuario debe reiniciar Claude Code para que las herramientas MCP (mcp__playwright__browser_*) aparezcan en esta sesión. Si Playwright no está disponible cuando se ejecuta esta habilidad, detente e indícale al usuario claramente: "Necesito Playwright MCP para raspar la página. Ejecuta claude mcp add playwright -s user -- npx -y @playwright/mcp@latest --isolated y reinicia Claude Code, luego inténtalo de nuevo."

En la primera ejecución, Playwright puede tardar entre 30 y 60 segundos antes de que su primer browser_navigate devuelva algo; esa es la descarga única de Chromium. Las ejecuciones posteriores comienzan en segundos. Si el usuario desea descargar previamente para evitar la espera, puede ejecutar npx playwright install chromium una vez antes de invocar esta habilidad.

Flujo de trabajo

Sigue estas cinco fases en orden. Cada fase tiene criterios de éxito explícitos: no avances hasta que la fase actual haya producido lo que la siguiente fase necesita.

Fase 0 — Analizar la URL y el objetivo de exportación

Paso 1 — URL

Extrae la URL del mensaje del usuario. Acepta estas formas:

  • /taste https://linear.app
  • "analiza el diseño de vercel.com" (agrega https:// si falta)
  • Una URL desnuda en cualquier parte del mensaje

Si el usuario no proporcionó una URL, pide una. Si proporcionó una ruta de archivo o algo que claramente no es una URL, pregunta si se refería a una página alojada. No continúes hasta que tengas una URL real.

Resuelve formas cortas comunes antes de navegar: linear.app → https://linear.app, https://www.stripe.com está bien tal cual.

Paso 2 — Extraer el dominio para nombrar archivos

De la URL, extrae el nombre de host y elimina cualquier prefijo www.. Ejemplos:

  • https://linear.app → linear.app
  • https://www.stripe.com → stripe.com
  • https://vercel.com/home → vercel.com

Guárdalo como {dominio}. Todos los archivos de salida se nombrarán según esto: {dominio}.md, {dominio}.json y cualquier archivo de exportación. Nunca uses el nombre genérico taste.md — ese nombre choca cuando el usuario ejecuta esta habilidad en múltiples sitios en el mismo directorio.

Paso 3 — Destino de exportación + Alcance del rastreo

Si el usuario ya especificó tanto un destino de exportación como un alcance de rastreo en su mensaje, omite esta pregunta por completo. Si falta alguno, pregunta una vez en un solo mensaje:

"Dos preguntas rápidas antes de comenzar:

Destino de exportación — ¿con qué herramienta estás construyendo?

 1  Cursor          → .cursor/rules/{dominio}-taste.mdc
 2  Windsurf        → .windsurf/rules/{dominio}-taste.md
 3  Claude Code     → CLAUDE.md (agrega sección Design Taste)
 4  GitHub Copilot  → .github/copilot-instructions.md (agrega)
 5  Bolt            → .bolt/prompt
 6  Antigravity     → GEMINI.md
 7  v0 by Vercel    → taste-tokens.css + instrucciones
 8  Figma Make      → taste-figma.css + instrucciones
 9  Lovable         → imprime texto para pegar en Project Knowledge
10  Omitir          → mantener solo {dominio}.md + {dominio}.json

Alcance del rastreo — ¿solo esta página, o explorar 2–3 páginas enlazadas?

 1  Solo esta página       → más rápido, enfocado exactamente en lo que me diste
 2  Explorar páginas enlazadas → visitaré 2–3 páginas de navegación y fusionaré los datos
```"

Almacena las respuestas como {exportTarget} y {crawlScope}. Valores predeterminados: {exportTarget} = "omitir", {crawlScope} = "individual". No preguntes de nuevo.

Fase 1 — Capturar datos de la página (Playwright MCP)

Ejecuta estos pasos en orden. Si algún paso da error, detén el pipeline e informa el error al usuario — no continúes silenciosamente con datos degradados.

  1. Cambiar el tamaño de la ventana gráfica a 1440×900 para que las medidas sean consistentes entre ejecuciones:

    mcp__playwright__browser_resize  width=1440  height=900
    
  2. Navegar a la URL:

    mcp__playwright__browser_navigate  url=<la URL>
    
  3. Esperar brevemente la hidratación del lado del cliente. Las SPA pesadas (figma.com, notion.so) necesitan unos segundos después de domcontentloaded para renderizar contenido real. Usa:

    mcp__playwright__browser_wait_for  time=3
    

    Si después de 3 segundos la instantánea de la página aún parece un esqueleto de carga, dale otros 3 segundos. Si todavía es un esqueleto después de eso, anótalo en la salida final ("la página puede estar renderizada de forma incompleta; algunas medidas son aproximadas").

  4. Tomar dos capturas de pantalla — primero la ventana gráfica, luego la página completa:

    4a. Captura de pantalla de la ventana gráfica (1440×900, sin escalar — esta es tu referencia visual principal para el Paso 1):

    mcp__playwright__browser_take_screenshot  type=jpeg  filename={dominio}-viewport.jpeg
    

    4b. Captura de pantalla condicional de página completa — primero verifica la altura de la página:

    mcp__playwright__browser_evaluate  function=() => document.documentElement.scrollHeight
    
    • Si ≤ 6× la altura de la ventana gráfica (≤ 5400px a 1440×900): toma una captura de pantalla normal de página completa:
      mcp__playwright__browser_take_screenshot  fullPage=true  type=jpeg  filename={dominio}-fullpage.jpeg
      
    • Si > 6× la altura de la ventana gráfica: omite la página completa (demasiado alta, desperdicia tokens). En su lugar, toma dos capturas de ventana gráfica dirigidas:
      // Mitad de página (50% de desplazamiento)
      mcp__playwright__browser_evaluate  function=() => window.scrollTo(0, document.documentElement.scrollHeight * 0.5)
      mcp__playwright__browser_take_screenshot  type=jpeg  filename={dominio}-mid.jpeg
      // Pie de página
      mcp__playwright__browser_evaluate  function=() => window.scrollTo(0, document.documentElement.scrollHeight)
      mcp__playwright__browser_take_screenshot  type=jpeg  filename={dominio}-footer.jpeg
      // Desplazarse de vuelta al inicio
      mcp__playwright__browser_evaluate  function=() => window.scrollTo(0, 0)
      

    Usa la captura de pantalla de la ventana gráfica como referencia visual principal en el Paso 1 — representa la primera impresión que el diseñador pretendía. Usa las capturas de página completa o de mitad+pie para verificar patrones que solo aparecen más abajo en la página (tipografía del pie de página, variaciones de color en secciones tardías, etc.). JPEG mantiene el costo de tokens bajo en comparación con PNG.

  5. Ejecutar el extractor DOM. Lee references/extract.js y pasa su contenido completo como argumento function:

    mcp__playwright__browser_evaluate  function=<contenido de references/extract.js>
    

    La herramienta devuelve un objeto JSON. Guárdalo mentalmente como domData — lo usarás en el Paso 1.

  6. (Limpieza opcional) El navegador permanece abierto para el resto de la sesión. No es necesario cerrarlo a menos que el usuario lo solicite.

Captura de varias páginas (solo si {crawlScope} es "multi"):

Después de capturar la página principal, extrae los enlaces de navegación y visita hasta 2 páginas adicionales del mismo sitio.

6a. Extraer enlaces de navegación de la página principal ya cargada:

(function() {
  const links = [];
  const seen = new Set([location.pathname]);
  const skip = /\/(login|logout|signup|sign-in|register|auth|account|checkout|cart|password|reset)\b/i;
  document.querySelectorAll('nav a, header a, [role="navigation"] a').forEach(a => {
    try {
      const u = new URL(a.href);
      if (u.hostname !== location.hostname) return;
      if (skip.test(u.pathname)) return;
      if (seen.has(u.pathname)) return;
      if (u.pathname === '/' && location.pathname !== '/') return;
      seen.add(u.pathname);
      links.push({ href: u.origin + u.pathname, text: (a.innerText || a.textContent).trim().slice(0, 40) });
    } catch(e) {}
  });
  return links.slice(0, 6);
})()

6b. Elegir 2 páginas de la lista devuelta. Prefiere:

  • Rutas más cortas (/product en lugar de /product/features/detail)
  • Nombres de sección distintos (Product, Community, Pricing, Docs — no solo diferentes slugs bajo la misma sección)
  • Evita la raíz / si ya la capturaste

6c. Para cada página adicional, ejecuta un bucle de captura más ligero (navegar → esperar 3s → solo captura de pantalla de ventana gráfica → extractor DOM). Omite las capturas de página completa/mitad/pie para las páginas 2-3 — la ventana gráfica es suficiente para confirmar la consistencia del diseño, y el extractor DOM captura la página completa independientemente. Nombra las capturas de pantalla {dominio}-viewport-2.jpeg, {dominio}-viewport-3.jpeg. Almacena los datos de cada página como pages[1], pages[2] (con pages[0] siendo la URL principal).

Si una página enlazada no se carga o está bloqueada, omítela silenciosamente y anótalo en el informe de la Fase 6.

6d. Fusionar datos antes de la Fase 2. Combina candidatos de color de todas las páginas (unión), tipografía de todas las páginas (unión). Cuando un valor aparece en 2+ páginas, es una señal del sistema — márcalo. Los valores que aparecen solo en una página son locales — aún captúralos, pero pésalos menos.

En los Pasos 1–3, indica siempre cuántas páginas se analizaron ("En 3 páginas: …") y distingue los patrones del sistema de los locales. El acuerdo entre varias páginas es la evidencia más sólida disponible para un principio de gusto.

Criterio de éxito para la Fase 1: tienes al menos una captura de pantalla Y un domData JSON poblado (de la página principal) con campos colors, typography, layout, effects, cards, images, spacingSamples, sectionGaps y grid. Si alguno de estos está completamente vacío y la captura de pantalla muestra contenido real, el extractor necesita mejoras — anótalo y continúa de todos modos.

Ruta de datos degradados: si domData.errors no está vacío, el extractor falló parcialmente. En el Paso 1, marca las categorías afectadas con ~approx (sección del extractor falló) y confía en la captura de pantalla para esas medidas. En la Fase 6, enumera las secciones fallidas como una advertencia en el informe.

Fase 2 — Ejecutar el análisis de 4 pasos

La captura de pantalla es la verdad fundamental. Antes de leer cualquier archivo de referencia: la captura de pantalla de la ventana gráfica muestra lo que un humano ve realmente. Los datos DOM proporcionan números exactos. Cuando entren en conflicto, confía en la captura de pantalla. Un color que aparece en el DOM pero cubre <5% del área de superficie visible es decorativo — no lo enumeres como un color de marca. Los divisores de sección que no aparecen en la captura de pantalla no existen, independientemente de lo que informe el DOM. Las sombras imperceptibles (≤3% de opacidad) son artefactos CSS, no decisiones de diseño.

Los cuatro archivos de referencia en references/ contienen las instrucciones completas para cada paso. Lee cada uno cuando llegues a él (no precargues los cuatro a la vez — los pasos son deliberadamente secuenciales y los pasos anteriores no necesitan instrucciones posteriores).

Para cada paso:

  1. Lee el archivo de referencia correspondiente.
  2. Genera la salida que solicita, en tu propia respuesta.
  3. Comienza la salida con la línea marcadora especificada en la referencia (por ejemplo, ### Paso 1 Salida — Mediciones).
  4. El siguiente paso recibe tus salidas anteriores como entrada — mantenlas en la conversación, no las resumas.

Paso 1 — Medir

  • Lee references/step1-measure.md
  • Entradas: domData (el JSON de browser_evaluate) + la captura de pantalla
  • Produce: 20 categorías de mediciones, cada valor citado con un px / hex / ratio específico

Paso 2 — Patrón

  • Lee references/step2-pattern.md
  • Entradas: Salida del Paso 1
  • Produce: 5-8 patrones sistemáticos, cada uno con Patrón / Evidencia / Objetivo de diseño

Paso 3 — Gusto

  • Lee references/step3-taste.md
  • Entradas: Salidas del Paso 1 + Paso 2
  • Produce: 4 principios de gusto (cada uno Trigger / Decisión / Razón / Evidencia), al menos una compensación de moderación

Paso 4 — Observador

  • Lee references/step4-observer.md
  • Entradas: Salidas del Paso 1 + 2 + 3 + la URL original

…[truncado para traducción]

Skills relacionados