Mate & Build/Builds/Cómo deRentas pasó de tener assets a tener un sistema de marca para IA
Mate & Build #04

Cómo deRentas pasó de tener assets a tener un sistema de marca para IA

Participante
Agustina (Agus) Irioni
Empresa
deRentas
Duración
3 horas
Fecha
Abril 2026
Herramientas
Claude CodeFigma MCPGoogle AntigravityClaude Code Starter Kit
Assets dispersos sin sistema
Antes
Brand system operable por IA
Después
3 horas
Cómo deRentas pasó de tener assets a tener un sistema de marca para IA

Hay una diferencia entre tener los ingredientes y tener una receta. Una empresa puede tener logo, paleta, tipografía, campañas activas, un equipo de diseño que sabe lo que hace — y aun así no tener un sistema. Cada pieza sale bien. La coherencia depende de quién la hace ese día.

Ese era el problema de deRentas. Y no lo sabían del todo cuando llegamos a la sesión.

El problema que trajo Agus

Agus Irioni es diseñadora gráfica en deRentas, plataforma argentina que alquila autos a conductores de rideshare — principalmente Uber — para que puedan trabajar sin vehículo propio. Operan en Buenos Aires y Córdoba.

Agus llegó a Mate & Build con algo concreto: no había una forma estandarizada de crear ciertas tipologías de piezas como decks, templates y creativos según el canal de comunicación. La información estaba dispersa. Tenían cosas armadas en Figma, pero sin estructura ni sistema real detrás. Cada vez que alguien necesitaba producir una pieza nueva, arrancaba desde cero o buscaba en cinco lugares distintos para encontrar la versión correcta del logo o el color exacto.

El pedido inicial era concreto: estandarizar la producción de piezas y centralizar los assets de marca.

Pero cuando empezamos a mirar qué había realmente, el diagnóstico fue más preciso.

El problema real

A deRentas no le faltaban assets. Le faltaba una fuente de verdad.

Tenían un logo en varios formatos. Tenían una paleta de colores — el amarillo característico, el negro, el blanco. Tenían una tipografía (PP Neue Montreal, en 6 pesos). Tenían campañas activas de abril 2026, más de 35 piezas de referencia.

El problema era la capa siguiente: no había ningún lugar donde todo eso estuviera documentado con reglas explícitas, accesible para cualquier persona del equipo, y — esto es lo clave — legible para un agente de IA.

Cada área producía piezas a su manera. La coherencia visual no venía del sistema; venía de la memoria de las personas. Y eso no escala.

Si querías que Claude Code produjera una pieza on-brand de forma autónoma, no tenía dónde buscar qué significa "on-brand". No había un BrandBook. No había design tokens. No había specs de templates. No había nada que un agente pudiera consumir sin interpretación.

Ese era el problema real: la ausencia de una estructura que conecte el brand system con la automatización.

Por qué construimos esto (y no otra cosa)

Cuando entendimos el diagnóstico, tuvimos que decidir qué construir en 3 horas.

La tentación en este tipo de sesión es ir directamente a lo visible — armar el primer deck, mostrar algo concreto rápido. Lo descartamos. Si hacíamos eso, Agus se iba con una pieza. No con un sistema.

El trade-off fue claro: menos output visible en la sesión, más leverage a largo plazo. Un BrandBook bien armado en Markdown, con design tokens en JSON, vale más que 10 decks generados sobre una base frágil.

También decidimos no sobrescalar. No era el momento de armar un sistema de agentes complejo ni de cubrir todos los casos de uso posibles. El objetivo era construir la base correcta para que Agus la lidere y expanda desde ahí. Un sistema que tuviera sentido incluso sin nosotros.

Eso definió el scope: Claude Starter Kit → BrandBook → design tokens → templates → Figma MCP → skill /figma-deck. En ese orden, sin saltear pasos.

Cómo lo construimos

Arrancamos por donde siempre en Mate & Build: entender antes de construir. Pasamos los primeros 45 minutos revisando qué había. Los assets de logo, las tipografías, las campañas existentes de RRSS. Eso nos dio el insumo para lo que vino después.

Paso 1: Claude Starter Kit. Usamos el template que tengo para onboarding de proyectos en Claude Code — CLAUDE.md del proyecto, estructura de carpetas, contexto de empresa. Esto no es glamoroso, pero sin esta base el sistema no tiene dónde apoyarse. Todo esto corrió dentro de Google Antigravity — el IDE agéntico de Google que usamos para correr Claude Code, tomando unos mates.

Setup de la sesión: dos MacBooks, mate y Claude Code corriendo dentro de Google Antigravity

Paso 2: BrandBook en Markdown. brand/BRANDBOOK.md como fuente de verdad. Documentamos el color system con 3 modos (amarillo, oscuro, claro), la tipografía PP Neue Montreal con sus 6 pesos y escalas por contexto, las reglas de uso del logo con variantes y clearspace, y la voz y tono rioplatense de la marca. No como PDF que nadie lee — como archivo Markdown que Claude Code lee directamente cada vez que necesita producir algo.

Paso 3: Design tokens en JSON. Acá es donde el brand system se vuelve algo que el tooling importa directo. colors.json, typography.json, spacing.json — los mismos valores del BrandBook, en formato estructurado. Y ojo: no es "para que la IA lo lea" — un LLM lee el color de un Markdown igual de bien. Los tokens pagan cuando los consume algo que NO es un agente — un build de CSS, un plugin de Figma — y como fuente única que evita que el color se vaya corriendo cuando el sistema escala.

Paso 4: Templates con specs. Cinco formatos definidos con sus dimensiones y reglas: deck 1920×1080px, carrusel 1080×1350px, story 1080×1920px, alerta WhatsApp 1200×1500px, doc A4. Para el deck de presentación: 7 tipos de slide, incluyendo estructura de deck de inversores de 14 slides.

Paso 5: Figma MCP. El Figma MCP corre como servidor local desde Figma Desktop — Claude Code se conecta ahí. Agus pudo crear componentes de marca en Figma de forma automática. Este paso fue el que empezó a hacer tangible lo que veníamos construyendo. Detalle de infra que descubrimos en el camino: sin Figma Desktop abierto el servidor MCP no existe, así que la primera corrida no aplicó tipografía hasta que bajamos la app y abrimos el archivo ahí.

Paso 6: Skill /figma-deck. El output final de la sesión. Un skill de Claude Code que genera presentaciones completas en Figma on-brand desde texto. El flujo: describís el deck → el skill planea la estructura → recopila el contenido → construye los slides uno a uno en Figma con el brand system ya incorporado. No hay que pensar en colores, tipografías ni specs. Eso ya está resuelto.

El momento "aha" de la sesión fue cuando vimos el primer slide generarse en Figma automáticamente, respetando el color system y la tipografía de deRentas, sin que nadie hubiera tocado Figma. Agus se quedó mirando la pantalla un segundo antes de decir algo.

Qué cambió — y qué queda

Al final de las 3 horas, deRentas tenía algo que no tenía al llegar: una fuente de verdad de su marca que un agente de IA puede consumir directamente.

El BrandBook existe. Los tokens están en JSON. Las specs de los 5 formatos están documentadas. El skill /figma-deck está en producción, generando su primer deck.

Lo que queda: Agus sigue expandiendo el sistema, con autonomía total sobre la base que construyó. Es una v1.0 diseñada para crecer — y la dueña del sistema es ella.

"Agus la rompió toda, armando un montón de cositas; ya tiene una buena estructura y sobre esto va a seguir trabajando."

En 3 horas, deRentas pasó de tener assets dispersos a tener un sistema de marca que un agente de IA puede operar de forma autónoma.

Una nota sobre timing: Claude Design

La sesión con Agus fue el 15 de abril. Dos días después, el 17, Anthropic Labs lanzó Claude Design. Una de sus features estrella: durante el onboarding, lee el codebase y los design files de un equipo y extrae un brand system — colores, tipografía, componentes — que después aplica en cada proyecto.

Acá vale ser honesto con cómo funciona Claude Design: no espera ni consume un tokens.json pre-armado. Hace lo contrario — extrae su propio brand system a partir de inputs desordenados (un Figma, una URL, un repo, imágenes). O sea, eso lo resuelve solo.

¿Entonces para qué tener tu propia versión armada a mano? Por control y portabilidad. Es portable y controlable — lo versionás con git, lo lee cualquier agente, no solo Claude Design. Si mañana usás otro modelo, otro IDE, otra herramienta, el sistema sigue funcionando. Y no dependés de qué tan bien lo extraiga una herramienta — tener el brand system explícito y versionado es la fuente de verdad que vos controlás, no la interpretación que hizo un onboarding automático.

Lo construimos así antes de que Claude Design existiera. Resulta que esa decisión envejeció bien.

Takeaways

La documentación de marca en Markdown no es solo para humanos. Es la interface entre tu brand y los agentes de IA que van a producir contenido. Si no está en un formato que Claude Code pueda leer, no existe para el sistema.

Tokens en JSON no son para el agente — un LLM lee el color de un Markdown igual. Pagan cuando los consume algo que NO es un agente (un build de CSS, un plugin de Figma) y como fuente única que evita drift cuando el sistema escala.

El diagnóstico define el build. Podríamos haber armado un deck en la primera hora y mostrar algo concreto rápido. En cambio, pasamos 45 minutos entendiendo el problema real. Ese tiempo fue el mejor gasto de la sesión.

El CLAUDE.md del proyecto es memoria operativa, no configuración. Es lo que hace que el sistema sea coherente en el tiempo, incluso cuando la persona que lo construyó no está presente.

Construir para que el sistema se expanda. El objetivo de la sesión no era entregar un sistema completo. Era construir la base correcta para que Agus la lidere y expanda desde ahí. Eso cambia qué construís y cómo lo documentás.

Recursos del build
---
name: figma-deck
description: Genera una presentación en Figma siguiendo el sistema de marca de tu empresa. Crea un archivo Figma nuevo con slides correctamente tipografiados, coloreados y layouteados según tu brand system. El usuario provee el contenido (textos, cifras, títulos) y el skill arma la estructura visual, incluyendo el logo real en cada slide. Usar cuando el usuario diga "armá un deck", "creá una presentación", "generá slides", "hacé un pitch deck", "armá la presentación para inversores", "creá slides en Figma", o cualquier pedido relacionado con presentaciones Figma.
argument-hint: <descripción del deck: tema, audiencia, cantidad de slides>
user-invocable: true
allowed-tools: Read, Glob, Bash, mcp__plugin_figma_figma__create_new_file, mcp__plugin_figma_figma__use_figma, mcp__plugin_figma_figma__get_screenshot
context: fork
agent: general-purpose
---

> **Template genérico — cómo usar este skill en tu proyecto**
>
> Este skill fue construido en una sesión de Mate & Build. Para adaptarlo a tu empresa:
> 1. Reemplazá todos los `[PLACEHOLDERS]` con los valores reales de tu brand system
> 2. Agregá tus archivos de logo en la carpeta que definas
> 3. Ajustá los 7 tipos de slide según tus templates de deck
> 4. Guardá en `skills/figma-deck/SKILL.md` dentro de tu proyecto

---

## Configuración de marca (reemplazar antes de usar)

Antes de activar este skill, definí estas variables en tu `CLAUDE.md` o en un archivo `brand/tokens/`:

```
BRAND_PRIMARY   = [COLOR PRINCIPAL — ej: #F6C300]
BRAND_DARK      = [COLOR OSCURO — ej: #0B0B0B]
BRAND_WHITE     = [COLOR CLARO — ej: #FFFFFF]
BRAND_SURFACE   = [COLOR DE CARD — ej: #303036]
BRAND_MUTED     = [COLOR DE TEXTO SECUNDARIO — ej: #6B6B6B]

FONT_FAMILY     = [TU_FUENTE — ej: PP Neue Montreal, Inter, etc.]
FONT_BOLD       = Bold
FONT_MEDIUM     = Medium
FONT_BOOK       = Regular (o Book)

LOGO_POSITIVO   = [ruta/al/logo-positivo.png]
LOGO_NEGATIVO   = [ruta/al/logo-negativo.png]
ISOTIPO         = [ruta/al/isotipo.png]
```

---

## Step 0 — Input Check

Si `$ARGUMENTS` está vacío, preguntar al usuario:
- ¿De qué trata el deck? (tema y audiencia)
- ¿Cuántos slides aproximadamente?
- ¿Hay algún slide obligatorio (portada, cierre, métricas clave)?

## Step 1 — Leer el sistema de marca

Leer antes de cualquier acción:
- `brand/templates/deck-spec.md` (o donde tengás definidos los tokens del deck)
- `brand/tokens/colors.json`
- `brand/tokens/typography.json`
- `brand/tokens/spacing.json`

**Tokens críticos que necesitás definir:**

| Propiedad | Placeholder | Ejemplo |
|---|---|---|
| Canvas | 1920 × 1080 px | (estándar 16:9, no cambiar) |
| Margin | [MARGIN_PX] | 60px |
| Card padding | [CARD_PADDING_PX] | 40px |
| Card gap | [CARD_GAP_PX] | 30px |
| Card radius | [CARD_RADIUS_PX] | 16px |
| Accent bar height | [ACCENT_BAR_H]px, color [BRAND_PRIMARY] | 8px |
| Logo size | [LOGO_W] × [LOGO_H]px | 195 × 45px |
| Logo posición | [LOGO_TOP]px top, [LOGO_RIGHT]px right | 45px / 60px |
| Page number | [PAGENUM_BOTTOM]px bottom, [PAGENUM_RIGHT]px right | 20px / 60px |
| Label sección | [LABEL_TOP]px top, [LABEL_LEFT]px left | 60px / 60px |
| BG oscuro | [BRAND_DARK] | #0B0B0B |
| BG card | [BRAND_SURFACE] | #303036 |
| Acento | [BRAND_PRIMARY] | #F6C300 |
| Texto sobre oscuro | [BRAND_WHITE] | #FFFFFF |
| Texto sobre claro | [BRAND_DARK] | #0B0B0B |

## Step 2 — Planear la estructura

Con base en la descripción del usuario y los 7 tipos de slide, diseñar la estructura completa. Mostrar al usuario (tabla N° / Tipo / Modo / Descripción) y **esperar confirmación** antes de continuar.

| Tipo | Cuándo usarlo |
|---|---|
| **Portada** | Slide 1 siempre — BG del color principal de marca, texto oscuro |
| **Sección** | Separadores entre bloques temáticos — BG oscuro, número grande en color de acento |
| **Dato/métrica** | KPIs, cifras únicas — cifra grande en color de acento |
| **3-cards** | Comparativas, ventajas, pasos — 3 columnas con tarjetas |
| **2-columnas** | Texto + dato o imagen — 55% izq / 45% der |
| **Lista con íconos** | Beneficios, características — máx 5 ítems, íconos en color de acento |
| **Cierre/CTA** | Último slide siempre — BG color principal o negro, contacto |

## Step 3 — Recopilar contenido por slide

Una vez confirmada la estructura, pedir el contenido de todos los slides en un solo mensaje (≤ 7 slides) o en bloques de 4-5 (más slides).

- **Portada:** título principal, subtítulo, label categoría/año
- **Sección:** nombre de sección, número decorativo (ej: "01")
- **Dato/métrica:** cifra principal, descripción corta, contexto/copy
- **3-cards:** titular; para cada card: título, body, número o etiqueta del ícono
- **2-columnas:** titular + body (izquierda); dato grande o texto destacado (derecha)
- **Lista:** titular; ítems (máx 5)
- **Cierre/CTA:** claim principal, datos de contacto, modo de fondo (color principal u oscuro)

## Step 4 — Preparar los assets del logo

Leer los archivos de logo locales como base64:

```bash
base64 -i '[LOGO_NEGATIVO]'   # → LOGO_NEG_B64 (slides oscuros)
base64 -i '[LOGO_POSITIVO]'   # → LOGO_POS_B64 (slides claros y de marca)
base64 -i '[ISOTIPO]'         # → ISOTIPO_B64 (watermark, opacity baja)
```

## Step 5 — Cargar skill figma-use (OBLIGATORIO)

Invocar el skill `figma:figma-use` antes de cualquier llamada a `use_figma`. Sin este paso, las llamadas al Plugin API fallan.

## Step 6 — Crear el archivo Figma

Llamar `mcp__plugin_figma_figma__create_new_file` con nombre descriptivo. Guardar el `fileKey` retornado.

## Step 7 — Generar los slides (uno por uno, secuencial)

### Helper functions (incluir en CADA llamada)

```javascript
function hexToRgb(hex) {
  return {
    r: parseInt(hex.slice(1,3), 16) / 255,
    g: parseInt(hex.slice(3,5), 16) / 255,
    b: parseInt(hex.slice(5,7), 16) / 255,
  };
}

async function imageFromBase64(b64) {
  const bytes = Uint8Array.from(atob(b64), c => c.charCodeAt(0));
  return figma.createImage(bytes);
}

async function createImageRect(b64, w, h, x, y, scaleMode = 'FIT') {
  const img = await imageFromBase64(b64);
  const rect = figma.createRectangle();
  rect.resize(w, h);
  rect.x = x; rect.y = y;
  rect.fills = [{ type: 'IMAGE', imageHash: img.hash, scaleMode }];
  return rect;
}
```

### Estructura base (aplicar a TODOS los slides)

Reemplazá `[BRAND_PRIMARY]`, `[BRAND_DARK]`, `[BRAND_WHITE]`, `[FONT_FAMILY]`, `[LOGO_H]`, `[LOGO_W]`, y los offsets según tus tokens.

```javascript
const frame = figma.createFrame();
frame.name = `Slide ${N} — ${TIPO}`;
frame.resize(1920, 1080);
frame.x = (N - 1) * 2000;
frame.fills = [{ type: 'SOLID', color: hexToRgb(BG_COLOR) }];

// Barra de acento top (excepto portada)
if (MODO !== 'brand') {
  const bar = figma.createRectangle();
  bar.name = 'Accent Bar';
  bar.resize(1920, [ACCENT_BAR_H]);
  bar.x = 0; bar.y = 0;
  bar.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
  frame.appendChild(bar);
}

// Label de sección (top-left)
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' });
const label = figma.createText();
label.fontName = { family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' };
label.fontSize = [LABEL_SIZE];
label.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_MUTED]') }];
label.characters = LABEL_SECCION;
label.x = [MARGIN_PX]; label.y = [LABEL_TOP];
frame.appendChild(label);

// Logo (top-right)
const logoB64 = (MODO === 'brand' || MODO === 'claro') ? LOGO_POS_B64 : LOGO_NEG_B64;
const logo = await createImageRect(logoB64, [LOGO_W], [LOGO_H], 1920 - [LOGO_RIGHT] - [LOGO_W], [LOGO_TOP]);
logo.name = 'Logo';
frame.appendChild(logo);

// Número de página (bottom-right)
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOOK]' });
const pageNum = figma.createText();
pageNum.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOOK]' };
pageNum.fontSize = [PAGENUM_SIZE];
pageNum.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_MUTED]') }];
pageNum.characters = String(N);
pageNum.x = 1920 - [PAGENUM_RIGHT] - pageNum.width;
pageNum.y = 1080 - [PAGENUM_BOTTOM] - pageNum.height;
frame.appendChild(pageNum);

figma.currentPage.appendChild(frame);
```

### Tipo 1 — Portada (MODO 'brand', BG_COLOR = [BRAND_PRIMARY])

```javascript
// Watermark isotipo (centrado, opacity baja — ej: 0.12)
const watermark = await createImageRect(ISOTIPO_B64, 800, 800, (1920-800)/2, (1080-800)/2, 'FIT');
watermark.name = 'Watermark Isotipo';
watermark.opacity = [WATERMARK_OPACITY]; // reemplazá con tu valor (ej: 0.12)
frame.appendChild(watermark);

await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });

const h1 = figma.createText();
h1.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
h1.fontSize = 96;
h1.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_DARK]') }];
h1.characters = TITULO;
h1.x = [MARGIN_PX]; h1.y = 220;
frame.appendChild(h1);

const h2 = figma.createText();
h2.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
h2.fontSize = 60;
h2.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_DARK]') }];
h2.characters = SUBTITULO;
h2.x = [MARGIN_PX]; h2.y = h1.y + h1.height + 32;
frame.appendChild(h2);
```

### Tipo 2 — Sección/separador (MODO 'oscuro', BG_COLOR = [BRAND_DARK])

```javascript
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });

const num = figma.createText();
num.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
num.fontSize = 96;
num.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
num.characters = NUMERO_SECCION;
num.x = 1920 - [MARGIN_PX] - num.width; num.y = 200;
frame.appendChild(num);

const h2 = figma.createText();
h2.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
h2.fontSize = 60;
h2.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
h2.characters = NOMBRE_SECCION;
h2.x = [MARGIN_PX]; h2.y = 400;
frame.appendChild(h2);
```

### Tipo 3 — Dato/métrica (MODO 'oscuro', BG_COLOR = [BRAND_DARK])

```javascript
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOOK]' });

const cifra = figma.createText();
cifra.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
cifra.fontSize = 96;
cifra.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
cifra.characters = CIFRA;
cifra.x = [MARGIN_PX]; cifra.y = 280;
frame.appendChild(cifra);

const desc = figma.createText();
desc.fontName = { family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' };
desc.fontSize = 34;
desc.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
desc.characters = DESCRIPCION;
desc.x = [MARGIN_PX]; desc.y = cifra.y + cifra.height + 40;
frame.appendChild(desc);

const copy = figma.createText();
copy.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOOK]' };
copy.fontSize = 24;
copy.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_MUTED]') }];
copy.characters = CONTEXTO;
copy.x = [MARGIN_PX]; copy.y = desc.y + desc.height + 24;
frame.appendChild(copy);
```

### Tipo 4 — 3-cards (MODO 'oscuro', BG_COLOR = [BRAND_DARK])

```javascript
// ancho de cada card: (1920 - MARGIN*2 - GAP*2) / 3
const cardW = Math.floor((1920 - [MARGIN_PX]*2 - [CARD_GAP_PX]*2) / 3);
const cardH = 680, cardY = 220;
const cardsData = [CARD1, CARD2, CARD3]; // { titulo, body, etiqueta }

await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOOK]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });

for (let i = 0; i < 3; i++) {
  const card = figma.createFrame();
  card.resize(cardW, cardH);
  card.x = [MARGIN_PX] + i * (cardW + [CARD_GAP_PX]);
  card.y = cardY;
  card.cornerRadius = [CARD_RADIUS_PX];
  card.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_SURFACE]') }];

  const iconBox = figma.createRectangle();
  iconBox.resize(56, 56);
  iconBox.x = 40; iconBox.y = 40;
  iconBox.cornerRadius = 12;
  iconBox.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
  card.appendChild(iconBox);

  const iconLabel = figma.createText();
  iconLabel.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
  iconLabel.fontSize = 24;
  iconLabel.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_DARK]') }];
  iconLabel.characters = cardsData[i].etiqueta;
  iconLabel.x = 40 + (56 - iconLabel.width) / 2;
  iconLabel.y = 40 + (56 - iconLabel.height) / 2;
  card.appendChild(iconLabel);

  const titulo = figma.createText();
  titulo.fontName = { family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' };
  titulo.fontSize = 34;
  titulo.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
  titulo.resize(cardW - 80, titulo.height);
  titulo.characters = cardsData[i].titulo;
  titulo.x = 40; titulo.y = 120;
  card.appendChild(titulo);

  const body = figma.createText();
  body.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOOK]' };
  body.fontSize = 24;
  body.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
  body.resize(cardW - 80, body.height);
  body.characters = cardsData[i].body;
  body.x = 40; body.y = titulo.y + titulo.height + 24;
  card.appendChild(body);

  frame.appendChild(card);
}
```

### Tipo 5 — 2-columnas (MODO 'oscuro', BG_COLOR = [BRAND_DARK])

```javascript
const colIzqW = Math.floor(1920 * 0.55) - [MARGIN_PX] - 15;
const colDerX = Math.floor(1920 * 0.55) + [MARGIN_PX];

await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOOK]' });

const h2 = figma.createText();
h2.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
h2.fontSize = 60;
h2.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
h2.resize(colIzqW, h2.height);
h2.characters = TITULAR_IZQ;
h2.x = [MARGIN_PX]; h2.y = 220;
frame.appendChild(h2);

const body = figma.createText();
body.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOOK]' };
body.fontSize = 24;
body.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
body.resize(colIzqW, body.height);
body.characters = BODY_IZQ;
body.x = [MARGIN_PX]; body.y = h2.y + h2.height + 40;
frame.appendChild(body);

// Separador vertical
const sep = figma.createRectangle();
sep.resize(1, 800);
sep.x = Math.floor(1920 * 0.55); sep.y = 140;
sep.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
frame.appendChild(sep);

// Dato destacado (col derecha)
const dato = figma.createText();
dato.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
dato.fontSize = 96;
dato.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
dato.characters = DATO_DER;
dato.x = colDerX; dato.y = 320;
frame.appendChild(dato);

const copyDer = figma.createText();
copyDer.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOOK]' };
copyDer.fontSize = 24;
copyDer.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
copyDer.characters = COPY_DER;
copyDer.x = colDerX; copyDer.y = dato.y + dato.height + 24;
frame.appendChild(copyDer);
```

### Tipo 6 — Lista con íconos (MODO 'oscuro', BG_COLOR = [BRAND_DARK])

```javascript
// Máx 5 ítems. Si el usuario provee más, avisar y usar solo los primeros 5.
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOOK]' });

const titular = figma.createText();
titular.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
titular.fontSize = 48;
titular.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
titular.characters = TITULAR_LISTA;
titular.x = [MARGIN_PX]; titular.y = 160;
frame.appendChild(titular);

const items = ITEMS.slice(0, 5);
const itemY0 = titular.y + titular.height + 60;
for (let i = 0; i < items.length; i++) {
  const yPos = itemY0 + i * 110;

  const iconBox = figma.createRectangle();
  iconBox.resize(48, 48);
  iconBox.x = [MARGIN_PX]; iconBox.y = yPos;
  iconBox.cornerRadius = 12;
  iconBox.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_PRIMARY]') }];
  frame.appendChild(iconBox);

  const itemText = figma.createText();
  itemText.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOOK]' };
  itemText.fontSize = 24;
  itemText.fills = [{ type: 'SOLID', color: hexToRgb('[BRAND_WHITE]') }];
  itemText.characters = items[i];
  itemText.x = [MARGIN_PX] + 48 + 24;
  itemText.y = yPos + (48 - itemText.height) / 2;
  frame.appendChild(itemText);
}
```

### Tipo 7 — Cierre/CTA (BG = [BRAND_PRIMARY] o [BRAND_DARK])

```javascript
const textColor = MODO === 'brand' ? '[BRAND_DARK]' : '[BRAND_WHITE]';

await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_BOLD]' });
await figma.loadFontAsync({ family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' });

if (MODO === 'brand') {
  const watermark = await createImageRect(ISOTIPO_B64, 700, 700, (1920-700)/2, (1080-700)/2, 'FIT');
  watermark.opacity = [WATERMARK_OPACITY];
  frame.appendChild(watermark);
}

const claim = figma.createText();
claim.fontName = { family: '[FONT_FAMILY]', style: '[FONT_BOLD]' };
claim.fontSize = 60;
claim.fills = [{ type: 'SOLID', color: hexToRgb(textColor) }];
claim.characters = CLAIM;
claim.x = [MARGIN_PX]; claim.y = 320;
frame.appendChild(claim);

const contacto = figma.createText();
contacto.fontName = { family: '[FONT_FAMILY]', style: '[FONT_MEDIUM]' };
contacto.fontSize = 24;
contacto.fills = [{ type: 'SOLID', color: hexToRgb(textColor) }];
contacto.characters = CONTACTO;
contacto.x = [MARGIN_PX]; contacto.y = claim.y + claim.height + 48;
frame.appendChild(contacto);
```

## Step 8 — Confirmar y entregar

1. Llamar `mcp__plugin_figma_figma__get_screenshot` para capturar el resultado visual
2. Reportar: URL del archivo Figma, lista de slides generados (N° / tipo / título), problemas con fuentes o imágenes si los hubo

---

## Reglas de calidad

- Nunca usar fuentes distintas a las definidas en tu brand system
- Nunca usar colores fuera de los tokens del brand
- Máximo 5 ítems en slides de lista — si hay más, avisar y proponer dividir en 2 slides
- Portada NUNCA lleva barra de acento (el fondo ya es el color de marca)
- Logo siempre en posición top-right en todos los slides
- Generar slides secuencialmente — nunca en paralelo

## If Something Goes Wrong

| Error | Acción |
|---|---|
| Error de fuente | Avisar que debe instalarla en Figma. Continuar con Inter como fallback temporal |
| Error en `imageFromBase64` / `figma.createImage` | Verificar que el base64 no está truncado. Si falla, omitir logo en ese slide y anotar en reporte |
| `create_new_file` falla | Pedir URL de archivo Figma existente y crear frames en ese archivo |
| Más de 10 slides | Recopilar contenido en bloques de 5, confirmar cada bloque antes de avanzar |
| Usuario cambia contenido a mitad | Regenerar solo los slides afectados, no todo el deck |

---

*Skill construido en Mate & Build #4 — deRentas x Mate & Build, 2026-04-15.*
*Template genérico disponible en mateandbuild.com.ar*

Brand Folder Template — para que Claude Code (u otro agente) pueda operar tu marca


Template genérico construido en la sesión de Mate & Build con Agus Irioni (deRentas).

Adaptalo a tu marca reemplazando los placeholders <...> por tus valores reales.


Qué es esto


Un brand system filesystem-based, pensado para que un agente de IA lo lea como contexto y produzca piezas on-brand sin interpretar valores.


La diferencia con un BrandBook clásico en PDF: este vive en archivos Markdown + JSON, versionados con git, accesibles para cualquier agente (Claude Code, Cursor, Claude Design, etc.).


Estructura


brand/
  BRANDBOOK.md            ← fuente de verdad para humanos + agentes
  tokens/
    colors.json           ← paleta con nombres semánticos
    typography.json       ← familias, pesos, escalas por contexto
    spacing.json          ← grids, márgenes, paddings
  guidelines/
    color-system.md       ← reglas de combinación, modos, contraste
    typography.md         ← escalas por contexto + patrones
    logo-usage.md         ← clearspace, mínimos, usos incorrectos
    voice-tone.md         ← voz, tono, banco de copy por canal
  templates/
    deck-spec.md          ← 1920×1080 — presentaciones
    social-feed-spec.md   ← 1080×1350 — carruseles
    social-story-spec.md  ← 1080×1920 — stories
    alert-spec.md         ← 1200×1500 — alertas (ej: WhatsApp)
    doc-spec.md           ← A4 — documentos


Cómo usarlo con Claude Code


  1. Copiá esta carpeta dentro de tu proyecto, en una carpeta brand/.
  2. Reemplazá todos los placeholders <...> por tus valores reales.
  3. En el CLAUDE.md del proyecto, agregá una línea que indique dónde vive el brand system:

## Brand system
   Toda decisión visual o de copy se apoya en `brand/`. Leer `brand/BRANDBOOK.md` antes de producir piezas. Los valores numéricos viven en `brand/tokens/*.json` — usarlos directo, no interpretar.

  1. Cuando un skill o agente necesite producir una pieza, va a leer primero el BrandBook + tokens, después aplicar.

Por qué funciona


  • Markdown legible: humanos lo editan, modelos lo leen sin parseo extra
  • Tokens en JSON: los valores numéricos no son interpretables — se aplican
  • Specs por formato: el agente sabe qué canvas usar antes de empezar
  • Versionable con git: cada cambio de marca es una PR, no un mail a diseño

Qué NO incluye este template


  • Assets binarios (logo .ai, .otf, etc.) — eso lo agregás vos en brand/assets/
  • Tu BrandBook real — los placeholders son la estructura, no el contenido

Referencia


Build de origen: Mate & Build #4 — deRentas × Mate & Build


¿Tenés un problema para resolver?

Proponé tu caso. Los más votados por la comunidad se resuelven primero en Mate & Build.

Proponé tu problema →