swiss-editorial-minimalist (SKILLS.md v3.1)
Una página creada por un modelo generalmente se ve como el promedio de todas las páginas que ha visto: un héroe con degradado, una fila de tarjetas redondeadas con iconos emoji, una sombra debajo de cada botón y un CDN de Tailwind que carga un arcoíris de colores. Nada de eso está mal, y nada de eso fue decidido.
Este archivo reemplaza esos valores predeterminados con decisiones. Cubre tres cosas: el estilo de la casa (qué mostrar y qué omitir), las reglas técnicas que lo mantienen (tokens, escalas, puntos de interrupción, accesibilidad) y las compuertas que verifican el resultado antes de enviarlo.
Sigue las reglas tal como están escritas. Cuando una solicitud entre en conflicto con ellas, la sección 0 indica qué hacer.
0. Meta-reglas (léase primero)
Qué hacer cuando recibes este archivo
-
Lee el archivo completo antes de escribir cualquier código. Las reglas dependen unas de otras.
-
No pidas aclaraciones sobre nada que este archivo ya decida. Ejecuta con suposiciones razonables y exponlas en una línea.
-
Si la solicitud entra en conflicto con el estilo de la casa (por ejemplo, "colorido", "divertido", "héroe con degradado", "iconos emoji", "tarjetas redondeadas de 20px"), confirma una vez antes de proceder:
Esta solicitud infringe la sección X de SKILLS.md. La interpretaré en el estilo Minimalista Suizo-Editorial, a menos que quieras abandonar la guía.
Espera la respuesta, luego construye.
-
La salida predeterminada es un archivo HTML completo con
<style>y<script>en línea. No entregues fragmentos a menos que el usuario lo solicite. -
Comienza siempre el CSS con el bloque
:rootde la sección 12.
Cómo nombrar este estilo
Usa estos términos para que el vocabulario se mantenga consistente. No uses "moderno", "limpio" o "elegante" por sí solos; no dicen nada específico.
- "Minimalista Suizo-Editorial": el predeterminado, descrito en este archivo.
- "Brutalismo Suave": bordes más gruesos y una cuadrícula más tosca.
- "Editorial Neobrutalista": se añade un color de acento y una sombra desplazada dura. Las sombras están prohibidas en el estilo predeterminado, así que usa este nombre solo cuando el usuario lo solicite explícitamente.
- "Revista Monocromática": liderada por la tipografía, sin tarjetas ilustradas.
1. Filosofía de diseño
Tres principios, ninguno negociable:
- El contenido es el rey; la tipografía es la arquitectura. No hay ilustraciones decorativas. El encabezado grande es el principal elemento visual.
- La estructura permanece visible. Los bordes, las cuadrículas y los números de sección aparecen tal como son. No se ocultan.
- Monocromático primero, color después. El valor predeterminado es negro, blanco y gris. El color aparece solo en modo oscuro o como un acento mínimo.
La página debe sentirse tranquila, firme, inteligente y editorial, como una revista impresa hecha por ingenieros.
2. Paleta
Modo claro (predeterminado)
:root {
--bg: #f5f5f5; /* fondo principal, no blanco puro */
--ink: #111111; /* texto principal, no negro puro */
--muted: #666666; /* texto secundario */
--line: #e0e0e0; /* bordes y divisores */
--card: #eeeeee; /* fondo de tarjeta */
--accent: #d4d4d4; /* acento neutral */
--dark: #0a0a0a; /* secciones de alto contraste (declaración, pie de página) */
--white: #ffffff;
}
Modo oscuro
body.dark {
--bg: #121212;
--ink: #f0f0f0;
--muted: #999999;
--line: #333333;
--card: #1e1e1e;
--accent: #2a2a2a;
--dark: #050505;
--white: #181818;
}
Reglas de color (obligatorias)
- El fondo del cuerpo nunca es
#fff. Usa blanco sucio#f5f5f5. - El texto nunca es
#000. Usa#111. - El color de la marca aparece una o dos veces por página como máximo, y siempre a través de una variable CSS, nunca codificado.
- Los colores brillantes están prohibidos para estado, iconos y texto. Ejemplos de lo que está prohibido: emerald-500, green-600, red-500, blue-500, yellow-400,
#27c93f,#ff5f56,#ffbd2e. Reemplázalos con símbolos monocromáticos (●, ▲, ✕, →) envar(--ink)ovar(--muted). - Las secciones de contraste (declaración, CTA, pie de página) usan
var(--dark)con texto claro. - El modo oscuro es obligatorio. Sigue
prefers-color-schemepor defecto y permite al usuario anularlo, guardando la elección enlocalStorage. El toggle usa el marcado obligatorio en la sección 5 ("Toggle de tema").
3. Tipografía
Combinación de fuentes
Encabezado: 'Space Grotesk' (o Inter Tight, General Sans, Neue Montreal)
Cuerpo: 'DM Sans' (o Inter, Satoshi, IBM Plex Sans)
Mono: 'JetBrains Mono' (o sistema monospace)
No uses fuentes decorativas, script ni serif para el texto del cuerpo. Se permite una serif solo para citas o firmas (por ejemplo, Georgia, cursiva).
Escala tipográfica (se requiere clamp, para que la tipografía escale sin media queries)
/* Héroe H1 */
tamaño de fuente: clamp(55px, 5.6vw, 94px); /* o clamp(32px, 4.3vw, 62px) para un héroe estrecho */
altura de línea: 1.025;
espaciado entre letras: -0.07em; /* negativo, siempre */
peso de fuente: 500; /* no 700, no 400 */
/* Sección H2 */
tamaño de fuente: clamp(42px, 4.2vw, 69px);
altura de línea: 1.08;
espaciado entre letras: -0.06em;
peso de fuente: 500;
/* Tarjeta H3 */
tamaño de fuente: clamp(22px, 2.2vw, 27px);
altura de línea: 1.2;
espaciado entre letras: -0.04em;
peso de fuente: 500;
/* Cuerpo */
tamaño de fuente: 16px–18px;
altura de línea: 1.7–1.8;
color: var(--muted);
/* Micro / ceja / etiqueta */
tamaño de fuente: 12px;
espaciado entre letras: 0.15em–0.17em;
peso de fuente: 700;
text-transform: uppercase;
Reglas tipográficas estrictas
- Los encabezados siempre usan espaciado entre letras negativo (entre -0.04em y -0.07em). Esta es la firma del estilo.
- El peso del encabezado es 500. El negrita 700 aplana la sensación editorial.
- Las cejas y las microetiquetas siempre están en MAYÚSCULAS con tracking amplio (0.15em o más).
- Los números de sección (01, 02, 03) aparecen como microetiquetas. No los ocultes.
- Un punto al final de un titular puede servir como acento, como opción:
<h1>Judul.<span style="color:var(--muted)">.</span></h1> - El texto del cuerpo está alineado a la izquierda. No centres párrafos largos.
4. Diseño y cuadrícula
Contenedor
.wrap {
ancho máximo: 1440px;
margen: auto;
relleno: 0 clamp(24px, 5vw, 84px);
}
Espaciado vertical
- Entre secciones:
padding: 130px 0en escritorio, reduciendo a85pxen móvil. - Altura del encabezado: 88px en escritorio, 75px en móvil.
- Espacio entre tarjetas: 15–16px. Mantenlo ajustado, no 24px o más.
Patrones de cuadrícula comunes
/* Héroe asimétrico */
.hero { cuadrícula-plantilla-columnas: 1.04fr .96fr; }
/* Encabezado de sección de dos columnas */
.section-head { cuadrícula-plantilla-columnas: 1fr 1fr; alinear-elementos: final; }
/* Características de tres columnas */
.features { cuadrícula-plantilla-columnas: repeat(3, 1fr); espacio: 15px; }
/* Declaración */
.statement-grid { cuadrícula-plantilla-columnas: 1fr 1fr; espacio: 60px; }
/* Testimonial (ver sección 8) */
.testimonial-grid { cuadrícula-plantilla-columnas: 1.2fr .8fr; espacio: 60px; }
Reglas de diseño (obligatorias)
- Las secciones están separadas por un borde de 1px
var(--line), no por una sombra o un fondo diferente. - Evita el radio de borde grande. Los botones y las tarjetas obtienen como máximo 4px. Solo las imágenes y capturas de pantalla toman 12–22px.
- Usa
align-items: enden los encabezados de sección para que el encabezado y el párrafo se asienten en la misma línea de base. Este es el truco editorial. - Las cuadrículas asimétricas (1.04fr / .96fr) se ven mejor que 1fr / 1fr.
- Nunca centres el texto del cuerpo. Siempre alinea a la izquierda.
- Cada sección necesita un
border-topoborder-bottomde 1pxvar(--line).
5. Componentes
Botones
.btn {
display: inline-flex;
align-items: center;
gap: 14px;
border-radius: 4px; /* casi cuadrado */
padding: 15px 20px;
background: var(--ink);
color: var(--bg);
border: 1px solid var(--ink);
font-size: 14px;
font-weight: 700;
cursor: pointer;
transition: transform .2s, background .2s;
}
@media (hover: hover) {
.btn:hover { transform: translateY(-2px); background: #333333; }
}
/* Variantes */
.btn.outline { background: transparent; color: var(--ink); border-color: var(--line); }
.btn.light { background: var(--bg); color: var(--ink); border-color: var(--bg); }
Reglas de botón:
- Cada botón tiene un icono de flecha: ↗ para un enlace externo, ↓ para un desplazamiento.
- Al pasar el ratón, el botón se eleva -2px, solo dentro de
@media (hover: hover). No escala ni añade sombra. - Nunca uses
#fffpara.btn.light. Usavar(--bg).
Tarjetas de características
┌─────────────────────────┐
│ [SVG line-art 8:5] │ ← ilustración abstracta monocromática, o vacía
├─────────────────────────┤
│ ETIQUETA MICRO │ ← mayúsculas, tracking amplio
│ Título de tarjeta. │ ← Space Grotesk 24–27px
│ Descripción 1–2 oraciones │ ← muted, 14px
└─────────────────────────┘
- Fondo
var(--card), sin radio de borde (o 4px como máximo). - Sin borde (la tarjeta se funde con el fondo), o
1px solid var(--line). - Hover:
transform: translateY(-5px), solo dentro de@media (hover: hover):@media (hover: hover) { .card:hover { transform: translateY(-5px); } } - La ilustración es SVG line-art con
stroke-width: 1.2px,fill: none, en el color de la tinta. No es una foto, un degradado ni un emoji.
Encabezado
- Altura 88px,
border-bottom: 1px solid var(--line). - Marca: logotipo de 34px y nombre en Space Grotesk 22px,
letter-spacing: -1.1px. - Navegación: 14px, peso 600, espacio 36px.
- Acciones: toggle de tema (icono de sol/luna, marcado obligatorio en "Toggle de tema" a continuación), el botón CTA y el menú hamburguesa en móvil.
- La navegación móvil se abre como un panel absoluto debajo del encabezado y se cierra con Escape.
- El menú hamburguesa necesita
aria-label,aria-expandedyaria-controls. El toggle de tema necesitaaria-labelyaria-pressed(ver más abajo).
Toggle de tema (marcado obligatorio)
Cada página tiene un toggle de modo oscuro, y siempre usa este marcado. No redibujes los iconos, los intercambies por emojis ni añadas una etiqueta de texto. Las rutas SVG, los valores id y la aria-label son fijos.
<div class="header-actions">
<!-- Botón de alternancia de modo oscuro -->
<button id="theme-toggle" type="button" class="theme-toggle" aria-label="Alternar modo oscuro/claro" aria-pressed="false">
<!-- Icono de sol (oculto en modo claro, visible en modo oscuro) -->
<svg id="sun-icon" class="theme-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.8" aria-hidden="true">
<circle cx="12" cy="12" r="5"></circle>
<path d="M12 1v2m0 18v2M4.22 4.22l1.42 1.42m12.72 12.72l1.42 1.42M1 12h2m18 0h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"></path>
</svg>
<!-- Icono de luna (visible en modo claro, oculto en modo oscuro) -->
<svg id="moon-icon" class="theme-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.8" aria-hidden="true">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"></path>
</svg>
</button>
<!-- El botón CTA y el menú hamburguesa van aquí, dentro del mismo contenedor -->
</div>
.header-actions { display: flex; align-items: center; gap: 16px; }
.theme-toggle {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 44px; /* objetivo táctil */
min-height: 44px;
padding: 8px;
color: var(--ink);
background: transparent;
border: 1px solid var(--line);
border-radius: var(--radius-sm);
cursor: pointer;
transition: background .2s;
}
@media (hover: hover) {
.theme-toggle:hover { background: var(--card); }
}
.theme-icon { width: 20px; height: 20px; }
/* El estado del icono sigue a body.dark, por lo que no se intercambian clases en JavaScript */
#sun-icon { display: none; }
#moon-icon { display: block; }
body.dark #sun-icon { display: block; }
body.dark #moon-icon { display: none; }
<!-- Primer elemento dentro de <body>, para que el tema guardado se aplique antes del primer pintado -->
<script>
(function () {
var KEY = 'theme';
var saved = null;
try { saved = localStorage.getItem(KEY); } catch (e) {}
var dark = saved ? saved === 'dark'
: window.matchMedia('(prefers-color-scheme: dark)').matches;
document.body.classList.toggle('dark', dark);
document.addEventListener('DOMContentLoaded', function () {
var btn = document.getElementById('theme-toggle');
if (!btn) return;
btn.setAttribute('aria-pressed', String(document.body.classList.contains('dark')));
btn.addEventListener('click', function () {
var isDark = document.body.classList.toggle('dark');
btn.setAttribute('aria-pressed', String(isDark));
try { localStorage.setItem(KEY, isDark ? 'dark' : 'light'); } catch (e) {}
});
});
})();
</script>
Reglas del toggle de tema:
- Mantén el contenedor (
.header-actions), el botónid="theme-toggle"y los ids de iconosun-iconymoon-iconexactamente como están escritos. Los scripts y la lista de verificación los buscan. - La luna se muestra en modo claro (clic para ir a oscuro). El sol se muestra en modo oscuro (clic para ir a claro). El estado predeterminado es claro, a menos que
prefers-color-scheme: darko una opción guardada indique lo contrario. - El botón toma su color solo de las variables:
var(--ink)para el icono y el texto,var(--line)para el borde,var(--card)para el fondo al pasar el ratón. Nunca codifiques un color. - El radio del borde es de 4px como máximo, el objetivo táctil es de al menos 44×44px y el estado de hover se encuentra dentro de
@media (hover: hover). - Los iconos son de 20px,
stroke="currentColor",stroke-width="1.8",fill="none", conaria-hidden="true". El botón lleva laaria-label. - Usa
aria-presseden este botón.aria-expandedes para el menú hamburguesa, no para el toggle de tema. - Guarda la elección en
localStoragebajo la clavetheme, con valoreslightodark. Envuelve las llamadas de almacenamiento entry/catch. - El toggle funciona sin Tailwind. El fragmento original usaba clases de utilidad de Tailwind
(
flex items-center gap-4,p-2,w-5 h-5,hidden/block), y esas se reemplazan aquí por el CSS vainilla anterior, porque el CDN de Tailwind está prohibido (sección 10). Si un proyecto ya ejecuta Tailwind con un paso de compilación, las clases de utilidad pueden permanecer, pero el color debe escribirsetext-[var(--ink)]. La formatext.var(--ink)es un error tipográfico y no hace nada.
Pie de página
- Fondo