Ir al contenido
Evaluar mi proyecto
Componentes · TarjetasDisponible

Tarjeta claymorfismo

Bloque de plastilina con relieve interior, ventana hundida y una pieza 3D que flota; se levanta y gira al apuntarla.

Plan de equipo

Todo el trabajo del equipo en un solo lugar, sin hojas de cálculo sueltas.

Código completo

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

tarjeta-arcilla.tsx52 líneas
Descargar
"use client";

import type { CSSProperties, ReactNode } from "react";

/** Tarjeta claymorfismo: bloque de plastilina con relieve interior y una "pieza" 3D que flota. React + TypeScript, sin dependencias. Personaliza con --gctar-*. */
export type TarjetaArcillaProps = {
  title?: string;
  text?: string;
  action?: string;
  color?: string;
  media?: ReactNode;
  onAction?: () => void;
  className?: string;
  style?: CSSProperties;
};

const CSS = `
.gctar-root { box-sizing: border-box; display: block; width: 100%; max-width: 300px; font: 600 15px/1.45 ui-rounded, "SF Pro Rounded", "Nunito", ui-sans-serif, system-ui, sans-serif; color: #3d2c4a; }
.gctar-root *, .gctar-root *::before, .gctar-root *::after { box-sizing: border-box; }
.gctar-root button { font: inherit; -webkit-tap-highlight-color: transparent; }
.gctar-root :focus-visible { outline: 3px solid #3d2c4a; outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .gctar-root *, .gctar-root *::before, .gctar-root *::after { animation: none !important; transition-duration: .01ms !important; } }
.gctar-card { --c: var(--gctar-bg, #ffd3e0); position: relative; padding: 22px 22px 24px; border-radius: 36px; background: var(--c); box-shadow: inset -10px -12px 20px color-mix(in srgb, var(--c) 70%, #5a1030), inset 10px 12px 20px color-mix(in srgb, var(--c) 40%, #fff), 18px 22px 34px -10px color-mix(in srgb, var(--c) 80%, #3a0a20); transition: transform .4s cubic-bezier(.34, 1.56, .64, 1); }
.gctar-card:hover { transform: translateY(-6px) rotate(-.6deg); }
.gctar-media { display: grid; place-items: center; height: 120px; margin-bottom: 16px; border-radius: 26px; background: color-mix(in srgb, var(--c) 55%, #fff); box-shadow: inset 6px 8px 14px color-mix(in srgb, var(--c) 60%, #5a1030), inset -6px -8px 14px rgba(255, 255, 255, .7); }
.gctar-blob { width: 64px; height: 64px; border-radius: 50%; background: #ffb347; box-shadow: inset -8px -10px 14px rgba(160, 70, 0, .45), inset 8px 8px 12px rgba(255, 255, 255, .6), 8px 14px 18px -4px rgba(120, 40, 20, .45); animation: gctar-float 3.4s ease-in-out infinite; }
.gctar-title { margin: 0 0 6px; font-size: 21px; font-weight: 800; letter-spacing: -.01em; }
.gctar-text { margin: 0 0 18px; color: color-mix(in srgb, #3d2c4a 82%, var(--c)); font-weight: 600; }
.gctar-btn { min-height: 46px; padding: 0 24px; border: 0; border-radius: 999px; background: #3d2c4a; color: #fff; font-weight: 800; cursor: pointer; box-shadow: inset -4px -5px 8px rgba(0, 0, 0, .4), inset 4px 5px 8px rgba(255, 255, 255, .25), 4px 8px 12px -4px rgba(61, 44, 74, .55); transition: transform .3s cubic-bezier(.34, 1.56, .64, 1); }
.gctar-btn:hover { transform: scale(1.06); }
.gctar-btn:active { transform: scale(.94, .9); }
@keyframes gctar-float { 50% { transform: translateY(-10px) scale(1.03, .97); } }`;

export function TarjetaArcilla({ title = "Plan de equipo", text = "Todo el trabajo del equipo en un solo lugar, sin hojas de cálculo sueltas.", action = "Ver plan", color, media, onAction, className = "", style }: TarjetaArcillaProps) {
  const vars = color ? ({ "--gctar-bg": color } as CSSProperties) : undefined;
  return (
    <div className={`gctar-root ${className}`} style={{ ...vars, ...style }}>
      <style>{CSS}</style>
      <article className="gctar-card">
        <div className="gctar-media" aria-hidden="true">
          {media ?? <span className="gctar-blob" />}
        </div>
        <h3 className="gctar-title">{title}</h3>
        <p className="gctar-text">{text}</p>
        <button className="gctar-btn" type="button" onClick={onAction}>
          {action}
        </button>
      </article>
    </div>
  );
}

Úsalo en tu proyecto

Instálalo con la CLI de shadcn.

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

Ejemplo de uso de Tarjeta claymorfismo

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

ejemplo.tsx5 líneas
import { TarjetaArcilla } from "./tarjeta-arcilla";

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

Propiedades de TarjetaArcilla

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

PropiedadTipoDescripción
title?stringOpcional.
text?stringOpcional.
action?stringOpcional.
color?stringOpcional.
media?ReactNodeOpcional.
onAction?() => voidOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

Personaliza Tarjeta claymorfismo 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
--gctar-bg#ffd3e0

Accesibilidad y rendimiento

El archivo tiene 52 líneas (4 KB) y define 1 animación con @keyframes. Esto es lo que hace Tarjeta claymorfismo 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-*.
  • Calcula tonos con color-mix(), así que un solo color base alcanza.
  • 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)