Evervault Card A hover-reveal card with encrypted text and a mixed gradient that follows the cursor.
A card with an amazing hover effect: moving the cursor reveals a stream of encrypted characters projected through a radial mask, tinted by a mixed primary gradient.
Preview Code
npx mvpblocks add evervault-card Open in
npm pnpm yarn bun
npm install framer-motion react pnpm install framer-motion react yarn add framer-motion react bun add framer-motion react "use client"; import { motion, useMotionTemplate, useMotionValue } from "framer-motion"; import type { MotionValue } from "framer-motion"; import React, { useState } from "react"; import { cn } from "@/lib/utils"; export const EvervaultCard = ({ text, className, }: { text?: string; className?: string; }) => { const mouseX = useMotionValue(0); const mouseY = useMotionValue(0); const [randomString, setRandomString] = useState(() => generateRandomString(1500), ); function onMouseMove({ currentTarget, clientX, clientY, }: React.MouseEvent<HTMLDivElement>) { const { left, top } = currentTarget.getBoundingClientRect(); mouseX.set(clientX - left); mouseY.set(clientY - top); const str = generateRandomString(1500); setRandomString(str); } return ( <div className={cn( "p-0.5 bg-transparent aspect-square flex items-center justify-center w-full h-full relative", className, )} > <div onMouseMove={onMouseMove} className="group/card rounded-3xl w-full relative overflow-hidden bg-transparent flex items-center justify-center h-full" > <CardPattern mouseX={mouseX} mouseY={mouseY} randomString={randomString} /> <div className="relative z-10 flex items-center justify-center"> <div className="relative h-44 w-44 rounded-full flex items-center justify-center text-foreground font-bold text-4xl"> <div className="absolute w-full h-full bg-card/90 backdrop-blur-sm rounded-full" /> <span className="text-foreground z-20">{text}</span> </div> </div> </div> </div> ); }; export function CardPattern({ mouseX, mouseY, randomString, }: { mouseX: MotionValue<number>; mouseY: MotionValue<number>; randomString: string; }) { const maskImage = useMotionTemplate`radial-gradient(250px at ${mouseX}px ${mouseY}px, white, transparent)`; const style = { maskImage, WebkitMaskImage: maskImage }; return ( <div className="pointer-events-none"> <div className="absolute inset-0 rounded-2xl [mask-image:linear-gradient(white,transparent)] group-hover/card:opacity-50"></div> <motion.div className="absolute inset-0 rounded-2xl bg-gradient-to-r from-[#465fff] to-[#7f97ff] opacity-0 group-hover/card:opacity-100 backdrop-blur-xl transition duration-500" style={style} /> <motion.div className="absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay group-hover/card:opacity-100" style={style} > <p className="absolute inset-x-0 text-xs h-full break-words whitespace-pre-wrap text-white font-mono font-bold transition duration-500"> {randomString} </p> </motion.div> </div> ); } const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; export const generateRandomString = (length: number) => { let result = ""; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; }; export const Icon = ({ className, ...rest }: React.SVGProps<SVGSVGElement>) => { return ( <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className={className} {...rest} > <path strokeLinecap="round" strokeLinejoin="round" d="M12 6v12m6-6H6" /> </svg> ); }; export default function EvervaultCardDemo() { return ( <div className="relative mx-auto flex h-[30rem] max-w-sm flex-col items-start rounded-2xl border border-border bg-card p-4"> <Icon className="absolute -top-3 -left-3 h-6 w-6 text-foreground" /> <Icon className="absolute -bottom-3 -left-3 h-6 w-6 text-foreground" /> <Icon className="absolute -top-3 -right-3 h-6 w-6 text-foreground" /> <Icon className="absolute -bottom-3 -right-3 h-6 w-6 text-foreground" /> <EvervaultCard text="hover" /> <h2 className="mt-4 text-sm font-light text-foreground"> Hover over this card to reveal the encrypted gradient effect. Running out of copy here. </h2> <p className="mt-4 rounded-full border border-border px-2 py-0.5 text-sm font-light text-foreground"> Watch me hover </p> </div> ); } Expand
EvervaultCard and the corner Icon are exported as named exports. Place the EvervaultCard inside any container and add the Icons at the corners:
"use client" ;
import { EvervaultCard, Icon } from "@/components/mvpblocks/cards/evervault-card/evervault-card" ;
export default function MyComponent () {
return (
< div className = "relative mx-auto flex max-w-sm flex-col items-start rounded-2xl border border-border bg-card p-4" >
< Icon className = "absolute -top-3 -left-3 h-6 w-6 text-foreground" />
< Icon className = "absolute -bottom-3 -left-3 h-6 w-6 text-foreground" />
< Icon className = "absolute -top-3 -right-3 h-6 w-6 text-foreground" />
< Icon className = "absolute -bottom-3 -right-3 h-6 w-6 text-foreground" />
< EvervaultCard text = "hover" />
< h2 className = "mt-4 text-sm font-light text-foreground" >
Hover over this card to reveal the encrypted gradient effect.
</ h2 >
< p className = "mt-4 rounded-full border border-border px-2 py-0.5 text-sm font-light text-foreground" >
Watch me hover
</ p >
</ div >
);
}
Prop Type Description textstringThe text shown at the center of the card classNamestringThe class name of the child component
Prop Type Description classNamestringThe class name of the SVG element ...restReact.SVGProps<SVGSVGElement>Any other SVG attributes
Cursor Tracking : A radial mask follows the mouse using motion values and a motion template
Encrypted Text : A random alphanumeric string is regenerated on every mouse move
Mixed Gradient : On hover, the encrypted layer is tinted with the current primary gradient (#465fff → #7f97ff)
Pure Surfaces : The card blends into any the current surface (bg-card, border-border, text-foreground)