Santiago cambia a escala de barrio
Un recorrido por las decisiones que cambian el espacio público y su evidencia.
Patrón canónico de encabezado de artículo para periodismo2, comentario, editorial sebastián y lepp.
Primero el componente, después la variación de marca y finalmente su uso dentro de una página.
Un recorrido por las decisiones que cambian el espacio público y su evidencia.
Un recorrido por las decisiones que cambian el espacio público y su evidencia.
<header class="ui-sample ui-content" data-article-header="true"><h2>Santiago cambia a escala de barrio</h2><p>Un recorrido por las decisiones que cambian el espacio público y su evidencia.</p><div><a rel="author" href="#autor">Sebastián Illanes</a> · <time dateTime="2026-08-25">25 de agosto de 2026</time> · 4 min</div></header>Cada cambio visible declara su autoridad; lo que permanece canónico no se vuelve a inventar en el producto.
Un recorrido por las decisiones que cambian el espacio público y su evidencia.
Compara la propuesta con cortes reales del repositorio. La ausencia de una muestra se declara y nunca se reconstruye de memoria.
Preparando comparación histórica…
La comparación convierte una regla abstracta en una diferencia visible y verificable.
Un recorrido por las decisiones que cambian el espacio público y su evidencia.
La prosa completa usa una voz técnica.La misma anatomía debe conservar lectura, foco y acciones sin cortar contenido ni crear scroll horizontal en la página.
Un recorrido por las decisiones que cambian el espacio público y su evidencia.
| Dimensión | Contrato |
|---|---|
| Propietario canónico | Sistema de diseño CIS y equipo editorial · core/core-style |
| Consumidores | Periodismo2, Comentario, Editorial Sebastián y LEPP |
| Dependencias | prosa canónica, metadatos editoriales |
| Estado | candidato |
Patrón propuesto. 0 implementaciones observadas en 0 repositorios.
La observación demuestra uso existente; la aceptación canónica sigue dependiendo de esta ficha y de su propietario.
| Dato | Resultado |
|---|---|
| Clasificación | Patrón propuesto |
| Implementaciones | 0 implementaciones observadas |
| Repositorios | Ningún repositorio observado |
| Snapshot | kit/componentes/componentes-observados.json |
El inventario conserva repositorio, archivo fuente y criterio de asociación. Observar una implementación no la convierte automáticamente en canónica.
| Estado requerido |
|---|
| base |
| destacado |
| archivo |
| contenido largo |
Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
<header class="ui-sample ui-content" data-article-header="true"><h2>Santiago cambia a escala de barrio</h2><p>Un recorrido por las decisiones que cambian el espacio público y su evidencia.</p><div><a rel="author" href="#autor">Sebastián Illanes</a> · <time dateTime="2026-08-25">25 de agosto de 2026</time> · 4 min</div></header>Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
<header class="ui-sample ui-content border border-slate-300 bg-white p-4 text-slate-950 flex flex-wrap items-center justify-between gap-3" data-article-header="true"><h2>Santiago cambia a escala de barrio</h2><p>Un recorrido por las decisiones que cambian el espacio público y su evidencia.</p><div><a class="underline underline-offset-4" rel="author" href="#autor">Sebastián Illanes</a> · <time dateTime="2026-08-25">25 de agosto de 2026</time> · 4 min</div></header>Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
import type { ReactNode } from "react";
export interface ArticleHeaderAuthor {
/** Nombre visible; vacío omite al autor. */
name: string;
/** Página de la persona o del equipo; sin enlace, el nombre va como texto. */
href?: string;
}
const AUTHORS: ArticleHeaderAuthor[] = [{ name: "Sebastián Illanes", href: "#autor" }];
export interface ArticleHeaderProps {
/** Título del artículo. */
title?: string;
/** Bajada: una o dos oraciones que resumen el artículo; vacía no se muestra. */
description?: string;
/** Autores en orden de firma; se unen con comas y «y». Una lista vacía omite la autoría. */
authors?: ArticleHeaderAuthor[];
/** Fecha de publicación en ISO 8601 (atributo `dateTime`). */
dateTime?: string;
/** Texto visible de la fecha dentro de `<time>`; vacío la oculta. */
time?: string;
/** Tiempo estimado de lectura («4 min»); vacío lo oculta. */
readingTime?: string;
className?: string;
}
function firmas(authors: ArticleHeaderAuthor[]): ReactNode[] {
return authors.flatMap((author, i) => [
i === 0 ? null : i === authors.length - 1 ? " y " : ", ",
author.href ? <a rel="author" href={author.href} key={i}>{author.name}</a> : author.name,
]);
}
/**
* Encabezado de artículo con título, bajada y línea de autoría, fecha y tiempo de lectura; va al inicio de una nota, crónica o ensayo.
*
* Autoría, fecha y tiempo de lectura van en una línea separada por « · »; cada parte vacía se omite.
*
* @example <ArticleHeader title="Una decisión explicada con evidencia" authors={[{ name: "Sebastián Illanes", href: "/autores/sebastian" }]} dateTime="2026-08-25" time="25 de agosto de 2026" readingTime="4 min" />
*/
export function ArticleHeader({
title = "Santiago cambia a escala de barrio",
description = "Un recorrido por las decisiones que cambian el espacio público y su evidencia.",
authors = AUTHORS,
dateTime = "2026-08-25",
time = "25 de agosto de 2026",
readingTime = "4 min",
className,
}: ArticleHeaderProps) {
const firmantes = authors.filter((author) => author.name);
const partes: ReactNode[] = [];
if (firmantes.length) partes.push(firmas(firmantes));
if (time) partes.push(<time dateTime={dateTime || undefined} key="fecha">{time}</time>);
if (readingTime) partes.push(readingTime);
if (!title && !description && !partes.length) return null;
return (
<header className={["ui-content", className].filter(Boolean).join(" ")} data-article-header>
{title ? <h2>{title}</h2> : null}
{description ? <p>{description}</p> : null}
{partes.length ? <div>{partes.flatMap((parte, i) => (i ? [" · ", parte] : [parte]))}</div> : null}
</header>
);
}