Evervault Card

A hover-reveal card with encrypted text and a mixed gradient that follows the cursor.

Evervault Card

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.

Installation

npm install framer-motion react
pnpm install framer-motion react
yarn add framer-motion react
bun add framer-motion react

Copy the Evervault Card Component

"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>  );}

Usage

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>
  );
}

Props

EvervaultCard

PropTypeDescription
textstringThe text shown at the center of the card
classNamestringThe class name of the child component

Icon

PropTypeDescription
classNamestringThe class name of the SVG element
...restReact.SVGProps<SVGSVGElement>Any other SVG attributes

Features

  • 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)

Last updated on