Design System v1.1 · Ecommerce

Gomilovers
Design System

Sistema de diseño derivado del Manual de Identidad Gomilovers (Brandbook Básico, 2025) para la tienda online. Tokens, componentes y patrones ecommerce listos para producción: accesibles, responsive y tematizables.

Personalidad de marca: cercana, confiable y seria — bienestar para adultos, nunca infantil. Gomitas nutracéuticas que hacen fácil el autocuidado y transmiten salud y confianza. Eso se traduce en: el beneficio como protagonista de cada pieza, radios generosos y botones píldora, gradientes monocromáticos sutiles dentro de una misma línea de color, contraste tipográfico con Poppins ExtraBold, frutas reales solo como acento secundario de salud y frescura, y el corazón reservado al logo (jamás como motivo decorativo recurrente).

Regla de oro: los componentes solo referencian tokens semánticos (capa 2). Los valores crudos viven únicamente en la capa de primitivos. Así el sistema se retematiza (incluido dark mode) cambiando una sola capa.
02

Color

Paleta extraída del manual (pp. 20–21). El rojo #E84755 es el color primario y debe dominar CTAs y acentos. El blanco puro transmite claridad y confianza. Los 8 secundarios aportan versatilidad sin alejarse del estilo central — aquí cada uno recibe además un rol de categoría de producto.

Primitivos · Marca

Rojo Gomilovers

#E84755 · CMYK 1 83 56 0

--c-brand-500

Vino

#91334E

--c-brand-700

Rojo tinte

#FCE4E7

--c-brand-100

Blanco puro

#FFFFFF

--c-white

Primitivos · Secundarios (manual p.21)

Malva

#B4709C

--c-malva-500

Azul

#4171AF

--c-azul-500

Cian

#38B9CC

--c-cian-500

Verde

#3E805C

--c-verde-500

Lima

#B1BF58

--c-lima-500

Amarillo

#FDCD4C

--c-amarillo-500

Naranja

#F39542

--c-naranja-500

Tinta 900

#1F1F1F

--c-ink-900

El manual imprime el amarillo como "#4FDCD4C" (7 dígitos): es una errata. El swatch es amarillo → valor canónico del sistema: #FDCD4C.

Tokens semánticos (lo que usan los componentes)

TokenApunta aUso
--color-action--c-brand-500Relleno de CTA primario. Máx. 1 por pantalla.
--color-action-hover--c-brand-700Hover/active del CTA.
--color-on-action#FFFFFFTexto/icono sobre el CTA — solo etiquetas grandes (≥19px bold).
--color-link--c-brand-700Enlaces y texto de marca sobre claro (pasa 4.5:1).
--surface / -raised / -sunkenblanco / blanco / #FAFAFAPágina / tarjetas / pozos.
--text / -muted / -subtletinta 900/700/500Texto primario / secundario / metadatos.
--focus-ring--c-azul-500Anillo de foco visible (contraste 3:1 sobre blanco y sobre rojo).
--color-cat-*secundariosAcento de apoyo por beneficio (ver §03) — el color acompaña, el beneficio define.

Regla 60 / 30 / 10

≈60% neutrales (blanco, fondos suaves) · ≈30% Rojo Gomilovers (CTAs, acentos, marca) · ≈10% secundarios (categorías, badges, estados). El rojo manda; los secundarios condimentan.

Tabla de contraste (WCAG AA, verificada)

Par texto / fondoRatioResultado
Tinta 900 #1F1F1F sobre blanco16.48:1AA texto normal ✓
Tinta 700 #4A4A4A sobre blanco8.86:1AA texto normal ✓
Tinta 500 #6F6F6F sobre blanco5.02:1AA texto normal ✓
Vino #91334E sobre blanco (links, precios)7.53:1AA texto normal ✓
Blanco sobre Rojo #E84755 (CTA)3.84:1AA texto grande / UI (≥19px bold) ✓
Blanco sobre Vino #91334E7.53:1AA texto normal ✓
Rojo #E84755 sobre blanco (iconos, bordes UI)3.84:1AA componente UI (3:1) ✓
Azul foco #4171AF sobre blanco4.99:1Anillo de foco ✓
Tinta 900 sobre Amarillo #FDCD4C (badge Nuevo)11.00:1AA texto normal ✓
Dark · #F4F2F2 sobre #12121416.78:1AA texto normal ✓
Dark · link #FF9AA4 sobre #1212149.28:1AA texto normal ✓
Política sobre el rojo: #E84755 con blanco da 3.84:1 → no alcanza 4.5:1 de texto normal. Por eso (a) las etiquetas de CTA primario son siempre ≥19px en peso 700 (califican como texto grande, exige 3:1), y (b) cualquier texto de marca en tamaño normal sobre fondo claro usa el Vino --color-link. Nunca rojo #E84755 en texto corrido pequeño.
03

Gradientes & Beneficios

El manual (p. 25) define los elementos gráficos que este sistema tokeniza: gradientes monocromáticos — siempre tonos de una misma línea de color del book, tomados con cuentagotas de la escala de Colores secundarios, con transición sutil —, vectores geométricos limpios y contraste tipográfico con ExtraBold sobredimensionada de fondo. Las categorías se definen por beneficio, nunca por una fruta o un color.

Tokens de gradiente (monocromáticos — 3 tonos de una sola línea)

Token3 tonos (misma línea, sin llegar a blanco)Uso
--g-brand#EC6874 → #E84755 → #CC3E4B (165°)Hero, newsletter, marca
--g-coral#EC6874 → #E84755Gomi Energy Para Ella — rojo principal + subtono · acentos de marca
--g-vino#A5586E → #91334E → #802D45Gomi Dreams / Descanso y relajación (morado oscuro) · fondos profundos
--g-amarillo#FDD66C → #FDCD4C → #DFB443Destacados, badges promocionales
--g-naranja#F5A864 → #F39542 → #D6833AAcentos cálidos, promos
--g-cian#5CC6D5 → #38B9CC → #31A3B4Frescura, secciones informativas
--g-azul#638BBD → #4171AF → #39639AGomi Energy Para Él (azul oscuro)
--g-verde#619779 → #3E805C → #377151Activa tu metabolismo (verde oscuro)
--g-lima#BFCB76 → #B1BF58 → #9CA84DNaturalidad, sellos de producto
--g-malva#C28AAE → #B4709C → #9E6389Acentos suaves
Regla del cuentagotas: cada gradiente usa 2–3 tonos de una misma línea del book, tomados con cuentagotas de la escala de «Colores secundarios»: tinte suave → color base → tono apenas más profundo. El tinte nunca se acerca al blanco y el cambio es sutil, sin saltos bruscos. NUNCA mezclar líneas — amarillo con naranja, celeste con azul o verde limón con verde oscuro son combinaciones incorrectas.

Paneles por beneficio

Composición canónica: gradiente monocromático + el beneficio como protagonista (titular Poppins ExtraBold) + palabra de fondo rotada al 14% de opacidad. La taxonomía es la de gomilovers.com: Activa tu metabolismo · Descanso y relajación · Energía y líbido. El color de cada panel es un acento de apoyo — lo que identifica a la categoría es el beneficio. Energía y líbido distingue sus dos productos: Para Ella (rojo principal) y Para Él (azul oscuro).

Activa tu metabolismo

--gradient-cat-metabolismo · --color-cat-metabolismo

Descanso y relajación

--gradient-cat-descanso · --color-cat-descanso

Energía y líbido · Para Ella

--gradient-prod-energia-ella · --color-prod-energia-ella

Energía y líbido · Para Él

--gradient-prod-energia-el · --color-prod-energia-el

Frutas reales — recurso SECUNDARIO: la fotografía de fruta transmite salud y frescura, pero no caracteriza productos ni categorías y nunca es protagonista de la composición (el protagonista es el beneficio). Cuando se use como acento (Higgsfield, nano banana pro), la fruta flota sobre el gradiente monocromático de una misma línea — nunca color plano, nunca líneas mezcladas. Prompt base: «studio food photography, [fruta] como elemento secundario, gradiente vertical suave de [hex claro] a [hex oscuro] del mismo color, sombra sutil, sin texto».
04

Tipografía

Poppins es la única familia tipográfica de la web (embebida en base64, cero sustitución): titulares y fondos en ExtraBold, cuerpo en Regular, etiquetas y tags en Medium/SemiBold. Las manuscritas del book — DK Lemon Yellow Sun y Please write me a song — son de apoyo gráfico para social media y piezas publicitarias exclusivamente: NUNCA en la web (la marca debe verse seria y confiable, no infantil). Montserrat fue retirada del sistema: no figura en el book.

Display · Poppins 800 · 48pxSabor y bienestar
H2 · Poppins 800 · 32pxen cada Gomita
H3 · Poppins 700 · 20pxGomi Balance — Vinagre de manzana
Body · Poppins 400 · 16pxGeneramos bienestar con productos innovadores y efectivos.
Small · Poppins 500 · 14px2 gomitas por día · 60 unidades por frasco
Tag · Poppins 500 · 13px / .12emSabor y bienestar hecho Gomitas

Escala

TokenFamilia / pesoTamaño / líneaUso
--text-displayPoppins 80048px / 1.05Hero. ExtraBold sobredimensionada también como fondo (contraste tipográfico).
--text-h2Poppins 80032px / 1.15Títulos de sección.
--text-h3Poppins 70020px / 1.3Títulos de tarjeta / producto.
--text-bodyPoppins 40016px / 1.5Párrafos. Nunca menor a 16px en cuerpo.
--text-smPoppins 50014px / 1.45Metadatos, captions.
--text-tagPoppins 500–70011–13px / .1em trackTag de marca, etiquetas, badges, iconografía.
Manuscritas — fuera de la web: DK Lemon Yellow Sun y Please write me a song se reservan para social media y piezas publicitarias (así lo indica el book). En la web no se cargan ni se usan: ningún @font-face, ningún token. Cualquier texto que en un arte publicitario iría en manuscrita, en la web se resuelve con Poppins.
/* Carga de fuentes — estrategia de este sistema:
   · Poppins (licencia OFL): embebida en base64 dentro del archivo → cero sustitución, offline.
   · Manuscritas del book (DK Lemon Yellow Sun, Please write me a song): NO se cargan en la web.
     Son exclusivas de social media y piezas publicitarias. */
05

Espaciado & Radius

Base de 4px. Los radios son el dial de personalidad: Gomilovers es juguetona → radios generosos y botones píldora.

--s-1 · 4px
--s-2 · 8px
--s-3 · 12px
--s-4 · 16px
--s-5 · 24px
--s-6 · 32px
--s-7 · 48px
--s-8 · 64px

Radius

--r-sm 8px
--r-md 12px
--r-lg 16px
--r-xl 24px
--r-full píldora
06

Sombras & Elevación

Tres niveles neutros + una sombra teñida de marca para el hover del CTA (refuerza identidad — solo en acciones primarias).

--shadow-sm
--shadow-md
--shadow-lg
--shadow-brand
07

Breakpoints & Responsive

Mobile-first: estilos base para móvil, media queries min-width hacia arriba. El tráfico ecommerce es mayoritariamente móvil.

TokenValorComportamiento requerido
base<480pxGrid 1 col · navbar condensada (logo + carrito) · drawer 100vw · CTA de PDP sticky-bottom.
--bp-sm480pxGrid 2 cols · drawer máx. 90vw.
--bp-md768pxGrid 3 cols · navbar con enlaces completos · PDP a 2 columnas (galería + buy-box).
--bp-lg1024pxGrid 4 cols · drawer 400px.
--bp-xl1280pxContenedor máx. 1200px centrado.
08

Componentes UI

Cada componente se entrega con todos sus estados: rest, hover, focus-visible, active, disabled, loading y error donde aplique. Touch targets ≥44px siempre.

Botones — variantes

Botones — tamaños y estados

Las etiquetas del CTA primario van en 19px / 700 mínimo (texto grande WCAG → blanco sobre #E84755 pasa con 3.84:1). Para acciones pequeñas usa la variante secondary (texto Vino sobre blanco, 7.53:1). El estado disabled añade aria-disabled y el loading aria-busy.
<button class="btn btn-primary">Agregar al carrito</button>
<button class="btn btn-primary" disabled aria-disabled="true">Deshabilitado</button>
<button class="btn btn-primary" aria-busy="true"><span class="spinner"></span>Agregando…</button>

Badges

Nuevo Oferta En stock Agotado Sueño & Relax

Formularios — estados

Ingresa un email válido

Stepper de cantidad

1 El − se deshabilita en el mínimo. Cada instancia controla su propia línea.

Barra de envío gratis

Te faltan S/ 45.10 para envío gratis

Product card — estados

Nuevo

Activa tu metabolismo

Gomi Balance — Vinagre de manzana para metabolismo y digestión

S/ 99.00

Agotado

Descanso y relajación

Gomi Dreams — Melatonina, valeriana y manzanilla

S/ 99.00

El nombre se recorta a 2 líneas (-webkit-line-clamp:2) — los nombres largos no rompen la tarjeta. Variante agotado: atenuada, badge gris, CTA deshabilitado. Variante skeleton: shimmer mientras carga.
09

Patrones Ecommerce

Especificaciones de los patrones de conversión. La demo (demo.html) los implementa funcionando.

PDP — Página de producto

ZonaRegla
GaleríaImagen principal sobre el gradiente de su categoría; fila de miniaturas debajo — botones reales, la activa lleva borde rojo y aria-pressed="true"; clic intercambia la imagen.
Título + precioH1 Poppins 800; precio en Vino, grande; badge de estado encima si aplica.
CTAPrimario píldora, etiqueta ≥19px/700; full-width y sticky-bottom en móvil (la fuga ViewContent→AddToCart es el mayor leak del funnel). Estado loading al agregar.
BeneficiosTiles pequeños con el tinte de la categoría (p. ej. «13 vitaminas», «2 al día», «Sin azúcar añadida»).
Cross-sellTarjetas compactas «Combínalo con» debajo — palanca directa de AOV.

Carrito

ReglaDetalle
Modelo de datosEl carrito es un array de líneas {id, nombre, precio, qty}. Nunca un contador global.
Por líneaMiniatura + nombre + precio + stepper propio + eliminar. Todo recálculo (total, barra de envío) es en vivo.
Envío gratisUmbral S/ 120. Barra role="progressbar" con relleno en gradiente cítrico.
CheckoutCTA primario full-width fijado al pie del drawer con el total visible.

Estados vacíos y de borde (obligatorios)

EstadoPatrón
Carrito vacíoÍcono de carrito (vector geométrico) + «Tu carrito está vacío» + CTA «Seguir comprando» dentro del drawer.
Sin resultadosMensaje + sugerencias de categorías — nunca un panel en blanco.
AgotadoTarjeta/PDP atenuadas, CTA deshabilitado + «Avísame» secundario.
CargandoSkeleton shimmer en tarjetas y PDP.
Error de formularioBorde danger + mensaje vinculado con aria-describedby + aria-invalid.
10

Accesibilidad

PolíticaImplementación
ContrasteAA: 4.5:1 texto normal, 3:1 texto grande y componentes UI. Tabla verificada en §02. El rojo de marca nunca se usa como texto corrido pequeño.
Foco visible:focus-visible con anillo azul --focus-ring de 3px + offset 2px en todo elemento interactivo (azul: visible sobre blanco y sobre rojo).
Touch targets≥44×44px en botones, steppers, iconos. Botones icon-only llevan aria-label.
Movimiento reducido@media (prefers-reduced-motion: reduce) desactiva marquee, slides y heartbeat; el toast pasa a fade.
Live regionsToast de confirmación con role="status" aria-live="polite"; cantidades del carrito con aria-live.
Drawer modalrole="dialog" aria-modal, trampa de foco, cierre con Esc y overlay, retorno de foco al disparador, fondo inert.
FormulariosTodo input con <label>; errores con aria-describedby y aria-invalid.
11

Motion

InteracciónTransiciónFallback reduced-motion
Hover CTAlift -1px + shadow-brand · .15sSolo cambio de color
Hover tarjetalift -6px + shadow-lg · .15s easeSolo borde
Drawer carritotranslateX .3s cubic-bezier(.2,.7,.3,1)Aparece sin deslizar
Toastslide-up .3sFade
Favoritoheartbeat scale 1→1.35→1 · .4sSolo cambio de color
Marqueevelocidad constante 80px/s, loop -50%Estático
Skeletonshimmer 1.4s infiniteFondo estático
12

Theming / Dark mode

La capa semántica es la que se reapunta: los componentes no cambian. Activa el modo oscuro con data-theme="dark" en <html> (prueba el botón flotante de esta página). El rojo de acción se mantiene — su contraste etiqueta/relleno no depende del tema — pero links y foco usan variantes claras.

[data-theme="dark"]{
  --surface:#121214; --surface-raised:#1C1C20; --surface-sunken:#0D0D0F;
  --text:#F4F2F2; --text-muted:#C6C2C3; --text-subtle:#969096;
  --border:#2C2A2E;
  --color-accent-soft:#3B2026;   /* tinte rojo oscuro */
  --color-link:#FF9AA4;          /* 9.3:1 sobre #121214 */
  --focus-ring:#7FB4E8;          /* azul claro, 3:1 sobre oscuro */
}
Re-verifica contraste en dark: un par que pasa sobre blanco puede fallar sobre casi-negro. Los valores de arriba ya están verificados (tabla §02).
13

Do / Don't

✓ Hacer

  • Usar el logotipo en su versión original sobre blanco; negativo o negro sobre fondos de color (únicas variantes permitidas).
  • Respetar el área de seguridad: X = ancho de la letra «S» del logo, con o sin tag descriptivo.
  • Gradientes siempre monocromáticos, dentro de una misma gama de la paleta oficial.
  • Frutas y alimentos reales como recurso fotográfico central, sobre su gradiente de gama.
  • Poppins ExtraBold sobredimensionada como elemento gráfico de fondo (contraste tipográfico).
  • Tipografías de apoyo solo como acento publicitario/social, 1–2 usos por pieza.
  • Etiquetas de CTA primario en ≥19px / 700.

✗ No hacer

  • No deformar, rotar ni deconstruir el logo; no alterar ubicaciones de sus elementos.
  • No usar colores ajenos a la gama corporativa — en logo ni en UI.
  • No aplicar efectos (sombras, biseles, contornos) al logotipo.
  • No mezclar gamas en un gradiente (p. ej. cian→naranja) ni usar fondos de color plano para las frutas.
  • No usar #E84755 como texto corrido pequeño sobre blanco (3.84:1 < 4.5:1) — usar Vino #91334E.
  • No usar DK Lemon Yellow Sun ni Please write me a song en la web — son exclusivas de social media y piezas publicitarias.
  • No usar el corazón como motivo decorativo recurrente — solo en el logo; la marca debe verse seria, no infantil.
  • No mezclar líneas de color en un gradiente (amarillo↛naranja, celeste↛azul, verde limón↛verde oscuro).
  • No identificar categorías ni productos con frutas o colores — la categoría se define por el beneficio.
  • No usar fuentes genéricas (Inter, Roboto, Arial) en ninguna pieza.
Logo: esta documentación usa una aproximación tipográfica («gomilovers ♥» en Poppins ExtraBold) como placeholder. En producción debe sustituirse por el asset vectorial oficial del manual, sin alteración alguna.
14

React + Tailwind

Para la tienda real: Tailwind leyendo las variables CSS — una sola fuente de verdad, sin hex duplicados, y el dark mode sigue funcionando gratis. Los componentes HTML/CSS de la demo mapean 1:1 a estas clases.

// tailwind.config.js
module.exports = {
  darkMode: ['selector', '[data-theme="dark"]'],
  theme: { extend: {
    colors: {
      action: 'var(--color-action)',
      'action-hover': 'var(--color-action-hover)',
      'on-action': 'var(--color-on-action)',
      'accent-soft': 'var(--color-accent-soft)',
      link: 'var(--color-link)',
      surface: 'var(--surface)',
      'surface-raised': 'var(--surface-raised)',
      'surface-sunken': 'var(--surface-sunken)',
      ink: 'var(--text)',
      'ink-muted': 'var(--text-muted)',
      line: 'var(--border)',
      'cat-metabolismo': 'var(--color-cat-metabolismo)',
      'cat-descanso': 'var(--color-cat-descanso)',
      'cat-energia': 'var(--color-cat-energia)',
    },
    backgroundImage: {
      'g-brand': 'var(--g-brand)', 'g-amarillo': 'var(--g-amarillo)',
      'g-cian': 'var(--g-cian)', 'g-verde': 'var(--g-verde)', 'g-malva': 'var(--g-malva)',
    },
    borderRadius: { pill: 'var(--r-full)', card: 'var(--r-lg)' },
    boxShadow: { brand: 'var(--shadow-brand)', card: 'var(--shadow-lg)' },
    fontFamily: {
      display: ['Poppins','sans-serif'], body: ['Poppins','sans-serif'],
      tag: ['Poppins','sans-serif'],
    },
  }},
}
// Button.jsx — variantes, tamaños y estados
export function Button({ variant='primary', size='md', loading=false, disabled=false, children, ...props }) {
  const base = 'inline-flex items-center justify-center gap-2 font-bold rounded-pill min-h-[52px] transition-all ' +
               'focus-visible:outline focus-visible:outline-[3px] focus-visible:outline-offset-2 ' +
               'focus-visible:outline-[var(--focus-ring)] disabled:opacity-45 disabled:cursor-not-allowed';
  const variants = {
    primary:   'bg-action text-on-action text-[19px] hover:bg-action-hover hover:shadow-brand hover:-translate-y-px',
    secondary: 'bg-surface text-link border-2 border-action hover:bg-accent-soft',
    ghost:     'text-ink-muted hover:bg-accent-soft hover:text-link',
  };
  const sizes = { sm:'px-5 py-2 text-base min-h-[44px]', md:'px-8 py-3', lg:'px-10 py-4 text-[21px] min-h-[60px]' };
  return (
    <button className={`${base} ${variants[variant]} ${sizes[size]}`}
            disabled={disabled || loading} aria-busy={loading} {...props}>
      {loading && <span className="spinner" aria-hidden="true" />}
      {children}
    </button>
  );
}