Ir al contenido
Evaluar mi proyecto
Componentes · HerosDisponible

Hero editorial

Titular grande con una palabra subrayada a mano y un círculo de color.

Diseñamos lo quetodavíano existe.

Un estudio pequeño para productos que necesitan ideas claras antes que pantallas bonitas.

  • Identidad
  • Producto digital
  • Sitios web
  • Sistemas de diseño

Código completo

Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.

editorial-hero.tsx102 líneas
Descargar
/**
 * Hero editorial: titular grande con una palabra en cursiva subrayada a mano, un círculo de color y una columna de texto asimétrica.
 * Las líneas suben y el subrayado se dibuja una sola vez al cargar. Solo CSS, sin JavaScript.
 *
 *   <EditorialHero
 *     lead="Diseñamos lo que" highlight="todavía" tail="no existe."
 *     description="Un estudio pequeño para productos que necesitan ideas claras."
 *     primary={{ label: "Cuéntanos tu idea", href: "/contacto" }}
 *     secondary={{ label: "Ver proyectos", href: "/proyectos" }}
 *     services={["Identidad", "Producto", "Sitios web"]}
 *   />
 */

import type { CSSProperties } from "react";

type Cta = { label: string; href: string };

export type EditorialHeroProps = {
  lead?: string;
  highlight?: string;
  tail?: string;
  description?: string;
  primary?: Cta;
  secondary?: Cta;
  services?: string[];
  /** Color del círculo y el subrayado. */
  accent?: string;
  className?: string;
  style?: CSSProperties;
};

const CSS = `
.gche-root { --gche-ink: #101012; --gche-accent: #5b3cff; position: relative; display: grid; grid-template-rows: 1fr auto; box-sizing: border-box; min-height: 640px; overflow: hidden; padding: clamp(24px, 4.5vw, 64px); background: #fbfbfa; color: var(--gche-ink); font-family: inherit; }
.gche-orb { position: absolute; top: -13vw; right: -9vw; width: min(36vw, 520px); aspect-ratio: 1; border-radius: 50%; background: var(--gche-accent); animation: gche-drift 14s ease-in-out infinite alternate; }
.gche-orb::after { content: ""; position: absolute; left: -26%; bottom: -18%; width: 52%; aspect-ratio: 1; border-radius: 50%; background: #ff8fb8; mix-blend-mode: multiply; }
.gche-main { position: relative; display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: clamp(24px, 4vw, 64px); align-items: end; padding-block: clamp(56px, 11vw, 150px) clamp(28px, 4vw, 48px); }
.gche-title { margin: 0; font-family: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif; font-size: clamp(38px, 6.2vw, 92px); font-weight: 400; line-height: .98; white-space: nowrap; letter-spacing: -.04em; text-wrap: balance; }
.gche-line { display: block; overflow: hidden; padding-bottom: .26em; margin-bottom: -.26em; }
.gche-line > span { display: inline-block; animation: gche-rise 1.1s cubic-bezier(.16, 1, .3, 1) both; }
.gche-line:nth-child(2) > span { animation-delay: .12s; } .gche-line:nth-child(3) > span { animation-delay: .24s; }
.gche-hl { position: relative; font-style: italic; }
.gche-hl svg { position: absolute; left: -2%; bottom: -.1em; width: 104%; height: .22em; overflow: visible; }
.gche-hl path { fill: none; stroke: var(--gche-accent); stroke-width: 6; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; animation: gche-draw 1.1s cubic-bezier(.65, 0, .35, 1) .7s forwards; vector-effect: non-scaling-stroke; }
.gche-side { position: relative; z-index: 1; display: grid; gap: 26px; padding-bottom: .5em; }
.gche-side p { margin: 0; max-width: 34ch; font-size: clamp(16px, 1.45vw, 19px); line-height: 1.6; color: #3d3d46; }
.gche-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 26px; }
.gche-primary { display: inline-flex; align-items: center; min-height: 52px; padding: 0 28px; border-radius: 999px; background: var(--gche-ink); color: #fff; font-size: 16px; font-weight: 600; text-decoration: none; transition: background-color .3s, transform .3s cubic-bezier(.16, 1, .3, 1); }
.gche-primary:hover { background: var(--gche-accent); transform: translateY(-2px); }
.gche-secondary { padding-bottom: 2px; border-bottom: 1.5px solid currentColor; color: inherit; font-size: 16px; font-weight: 600; text-decoration: none; transition: color .25s, border-color .25s; }
.gche-secondary:hover { color: var(--gche-accent); }
.gche-primary:focus-visible, .gche-secondary:focus-visible { outline: 2px solid var(--gche-accent); outline-offset: 4px; }
.gche-foot { position: relative; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 32px; padding-top: 20px; border-top: 1.5px solid var(--gche-ink); font-size: 14px; font-weight: 600; letter-spacing: .01em; }
@keyframes gche-rise { from { transform: translateY(105%); } }
@keyframes gche-draw { to { stroke-dashoffset: 0; } }
@keyframes gche-drift { to { transform: translate(-3vw, 3vw) scale(1.05); } }
@media (max-width: 860px) {
  .gche-main { grid-template-columns: 1fr; align-items: start; padding-top: 72px; }
  .gche-title { white-space: normal; }
  .gche-orb { top: -22vw; right: -24vw; width: 70vw; opacity: .22; }
}
@media (prefers-reduced-motion: reduce) { .gche-orb, .gche-line > span { animation: none; } .gche-hl path { animation: none; stroke-dashoffset: 0; } }
`;

export function EditorialHero({
  lead = "Diseñamos lo que",
  highlight = "todavía",
  tail = "no existe.",
  description = "Un estudio pequeño para productos que necesitan ideas claras antes que pantallas bonitas.",
  primary = { label: "Cuéntanos tu idea", href: "#contacto" },
  secondary = { label: "Ver proyectos", href: "#proyectos" },
  services = ["Identidad", "Producto digital", "Sitios web", "Sistemas de diseño"],
  accent,
  className,
  style,
}: EditorialHeroProps) {
  return (
    <>
      <style>{CSS}</style>
      <section className={["gche-root", className].filter(Boolean).join(" ")} style={{ ["--gche-accent" as string]: accent, ...style } as CSSProperties}>
        <span className="gche-orb" aria-hidden="true" />
        <div className="gche-main">
          <h1 className="gche-title">
            <span className="gche-line"><span>{lead}</span></span>
            <span className="gche-line"><span><span className="gche-hl">{highlight}<svg viewBox="0 0 300 16" preserveAspectRatio="none" aria-hidden="true"><path pathLength="1" d="M3 11 C 50 2, 110 14, 170 6 S 265 9, 297 4" /></svg></span></span></span>
            <span className="gche-line"><span>{tail}</span></span>
          </h1>
          <div className="gche-side">
            <p>{description}</p>
            <div className="gche-actions">
              <a className="gche-primary" href={primary.href}>{primary.label}</a>
              <a className="gche-secondary" href={secondary.href}>{secondary.label}</a>
            </div>
          </div>
        </div>
        <ul className="gche-foot" style={{ margin: 0, listStyle: "none", padding: "20px 0 0" }}>
          {services.map((service) => <li key={service}>{service}</li>)}
        </ul>
      </section>
    </>
  );
}

Úsalo en tu proyecto

Instálalo con la CLI de shadcn.

terminal.sh1 líneas
npx shadcn@latest add https://www.gassierconsulting.com/r/hero-editorial

Ejemplo de uso de Hero editorial

Después de copiar editorial-hero.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.

ejemplo.tsx5 líneas
import { EditorialHero } from "./editorial-hero";

export default function Ejemplo() {
  return <EditorialHero lead="Ejemplo" />;
}

Propiedades de EditorialHero

EditorialHero acepta 10 propiedades: todas son opcionales y tienen un valor por defecto, así que funciona sin configurar nada.

PropiedadTipoDescripción
lead?stringOpcional.
highlight?stringOpcional.
tail?stringOpcional.
description?stringOpcional.
primary?CtaOpcional.
secondary?CtaOpcional.
services?string[]Opcional.
accent?stringColor del círculo y el subrayado.
className?stringOpcional.
style?CSSPropertiesOpcional.

Accesibilidad y rendimiento

El archivo tiene 102 líneas (6 KB) y define 3 animaciones con @keyframes. Esto es lo que hace Hero editorial por quien lo usa:

  • Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
  • Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
  • Expone su estado a tecnologías de apoyo con atributos aria-*.
Licencia
MIT
Dependencias
React >=18
Compatibilidad
React · Next.js · Sin Tailwind

Acerca del producto

Un hero de aire editorial: titular enorme en tipografía con serifa del sistema, una palabra en cursiva que se subraya con un trazo dibujado, un círculo de color que flota y una columna de texto asimétrica con llamadas a la acción. Las líneas suben y el subrayado se dibuja una sola vez.

Incluye

Una sección completa en un solo archivo React + TypeScript, con los estilos dentro. No usa Tailwind ni bibliotecas externas.

  • Titular en tres partes: lead, highlight y tail
  • Subrayado SVG que se dibuja al cargar
  • Color de acento configurable
  • Se apila en pantallas estrechas
  • Sin JavaScript

Cómo usarlo

Todas las propiedades tienen valor por defecto. Pasa lead, highlight, tail, description, primary, secondary y services para tu contenido.