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.
"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.
npx shadcn@latest add https://www.gassierconsulting.com/r/tarjeta-arcillaEjemplo de uso de Tarjeta claymorfismo
Después de copiar tarjeta-arcilla.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
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.
| Propiedad | Tipo | Descripción |
|---|---|---|
title? | string | Opcional. |
text? | string | Opcional. |
action? | string | Opcional. |
color? | string | Opcional. |
media? | ReactNode | Opcional. |
onAction? | () => void | Opcional. |
className? | string | Opcional. |
style? | CSSProperties | Opcional. |
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.
| Variable | Valor 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".