Arranca en 30 segundos
Descarga la base, pégala y ya estás dentro del sistema. Todo lo demás en esta página es la explicación de esa base.
Carga Plus Jakarta Sans y pega tokens.css.
Nunca escribas un color, radio o tiempo "a mano": todo sale de los tokens.
Copia los componentes de las secciones 8 a 13 — el botón de Copiar está en cada bloque.
Antes de entregar, corre el checklist y revisa los anti-patrones.
1 · Los seis principios
Todo lo demás en esta guía es consecuencia de estos seis. Si algo no está documentado, resuélvelo con ellos.
1 · El fondo manda el color
El verde solo existe sobre oscuro. El navy solo sobre claro. Es la regla que más se rompe y la que más delata un diseño que no es nuestro.
2 · Bordes de medio píxel
.5px solid, nunca 1px. Un borde grueso separa una interfaz cara de una barata.
3 · Todo lo que se toca, responde
Un botón que no se mueve al pasarle el cursor se siente muerto.
4 · Movimiento lento y suave
Un solo easing, y las cosas suben 2 o 3 píxeles, no 10. Si la animación se nota, está mal calibrada.
5 · Jerarquía con color
Un texto secundario es #5b6478, no negro al 50%. La opacidad se adivina en pantalla y desaparece impresa.
6 · Nada se inventa
Si no hay dato, va un guion largo —. Un cero fingiendo ser dato es peor que un hueco honesto.
2 · Logo
Dos versiones oficiales en SVG (383×68). Usar siempre estas, en toda página, diseño e imagen.
| Versión | URL | Cuándo |
|---|---|---|
| AZUL | …/69cde95ac859395cde4752e3.svg | Fondos claros y blancos |
| BLANCO | …/69cde95a69eb1fa3e7917e1d.svg | Fondos oscuros y navy |
- Tamaños: nav 180px · sidebar de app alto 32px · footer 140px · OG alto ~48px
- Siempre enlaza a
https://superleads.mx(o al inicio si es app interna) - El logo va solo: sin caja blanca detrás ni contenedor decorativo. Si el fondo es oscuro, usa la versión blanca — no metas el azul en un recuadro
- Ícono de "acceder":
…/68bdf4dd6d0aaa7737d9cfdd.png - La versión texto y el PNG viejo ya no se usan en diseños nuevos
3 · Color
Tres primarios resuelven el 80% de cualquier pantalla. Los secundarios sostienen y matizan; los de estado están reservados y nunca se reciclan.
Colores primarios
Colores secundarios
Neutros y texto
Textos sobre fondo oscuro
#ffffff — Texto principal
#7a9fd4 — Subtítulos y descripciones
#4a6aaa — Labels, notas, contadores
#3a5a9a — Texto de apoyo, el más tenue permitido
Colores de estado
Reservados. Nunca decorativos ni como "serie 4" de una gráfica. Siempre acompañados de texto o ícono — el color solo nunca comunica.
Tokens — copia esto al inicio de tu CSS
:root{
/* — Primarios — */
--green:#56EF9F; --navy:#002582; --navy-deep:#001240;
/* — Secundarios — */
--green-d:#2BC878; --navy-mid:#001a5e;
--blue:#0039C8; --blue-mid:#2A89FB;
--blue-soft:#F4F7FF; --blue-softer:#EEF2FF;
/* — Neutros — */
--ink:#1a1a1a; --border:#e0e8f8;
--muted:#5b6478; --dim:#98a1b0;
/* — Estado — */
--ok:#0ca30c; --warn:#eb6834;
--bad:#d03b3b; --destructive:#d92d43;
/* — Gráficas (paleta validada, separada de la marca) — */
--chart-1:#2a78d6; --chart-2:#eb6834; --chart-3:#1baf7a;
/* — Movimiento — */
--ease:cubic-bezier(.16,1,.3,1);
/* — Sombras — */
--shadow-sm:0 1px 2px rgba(0,37,130,.04);
--shadow-card:0 10px 32px rgba(0,37,130,.08);
--shadow-btn:0 10px 28px rgba(0,37,130,.22);
--shadow-cta:0 10px 28px rgba(86,239,159,.28);
--shadow-pill:0 10px 32px rgba(0,37,130,.08);
}Reglas de uso — las que no se negocian
| Regla | Por qué |
|---|---|
| Verde SOLO sobre navy/oscuro. Nunca sobre blanco. | Sobre blanco no alcanza contraste y se ve barato. Sobre claro, usa navy o blue. |
| Navy para texto y botones sobre fondos claros. | Es la voz de la marca en documentos y formularios. |
| Blue para links, bordes activos y eyebrows claros. | Es el "verde del contexto claro". |
| Los colores de estado no se reciclan. | Si el rojo también es decorativo, el rojo de alerta deja de alarmar. |
Las gráficas usan --chart-*, no la marca. | La paleta de marca no pasa pruebas de daltonismo en marcas pequeñas. |
| Texto siempre en tinta, nunca del color de su serie. | Un valor pintado del color de su barra se vuelve ilegible. |
4 · Tipografía
Familia única: Plus Jakarta Sans. No hay segunda fuente.
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,400;0,500;0,600;0,700;0,800;1,700;1,800&display=swap" rel="stylesheet">
Hero H1 con énfasis
46–50px · 800 · -1.8px · 1.07
Título de página
32–36px · 800 · -0.8px · 1.12
Título de tarjeta
16–22px · 800 · -0.3px · 1.2
Subtítulo de sección — la línea que explica de qué va lo que sigue, en tono tranquilo.
14–15px · 400 · 1.7
Texto body. El cuerpo de todo lo que se lee de corrido, con interlineado generoso para que el ojo no se pierda entre renglones largos.
13–15px · 400–500 · 1.78
10–11px · 700 · 1.3px · mayúsculas
$4,260,000.00
Stat · 26–32px · 800 · -1px · tabular-nums
Reglas
- Énfasis en H1:
<em>italic — verde sobre oscuro, azul sobre claro - Números en columna o que cambian en vivo:
font-variant-numeric: tabular-nums. Sin esto los dígitos bailan al actualizarse - Nunca centres párrafos de más de dos líneas. Títulos sí, texto corrido no
- Ancho de lectura: 65–75 caracteres (
max-width: 46remen documentos)
5 · Espaciado y radios
Escala de múltiplos de 4, sin excepción: 4 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 56 · 72
8px
controles
12px
tarjetas
16–24px
contenedores
pill
badges
| Contexto | Desktop | Mobile |
|---|---|---|
| Hero / Footer / CTA block | 72px 56px | 28px 18px |
| Sección estándar | 72px 56px | 28px 18px |
| Tarjeta | 20–24px | 16px |
| Panel interno | 16–20px | 14px |
6 · Pantallas — de un celular a una sala de juntas
Lo que se ve en una laptop de 15" no sirve en una tele a cuatro metros ni en un teléfono en la mano. Esta sección deja resuelto qué pasa en cada tamaño para que nadie tenga que pensarlo.
6.1 · La pregunta que casi nadie hace
Un texto de 14px se lee perfecto a 50 cm y es invisible a 3 metros. Antes de elegir tamaños, pregúntate a qué distancia está el ojo:
Celular 30 cm · Laptop 50–60 cm · Monitor 60–80 cm · Sala de juntas o TV 2–5 m. Entre la laptop y la sala hay 5 veces más distancia: el contenido tiene que crecer en la misma proporción.
6.2 · Los cinco anchos que existen
Todo dispositivo del mundo cae en uno de estos cinco. Los puntos de corte están donde de verdad cambia el uso, no donde salió un teléfono nuevo.
| Rango | Qué es | Distancia | Columnas | Padding lateral | Texto base |
|---|---|---|---|---|---|
320–639 | Celular | 30 cm | 1 | 18px | 14px |
640–1023 | Tablet · ventana partida | 40 cm | 2 | 24px | 14px |
1024–1439 | Laptop 13"–15" | 50–60 cm | 2–3 | 40px | 14px |
1440–2559 | Monitor 24"–27" | 60–80 cm | 3–4 | 56px | 15px |
2560+ | Monitor 32" · TV · proyector | 1–5 m | 4 + tope de ancho | 56px | 16px |
6.3 · Qué se hace en cada uno
El tamaño no es solo cuánto cabe: es qué está haciendo la persona.
Celular
- Consulta rápida, de pie, una sola mano
- Nunca se llena un Rayos X aquí
- Sí se lee la hoja del cliente y se contesta WhatsApp
- Todo a una columna · botones de ancho completo
- Acciones importantes abajo: es donde llega el pulgar
Tablet
- Lectura y presentación uno a uno
- También: laptop con la ventana a media pantalla
- Dos columnas · la barra lateral se esconde
- Área táctil de 44px obligatoria: se usa con dedo
Laptop 13"–15"
- Donde se trabaja de verdad: aquí se llena el Rayos X en vivo
- El tamaño más común del equipo — optimiza para acá
- Barra lateral + contenido
- Ojo: 15" y 13" comparten ancho, pero en 13" todo se ve 15% más chico
Monitor 24"–27"
- Trabajo con datos: analítica, tablas largas, varias ventanas
- Contenido topado a 1240–1400px y centrado
- Texto base sube a 15px
- No estires el contenido: una línea de 2000px no se puede leer
Sala de juntas · TV
- Presentar a un grupo, a metros de distancia
- Texto base 16px · cifras protagonistas al doble
- Nada por debajo de 14px en pantalla — no se ve
- Máximo 3 ideas por vista
6.4 · Los puntos de corte, en código
Cinco rangos, cuatro cortes. No inventes más: cada corte extra es una combinación más que alguien tiene que probar.
/* Base: móvil primero. Sin media query = celular. */ :root{ --max:1240px; --pad:18px; } body{ font-size:14px; } /* 640 — tablet y ventanas a media pantalla */ @media (min-width:640px){ :root{ --pad:24px } } /* 1024 — laptop: aparece la barra lateral */ @media (min-width:1024px){ :root{ --pad:40px } } /* 1680 — monitor grande: crece el TEXTO, no el ancho */ @media (min-width:1680px){ :root{ --pad:56px } body{ font-size:15px } } /* 2400 — sala de juntas y 4K */ @media (min-width:2400px){ :root{ --max:1420px } body{ font-size:16px } }
Antes de escribir un @media, prueba con una rejilla que se acomode sola. No se rompe en el ancho que no probaste — y son la mayoría.
Pero escríbela bien: minmax(280px, 1fr) desborda cuando el contenedor mide menos de 280px (pasa dentro de tarjetas, en celulares chicos y en ventanas partidas). La forma a prueba de todo es:
/* ❌ Desborda si el contenedor es más angosto que 280px */ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); /* ✅ El min() lo deja encogerse hasta el ancho disponible */ grid-template-columns: repeat(auto-fit, minmax(min(280px,100%), 1fr));
6.5 · El caso SuperLeads: la videollamada
Nuestro escenario más delicado no es una pantalla: son dos a la vez. El asesor comparte su laptop y el cliente lo ve en lo que tenga.
| Lado | Realidad | Consecuencia de diseño |
|---|---|---|
| El asesor | Laptop 13"–15", ventana de Zoom encima | El área útil real es de ~1100px, no 1440. Diseña para eso. |
| El cliente | Recibe el video escalado; a veces lo ve en un celular | Lo compartido pierde ~30% de nitidez: nada crítico por debajo de 14px. |
| Compresión | El video comprime: los tonos suaves se aplastan | Los grises tenues desaparecen. Jerarquía por color y tamaño, no por sutileza. |
| Lo que se comparte | La pantalla completa, con la barra lateral | Por eso existe el modo presentación (§18): oculta el menú y deja el contenido. |
La prueba real: comparte la pantalla en una llamada contigo mismo desde el celular. Si no puedes leer la cifra principal desde el teléfono, está muy chica.
6.6 · Dos cosas que no son el ancho
Zoom del navegador
Mucha gente trabaja al 110% o 125% — sobre todo en 13". Un usuario a 125% en una pantalla de 1440px ve 1152px de ancho: se le aplica el diseño de laptop chica. Por eso los cortes se ponen donde cambia el uso, no donde está el hardware.
Alto de pantalla
Una laptop de 13" tiene ~700px de alto útil con el navegador abierto. Lo que debe verse sin desplazar: el título, la cifra principal y la primera acción. Todo lo demás puede quedar abajo.
Densidad (Retina)
Una pantalla Retina de 2880px reporta 1440px al navegador. Los píxeles CSS son los que importan; la densidad solo pide logos en SVG — que ya usamos siempre.
6.7 · Dónde se rompen las pantallas
Los cinco puntos donde falla el 90% de los diseños, y qué revisar en cada uno:
| Ancho | Qué se rompe | La causa |
|---|---|---|
320px | Tablas y URLs largas empujan la página | Falta overflow-wrap:anywhere y envolver la tabla en un contenedor con overflow-x:auto |
~430px | Una rejilla salta a 2 columnas y todo queda ilegible | minmax con mínimo muy chico. Sube el mínimo a 240–280px |
768px | Se esconde el menú y queda pantalla sin salida | El botón de menú o de volver solo existía en la barra lateral |
1024px | Contenido aplastado entre barra lateral y márgenes | Falta min-width:0 en el área de contenido |
2560px+ | Todo diminuto y perdido en el centro | El ancho se topó pero el texto nunca creció |
6.8 · Prueba de pantallas — los cinco anchos
Antes de entregar, abre el inspector y ponte en estos cinco. Son 90 segundos:
7 · Sombras y bordes
Grandes, suaves y teñidas de navy — nunca negras ni duras. Una sombra negra sobre nuestro azul se ve sucia.
Al ras · solo borde
Apoyado · tarjeta en reposo
Levantado · hover, panel
Encima · modal, píldora
/* Nivel 0 — al ras */ border:.5px solid var(--border); /* Nivel 1 — apoyado */ box-shadow:0 1px 2px rgba(0,37,130,.04); /* Nivel 2 — levantado */ box-shadow:0 10px 32px rgba(0,37,130,.08); /* Nivel 3 — encima de todo */ box-shadow:0 8px 40px rgba(0,0,0,.12); /* Intención — CTA verde en hover */ box-shadow:0 10px 28px rgba(86,239,159,.28); /* Intención — navy en hover */ box-shadow:0 10px 28px rgba(0,37,130,.22);
Bordes
- Estructurales: siempre
.5px solid. En Tailwind:border-[0.5px] - Sobre claro:
#e0e8f8· Sobre oscuro:rgba(255,255,255,.07), hoverrgba(86,239,159,.25) - Punteado solo para zonas de "agregar" y estados vacíos
8 · Movimiento — el sentir del clic
Esta sección separa una interfaz que se siente cara de una que se siente lenta. Todo se mide desde que el dedo toca.
La única curva
--ease:cubic-bezier(.16,1,.3,1);
Sale rápido y frena suave. Todo usa esta curva. Si algo usa linear o ease-in-out, está fuera del sistema.
Los tiempos
| Interacción | Duración | Qué se mueve |
|---|---|---|
| Presionado (active) | 0ms — inmediato | Baja a scale(.98) o pierde su lift. Debe ser instantáneo: es el acuse de recibo del clic. |
| Hover de botón | 200ms | translateY(-2px) + sombra de intención |
| Hover de tarjeta | 300ms | translateY(-3px) + sombra nivel 2 |
| Cambio de color | 200ms | color, background, border-color |
| Panel / acordeón | 300ms | opacity + translateY(6px→0) |
| Modal / overlay | 250ms | opacity + scale(.95→1) |
| Fondo decorativo | 90–130s | Deriva imperceptible (§16) |
La regla de los 400 ms
Lo que tarda una acción define cómo se comunica:
| Tarda | Qué mostrar |
|---|---|
< 100ms | Nada. Solo el estado active del botón. |
100–400ms | Nada más que el active. Un spinner que parpadea molesta más que ayuda. |
400ms – 2s | Spinner dentro del botón + botón deshabilitado. El texto no cambia. |
2s – 10s | Spinner + texto que cambia ("Guardando…", "Analizando…"). |
> 10s | Pantalla de proceso con etapas que avanzan. El usuario tiene que ver que algo pasa, no un spinner eterno. |
Retrasos de guardado (debounce)
| Acción | Espera | Por qué |
|---|---|---|
| Autoguardado de formulario | 2500ms | Suficiente para no guardar en cada tecla, corto para no perder trabajo. |
| Autoguardado de nota | 1200ms | El texto libre se escribe en ráfagas más cortas. |
| Búsqueda mientras se escribe | 300ms | Debajo se siente nervioso; arriba, lento. |
| Al salir de la pantalla | 0ms | Todo debounce pendiente debe dispararse. Nunca se pierde lo tecleado. |
Todo botón que dispara algo debe, en este orden: 1) hundirse al instante · 2) deshabilitarse mientras trabaja · 3) decir cómo terminó (Guardado 14:32 o el mensaje real del error). Nunca "algo salió mal" — siempre qué salió mal y qué hacer.
9 · Botones
Pásales el cursor: todos son los reales del sistema.
Primario — verde (CTA principal)
El de la acción más importante de la pantalla. Solo uno por vista.
.btn-primary{
display:inline-flex;align-items:center;justify-content:center;gap:8px;
background:var(--green);color:var(--navy);
padding:14px 26px;border-radius:8px;border:none;
font-family:inherit;font-size:14px;font-weight:700;cursor:pointer;
transition:transform .2s var(--ease),box-shadow .2s var(--ease),background-color .2s;
}
.btn-primary:hover{transform:translateY(-2px);box-shadow:var(--shadow-cta)}
.btn-primary:active{transform:translateY(0);box-shadow:none}
.btn-primary:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none}
.btn-primary:focus-visible{outline:2px solid var(--blue);outline-offset:2px}Secundario — navy
La acción importante pero no principal, sobre fondo claro.
.btn-navy{
background:var(--navy);color:#fff;
padding:12px 22px;border-radius:8px;border:none;
font-size:13px;font-weight:700;cursor:pointer;
transition:transform .2s var(--ease),box-shadow .2s var(--ease),background-color .2s;
}
.btn-navy:hover{background:var(--navy-mid);transform:translateY(-2px);box-shadow:var(--shadow-btn)}
.btn-navy:active{transform:translateY(0);box-shadow:none}Terciario, fantasma y destructivo
/* Terciario — acciones de apoyo en fila */ .btn-outline{background:#fff;color:var(--navy);border:.5px solid var(--border); padding:10px 18px;border-radius:8px;font-size:13px;font-weight:700} .btn-outline:hover{background:var(--navy);color:#fff;border-color:var(--navy)} /* Fantasma — navegación, cancelar */ .btn-ghost{background:transparent;color:var(--muted);padding:10px 18px;font-size:13px;font-weight:600} .btn-ghost:hover{background:rgba(0,37,130,.05);color:var(--navy)} /* Destructivo — discreto hasta que se necesita */ .btn-danger{background:transparent;color:var(--muted);padding:8px;border-radius:8px} .btn-danger:hover{background:#fef2f2;color:var(--destructive)}
Tamaños e íconos
| Tamaño | Padding | Fuente | Cuándo |
|---|---|---|---|
| Grande | 16px 30px | 15px | Hero, CTA de cierre |
| Normal | 14px 26px | 14px | Acción principal |
| Compacto | 10px 18px | 13px | Barras de acciones |
| Mini | 6px 14px | 12px | Dentro de tarjetas, nav |
| Ícono | 36px cuadrado | — | Solo ícono, title obligatorio |
- Íconos de
14–16px,stroke-width:2,fill:none - Color: navy sobre verde · blanco sobre navy · hereda en outline y ghost
gap:8pxrespecto al texto. Ícono a la izquierda, salvo flechas de avance
El botón no cambia de tamaño al entrar en carga (reserva el ancho). Un botón que se encoge y crece es el detalle que arruina una interfaz por lo demás correcta.
10 · Formularios
Achica la ventana y mira la rejilla: se compacta sola de dos columnas a una, sin media queries.
La rejilla que se compacta sola
.form-grid{
display:grid;
grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));
gap:20px;
}
/* Campo que necesita todo el ancho */
.form-grid .full{grid-column:1/-1}auto-fit + minmax es la clave: si caben dos columnas de 280px las pone, si no colapsa a una. Nunca uses repeat(2, 1fr) fijo — se desborda en móvil. Para grupos de tres: minmax(200px, 1fr).
Formulario vivo
Como aparece en el panel y en la hoja del cliente.
Se muestra junto al colegio durante la llamada.
Solo alumnos pagando colegiatura hoy — sin lista de espera.
Liga o celular — el botón verde abre la conversación al instante.
Correo inválido.
El botón nunca desaparece: se apaga y ocupa el mismo espacio.
Marca todas: lo normal es más de una.
Anatomía de un campo
.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:13px;font-weight:500;color:var(--navy)}
.field input,.field textarea,.field select{
width:100%;padding:10px 14px;
border:.5px solid var(--border);border-radius:8px;background:#fff;
font-family:inherit;font-size:14px;color:var(--ink);
transition:border-color .2s,box-shadow .2s;
}
.field input::placeholder{color:var(--dim)}
.field input:hover{border-color:#c9d6f0}
.field input:focus{
outline:none;border-color:var(--blue);
box-shadow:0 0 0 3px rgba(0,57,200,.10);
}
.hint{font-size:11px;line-height:1.45;color:var(--muted)}
.err-msg{font-size:12px;font-weight:500;color:var(--destructive)}
.field input[aria-invalid="true"]{border-color:var(--destructive)}
/* Número protagonista */
.field input.grande{height:56px;font-size:24px;font-weight:600;
color:var(--navy);font-variant-numeric:tabular-nums}El hint es obligatorio en cualquier campo donde quepa duda de qué contar o en qué unidad. Resuelve la pregunta antes de que se haga: qué incluir, qué no, o a qué cálculo alimenta el dato.
La regla de los tres estados
Un Sí/No con "No" preseleccionado hace que el campo se vea contestado sin que nadie lo haya contestado — y contamina los datos.
Clic sobre la opción ya activa la des-selecciona. Y en el código: if (valor != null), nunca if (valor) — porque 0 es una respuesta.
| Valor | Significa | Se ve |
|---|---|---|
null | Sin preguntar | Ningún chip activo |
0 / no | Respondió que no | Chip "No" activo |
1 / sí | Respondió que sí | Chip "Sí" activo |
Validación y autoguardado
- Valida al salir del campo (
blur), no en cada tecla — marcar en rojo un correo a medio teclear es hostil - Solo lo verdaderamente obligatorio bloquea. Un campo que frena el avance rompe la conversación en una sesión en vivo
- Si el envío falla, lleva al usuario al error. Un botón que no hace nada porque hay un error en otra pantalla es un botón roto
- Se guarda solo, y se dice: debounce 2.5s, flush al salir, indicador
Guardando… → Guardado 14:32 - El botón de avanzar se llama "Guardar y Continuar", no "Continuar" — nombra lo que hace y da tranquilidad
13 · Tarjetas
Pásales el cursor: suben 3px con sombra teñida de navy.
Sobre fondo claro
Blanco, borde .5px, radio 12px, sombra nivel 1.
Misma altura
Todas las tarjetas de una rejilla miden igual.
Sobre fondo oscuro
Fondo blanco al 4%, borde blanco al 7%. Hover: borde verde al 25%.
.card{
background:#fff;border:.5px solid var(--border);border-radius:12px;
padding:20px;box-shadow:var(--shadow-sm);
transition:transform .3s var(--ease),box-shadow .3s,border-color .3s;
}
.card:hover{transform:translateY(-3px);box-shadow:var(--shadow-card);
border-color:rgba(0,57,200,.25)}
/* Sobre oscuro */
.card-dark{background:rgba(255,255,255,.04);border:.5px solid rgba(255,255,255,.07)}
.card-dark:hover{border-color:rgba(86,239,159,.25)}
/* Rejilla uniforme */
.cards{display:grid;gap:24px;grid-template-columns:repeat(auto-fill,minmax(min(280px,100%),1fr))}Todas las tarjetas con la misma altura y el mismo ancho (height:100% en el hijo). Una tarjeta "destacada" del doble de ancho deja huecos con casi cualquier número de elementos — la simetría gana.
14 · Eyebrows, badges y stats
Eyebrow
.eyebrow{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.eyebrow::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--blue)}
.eyebrow span{font-size:11px;font-weight:700;text-transform:uppercase;
letter-spacing:1.3px;color:var(--blue)}
/* Sobre oscuro */
.eyebrow-dark::before{background:var(--green)}
.eyebrow-dark span{color:var(--green)}Badges y pills
Stats
El stat héroe (la cifra que sostiene la conversación) va solo, sobre navy-deep, a 48–60px, con su contexto humano debajo en una fila de stats chicos. Una cifra grande sin contexto es un número; con contexto es un argumento.
15 · Grids y layout
| Uso | Columnas |
|---|---|
| Hero | 1fr 1fr |
| Tarjetas de features | repeat(auto-fill, minmax(280px, 1fr)) |
| Stats bar | repeat(auto-fit, minmax(160px, 1fr)) |
| Formulario | repeat(auto-fit, minmax(280px, 1fr)) |
| CTA block | 1fr auto |
| Contenido + widget | 1fr 1fr |
| Panel de app | sidebar 288px + 1fr |
Anchos máximos: app 1400px · página de contenido 1100px · documento de lectura 46rem.
Usa auto-fit/auto-fill con minmax antes que media queries. El layout que se acomoda solo no se rompe en el tamaño que no probaste.
16 · Visualización de datos
La paleta de marca NO se usa en gráficas: el verde y el navy no pasan las pruebas de contraste ni de daltonismo en marcas pequeñas.
Comparación — barras a la misma escala
Composición — apilada al 100% con separación de 2px
Reglas
- Un solo tono claro→oscuro para magnitudes. Dos tonos + gris para polaridad. Nunca arcoíris
- El color sigue a la entidad, no a su posición: si un filtro cambia el número de series, las que quedan no cambian de color
- Texto en tinta, nunca del color de la serie. La marca de color va al lado
- Leyenda siempre con 2+ series, y etiqueta directa en las importantes
- Marcas finas: líneas 2px, puntos ≥8px, separación de 2px entre segmentos apilados
- Contraste en marcas oscuras: sobre relleno oscuro el texto va blanco, sin excepción
- Nunca dos ejes Y. Dos magnitudes distintas → dos gráficas
- Sin dato, no hay gráfica. No dibujes un cero: oculta el panel
Números en la interfaz
- Moneda con dos decimales y símbolo (
$134,000.00), porcentajes con 1–2 decimales - Sin dato:
—(guion largo), nunca0,N/Ani vacío - Fechas en
America/Mexico_City, formato medium (14 ago 2026)
17 · Fondos y elementos decorativos
Círculos difusos muy tenues, muy grandes, siempre detrás. Y una deriva tan lenta que a simple vista está quieta.
.fondo{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.globo-1{position:absolute;top:-30%;right:-15%;width:520px;height:520px;
border-radius:50%;background:rgba(42,137,251,.05);filter:blur(100px)}
.globo-2{position:absolute;bottom:-30%;left:-10%;width:480px;height:480px;
border-radius:50%;background:rgba(86,239,159,.05);filter:blur(110px)}
/* Deriva — el fondo respira sin que nadie lo note */
@keyframes deriva{
0%,100%{transform:translate3d(0,0,0) scale(1)}
50% {transform:translate3d(-48px,36px,0) scale(1.08)}
}
.globo-1{animation:deriva 90s ease-in-out infinite}
.globo-2{animation:deriva 130s ease-in-out infinite reverse}
/* Círculo de acento en secciones oscuras */
section::before{content:"";position:absolute;right:-100px;top:-100px;
width:480px;height:480px;border-radius:50%;
background:rgba(86,239,159,.03);pointer-events:none}Separador de barra de stats (sobre oscuro): rejilla con gap:1px y fondo #0a3070 — el de la cabecera de esta página.
18 · Estados de la interfaz
Toda pantalla que carga datos necesita cuatro diseños, no uno.
Vacío
Aún no hay diagnósticos. Inicia una sesión para descubrir oportunidades.
Cargando
Consultando el censo del INEGI…
Arriba de 10s: etapas que avanzan.
Error
No se pudo guardar: verifica que la migración 0010 esté aplicada.
El mensaje real, junto a la acción que falló. Nunca destruye lo escrito.
Éxito
Discreto: Guardado 14:32 en tinta.
Toast solo para acciones grandes · 3s · abajo al centro.
19 · Modos especiales
Modo presentación
- Oculta la navegación y deja solo el contenido, para compartir pantalla
- El botón que lo activa debe ser visible desde cualquier pantalla: si se puede encender en un lado y no apagar en otro, es una trampa
- El estado persiste y se restaura antes del primer pintado, para que no haya parpadeo
Modo privado (métricas ocultas)
Conversión
6.16%
Ocupación
70.00%
filter: blur(7px); user-select: none;— no se lee ni se copia- Los nombres se ven, las cifras no. Un ojo al lado revela u oculta
- Arranca oculto por defecto: es más seguro descubrir a propósito que tapar a las prisas
20 · Comportamientos (JavaScript)
Los cinco comportamientos que hacen que la interfaz se sienta viva. Cópialos tal cual: ya traen resueltos los casos que rompen en producción.
19.1 · Autoguardado con flush de salida
Guarda solo mientras se escribe, y nunca pierde lo tecleado aunque el usuario cierre o navegue: el guardado pendiente se dispara al salir.
let temporizador = null, pendiente = false;
function alCambiar(valor){
if (temporizador) clearTimeout(temporizador);
pendiente = true;
temporizador = setTimeout(() => { pendiente = false; guardar(valor); }, 2500);
}
// Flush: lo que salva el trabajo cuando se cierra o se navega
function flush(){
if (!pendiente) return;
pendiente = false;
guardar(obtenerValorActual());
}
window.addEventListener("pagehide", flush); // cerrar / cambiar de pestaña
// y al desmontar el componente, llama flush() también19.2 · Control de tres estados
Sí / No / sin contestar. Clic en la opción activa la des-selecciona.
function marcar(clave, opcion){
const actual = valores[clave]; // 1 | 0 | undefined
const nuevo = opcion === "si" ? 1 : 0;
if (actual === nuevo) delete valores[clave]; // des-selecciona → sin contestar
else valores[clave] = nuevo;
pintar();
}
// SIEMPRE comparar contra null, nunca por verdadero/falso:
// 0 es una respuesta válida ("no tienen ese rol"), no un vacío.
if (valor != null) { /* fue contestado */ }19.3 · Acción con estado y error legible
El patrón de toda acción de servidor: devuelve el resultado, no lances el error. Los frameworks censuran los mensajes de errores lanzados en producción y el usuario se queda sin saber qué pasó.
// Servidor — devuelve, no lanza async function guardarDatos(datos){ try { await base.actualizar(datos); return { ok: true }; } catch (e) { registrar("guardado_fallido", e); // bitácora return { ok: false, mensaje: e.message }; // viaja íntegro } } // Cliente — muestra el mensaje REAL boton.disabled = true; boton.textContent = "Guardando…"; const r = await guardarDatos(datos); boton.disabled = false; if (r.ok) estado.textContent = "Guardado " + new Date().toLocaleTimeString("es-MX"); else estado.textContent = r.mensaje; // nunca "algo salió mal"
19.4 · Proceso largo con etapas
Arriba de 10 segundos, un spinner solo no basta: hay que contar qué está pasando.
const ETAPAS = ["Ubicando la zona…","Consultando el censo…","Leyendo la serie…","Redactando…"];
let i = 0;
const reloj = setInterval(() => {
i = Math.min(i + 1, ETAPAS.length - 1);
texto.textContent = ETAPAS[i];
}, 2600);
const resultado = await procesoLargo();
clearInterval(reloj);19.5 · Copiar y descargar
Los dos que hacen útil un documento como este.
function copiar(boton, texto){
navigator.clipboard.writeText(texto).then(() => {
const antes = boton.textContent;
boton.textContent = "✓ Copiado";
setTimeout(() => boton.textContent = antes, 1600);
});
}
function descargar(nombre, contenido, tipo = "text/plain"){
const url = URL.createObjectURL(new Blob([contenido], {type: tipo}));
const a = Object.assign(document.createElement("a"), {href: url, download: nombre});
a.click(); URL.revokeObjectURL(url);
}Ningún comportamiento puede perder trabajo del usuario ni ocultarle por qué falló. Si tu código no cumple esas dos, todavía no está listo.
21 · PDFs — el documento SuperLeads
Producimos muchos PDFs y todos deben verse hermanos: mismo papel, mismo logo en el mismo lugar, mismos tamaños. Esta sección es la receta exacta — si la sigues, tu documento se ve SuperLeads sin que tengas que decidir nada.
Un PDF no es una página web impresa. En pantalla la jerarquía puede vivir de fondos y sombras; en papel vive de tipografía, filetes y espacio en blanco. Todo lo demás gasta tinta y estorba.
20.1 · Los cuatro documentos
Todo lo que produce SuperLeads cae en uno de estos cuatro. Elige el tuyo antes de empezar:
| Documento | Extensión | Portada | Se entrega |
|---|---|---|---|
| Hoja del cliente | 1 página, siempre | No | Al cerrar la sesión, en pantalla o impresa |
| Diagnóstico / reporte | 4 a 12 páginas | Sí | Después de la sesión, por correo |
| Propuesta comercial | 6 a 14 páginas | Sí | Como seguimiento formal |
| Documento legal | Variable | No — encabezado sobrio | Para firma |
Si tu documento no cabe en ninguno, casi siempre es porque son dos documentos.
20.2 · La página
| Propiedad | Valor | Por qué |
|---|---|---|
| Tamaño | Carta (216 × 279 mm) | Es el estándar en México. Nunca A4: al imprimirse aquí sale recortado o con franjas. |
| Márgenes | 20mm arriba · 16mm lados e inferior | Arriba va más por el encabezado. Menos de 16mm y las impresoras caseras cortan. |
| Ancho de texto | Máximo 165mm | Arriba de eso el renglón es tan largo que el ojo se pierde al saltar de línea. |
| Orientación | Vertical | Horizontal solo para tablas de 6+ columnas, y en página aparte. |
| Fondo | Blanco | Color a página completa solo en la portada. |
20.3 · Anatomía — dónde va cada cosa
Las tres páginas de cualquier documento largo. Las proporciones son reales:
14 de agosto de 2026
Confidencial — uso exclusivo del destinatario
20.4 · El logo en documentos
| Dónde | Versión | Ancho | Posición |
|---|---|---|---|
| Portada | Blanco sobre navy-deep | 52mm | Superior izquierda, a 20 mm de los márgenes |
| Encabezado interior | Azul | 26mm | Superior izquierda del encabezado |
| Hoja del cliente | Azul | 30mm | Superior izquierda |
| Pie de página | Nunca. En el pie va texto, no marca. | ||
El logo aparece una sola vez por página. Repetirlo en cada sección no refuerza la marca: la abarata.
20.5 · Tipografía impresa — en puntos, no en píxeles
El papel se mide en puntos. Traducir píxeles de pantalla a papel es el error que hace que un PDF se vea "de web impresa".
| Rol | Tamaño | Peso | Color |
|---|---|---|---|
| Título de portada | 32pt | 800 | Blanco |
| Cifra protagonista | 26pt | 700 | Navy |
| Título de sección | 12.5–14pt | 600–700 | Navy |
| Subtítulo | 11.5pt | 600 | Navy |
| Cuerpo | 11pt · interlineado 1.5 | 400 | #111827 |
| Valor de dato | 11pt | 600 | #111827 |
| Etiqueta de dato | 9.5pt · letter-spacing .04em | 500 | #5b6472 |
| Folio | 9pt | 400 | #98a1b0 |
| Nota al pie / legal | 8.5pt | 400 | #5b6472 |
Debajo de eso el texto no se lee impreso, y en pantalla obliga a hacer zoom. Si tu documento no cabe, sobra material — no aprietes la tipografía.
20.6 · Color en papel
La paleta se reduce: el papel no tiene retroiluminación y las impresoras no resuelven tintes suaves.
| Uso | Valor | Regla |
|---|---|---|
| Tinta principal | #111827 | No negro puro. El #000 impreso se ve duro y barato. |
| Títulos | #002582 navy | Único color de marca en el cuerpo. |
| Etiquetas | #5b6472 | Jerarquía por color, jamás por opacidad. |
| Filetes | #d8dce4 | Líneas de 1px reales (en papel .5px desaparece). |
| Verde | Solo dentro de bloques navy | Sobre blanco no se lee y gasta tinta de color. |
| Fondos | Blanco | Color a sangre solo en portada o bloque de cierre. |
El documento debe leerse en blanco y negro. Imprime una prueba en escala de grises: si algo se pierde, ese algo dependía del color.
20.7 · Saltos de página
Lo que separa un PDF cuidado de uno automático:
@page{ size: letter; margin: 20mm 16mm 16mm; }
/* Un título NUNCA se queda solo al final de una página */
h1,h2,h3{ break-after: avoid; }
/* Lo que no se puede partir: un par etiqueta-valor, una imagen con su pie,
una fila de tabla, una tarjeta de cifra */
.dato, figure, tr, .cifra{ break-inside: avoid; }
/* Las SECCIONES sí pueden partirse. Prohibirlo deja huecos blancos al pie
de cada hoja — el error más común y el más feo. */
section{ break-inside: auto; }
/* Nuevo capítulo, nueva hoja */
.capitulo{ break-before: page; }
/* Nunca una línea suelta arriba o abajo */
p{ orphans: 3; widows: 3; }20.8 · De pantalla a papel
Si el PDF nace de una página web, esto es lo que hay que apagar y encender:
/* Movimiento reducido — esta guía cumple su propia sección 23.2 */
@media (prefers-reduced-motion: reduce){
*,*::before,*::after{
animation-duration:.01ms !important;animation-iteration-count:1 !important;
transition-duration:.01ms !important;scroll-behavior:auto !important;
}
html{scroll-behavior:auto}
}
/* Enlace de salto (sección 23.3) */
.saltar{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.saltar:focus{position:fixed;width:auto;height:auto;clip:auto;clip-path:none;left:16px;top:16px;z-index:999;background:var(--navy);color:#fff;padding:10px 18px;border-radius:8px;text-decoration:none;font-size:13px;font-weight:700}
kbd{font-family:ui-monospace,Menlo,monospace;font-size:11px;background:#fff;border:.5px solid var(--border);border-bottom-width:2px;border-radius:5px;padding:1px 5px;color:var(--navy)}
@media print{
*{ print-color-adjust: exact; -webkit-print-color-adjust: exact; }
html,body{ background:#fff !important; }
/* Fuera todo lo que es de pantalla */
nav,.sidebar,.topbar,button,.no-print{ display:none !important; }
/* Las tarjetas se APLANAN: en papel solo gastan tinta y parten
el texto en islas que cuestan más leer */
.card{ border:0 !important; box-shadow:none !important;
background:transparent !important; padding:0 !important; }
/* Los bloques oscuros se invierten: texto claro sobre navy es
ilegible impreso y se come un cartucho */
.bloque-navy{ background:transparent !important; color:var(--navy) !important; }
/* El ancho de pantalla estrecha la hoja; en papel manda el margen */
.doc{ max-width:none; width:100%; }
body{ font-size:11pt; line-height:1.5; }
/* Los enlaces largos se salen de la columna */
a{ overflow-wrap:anywhere; }
}Genera el PDF y míralo completo antes de mandarlo: hojas en blanco, títulos huérfanos, tablas cortadas, enlaces que se salen del margen. El documento se ve igual en pantalla que en papel — así nadie imprime sorpresas.
20.9 · Nombre del archivo y metadatos
El nombre del archivo es parte del documento: es lo primero que ve el cliente en su bandeja y lo que decide si lo encuentra en seis meses.
SuperLeads_TipoDeDocumento_Institucion_AAAA-MM-DD.pdf
// Ejemplos
SuperLeads_RayosX_CentroEscolarMexiquense_2026-08-14.pdf
SuperLeads_Propuesta_ColegioDelValle_2026-08-20.pdf
SuperLeads_HojaCliente_InstitutoFrontera_2026-08-14.pdf- Sin espacios, sin acentos, sin eñes — se rompen al descargar en Windows y en algunos correos
- Fecha al final y en ISO (AAAA-MM-DD): así los archivos se ordenan solos cronológicamente
- Institución en PascalCase, sin abreviar
Y en las propiedades del PDF: Título = el título real del documento (no "Documento1"), Autor = SuperLeads, Idioma = es-MX. Es lo que leen los lectores de pantalla y los buscadores de escritorio.
20.10 · Checklist del PDF
22 · Google Docs y Sheets
El mismo sistema, sin CSS. Configura esto una vez, guárdalo como plantilla y todo lo que salga de Drive se verá SuperLeads.
21.1 · Tipografía en Docs
- Plus Jakarta Sans sí está en Google Docs: menú de fuentes → Más fuentes → búscala y agrégala. Es la primera opción, siempre.
- Si el documento se comparte fuera y hace falta una fuente universal: Inter, y en último caso Arial. Nunca Times New Roman ni Calibri — ninguna es de la marca.
21.2 · Estilos de párrafo (configúralos una sola vez)
En Docs, dale formato a un párrafo y luego Formato → Estilos de párrafo → Actualizar para que coincida. Después: Opciones → Guardar como estilos predeterminados.
| Estilo de Docs | Tamaño | Peso | Color | Espacio antes |
|---|---|---|---|---|
| Título | 32 pt | Negrita | #002582 | — |
| Subtítulo | 13 pt | Normal | #5b6472 | 6 pt |
| Título 1 | 16 pt | Negrita | #002582 | 18 pt |
| Título 2 | 13 pt | Negrita | #002582 | 14 pt |
| Título 3 | 11 pt | Negrita | #111827 | 10 pt |
| Texto normal | 11 pt | Normal | #111827 | interlineado 1.5 |
Márgenes del documento: 1.6 cm en los cuatro lados (equivale a los 16 mm del PDF).
21.3 · La paleta en Drive
En cualquier selector de color de Docs, Sheets o Slides: Personalizado → pega el hex. Se quedan guardados en el archivo y aparecen como recientes.
002582 Navy — títulos y encabezados de tabla 001240 Navy profundo — portadas y bloques de cierre 56EF9F Verde — SOLO sobre navy, nunca sobre blanco 0039C8 Blue — enlaces 111827 Tinta — texto del cuerpo 5B6472 Gris texto — etiquetas y subtítulos D8DCE4 Filete — bordes de tabla F4F7FF Azul suave — relleno de filas alternas
21.4 · Tablas en Docs y Sheets
| Elemento | Formato |
|---|---|
| Fila de encabezado | Fondo #002582, texto blanco, negrita, 10 pt, MAYÚSCULAS con espaciado |
| Filas alternas | Blanco y #F4F7FF — nunca gris |
| Bordes | #D8DCE4 a 1 pt. Solo horizontales; los verticales estorban |
| Relleno de celda | 6 pt arriba y abajo, 10 pt a los lados |
| Números | Alineados a la derecha; el texto a la izquierda. Siempre. |
| Fila congelada | En Sheets, congela la fila 1 (Ver → Inmovilizar) |
21.5 · Reglas de Sheets
- Moneda: formato de contabilidad con dos decimales (
$134,000.00). Los negativos en#d03b3b, no entre paréntesis. - Porcentajes: uno o dos decimales, nunca más.
- Sin dato: celda vacía o
—. Nunca 0 niN/A— un cero se suma y contamina los totales. - Formato condicional: usa los tres colores de estado (
#0ca30c/#eb6834/#d03b3b) como relleno claro con texto oscuro, no como fondo saturado. - Una hoja, una tabla. Varias tablas en la misma hoja rompen filtros, ordenamientos y cualquier exportación.
- La fila 1 es de encabezados, sin celdas combinadas: las combinaciones rompen filtros y tablas dinámicas.
21.6 · Exportar a PDF desde Drive
- Archivo → Descargar → PDF, y revísalo: Docs parte las tablas de otra forma que la vista de edición.
- En Sheets, antes de exportar: Archivo → Imprimir → tamaño Carta, márgenes normales, ajustar al ancho, repetir fila congelada, y apagar las líneas de cuadrícula.
- Renombra el archivo con la convención de la sección 20.9 antes de enviarlo.
23 · Aplicación móvil — iOS y Android
Cuando SuperLeads tenga app en la App Store y en Play Store, esto ya está decidido: el ícono, la navegación, los tamaños y los patrones. Aquí no se razona, se ejecuta.
Una app no es la web metida en un teléfono. Cambian tres cosas de raíz: no hay cursor (el hover no existe), la pantalla tiene zonas prohibidas (notch y barra de gestos), y la navegación vive abajo, donde llega el pulgar. Todo lo demás de esta guía se mantiene: mismos colores, misma tipografía, mismo movimiento.
23.1 · El ícono de la app
Es lo único de la marca que se ve siempre, y compite con otros treinta íconos en una pantalla de inicio.
Entrégalo cuadrado. El sistema redondea.
Adaptable: la máscara puede ser círculo, cuadrado o gota.
De aquí salen todos los tamaños.
| Regla | Detalle |
|---|---|
| El símbolo, no el logotipo | Solo la marca gráfica, sin la palabra. A 60px una palabra es una mancha. |
| Fondo navy-deep sólido | #001240 con el símbolo en verde #56EF9F: nuestro verde sobre oscuro, que sí se ve a 40px. |
| Sin transparencia | iOS la rellena de negro. El ícono siempre es un cuadrado opaco. |
| Sin esquinas redondeadas propias | Cada sistema aplica su máscara. Si las redondeas tú, salen dobles. |
| Sin texto, degradados ni sombras | Ni "app", ni versión, ni brillos. Plano y limpio. |
| Zona segura | El símbolo ocupa el 60–66% central: en Android la máscara recorta hasta un 25% del borde. |
Qué entregar
| Plataforma | Archivo | Medida | Nota |
|---|---|---|---|
| Master | icono-master.png | 1024 × 1024 px | PNG sin canal alfa. De aquí sale todo. |
| iOS | AppIcon | 1024 × 1024 px | Xcode genera los demás tamaños solo. |
| Android | ic_launcher_foreground | 432 × 432 px | Solo el símbolo, dentro de los 264px centrales. |
ic_launcher_background | 432 × 432 px | Navy-deep sólido, nada más. | |
ic_launcher_monochrome | 432 × 432 px | Silueta blanca sobre transparente (temas de Android 13+). |
Reduce el ícono a 40×40 y míralo entre los íconos reales de tu teléfono. Si no se distingue de un vistazo, tiene demasiado detalle.
23.2 · Iconografía dentro de la app
La misma familia que en web — Lucide — para que los productos se vean hermanos. Lo que cambia son los tamaños:
| Uso | Tamaño | Grosor |
|---|---|---|
| Barra de pestañas | 24 pt/dp (28 si va sin etiqueta) | 2 |
| Barra superior | 22 pt/dp | 2 |
| Dentro de listas | 20 pt/dp | 2 |
| Dentro de botones | 18 pt/dp | 2 |
| Junto a texto pequeño | 16 pt/dp | 1.75 |
| Estado vacío | 40–48 pt/dp | 1.5 |
- Rejilla de 24: todo ícono se dibuja en un lienzo de 24×24 y se escala. Nada de medidas intermedias.
- Línea, no relleno — salvo el ícono de la pestaña activa, que sí puede ir relleno para marcar el estado.
- Un ícono nunca va solo si su significado no es obvio: cinco íconos sin etiqueta son cinco adivinanzas.
- Nunca inventes uno que ya exista en Lucide; si no existe, dibújalo en la rejilla de 24 con grosor 2.
23.3 · La pantalla: zonas prohibidas y zona del pulgar
Lo que manda es el pulgar
Con el teléfono en una mano, el pulgar alcanza cómodo el tercio inferior. Por eso:
- La navegación va abajo, nunca arriba
- La acción principal, abajo a la derecha (botón flotante) o de ancho completo al pie
- Arriba solo información y acciones de poco uso
- Nunca "Guardar" en la esquina superior derecha de un formulario largo
Zonas prohibidas (safe areas)
| Zona | Qué ocupa | Regla |
|---|---|---|
| Arriba | Notch / isla dinámica · barra de estado | Nada tocable ni legible ahí. El fondo sí se extiende debajo. |
| Abajo | Barra de gestos (iOS) · navegación (Android) | La barra de pestañas lleva ~34pt de relleno extra abajo. |
| Lados | Bordes curvos y gesto de volver | Margen lateral mínimo de 16pt. |
/* El fondo llena la pantalla; el contenido respeta las zonas del sistema */
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: max(16px, env(safe-area-inset-left));
padding-right: max(16px, env(safe-area-inset-right));23.4 · Medidas exactas
| Elemento | iOS | Android | SuperLeads |
|---|---|---|---|
| Alto de barra superior | 44 pt | 56 dp | Título 17pt/700 navy |
| Alto de barra de pestañas | 49 pt + safe area | 56 dp + safe area | Fondo blanco, borde superior .5px |
| Área tocable mínima | 44 × 44 pt | 48 × 48 dp | Usa 48 y cumples ambas |
| Margen lateral | 16 pt | 16 dp | 16 · 20 en pantallas de lectura |
| Separación entre tocables | 8 pt/dp mínimo | Menos y se toca el equivocado | |
| Alto de fila | 44 pt simple · 60 pt doble | 48 · 64 dp | 64 con título y subtítulo |
| Botón principal | 48 pt/dp de alto | Radio 8, ancho completo menos márgenes | |
| Botón flotante (FAB) | 56 × 56 dp | Verde con símbolo navy, a 16 del borde | |
23.5 · Navegación — tres patrones y ninguno más
1 · Barra de pestañas
La estructura principal. Entre 3 y 5, nunca más. Cada pestaña es un mundo que recuerda dónde te quedaste. Ícono + etiqueta siempre.
2 · Apilar (push)
Ir al detalle. Entra desde la derecha, con flecha de volver arriba a la izquierda y gesto desde el borde. Máximo 3 niveles.
3 · Hoja (sheet)
Tarea corta: filtros, formulario breve, confirmar. Sube desde abajo, con agarradera, se cierra arrastrando. Nunca para tareas largas.
El menú hamburguesa. Esconde la navegación tras un toque, vive arriba (lejos del pulgar) y hace que media app no exista para el usuario. Si no cabe en 5 pestañas, la última es "Más" — que es una pantalla, no un cajón.
23.6 · Lo que reemplaza al hover
| En web | En app | Cómo |
|---|---|---|
| Hover | Presionado | Al tocar: opacidad .7 o fondo rgba(0,37,130,.06), inmediato. Se quita al soltar. |
| Tooltip | Texto debajo | El hint va visible bajo el campo. Nada de descubrir tocando. |
| Confirmación | Háptica | Ligera al elegir, media al completar, de error al fallar. Nunca en cada toque. |
Y dos gestos que se dan por hechos: arrastrar desde el borde izquierdo = volver (nunca lo bloquees) y jalar hacia abajo = actualizar en cualquier lista.
23.7 · Tipografía y color en app
| Rol | Tamaño | Peso |
|---|---|---|
| Título grande de pantalla | 28–34 pt | 800 |
| Título de barra | 17 pt | 700 |
| Título de fila | 16 pt | 600 |
| Cuerpo | 16 pt | 400 |
| Secundario | 14 pt | 400 |
| Etiqueta de pestaña | 10–11 pt | 600 |
| Mínimo absoluto | 12 pt | — |
El cuerpo en app es 16pt, no los 14px de la web: la pantalla está más cerca pero es mucho más chica, y en iOS un campo de menos de 16pt hace que la vista haga zoom sola al enfocarlo. Además la app debe respetar el tamaño de texto del sistema — hay quien lo trae al 130% — así que nada de altos fijos en contenedores con texto.
Color y modo oscuro
El modo oscuro no es opcional: el sistema lo activa solo y una app que lo ignora se ve rota de noche.
| Rol | Claro | Oscuro |
|---|---|---|
| Fondo de pantalla | #F4F7FF | #060a18 |
| Superficie | #FFFFFF | #0c1530 |
| Texto principal | #1a1a1a | #EEF1FB |
| Texto secundario | #5b6478 | #b4c0db |
| Borde | #e0e8f8 | rgba(255,255,255,.10) |
| Acción principal | #002582 navy | #56EF9F verde |
Fíjate en la última fila: en oscuro el botón principal se vuelve verde, porque ahí el fondo ya es oscuro y el verde por fin es el acento correcto. Es el principio de siempre: el fondo manda el color.
23.8 · Patrones de pantalla
| Pantalla | Cómo se arma |
|---|---|
| Lista | Filas de 64pt, título 16 + subtítulo 14, separador .5px con sangría. Jalar para actualizar. Al final, cargar más solo, sin botón. |
| Detalle | Encabezado con lo importante, luego secciones. Acciones fijas al pie. Se llega apilando, se sale con flecha o gesto. |
| Formulario | Una columna, un campo por renglón siempre. Teclado correcto por campo. El botón de guardar sube con el teclado, no queda tapado. |
| Vacío | Ícono de 48pt, título 17pt, una línea y el botón que lo resuelve. Nunca una pantalla en blanco. |
| Carga | Esqueleto (bloques del tamaño del contenido), no una rueda. Se siente el doble de rápido. |
| Error | Mensaje real y botón de Reintentar. Jamás un código a secas. |
| Sin conexión | Barra fija arriba: "Sin conexión — se guardará al reconectar". Lo tecleado nunca se pierde. |
23.9 · iOS y Android: lo que sí cambia
La marca es la misma; lo que cambia es lo que el usuario ya tiene aprendido de su teléfono. Respétalo: pelearse con el sistema se siente como una app mal hecha.
| Detalle | iOS | Android |
|---|---|---|
| Título de la barra | Centrado | A la izquierda |
| Volver | Flecha + gesto desde el borde | Flecha + gesto del sistema |
| Acción flotante | Botón al pie, ancho completo | FAB circular abajo a la derecha |
| Confirmaciones | Hoja desde abajo | Diálogo centrado |
| Avisos breves | Banner arriba | Snackbar abajo |
| Tipografía | Plus Jakarta Sans en ambos — es nuestra marca, no la del sistema | |
| Radios | Los de la guía: 8 en controles, 12 en tarjetas | |
23.10 · Checklist de app
24 · Impresión en pantalla
/* Movimiento reducido — esta guía cumple su propia sección 23.2 */
@media (prefers-reduced-motion: reduce){
*,*::before,*::after{
animation-duration:.01ms !important;animation-iteration-count:1 !important;
transition-duration:.01ms !important;scroll-behavior:auto !important;
}
html{scroll-behavior:auto}
}
/* Enlace de salto (sección 23.3) */
.saltar{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.saltar:focus{position:fixed;width:auto;height:auto;clip:auto;clip-path:none;left:16px;top:16px;z-index:999;background:var(--navy);color:#fff;padding:10px 18px;border-radius:8px;text-decoration:none;font-size:13px;font-weight:700}
kbd{font-family:ui-monospace,Menlo,monospace;font-size:11px;background:#fff;border:.5px solid var(--border);border-bottom-width:2px;border-radius:5px;padding:1px 5px;color:var(--navy)}
@media print{
*{print-color-adjust:exact;-webkit-print-color-adjust:exact}
@page{size:letter;margin:16mm}
html,body{background:#fff !important}
.no-print,nav,.sidebar,.topbar,button{display:none !important}
/* Las tarjetas se aplanan: en papel solo gastan tinta */
.card{border:0 !important;box-shadow:none !important;
background:transparent !important;padding:0 !important}
body{font-size:11pt;line-height:1.5}
h1,h2,h3{break-after:avoid}
figure,.par-dato{break-inside:avoid}
/* Las secciones SÍ pueden partirse: evitarlo deja huecos al pie */
}- Jerarquía por color, nunca por opacidad: la mayoría de las impresoras no resuelven un azul al 30%
- El documento se ve igual en pantalla que en papel — así nadie imprime sorpresas
25 · Accesibilidad
No es una capa que se agrega al final: es parte de que algo esté bien hecho. Una interfaz que deja fuera a alguien está incompleta, por bonita que se vea.
23.1 · Los cinco que nunca se negocian
| Regla | Valor | Cómo se verifica |
|---|---|---|
| Contraste de texto | 4.5:1 normal · 3:1 en 18pt+ o negritas 14pt+ | Inspector del navegador sobre el texto |
| Contraste de controles | 3:1 en bordes de campo, íconos y estados | Un campo con borde tenue no se ve con luz de día |
| Foco visible | outline: 2px solid var(--blue); outline-offset: 2px | Recorre la página entera con Tab |
| Área táctil | 44 × 44 px mínimo | Un ícono de 16px necesita padding alrededor |
| Nunca solo color | Estado = color + ícono o texto | Míralo en escala de grises |
23.2 · Movimiento reducido
Somos una marca que cuida el movimiento — por eso mismo tenemos que saber apagarlo. Para alguien con vértigo o migraña vestibular, una animación puede provocar mareo real. El sistema operativo ya lo pregunta; solo hay que escuchar.
@media (prefers-reduced-motion: reduce){
*,*::before,*::after{
animation-duration:.01ms !important;
animation-iteration-count:1 !important;
transition-duration:.01ms !important;
scroll-behavior:auto !important;
}
}Con esto la deriva del fondo se detiene, los paneles aparecen sin deslizarse y el scroll deja de ser suave — pero nada deja de funcionar. Los cambios de color se mantienen: son información, no decoración.
23.3 · Estructura que se puede navegar sin ver
Un lector de pantalla no ve el diseño: recorre el esqueleto. Si el esqueleto está mal, la página es un muro de texto.
- Un solo
<h1>por página, y los niveles sin saltarse (de h2 a h4 no). El tamaño lo decide el CSS, no la etiqueta. - Etiquetas de región:
<header>,<nav>,<main>,<footer>— con eso se salta entre zonas directamente. lang="es"en el<html>. Sin esto un lector de pantalla lee español con fonética en inglés: incomprensible.- Enlace de salto como primer elemento, para brincar el menú:
<a href="#contenido" class="saltar">Ir al contenido</a>
/* Se oculta recortándolo, NO mandándolo a left:-9999px: esa técnica
vieja genera scroll horizontal en la página. */
.saltar{position:absolute;width:1px;height:1px;overflow:hidden;
clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.saltar:focus{position:fixed;width:auto;height:auto;clip:auto;clip-path:none;
left:16px;top:16px;z-index:999;
background:var(--navy);color:#fff;padding:10px 18px;border-radius:8px}23.4 · Formularios
<div class="field">
<label for="matricula">Matrícula actual</label>
<input id="matricula" type="number" inputmode="numeric"
aria-describedby="ayuda-matricula error-matricula"
aria-invalid="false">
<p id="ayuda-matricula" class="hint">Solo alumnos pagando hoy.</p>
<p id="error-matricula" class="err-msg"></p>
</div>
<!-- El estado de guardado se anuncia solo, sin robar el foco -->
<span aria-live="polite">Guardado 14:32</span>labelconforsiempre. Un placeholder no es una etiqueta: desaparece al escribir y no lo lee el lector.aria-describedbyconecta el hint y el error al campo, para que se lean junto con él.aria-live="polite"en el indicador de guardado: se anuncia sin interrumpir lo que se está escribiendo.inputmodecorrecto: en celular abre el teclado numérico y evita errores de captura.
23.5 · Imágenes e íconos
| Caso | Qué hacer |
|---|---|
| Logo | alt="SuperLeads" — el nombre, no "logotipo de SuperLeads" |
| Ícono decorativo junto a texto | alt="" o aria-hidden="true". Leerlo duplica el mensaje. |
| Botón de solo ícono | aria-label="Borrar diagnóstico" + title |
| Gráfica | Describe la conclusión: "Conversión de 3.29%, por debajo de la meta de 5%" — no "gráfica de barras" |
| Foto de fondo | alt="". Si no aporta información, no debe estorbar. |
23.6 · Zoom y tamaño de texto
- La página debe funcionar al 200% de zoom sin scroll horizontal ni texto cortado. Las rejillas con
auto-fitya lo resuelven solas. - Nunca menos de 11px en texto funcional. Los 10px se reservan para eyebrows y badges en MAYÚSCULAS, que se leen por forma.
- Nunca
user-scalable=nonimaximum-scale=1en el viewport: le quita a alguien la posibilidad de acercar. - Usa
rempara tamaños de texto cuando puedas: respeta el ajuste del navegador de quien lee.
23.7 · Documentos accesibles
Un PDF también se lee con lector de pantalla — y la mayoría en el mundo no se pueden leer.
- Texto real, nunca texto dentro de una imagen. Si la cifra es una captura de pantalla, para un lector de pantalla no existe.
- Idioma del documento en las propiedades (
es-MX). - Orden de lectura lógico: si el PDF sale de HTML bien estructurado, ya lo hereda.
- Encabezados reales (H1, H2), no texto grande en negritas.
- En Google Docs, usa los estilos de párrafo de la sección 21.2 — de ahí sale la estructura del PDF exportado.
1) Recorre la pantalla con Tab: ¿se ve siempre dónde estás y el orden tiene sentido? · 2) Ponle 200% de zoom: ¿se sigue usando? · 3) Mírala en escala de grises: ¿se entiende todo? Si pasa las tres, está lista.
26 · Checklist antes de entregar
Márcalo. Si algo queda sin palomear, no está listo.
Marca
Estructura
Interacción
Contenido
Accesibilidad
Cierre
27 · Anti-patrones
Lo que delata un diseño fuera del sistema. Si tu pantalla tiene algo de la columna izquierda, corrígelo.
| ❌ No | ✅ Sí |
|---|---|
Verde #56EF9F sobre blanco | Navy o blue sobre claro; verde solo sobre oscuro |
border: 1px solid #ddd | border: .5px solid var(--border) |
Sombras negras rgba(0,0,0,.2) | Sombras teñidas de navy |
opacity: .5 para jerarquía de texto | El color --muted o --dim |
transition: all .3s ease | Propiedades nombradas + var(--ease) |
| Hover que mueve 8px | translateY(-2px) botón · -3px tarjeta |
repeat(2, 1fr) fijo en formularios | repeat(auto-fit, minmax(min(280px,100%), 1fr)) |
minmax(280px, 1fr) sin min() | Con min(280px,100%): si no, desborda en contenedores angostos |
Un <select> con 4 opciones | Chips, todas visibles |
| Toggle con "No" preseleccionado | Tres estados, nada activo al inicio |
| "Ocurrió un error, intenta de nuevo" | El mensaje real y qué hacer |
Mostrar 0 cuando no hay dato | — |
| Botón que se encoge al cargar | Ancho reservado, spinner adentro |
| Tarjeta destacada del doble de ancho | Cuadrícula uniforme |
| Colores de marca en gráficas | Paleta --chart-* validada |
| Un spinner eterno sin explicación | Etapas que avanzan arriba de 10s |
| Acción principal al fondo del menú | Acción principal arriba |
Animar sin respetar prefers-reduced-motion | Un bloque de 6 líneas que lo apaga todo |
user-scalable=no en el viewport | Dejar que la gente pueda acercar |
Placeholder en vez de label | label for siempre |
| PDF en A4 o con la cifra dentro de una imagen | Carta, y texto real seleccionable |
| Logo repetido en cada sección del PDF | Una vez por página |
Resuélvelo con los seis principios — y luego agrégalo a esta guía.
28 · Para inteligencias artificiales
Pega este bloque al inicio de tu conversación con Claude, ChatGPT o quien sea. Contiene el sistema completo: con esto no tiene nada que adivinar.
Diseña y programa siguiendo el sistema de SuperLeads. Reglas obligatorias: TIPOGRAFÍA: "Plus Jakarta Sans" (Google Fonts), única familia. TOKENS (úsalos siempre, nunca colores sueltos): --green:#56EF9F; --navy:#002582; --navy-deep:#001240; --green-d:#2BC878; --navy-mid:#001a5e; --blue:#0039C8; --blue-mid:#2A89FB; --blue-soft:#F4F7FF; --blue-softer:#EEF2FF; --ink:#1a1a1a; --border:#e0e8f8; --muted:#5b6478; --dim:#98a1b0; --ok:#0ca30c; --warn:#eb6834; --bad:#d03b3b; --destructive:#d92d43; --chart-1:#2a78d6; --chart-2:#eb6834; --chart-3:#1baf7a; --ease:cubic-bezier(.16,1,.3,1); COLOR: el verde SOLO sobre fondo oscuro (nunca sobre blanco). El navy para texto y botones sobre claro. El blue para links y bordes activos. Los colores de estado no se usan como decorativos. Las gráficas usan --chart-*, nunca la marca. El texto va en tinta, nunca del color de su serie. FORMA: bordes .5px (jamás 1px). Radios: 8px controles, 12px tarjetas, pill en badges. Espaciado en múltiplos de 4. Sombras teñidas de navy, nunca negras: tarjeta 0 10px 32px rgba(0,37,130,.08); CTA 0 10px 28px rgba(86,239,159,.28). MOVIMIENTO: un solo easing --ease. Hover de botón translateY(-2px) en 200ms; de tarjeta -3px en 300ms; active instantáneo. Nunca "transition: all". TIPOS: H1 46-50px/800/-1.8px. Título de página 32-36px/800/-0.8px. Tarjeta 16-22px/800. Body 13-15px/1.78. Eyebrow 10-11px/700/1.3px mayúsculas. Stats con tabular-nums. LAYOUT: rejillas con repeat(auto-fit,minmax(min(280px,100%),1fr)) antes que media queries. Todo grid item lleva min-width:0 (sin esto el contenido desborda). Tarjetas de una rejilla, todas del mismo tamaño. FORMULARIOS: label 13px/500 navy; input padding 10px 14px, borde .5px, focus con borde --blue y halo rgba(0,57,200,.10); hint 11px --muted debajo. Nada preseleccionado: tres estados (null / 0 / 1) y comparar con != null. ESTADOS: toda pantalla necesita vacío, cargando, error y éxito. Los errores muestran el mensaje REAL y qué hacer. Sin dato se escribe "—", nunca 0. ACCESIBILIDAD: contraste 4.5:1 en texto y 3:1 en controles; foco visible con outline 2px var(--blue); área táctil 44px; nada depende solo del color; un solo h1 con niveles sin saltos; lang="es"; label for + aria-describedby en campos; aria-live="polite" para avisos de guardado; y SIEMPRE el bloque de prefers-reduced-motion que apaga animaciones y transiciones. APP MÓVIL (iOS/Android): el ícono es el SÍMBOLO sin la palabra, sobre navy-deep sólido, sin transparencia ni esquinas redondeadas propias (el sistema aplica su máscara), símbolo al 60-66% central, master 1024x1024. Iconografía Lucide en rejilla de 24 con grosor 2: 24pt en pestañas, 20 en listas, 18 en botones. Navegación ABAJO con 3-5 pestañas siempre con etiqueta — el menú hamburguesa está prohibido. Área tocable 48x48 mínimo, separada 8. Respeta safe areas con env(safe-area-inset-*). Cuerpo a 16pt (no 14) y respeta el tamaño de texto del sistema. No existe hover: se sustituye por estado presionado inmediato, hints visibles y háptica. Modo oscuro obligatorio, y EN OSCURO la acción principal es verde (#56EF9F) en vez de navy. Esqueletos en vez de spinners. PDF / DOCUMENTOS: tamaño Carta (nunca A4), márgenes 20mm arriba y 16mm el resto. Logo blanco 52mm en portada, azul 26mm en el encabezado interior, una sola vez por página, nunca en el pie. Cuerpo 11pt/1.5, títulos 12.5-14pt, etiquetas 9.5pt, folio 9pt, mínimo absoluto 8.5pt. Tinta #111827 (no negro puro), títulos navy, filetes #d8dce4 a 1pt. Verde solo dentro de bloques navy. Títulos con break-after:avoid; pares dato/valor y figuras con break-inside:avoid; las secciones SÍ pueden partirse. Nombre de archivo: SuperLeads_Tipo_Institucion_AAAA-MM-DD.pdf. Debe entenderse en blanco y negro. NUNCA: verde sobre blanco · borde 1px · sombra negra · opacity para jerarquía · transition:all · dual axis en gráficas · un cero inventado · "ocurrió un error" · acción principal al fondo del menú.
La guía completa en texto está en guía.md — si tu IA acepta archivos, dale ese en vez del resumen.