Ir al contenido
Evaluar mi proyecto
Componentes · HerosDisponible

Hero neobrutalista en bento

Cajas de colores planos con borde grueso y sombra dura, cinta que corre y piezas que se hunden al pulsar.

Haz cosas que se noten

Una caja para cada idea, bordes que no piden perdón y botones que se sienten. Sin gradientes tímidos.

Empieza ya
Proyectos lanzados50+

Código completo

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

hero-neobrutal-bento.tsx73 líneas
Descargar
"use client";

import type { CSSProperties } from "react";

/** Hero neobrutalista en bento: cajas de colores planos con borde grueso y sombra dura, una cinta que corre y piezas que se hunden al pulsar. React + TypeScript, sin dependencias. */
export type HeroNeobrutalBentoProps = {
  title?: string;
  description?: string;
  cta?: string;
  href?: string;
  className?: string;
  style?: CSSProperties;
};

const CSS = `
.gchnb-root { box-sizing: border-box; position: relative; container-type: inline-size; width: 100%; min-height: 620px; overflow: hidden; padding: clamp(16px, 4cqi, 48px); background: #fff4d1; color: #111; font: 700 16px/1.4 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; }
.gchnb-root *, .gchnb-root *::before, .gchnb-root *::after { box-sizing: border-box; }
.gchnb-root a { -webkit-tap-highlight-color: transparent; }
.gchnb-root :focus-visible { outline: 4px solid #2f5bff; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .gchnb-root *, .gchnb-root *::before, .gchnb-root *::after { animation: none !important; transition-duration: .01ms !important; } }
.gchnb-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: minmax(120px, auto); gap: 18px; }
.gchnb-box { position: relative; padding: 22px; border: 4px solid #111; background: var(--c, #fff); box-shadow: 8px 8px 0 #111; transition: transform .12s, box-shadow .12s; }
.gchnb-box:hover { transform: translate(4px, 4px); box-shadow: 4px 4px 0 #111; }
.gchnb-main { grid-column: span 4; grid-row: span 2; display: grid; align-content: center; gap: 18px; --c: #ff90e8; }
.gchnb-title { margin: 0; font: 900 clamp(38px, 7.4cqi, 92px)/.92 ui-sans-serif, system-ui, -apple-system, sans-serif; letter-spacing: -.045em; text-transform: uppercase; text-wrap: balance; }
.gchnb-desc { margin: 0; max-width: 40ch; font-weight: 600; font-size: clamp(15px, 1.8cqi, 19px); }
.gchnb-cta { justify-self: start; display: inline-flex; align-items: center; min-height: 54px; padding: 0 26px; border: 4px solid #111; background: #fff; color: #111; font-weight: 900; text-transform: uppercase; letter-spacing: .04em; text-decoration: none; box-shadow: 5px 5px 0 #111; transition: transform .1s, box-shadow .1s, background .1s; }
.gchnb-cta:hover { background: #ffe14d; }
.gchnb-cta:active { transform: translate(5px, 5px); box-shadow: 0 0 0 #111; }
.gchnb-stat { grid-column: span 2; --c: #7cf5c3; display: grid; align-content: space-between; }
.gchnb-stat b { font: 900 clamp(42px, 6cqi, 72px)/1 ui-sans-serif, system-ui, sans-serif; letter-spacing: -.05em; }
.gchnb-sticker { grid-column: span 2; --c: #ffe14d; display: grid; place-items: center; text-align: center; font: 900 24px/1.1 ui-sans-serif, system-ui, sans-serif; text-transform: uppercase; transform: rotate(-3deg); }
.gchnb-sticker:hover { transform: rotate(2deg) translate(4px, 4px); }
.gchnb-tape { grid-column: 1 / -1; padding: 0; overflow: hidden; background: #111; color: #ffe14d; display: flex; }
.gchnb-tape:hover { transform: none; box-shadow: 8px 8px 0 #111; }
.gchnb-run { display: flex; flex-shrink: 0; gap: 36px; padding: 14px 18px; white-space: nowrap; font: 900 22px/1 ui-sans-serif, system-ui, sans-serif; text-transform: uppercase; letter-spacing: .04em; animation: gchnb-run 18s linear infinite; }
@container (max-width: 760px) { .gchnb-main { grid-column: 1 / -1; } .gchnb-stat, .gchnb-sticker { grid-column: span 3; } }
@keyframes gchnb-run { to { transform: translateX(-100%); } }`;

export function HeroNeobrutalBento({ title = "Haz cosas que se noten", description = "Una caja para cada idea, bordes que no piden perdón y botones que se sienten. Sin gradientes tímidos.", cta = "Empieza ya", href = "#", className = "", style }: HeroNeobrutalBentoProps) {
  const words = ["Diseño sin miedo", "Código limpio", "Entrega semanal", "Cero relleno"];
  return (
    <section className={`gchnb-root ${className}`} style={style}>
      <style>{CSS}</style>
      <div className="gchnb-grid">
        <div className="gchnb-box gchnb-main">
          <h1 className="gchnb-title">{title}</h1>
          <p className="gchnb-desc">{description}</p>
          <a className="gchnb-cta" href={href}>
            {cta}
          </a>
        </div>
        <div className="gchnb-box gchnb-stat">
          <span>Proyectos lanzados</span>
          <b>50+</b>
        </div>
        <div className="gchnb-box gchnb-sticker" aria-hidden="true">
          100% a la medida
        </div>
        <div className="gchnb-box gchnb-tape" aria-hidden="true">
          {[0, 1].map((n) => (
            <span key={n} className="gchnb-run">
              {words.concat(words).map((word, index) => (
                <span key={index}>{word} ✺</span>
              ))}
            </span>
          ))}
        </div>
      </div>
    </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-neobrutal-bento

Ejemplo de uso de Hero neobrutalista en bento

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

ejemplo.tsx5 líneas
import { HeroNeobrutalBento } from "./hero-neobrutal-bento";

export default function Ejemplo() {
  return <HeroNeobrutalBento title="Ejemplo" />;
}

Propiedades de HeroNeobrutalBento

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

PropiedadTipoDescripción
title?stringOpcional.
description?stringOpcional.
cta?stringOpcional.
href?stringOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

Personaliza Hero neobrutalista en bento con variables CSS

Define estas variables en el contenedor o en tu hoja de estilos para cambiar los colores sin tocar el componente. Si no las defines, se usa el valor por defecto.

VariableValor por defecto
--c#fff

Accesibilidad y rendimiento

El archivo tiene 73 líneas (5 KB) y define 1 animación con @keyframes. Esto es lo que hace Hero neobrutalista en bento 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-*.
  • Es un componente de cliente de Next.js: incluye la directiva "use client".
Licencia
MIT
Dependencias
React >=18
Compatibilidad
React 18 y 19 · Next.js (componente de cliente)