Communitygithub.com

stevembarclay/pencilplaybook

PencilPlaybook es el Skills de UI / Taste-Skill para Pencil.dev + Claude Code — un manual de diseño que le da a Claude percepciones psicológicas reales y barreras de seguridad de nivel senior para que deje de producir contenido genérico de IA.

¿Qué es pencilplaybook?

PencilPlaybook es un skill de diseño UI para Pencil.dev y Claude Code que transforma a Claude en un diseñador senior con criterio perceptual y psicológico. Este skill proporciona un conjunto completo de andamios (scaffolds) para los arquetipos de diseño más comunes, desde paneles de control y tablas hasta páginas de marketing y formularios. También incluye flujos de trabajo para "arqueología del canvas" (inspección de archivos .pen), directrices sobre jerarquía visual, espaciado, tipografía y color basadas en principios de la Gestalt y psicología cognitiva, además de un asistente de configuración que guía al usuario en la personalización de tokens de marca, resolución y dimensiones. Está diseñado para evitar que Claude genere "slop" (contenido genérico sin personalidad) imponiendo reglas de diseño estrictas y verificaciones perceptuales. Soporta plataformas como Claude Code y Cursor, y su documentación detallada incluye ejemplos de código, guías de configuración y workflows como Canvas Archaeology para entender y modificar diseños existentes.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add stevembarclay/pencilplaybook

Preguntar en tu IA favorita

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

Documentación

Pencil Pro

Regla de Resolución Primaria

Este skill debe ser configurado antes del primer uso.

Si el usuario dice "ejecuta el asistente de configuración de PencilPlaybook" o pide configurar PencilPlaybook: → Lee .claude/skills/pencilplaybook/setup.md y sigue las instrucciones exactamente.

Si el usuario dice "construye mi primera pantalla con PencilPlaybook" o pide empezar a diseñar: → Lee .claude/skills/pencilplaybook/onboarding.md y sigue las instrucciones exactamente.

Resolución configurada: (ejecuta setup para establecerla)

Si la raíz de una pantalla en un archivo .pen existente no coincide con tu resolución configurada, anótalo antes de editar. No construyas sobre un lienzo con tamaño incorrecto sin señalar la desviación.

Excepción común — páginas de marketing: Diseña a 1440px independientemente de la resolución de tu aplicación. Las páginas de marketing se consumen en anchos de navegador variables — diseña a 1440px, verifica a 390px.


Inicio de Sesión (Cada Sesión de Pencil)

1. get_editor_state()                           — verifica documento activo y selección
2. open_document("ruta/a/tu-archivo.pen")       — abre el archivo destino
3. get_guidelines(topic="web-app")              — carga las directrices de diseño
4. set_variables(<mapa de tokens abajo>)         — inyecta los tokens de marca
5. get_variables()                              — confirma que los tokens están almacenados
6. snapshot_layout()                            — verifica las dimensiones del lienzo

Tu mapa de tokens — ejecuta set_variables con este objeto al inicio de cada sesión. Las variables pueden no persistir entre sesiones de Claude Code.

{
  "color-primary":        "TU_HEX",
  "color-primary-dark":   "TU_HEX",
  "color-accent":         "TU_HEX",
  "color-background":     "TU_HEX",
  "color-surface":        "TU_HEX",
  "color-border":         "TU_HEX",
  "color-text":           "TU_HEX",
  "color-text-muted":     "TU_HEX",
  "color-success":        "TU_HEX",
  "color-warning":        "TU_HEX",
  "color-error":          "TU_HEX",
  "font-sans":            "TU_FUENTE",
  "font-mono":            "TU_FUENTE",
  "font-serif":           "TU_FUENTE",
  "spacing-card":         "24",
  "spacing-gap-sm":       "8",
  "spacing-gap-md":       "16",
  "spacing-gap-lg":       "24",
  "spacing-gap-xl":       "32",
  "content-max-width":    "TU_VALOR",
  "sidebar-width":        "TU_VALOR"
}

Después de set_variables, llama a get_variables() para confirmar que todos los tokens están almacenados.


Scripts de Andamio

Nueve scripts de andamio que cubren los arquetipos de diseño más comunes. Ejecuta el asistente de configuración para rellenar los valores de dimensión y color a continuación antes de usarlos.


Andamio A — Panel de Control de App

Métricas, KPIs, feed de actividad, monitorización

sidebar=I("raíz", {name:"Sidebar", width:ANCHURA_SIDEBAR_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"FONDO_SIDEBAR", display:"flex", flexDirection:"column"})
pageArea=I("raíz", {name:"PageArea", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, x:ANCHURA_SIDEBAR_ANDAMIO, bg:"FONDO_PAGINA"})
pageHeader=I("pageArea", {name:"PageHeader", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:64, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", px:32})
statsBar=I("pageArea", {name:"StatsBar", y:64, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:80, bg:"FONDO_ESTADISTICAS", display:"flex", alignItems:"center", gap:24, px:32})
contentWrap=I("pageArea", {name:"ContentWrap", y:144, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_CONTENIDO_A_ANDAMIO, display:"flex", justifyContent:"center", p:32})
contentInner=I("contentWrap", {name:"ContentInner", width:MAX_CONTENIDO_ANDAMIO, display:"flex", flexDirection:"column", gap:24})

Después del andamio: snapshot_layout() — verifica que pageArea.width y contentInner.width son correctos.


Andamio B — Lista / Cola de App

Tablas, bibliotecas de activos, colas, gestión de usuarios

sidebar=I("raíz", {name:"Sidebar", width:ANCHURA_SIDEBAR_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"FONDO_SIDEBAR"})
pageArea=I("raíz", {name:"PageArea", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, x:ANCHURA_SIDEBAR_ANDAMIO, bg:"FONDO_PAGINA"})
pageHeader=I("pageArea", {name:"PageHeader", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:64, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", px:32})
commandStrip=I("pageArea", {name:"CommandStrip", y:64, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:52, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", gap:16, px:32})
tableWrap=I("pageArea", {name:"TableWrap", y:116, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_CONTENIDO_B_ANDAMIO, display:"flex", justifyContent:"center", px:32, pt:24})
tableInner=I("tableWrap", {name:"TableInner", width:MAX_CONTENIDO_ANDAMIO, display:"flex", flexDirection:"column", gap:0})
tableHeader=I("tableInner", {name:"TableHeader", width:MAX_CONTENIDO_ANDAMIO, height:40, bg:"FONDO_CABECERA_TABLA", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center"})

Andamio C — Detalle / Revisión de App

Vistas de detalle de dos paneles, flujos de revisión, diseños lado a lado

sidebar=I("raíz", {name:"Sidebar", width:ANCHURA_SIDEBAR_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"FONDO_SIDEBAR"})
pageArea=I("raíz", {name:"PageArea", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, x:ANCHURA_SIDEBAR_ANDAMIO, bg:"FONDO_PAGINA"})
pageHeader=I("pageArea", {name:"PageHeader", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:64, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE"})
actionBar=I("pageArea", {name:"ActionBar", y:64, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:56, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE"})
contentWrap=I("pageArea", {name:"ContentWrap", y:120, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_CONTENIDO_C_ANDAMIO, display:"flex", justifyContent:"center"})
contentInner=I("contentWrap", {name:"ContentInner", width:MAX_CONTENIDO_ANDAMIO, height:ALTURA_CONTENIDO_C_ANDAMIO, display:"flex", gap:0})
leftPanel=I("contentInner", {name:"LeftPanel", width:PANEL_IZQUIERDO_ANDAMIO, height:ALTURA_CONTENIDO_C_ANDAMIO, bg:"COLOR_SUPERFICIE", borderRight:"1px solid COLOR_BORDE"})
rightPanel=I("contentInner", {name:"RightPanel", width:PANEL_DERECHO_ANDAMIO, height:ALTURA_CONTENIDO_C_ANDAMIO, bg:"FONDO_PAGINA", p:24, display:"flex", flexDirection:"column", gap:20})

Nota: La división izquierda/derecha por defecto es de ~40/60. Ajusta por característica — divisiones comunes: 40/60, 38/62, 50/50.


Andamio D — Página de Marketing

Páginas de aterrizaje, páginas de producto — siempre 1440px de ancho independientemente del lienzo de la app

navbar=I("raíz", {name:"Navbar", width:1440, height:72, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", px:80})
heroSection=I("raíz", {name:"HeroSection", y:72, width:1440, height:600, bg:"FONDO_HERO", display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center"})
heroContent=I("heroSection", {name:"HeroContent", width:MAX_CONTENIDO_MARKETING_ANDAMIO, display:"flex", flexDirection:"column", alignItems:"center", gap:24})
section1=I("raíz", {name:"Section1", y:672, width:1440, height:480, bg:"COLOR_SUPERFICIE", display:"flex", flexDirection:"column", alignItems:"center", py:80})
section1Content=I("section1", {name:"Section1Content", width:MAX_CONTENIDO_MARKETING_ANDAMIO})

Las páginas de marketing son mobile-first. Diseña a 1440px y verifica el diseño a 390px de ancho antes de la entrega.


Andamio E — Modal / Diálogo

Confirmaciones, acciones destructivas, formularios de edición rápida, paneles laterales

Ejecuta primero el Andamio A, B o C. Luego añade este modal superpuesto sobre el pageArea — no lo insertes en la raíz.

backdrop=I("pageArea", {name:"ModalBackdrop", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"rgba(0,0,0,0.48)", display:"flex", alignItems:"center", justifyContent:"center"})
modal=I("backdrop", {name:"Modal", width:480, bg:"COLOR_SUPERFICIE", borderRadius:8, border:"1px solid COLOR_BORDE", display:"flex", flexDirection:"column", overflow:"hidden"})
modalHeader=I("modal", {name:"ModalHeader", height:56, px:24, display:"flex", alignItems:"center", justifyContent:"space-between", borderBottom:"1px solid COLOR_BORDE"})
modalBody=I("modal", {name:"ModalBody", px:24, py:20, display:"flex", flexDirection:"column", gap:16})
modalFooter=I("modal", {name:"ModalFooter", height:60, px:24, display:"flex", alignItems:"center", justifyContent:"flex-end", gap:12, borderTop:"1px solid COLOR_BORDE"})

Después del andamio: snapshot_layout() — confirma que el modal es visible y está centrado. Ajusta el ancho del modal según el caso de uso: 380px (confirmación compacta), 480px (formulario estándar), 600px (formulario ancho), 720px (detalle/vista previa).


Andamio F — Asistente / Stepper

Formularios de varios pasos, flujos de incorporación, secuencias de configuración, pago

sidebar=I("raíz", {name:"Sidebar", width:ANCHURA_SIDEBAR_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"FONDO_SIDEBAR"})
pageArea=I("raíz", {name:"PageArea", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, x:ANCHURA_SIDEBAR_ANDAMIO, bg:"FONDO_PAGINA"})
pageHeader=I("pageArea", {name:"PageHeader", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:64, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", px:32})
stepperBar=I("pageArea", {name:"StepperBar", y:64, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:60, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", justifyContent:"center"})
contentWrap=I("pageArea", {name:"ContentWrap", y:124, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_CONTENIDO_F_ANDAMIO, display:"flex", justifyContent:"center", px:32, pt:32})
contentInner=I("contentWrap", {name:"ContentInner", width:640, display:"flex", flexDirection:"column", gap:24})
actionFooter=I("pageArea", {name:"ActionFooter", y:Y_PIE_ASISTENTE_ANDAMIO, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:72, bg:"COLOR_SUPERFICIE", borderTop:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", justifyContent:"space-between", px:32})

Nota: ContentInner tiene 640px de ancho por defecto — formulario de una columna enfocado. Botón de retroceso a la izquierda, Siguiente/Enviar a la derecha en ActionFooter (justifyContent:"space-between").


Andamio G — Pantalla Móvil

390×844px (estándar iPhone 14). Úsalo para todas las pantallas móviles — codificado, no requiere valores de configuración.

statusBar=I("raíz", {name:"StatusBar", width:390, height:44, bg:"FONDO_PAGINA"})
navBar=I("raíz", {name:"NavBar", y:44, width:390, height:56, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", px:16})
scrollContent=I("raíz", {name:"ScrollContent", y:100, width:390, height:688, bg:"FONDO_PAGINA", display:"flex", flexDirection:"column", overflow:"hidden"})
contentPad=I("scrollContent", {name:"ContentPad", width:390, display:"flex", flexDirection:"column", gap:16, px:16, pt:16})
bottomNav=I("raíz", {name:"BottomNav", y:788, width:390, height:56, bg:"COLOR_SUPERFICIE", borderTop:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", justifyContent:"space-around"})

Nota: Elimina statusBar y establece navBar.y=0 si no se muestra el chrome del sistema. Elimina bottomNav para apps sin navegación por pestañas. Los objetivos táctiles dentro de este andamio deben tener ≥44×44px.


Andamio H — Formulario / Entrada de Datos

Páginas de configuración, edición de perfil, entrada de datos pesada — formulario de una columna, centrado

sidebar=I("raíz", {name:"Sidebar", width:ANCHURA_SIDEBAR_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"FONDO_SIDEBAR"})
pageArea=I("raíz", {name:"PageArea", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, x:ANCHURA_SIDEBAR_ANDAMIO, bg:"FONDO_PAGINA"})
pageHeader=I("pageArea", {name:"PageHeader", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:64, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", justifyContent:"space-between", px:32})
formWrap=I("pageArea", {name:"FormWrap", y:64, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_CONTENIDO_H_ANDAMIO, display:"flex", justifyContent:"center", px:32, pt:32})
formInner=I("formWrap", {name:"FormInner", width:600, display:"flex", flexDirection:"column", gap:28})
formSection=I("formInner", {name:"FormSection1", display:"flex", flexDirection:"column", gap:16})
formActions=I("formInner", {name:"FormActions", display:"flex", gap:12, justifyContent:"flex-end"})

Nota: El ancho de FormInner es de 600px por defecto. Usa 480px para flujos simples, 800px para diseños anchos de dos columnas. Añade más nodos FormSection dentro de formInner para agrupar campos relacionados.


Andamio I — Estado Vacío / Paso de Incorporación

Vistas sin datos, indicaciones de primer uso, descubrimiento de funciones, pantallas en blanco

sidebar=I("raíz", {name:"Sidebar", width:ANCHURA_SIDEBAR_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, bg:"FONDO_SIDEBAR"})
pageArea=I("raíz", {name:"PageArea", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_LIENZO_ANDAMIO, x:ANCHURA_SIDEBAR_ANDAMIO, bg:"FONDO_PAGINA"})
pageHeader=I("pageArea", {name:"PageHeader", width:ANCHURA_AREA_PAGINA_ANDAMIO, height:64, bg:"COLOR_SUPERFICIE", borderBottom:"1px solid COLOR_BORDE"})
emptyCenter=I("pageArea", {name:"EmptyCenter", y:64, width:ANCHURA_AREA_PAGINA_ANDAMIO, height:ALTURA_CONTENIDO_H_ANDAMIO, display:"flex", alignItems:"center", justifyContent:"center"})
emptyContent=I("emptyCenter", {name:"EmptyContent", width:400, display:"flex", flexDirection:"column", alignItems:"center", gap:20})
illustrationArea=I("emptyContent", {name:"IllustrationArea", width:200, height:160, borderRadius:12, bg:"COLOR_SUPERFICIE", border:"1px solid COLOR_BORDE", display:"flex", alignItems:"center", justifyContent:"center"})
textStack=I("emptyContent", {name:"TextStack", width:400, display:"flex", flexDirection:"column", alignItems:"center", gap:8})
emptyActions=I("emptyContent", {name:"EmptyActions", display:"flex", gap:12})

Nota: Reemplaza IllustrationArea con G("illustrationArea", "ai", "tu prompt") para generar una ilustración. Mantén el texto del estado vacío corto: un título (16–18px), una línea de apoyo (14px atenuado), un CTA principal.


Flujos de Trabajo Principales

Flujo 1: Arqueología del Canvas

Úsalo cuando: "qué hay en este...

Skills relacionados