Ir al contenido
Evaluar mi proyecto
Componentes · FootersDisponible

Footer de placa de aluminio

Placa de aluminio cepillado con tornillos, texto grabado, enlaces con relieve que se hunden y luz piloto verde.

Taller 9Mod. 2026 · Serie A
En servicio

Código completo

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

footer-placa.tsx71 líneas
Descargar
"use client";

import type { CSSProperties } from "react";

/** Footer skeuomórfico de placa de aluminio atornillada: texto grabado, enlaces con relieve, interruptor de estado y remaches. React + TypeScript, sin dependencias. */
export type FooterPlacaProps = {
  brand?: string;
  model?: string;
  links?: { label: string; href?: string }[];
  legal?: string;
  className?: string;
  style?: CSSProperties;
};

const CSS = `
.gcfpl-root { box-sizing: border-box; container-type: inline-size; width: 100%; padding: clamp(14px, 3cqi, 32px); background: #5b5e66; color: #4a4d55; font: 700 13px/1.4 "Helvetica Neue", Arial, ui-sans-serif, system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; }
.gcfpl-root *, .gcfpl-root *::before, .gcfpl-root *::after { box-sizing: border-box; }
.gcfpl-root :focus-visible { outline: 3px solid #2f7bff; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .gcfpl-root *, .gcfpl-root *::before, .gcfpl-root *::after { transition-duration: .01ms !important; } }
.gcfpl-plate { position: relative; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 20px clamp(16px, 4cqi, 48px); padding: 28px clamp(36px, 6cqi, 64px); border-radius: 12px; background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0) 0 2px, rgba(255, 255, 255, .22) 2px 3px, rgba(0, 0, 0, .03) 3px 4px), linear-gradient(180deg, #eceef2, #cfd2d9 50%, #dcdee4); box-shadow: inset 0 1px 0 #fff, inset 0 -2px 3px rgba(0, 0, 0, .2), 0 2px 0 #3d4047, 0 12px 20px -6px rgba(0, 0, 0, .6); text-shadow: 0 1px 0 rgba(255, 255, 255, .9); }
.gcfpl-screw { position: absolute; width: 14px; height: 14px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, #9a9da6 70%); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .35), 0 1px 0 rgba(255, 255, 255, .7); }
.gcfpl-screw::after { content: ""; position: absolute; left: 2px; right: 2px; top: 50%; height: 2px; margin-top: -1px; background: rgba(0, 0, 0, .45); transform: rotate(var(--r, 30deg)); }
.gcfpl-brand { font: 900 24px/1 "Helvetica Neue", Arial, sans-serif; letter-spacing: .18em; color: #3d4047; }
.gcfpl-model { display: block; margin-top: 6px; font-size: 11px; letter-spacing: .2em; color: #6e717a; }
.gcfpl-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 0; padding: 0; list-style: none; }
.gcfpl-links a { display: inline-flex; align-items: center; min-height: 40px; padding: 0 18px; border-radius: 8px; color: #4a4d55; text-decoration: none; background: linear-gradient(180deg, #f6f7f9, #cdd0d7); box-shadow: inset 0 1px 0 #fff, 0 2px 0 #9a9da6, 0 4px 6px rgba(0, 0, 0, .25); transition: transform .08s, box-shadow .08s; }
.gcfpl-links a:hover { filter: brightness(1.04); }
.gcfpl-links a:active { transform: translateY(2px); box-shadow: inset 0 2px 4px rgba(0, 0, 0, .3), 0 0 0 #9a9da6; }
.gcfpl-led { display: flex; align-items: center; gap: 10px; font-size: 11px; letter-spacing: .16em; }
.gcfpl-led i { width: 12px; height: 12px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #d8ffd2, #32d34a 60%, #14912a); box-shadow: 0 0 10px 2px rgba(50, 211, 74, .6), 0 1px 0 rgba(255, 255, 255, .8); }
.gcfpl-legal { margin: 14px 0 0; text-align: center; font-size: 11px; letter-spacing: .16em; color: #c9ccd4; }
@container (max-width: 760px) { .gcfpl-plate { grid-template-columns: 1fr; justify-items: center; text-align: center; } }`;

export function FooterPlaca({ brand = "Taller 9", model = "Mod. 2026 · Serie A", links = [{ label: "Catálogo" }, { label: "Servicio" }, { label: "Contacto" }, { label: "Garantía" }], legal = "Fabricado con paciencia · © 2026", className = "", style }: FooterPlacaProps) {
  return (
    <footer className={`gcfpl-root ${className}`} style={style}>
      <style>{CSS}</style>
      <div className="gcfpl-plate">
        {([
          { left: 12, top: 12, r: 25 },
          { right: 12, top: 12, r: 70 },
          { left: 12, bottom: 12, r: 110 },
          { right: 12, bottom: 12, r: 160 },
        ] as { left?: number; right?: number; top?: number; bottom?: number; r: number }[]).map(({ r, ...pos }, index) => (
          <span key={index} className="gcfpl-screw" aria-hidden="true" style={{ ...pos, "--r": `${r}deg` } as CSSProperties} />
        ))}
        <div>
          <span className="gcfpl-brand">{brand}</span>
          <span className="gcfpl-model">{model}</span>
        </div>
        <nav aria-label="Pie de página">
          <ul className="gcfpl-links">
            {links.map((link) => (
              <li key={link.label}>
                <a href={link.href ?? "#"} onClick={(event) => !link.href && event.preventDefault()}>
                  {link.label}
                </a>
              </li>
            ))}
          </ul>
        </nav>
        <span className="gcfpl-led">
          <i aria-hidden="true" />
          En servicio
        </span>
      </div>
      <p className="gcfpl-legal">{legal}</p>
    </footer>
  );
}

Úsalo en tu proyecto

Instálalo con la CLI de shadcn.

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

Ejemplo de uso de Footer de placa de aluminio

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

ejemplo.tsx5 líneas
import { FooterPlaca } from "./footer-placa";

export default function Ejemplo() {
  return <FooterPlaca brand="Ejemplo" />;
}

Propiedades de FooterPlaca

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

PropiedadTipoDescripción
brand?stringOpcional.
model?stringOpcional.
links?{ label: string; href?: string }[]Opcional.
legal?stringOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

Personaliza Footer de placa de aluminio 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
--r30deg

Accesibilidad y rendimiento

El archivo tiene 71 líneas (5 KB) y no necesita @keyframes. Esto es lo que hace Footer de placa de aluminio 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)