Tarjeta de papel riso
Papel impreso con dos tintas desalineadas, grano y cinta.
Noche de proyectos
Viernes 24 · 7 pm · Casa Taller. Trae tu prototipo y cuéntanos en qué estás trabajando.
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
/**
* Tarjeta de papel impreso en riso: dos tintas que no coinciden del todo, grano de papel, cinta y una ligera inclinación
* que se endereza al pasar el puntero.
*
* <PaperCard inkA="#ff48b0" inkB="#0078bf" tilt={-2}>
* <h3>Noche de proyectos</h3>
* </PaperCard>
*/
import type { CSSProperties, HTMLAttributes } from "react";
export type PaperCardProps = HTMLAttributes<HTMLDivElement> & {
/** Las dos tintas de impresión. */
inkA?: string;
inkB?: string;
/** Inclinación en grados. */
tilt?: number;
};
const GRAIN = "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E\")";
const CSS = `
.gcr-card { --gcr-a: #ff48b0; --gcr-b: #0078bf; --gcr-tilt: -2deg; position: relative; box-sizing: border-box; width: 100%; max-width: 330px; padding: 30px 28px 28px; background: #f6f4ef; color: #1f1d2b; font-family: inherit;
box-shadow: 0 1px 1px rgba(0, 0, 0, .12), 0 14px 26px -12px rgba(0, 0, 0, .35); transform: rotate(var(--gcr-tilt)); transition: transform .5s cubic-bezier(.16, 1, .3, 1), box-shadow .5s; }
.gcr-card:hover { transform: rotate(0deg) translateY(-6px); box-shadow: 0 1px 1px rgba(0, 0, 0, .12), 0 26px 36px -16px rgba(0, 0, 0, .4); }
.gcr-card::before { content: ""; position: absolute; inset: 0; pointer-events: none; background-image: ${GRAIN}; opacity: .22; mix-blend-mode: multiply; }
.gcr-ink { position: absolute; right: 22px; top: 22px; width: 96px; height: 96px; border-radius: 50%; background: var(--gcr-a); mix-blend-mode: multiply; transition: transform .5s cubic-bezier(.16, 1, .3, 1); }
.gcr-ink + .gcr-ink { right: 58px; top: 38px; background: var(--gcr-b); }
.gcr-card:hover .gcr-ink { transform: translate(-3px, -3px); }
.gcr-card:hover .gcr-ink + .gcr-ink { transform: translate(3px, 3px); }
.gcr-tape { position: absolute; top: -13px; left: 50%; width: 92px; height: 28px; background: rgba(255, 255, 255, .55); box-shadow: 0 1px 2px rgba(0, 0, 0, .18); transform: translateX(-50%) rotate(3deg); }
.gcr-body { position: relative; padding-top: 120px; }
.gcr-body h3 { margin: 0 0 8px; color: var(--gcr-b); font-size: 30px; font-weight: 900; line-height: 1.02; letter-spacing: -.03em; text-transform: uppercase; mix-blend-mode: multiply; }
.gcr-body p { margin: 0; font-size: 15px; line-height: 1.55; }
@media (prefers-reduced-motion: reduce) { .gcr-card, .gcr-ink { transition: none; } }
`;
export function PaperCard({ inkA, inkB, tilt = -2, className, style, children, ...props }: PaperCardProps) {
return (
<>
<style>{CSS}</style>
<div {...props} className={["gcr-card", className].filter(Boolean).join(" ")} style={{ ["--gcr-a" as string]: inkA, ["--gcr-b" as string]: inkB, ["--gcr-tilt" as string]: `${tilt}deg`, ...style } as CSSProperties}>
<span className="gcr-tape" aria-hidden="true" />
<span className="gcr-ink" aria-hidden="true" />
<span className="gcr-ink" aria-hidden="true" />
<div className="gcr-body">{children}</div>
</div>
</>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/tarjeta-papelEjemplo de uso de Tarjeta de papel riso
Después de copiar paper-card.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { PaperCard } from "./paper-card";
export default function Ejemplo() {
return <PaperCard />;
}Accesibilidad y rendimiento
El archivo tiene 51 líneas (3 KB) y no necesita @keyframes. Esto es lo que hace Tarjeta de papel riso por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Expone su estado a tecnologías de apoyo con atributos aria-*.
Acerca del producto
Una tarjeta que imita un impreso en risografía: dos tintas que se multiplican sin coincidir del todo, grano de papel con un filtro SVG, una cinta adhesiva y una ligera inclinación que se endereza al pasar el puntero.
Incluye
Un solo archivo React + TypeScript, con los estilos dentro. No usa Tailwind ni bibliotecas externas.
- Dos tintas configurables (inkA, inkB)
- Grano de papel con SVG embebido, sin imágenes
- Inclinación configurable (tilt)
- Sin JavaScript
Cómo usarlo
Pon tu contenido dentro; el título usa la segunda tinta. Combina con fondos de escritorio lisos.