# Reformix — Design System **Fecha:** 24-may-2026 **Fuente:** [specs.md](../specs.md) + [copy/COPY-GUIDE.md](../copy/COPY-GUIDE.md) + [negocio/modelo-negocio.md](../negocio/modelo-negocio.md) **Stack:** Next.js 14 + Tailwind + shadcn/ui > **Filosofía:** Cada decisión visual aquí tiene traducción directa a token de código en `design-tokens.css` y `tailwind.config.ext.js`. Si un color no está en los tokens, no existe. Si un espaciado no está en la escala, no se usa. --- ## 1. Contexto y personalidad de marca ### Proyecto **Reformix** — *"Un mercado de reformas más justo. Para los profesionales que cumplen lo que prometen."* SaaS B2B para empresas pequeñas de reformas en España, con captación de leads del cliente final a través de agente IA de voz + render + presupuesto entregado por WhatsApp. ### Audiencias visuales | Audiencia | Perfil | Implicación visual | |---|---|---| | **Reformista** (paga el SaaS) | Hombre 35-55, técnico de obra, perfil tech medio-bajo, usa WhatsApp, no le impresiona el diseño chulo, le impresiona la utilidad clara | Cero hipsterismo, claridad brutal, jerarquía evidente, datos sobre estilo | | **Cliente final** (usa el widget) | Hombre/mujer 30-65, propietario de vivienda, dispuesto a invertir 10-50 K€, tiene miedo de equivocarse | Tranquilizador, tipográficamente legible, tonos cálidos que no asusten, evitar agresividad visual | ### Personalidad de marca | Eje | Valor | Por qué | |---|---|---| | **Adjetivo 1** | **Profesional** | Es una herramienta de trabajo, no de juego. Los reformistas dependen de su credibilidad. | | **Adjetivo 2** | **Cercano** | El producto compite con marketplaces fríos (Habitissimo) y CRMs aburridos. La cercanía es diferencial. | | **Adjetivo 3** | **Honesto** | El sector está "deshonesto" según la entrevista. Posicionarnos como árbitros justos exige una estética que respalde eso. | | **NO somos** | **Corporativo frío · spammy · hipster techie** | Nada de azul corporativo genérico. Nada de "next-gen AI-powered platform". Nada de Comic Sans irónico ni gradientes psicodélicos. | ### Referencias visuales - **Linear** — rigor tipográfico, jerarquía clara, dark mode sólido. - **Notion** — calidez, accesibilidad, espacios generosos. - **Stripe** — profesionalidad sin frialdad, tipografía con carácter. - **Holded** (referencia española B2B) — confiable, claro, no innovador agresivo. **NO referencia:** Habitissimo, Wallapop, idealista (demasiado marketplace/portal); cualquier "AI startup template" de Vercel; landings con animaciones 3D innecesarias. --- ## 2. Identidad verbal > Reglas detalladas en [copy/COPY-GUIDE.md](../copy/COPY-GUIDE.md). Resumen aquí para alinear con visual. ### Tono - **Tuteo** universal. Reformista y cliente final. - **Frases cortas**, 2-3 líneas máximo por párrafo. - **Honestidad explícita** sobre limitaciones: *"Es orientativo. Tu visita sigue siendo la que cierra."* - **Lenguaje del sector** cuando aplique: showrooming, calidad básica/media/premium, ticket medio. - **Sin jerga corporativa**: no "optimizar pipeline", no "next-gen", no "transformación digital". ### Naming - **Producto:** Reformix (sin tilde, sin guión, una palabra). - **Producto interno:** *Asistente IA* (cara visible del agente de voz) en vez de "voicebot" o "agente conversacional". - **Métricas internas para reformista:** *Leads cualificados* (no "captados" ni "prospects"), *Visita gratuita*, *Presupuesto orientativo* (no "presupuesto"). - **Planes:** Starter / Pro / Business (estándar SaaS). - **Sello futuro:** *Precio Justo Certificado* (sin "®" ni tipo corporativo). Mayúscula inicial siempre. --- ## 3. Color ### 3.1 Paleta primaria — "Architectural Warmth" Decisión: rechazamos el azul SaaS genérico. Adoptamos una paleta inspirada en la cerámica y los acabados naturales — habla el lenguaje del sector sin caer en lo rústico. #### Brand colors | Token | Hex | Uso | Justificación | |---|---|---|---| | `--color-primary-900` | `#1F3A2E` | Texto en superficies claras, headings | Verde bosque oscuro: serio, sólido, asociado a "natural" sin ser ecológico panfletario | | `--color-primary-700` | `#2F5C46` | Botones primarios, links activos | Verde oliva profundo: profesional, transmite "experiencia" | | `--color-primary-500` | `#4D8A6D` | Acento medio, hover de botones | | | `--color-primary-300` | `#A8C8B5` | Backgrounds suaves, badges | | | `--color-primary-100` | `#E8F0EB` | Backgrounds muy suaves, hover states | | | `--color-primary-50` | `#F4F8F5` | Background de sección destacada | | #### Accent (terracota) | Token | Hex | Uso | |---|---|---| | `--color-accent-900` | `#7A3517` | Énfasis muy fuerte (rara vez) | | `--color-accent-600` | `#C25E33` | CTAs secundarios destacados, alertas no críticas, highlights | | `--color-accent-400` | `#E08A5F` | Iconos decorativos, badges | | `--color-accent-100` | `#FAEAE0` | Background de bloques destacados | > El terracota se usa con **moderación**: el CTA principal es verde oliva (primary-700), el terracota es para llamar la atención sobre un solo elemento en cada vista. ### 3.2 Neutrales (Stone — warm gray con tinte oliva) | Token | Hex | Uso | |---|---|---| | `--color-neutral-950` | `#161816` | Texto sobre fondo blanco — el negro más cálido | | `--color-neutral-900` | `#262826` | Headings sobre fondo claro | | `--color-neutral-700` | `#4A4E4A` | Texto body principal | | `--color-neutral-500` | `#7A807A` | Texto secundario, placeholders | | `--color-neutral-400` | `#9DA29D` | Texto disabled, separadores | | `--color-neutral-300` | `#C4C9C4` | Bordes | | `--color-neutral-200` | `#DDE0DD` | Bordes suaves, líneas divisorias | | `--color-neutral-100` | `#EDEFED` | Backgrounds muy suaves, cards alternas | | `--color-neutral-50` | `#F7F8F7` | Background secundario | | `--color-white` | `#FFFFFF` | Background principal, surfaces | ### 3.3 Escala semántica | Token | Hex | Uso | |---|---|---| | `--color-success-700` | `#2D7A4F` | Texto de success en badges | | `--color-success-500` | `#4DAA73` | Iconos de success, bordes | | `--color-success-100` | `#E0F0E6` | Background de mensajes de success | | `--color-warning-700` | `#9A6B0E` | Texto warning | | `--color-warning-500` | `#DA9A2C` | Iconos warning | | `--color-warning-100` | `#FAEFD3` | Background warning (banner licencia urbanística) | | `--color-danger-700` | `#A8331F` | Texto error | | `--color-danger-500` | `#D85940` | Iconos error | | `--color-danger-100` | `#FAE0DA` | Background error | | `--color-info-700` | `#1F5C7A` | Texto info | | `--color-info-500` | `#3D8AAA` | Iconos info | | `--color-info-100` | `#DDEDF5` | Background info | ### 3.4 Surfaces y combinaciones validadas (WCAG AA) | Combinación | Contraste | OK | |---|---|---| | `neutral-950` sobre `white` | 16.5:1 | ✅ AAA | | `neutral-700` sobre `white` | 7.8:1 | ✅ AAA | | `neutral-500` sobre `white` | 4.6:1 | ✅ AA | | `white` sobre `primary-700` | 7.2:1 | ✅ AAA — botón primario | | `white` sobre `accent-600` | 4.8:1 | ✅ AA — botón terracota | | `primary-900` sobre `primary-50` | 12.4:1 | ✅ AAA — texto en bloques destacados | | `danger-700` sobre `danger-100` | 6.1:1 | ✅ AA — mensajes de error | > **Regla:** ningún texto debe usar `neutral-400` o más claro sobre fondo blanco (no pasa AA). --- ## 4. Tipografía ### 4.1 Selección | Rol | Fuente | Por qué | |---|---|---| | **Display + Headings (H1, H2)** | **Instrument Serif** (Google Fonts) | Serif moderna con carácter. Da "peso editorial" que diferencia frente al SaaS-Inter genérico. Suena profesional sin ser corporativo. Pesa muy poco. | | **Sub-headings (H3, H4, H5)** | **Inter** | Misma familia que el body para coherencia. Semibold da jerarquía sin cambio de fuente. | | **Body + UI** | **Inter** | Estándar de legibilidad universal. Funciona en móvil. La conocen todos los devs. | | **Mono (rara vez — código, ID, datos técnicos)** | **JetBrains Mono** | Estándar dev-friendly. Solo para panel de leads y debug. | > **Decisión consciente:** evitar fuentes "techie" tipo Geist o IBM Plex. Inter es boring pero universal, y Instrument Serif aporta el carácter sin pedir permiso. ### 4.2 Escala tipográfica (modular ratio 1.25 — Major Third) | Token | Tamaño | Line-height | Uso típico | |---|---|---|---| | `text-xs` | 12px / 0.75rem | 1.5 | Captions, footnotes, badges | | `text-sm` | 14px / 0.875rem | 1.5 | Labels de form, secondary text, helper | | `text-base` | 16px / 1rem | 1.6 | **Body por defecto** (mínimo legible móvil) | | `text-lg` | 18px / 1.125rem | 1.5 | Body grande, intros, microcopy hero | | `text-xl` | 20px / 1.25rem | 1.4 | H5, subhead pequeño | | `text-2xl` | 24px / 1.5rem | 1.3 | H4 | | `text-3xl` | 30px / 1.875rem | 1.3 | H3 | | `text-4xl` | 36px / 2.25rem | 1.2 | H2 | | `text-5xl` | 48px / 3rem | 1.1 | H1 mobile, headings de sección | | `text-6xl` | 60px / 3.75rem | 1.05 | H1 desktop, hero | | `text-7xl` | 72px / 4.5rem | 1.0 | Display hero desktop (raro) | ### 4.3 Pesos cargados | Familia | Pesos | Justificación | |---|---|---| | Instrument Serif | 400 (regular), 400 italic | Diseñada para una sola weight, pero italic da énfasis en titulares | | Inter | 400, 500, 600, 700 | Regular body, medium labels, semibold botones y H3-H5, bold solo para énfasis fuerte | | JetBrains Mono | 400, 500 | Muy poco uso | ### 4.4 Reglas de uso - **H1 hero (desktop):** Instrument Serif, `text-6xl`, regular. Sin negrita. - **H1 hero (mobile):** Instrument Serif, `text-5xl`, regular. - **H2 sección:** Instrument Serif, `text-4xl`, regular. - **H3-H5:** Inter Semibold, `text-3xl` / `text-2xl` / `text-xl`. - **Body por defecto:** Inter Regular, `text-base`, line-height 1.6, color `neutral-700`. - **Labels de form:** Inter Medium, `text-sm`, color `neutral-900`. - **Botones:** Inter Semibold, `text-base` (md) / `text-sm` (sm) / `text-lg` (lg). - **Captions y helper text:** Inter Regular, `text-sm`, color `neutral-500`. --- ## 5. Espaciado y layout ### 5.1 Escala de espaciado (base 4px — coherente con Tailwind) | Token | Valor | Uso típico | |---|---|---| | `space-1` | 4px / 0.25rem | Gaps mínimos entre iconos y texto | | `space-2` | 8px / 0.5rem | Padding interno compacto (badges, pills) | | `space-3` | 12px / 0.75rem | Gap entre elementos relacionados | | `space-4` | 16px / 1rem | Padding estándar de inputs y cards pequeños | | `space-6` | 24px / 1.5rem | Separación entre bloques de un mismo grupo | | `space-8` | 32px / 2rem | Padding de cards grandes, márgenes de sección móvil | | `space-12` | 48px / 3rem | Separación entre secciones móvil | | `space-16` | 64px / 4rem | Separación entre secciones desktop | | `space-24` | 96px / 6rem | Padding vertical del hero | | `space-32` | 128px / 8rem | Separación generosa entre bloques desktop grandes | ### 5.2 Contenedores y grid | Token | Valor | Uso | |---|---|---| | `container-narrow` | 720px | Bloques de lectura largos (FAQ, T&C) | | `container-default` | 1200px | Landings, app general | | `container-wide` | 1440px | Panel del reformista con muchas columnas | | `gutter-mobile` | 24px | Padding lateral móvil | | `gutter-desktop` | 48px | Padding lateral desktop | ### 5.3 Breakpoints (Tailwind defaults) | Token | Valor | Dispositivo | |---|---|---| | `sm` | 640px | Móvil grande / phablet | | `md` | 768px | Tablet portrait | | `lg` | 1024px | Tablet landscape / desktop pequeño | | `xl` | 1280px | Desktop estándar | | `2xl` | 1536px | Desktop grande | --- ## 6. Componentes base ### 6.1 Border radius | Token | Valor | Uso | |---|---|---| | `rounded-sm` | 4px | Tags, badges pequeños | | `rounded-md` | 6px | Inputs, controles pequeños | | `rounded-lg` | 10px | Botones, cards, contenedores | | `rounded-xl` | 14px | Cards destacadas, hero blocks | | `rounded-2xl` | 20px | Modales, popovers grandes | | `rounded-full` | 9999px | Avatares, pills de estado, iconos circulares | > **Personalidad:** redondeado generoso (10-14px en cards) — friendly, moderno, pero no infantil (evitamos 24px+ en bloques que no sean decorativos). ### 6.2 Sombras (warm, sutiles) | Token | Valor | Uso | |---|---|---| | `shadow-xs` | `0 1px 2px rgba(22, 24, 22, 0.05)` | Bordes muy sutiles, divisores elevados | | `shadow-sm` | `0 1px 3px rgba(22, 24, 22, 0.08), 0 1px 2px rgba(22, 24, 22, 0.04)` | Cards estáticos, inputs | | `shadow-md` | `0 4px 6px rgba(22, 24, 22, 0.07), 0 2px 4px rgba(22, 24, 22, 0.04)` | Cards interactivos, hover | | `shadow-lg` | `0 10px 15px rgba(22, 24, 22, 0.08), 0 4px 6px rgba(22, 24, 22, 0.05)` | Dropdowns, popovers | | `shadow-xl` | `0 20px 25px rgba(22, 24, 22, 0.1), 0 10px 10px rgba(22, 24, 22, 0.04)` | Modales | | `shadow-glow` | `0 0 0 4px rgba(47, 92, 70, 0.15)` | Focus ring (primary-700 al 15 %) | > Sombras con base de `neutral-950` (no negro puro) para coherencia con la paleta cálida. ### 6.3 Botones | Variante | Background | Texto | Border | Uso | |---|---|---|---|---| | **Primary** | `primary-700` | `white` | — | CTA principal único por vista. *"Empezar gratis 14 días"*, *"Quiero mi presupuesto"* | | **Secondary** | `white` | `primary-700` | `primary-700` 1px | Acciones secundarias. *"Ver demo"* | | **Accent** | `accent-600` | `white` | — | Solo para acciones de waitlist o "Próximamente". Máximo 1 por vista. | | **Ghost** | `transparent` | `neutral-700` | — | Navegación, acciones de tercer nivel | | **Danger** | `danger-500` | `white` | — | Eliminar lead, revocar consentimiento | | **Link** | `transparent` | `primary-700` underline | — | Enlaces dentro de texto | #### Estados | Estado | Modificación | |---|---| | Default | Como tabla arriba | | Hover | Background −10 % luminosidad / opacity 0.95 | | Active | Background −15 % luminosidad / scale-95 | | Disabled | Opacity 0.5, cursor not-allowed | | Loading | Spinner inline, texto invisible o "Cargando..." | | Focus | `shadow-glow` (focus ring 4px al 15 % primary) | #### Tamaños | Tamaño | Padding | Font | Height | |---|---|---|---| | `sm` | `px-3 py-1.5` | `text-sm` semibold | 32px | | `md` (default) | `px-4 py-2.5` | `text-base` semibold | 44px | | `lg` | `px-6 py-3.5` | `text-lg` semibold | 52px | ### 6.4 Inputs | Atributo | Valor | |---|---| | Background | `white` | | Border default | `neutral-300` 1px | | Border focus | `primary-700` 2px + `shadow-glow` | | Border error | `danger-500` 2px | | Padding | `px-4 py-2.5` | | Border radius | `rounded-md` | | Font | `text-base` regular | | Color texto | `neutral-900` | | Color placeholder | `neutral-500` | | Label | `text-sm` medium, `neutral-900`, `mb-1.5` | | Helper | `text-sm` regular, `neutral-500`, `mt-1.5` | | Error message | `text-sm` regular, `danger-700`, `mt-1.5` | ### 6.5 Cards | Atributo | Valor | |---|---| | Background | `white` | | Border | `neutral-200` 1px | | Border radius | `rounded-xl` (14px) | | Padding | `p-6` mobile · `p-8` desktop | | Shadow default | `shadow-sm` | | Shadow hover (si interactivo) | `shadow-md` + transición 200ms | ### 6.6 Badges y pills (estados de lead) | Estado | Background | Texto | Icon | |---|---|---|---| | Nuevo | `primary-100` | `primary-900` | 🆕 | | Contactado | `info-100` | `info-700` | 📞 | | Visita agendada | `warning-100` | `warning-700` | 📅 | | Ganado | `success-100` | `success-700` | ✅ | | Perdido | `neutral-100` | `neutral-700` | ❌ | Estilo: `rounded-full`, `px-2.5 py-0.5`, `text-xs` semibold. ### 6.7 Alerts / banners | Tipo | Background | Border-left 4px | Texto | Uso | |---|---|---|---|---| | Info | `info-100` | `info-500` | `info-700` | Banner aviso | | Warning | `warning-100` | `warning-500` | `warning-700` | **"Esta obra puede requerir licencia urbanística"** | | Success | `success-100` | `success-500` | `success-700` | Confirmación de envío | | Danger | `danger-100` | `danger-500` | `danger-700` | Error de submit | Padding `p-4`, radius `rounded-lg`, icono 20px a la izquierda. --- ## 7. Iconografía ### Librería: **Lucide** (compatible nativamente con shadcn/ui) - **Tamaño base inline:** 16px (junto a texto inline) - **Tamaño base UI:** 20px (botones, alerts, badges) - **Tamaño standalone:** 24px (hero, features destacadas) - **Stroke width:** 1.75 (Lucide default — equilibrio entre fino y legible) - **Color por defecto:** hereda `currentColor` (configurable por contexto) ### Iconos clave del proyecto (recurrentes) | Concepto | Icono Lucide | |---|---| | Llamada / agente voz | `Phone`, `PhoneCall`, `Mic` | | WhatsApp (custom SVG) | Icono WhatsApp oficial (no en Lucide) | | Render / cámara | `Camera`, `ImageIcon` | | Presupuesto / factura | `Receipt`, `FileText` | | Lead nuevo | `Sparkles` | | Visita | `Calendar`, `MapPin` | | Licencia urbanística | `BookOpen`, `FileCheck2`, `Building2` | | Reformista pro | `HardHat`, `Hammer` | | Cliente final | `Home`, `User` | | Sello Precio Justo | `BadgeCheck` | | Configurador | `Settings2`, `SlidersHorizontal` | --- ## 8. Motion y transiciones ### Duraciones | Token | Valor | Uso | |---|---|---| | `duration-fast` | 150ms | Hover, focus, micro-feedback | | `duration-base` | 250ms | Transiciones estándar (cards, modales pequeños) | | `duration-slow` | 400ms | Aparición de modales grandes, transiciones de sección | ### Easing | Token | Valor | Uso | |---|---|---| | `ease-out` | `cubic-bezier(0.16, 1, 0.3, 1)` | Entradas (recomendado por defecto) | | `ease-in` | `cubic-bezier(0.7, 0, 0.84, 0)` | Salidas | | `ease-in-out` | `cubic-bezier(0.65, 0, 0.35, 1)` | Movimientos en ambos sentidos | ### Qué se anima - Hover de botones (background) - Focus de inputs (ring) - Aparición de modales y popovers - Cuenta atrás *"Te llamamos en 1:47"* (animación de los dígitos) - Pasos del wizard (slide horizontal suave) - Aparición del render generado (fade-in + ligero scale-up) ### Qué NO se anima - Texto de lectura largo - Tablas y datos del panel - Logos - Iconos estáticos ### Reduced motion Respetar siempre `prefers-reduced-motion`: deshabilitar todas las animaciones excepto fade simples (opacity). --- ## 9. Imagery y fotografía ### Estilo de imagen - **Fotografías reales** de cocinas y baños como base. Antes/después. - **Renders IA** generados por el propio producto en hero y casos de uso. - Tonos cálidos, luz natural, no demasiado pulcras (que parezcan casa real, no catálogo IKEA). - Evitar stock genérico de "team handshake" o "businessman with laptop". ### Aspect ratios recomendados - Hero principal: 16:9 desktop, 4:5 mobile - Cards de testimonio: 1:1 o 4:5 - Antes/después: 1:1 con divisoria deslizante --- ## 10. Aplicación a las superficies de specs.md ### Landing B2B (superficie A) - Hero: H1 Instrument Serif `text-6xl` en `neutral-950`, subtitle `text-xl` Inter en `neutral-700`, CTA primary verde oliva - Sección "Lo que está roto hoy": background `neutral-50`, cards con icono terracota + texto neutral - Demo del widget: contenedor con `shadow-xl` y `rounded-2xl` para destacarlo - Pricing: 3 cards con tier Pro destacada (border `primary-700` 2px + ribbon "Recomendado") - "Próximamente": bloque con background `accent-100`, textos `accent-900`, CTA accent-600 ### Landing B2C (superficie B) - Hero con imagen antes/después grande arriba - Branding del reformista en header en card propio con `shadow-sm` - Form: 3 pasos con progress bar arriba (verde oliva), inputs con `rounded-md` generoso - Pantalla de cuenta atrás: dígitos grandes `text-7xl` Instrument Serif, fondo `primary-50` ### Panel reformista (superficie D) - Sidebar oscuro (`primary-900` background, `primary-100` texto) con logo Reformix arriba - Lista de leads tipo tabla con filas hover en `neutral-50` - Detalle de lead: card con `shadow-md` mostrando todos los artefactos en tabs - Botón "Marcar Ganado" en `success-500` - Modal de "precio final firmado" enfocado y con focus trap --- ## 11. Checklist de calidad - [x] Contraste WCAG AA verificado en todas las combinaciones críticas - [x] La escala tipográfica respeta 16px como mínimo legible móvil - [x] Cubrimos los 4 estados semánticos (success, warning, danger, info) - [x] 10 niveles de neutrales con tinte cálido (no grays fríos genéricos) - [x] Escala de espaciado consistente (base 4px, sin valores arbitrarios) - [x] Border-radius coherente con personalidad (generoso pero no infantil) - [x] Fuentes disponibles en Google Fonts gratis (Instrument Serif + Inter + JetBrains Mono) - [x] Tokens con nombre semántico (`primary-700` no `green-medium`) - [x] Iconografía con librería elegida (Lucide) - [x] Identidad verbal documentada con tono claro y ejemplos - [x] Decisiones justificadas con conexión a la personalidad de marca - [x] Aplicación a superficies del producto descrita --- ## 12. Archivos asociados - [`design-tokens.json`](design-tokens.json) — Tokens en formato estándar (importables en Figma Tokens o style-dictionary) - [`design-tokens.css`](design-tokens.css) — CSS Custom Properties listas para `:root` - [`tailwind.config.ext.js`](tailwind.config.ext.js) — Extensión de la config de Tailwind con los tokens --- ## Próximos pasos 1. **Validación visual rápida** con el equipo (15 min): proyectar la paleta y los 3-4 ejemplos de aplicación. Confirmar que verde-oliva + terracota encaja con la intuición del equipo. 2. **Generar mockups en Stitch o Figma** usando los tokens y el copy de [COPY-GUIDE.md](../copy/COPY-GUIDE.md) — sin lorem ipsum. 3. Instalar shadcn/ui con tema custom basado en los tokens, antes de empezar a programar. 4. Crear un Storybook ligero (post-MVP) con los componentes core para que el equipo no reinvente cada vez.