Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/the-craft/llms.txt

Use this file to discover all available pages before exploring further.

The Home page is the first incantation cast when a visitor arrives at the grimoire. It renders a single 3D card centred on the screen — styled as the leather cover of an ancient spellbook — and invites the visitor to flip it open and enter the portfolio. The entire interaction is driven by Framer Motion’s spring physics, making the reveal feel weighty and ceremonial rather than instant.

What It Renders

The page mounts a perspective-1000 container that holds a single motion.div with preserve-3d applied. Framer Motion’s animate prop toggles rotateY between 0 and 180 degrees when the card is clicked:
<motion.div
  className="w-full h-full relative preserve-3d cursor-pointer"
  animate={{ rotateY: isFlipped ? 180 : 0 }}
  transition={{ duration: 0.8, type: "spring", stiffness: 60, damping: 15 }}
  onClick={() => setIsFlipped(!isFlipped)}
>
The card flip is triggered by clicking anywhere on the card. The outer motion.div holds the onClick handler that toggles the isFlipped boolean state. The “Open the Book” button on the back face calls e.stopPropagation() before navigating to /about, so it doesn’t re-flip the card on the way out.

Front Face — The Cover

The front face carries the backface-hidden class and a parchment-texture background. Its contents, from top to bottom:
  • An inner border inset absolute inset-2 for decorative framing
  • A centred heading block with the subtitle and the practitioner’s name
  • A large background <Sigil> at 10% opacity behind a fully-opaque foreground <Sigil> with a teal drop-shadow glow
  • A "Tap to Reveal" prompt in Cinzel Small Caps at the bottom
<h2 className="font-cursive text-3xl text-midnight/60 mb-2">
  The Grimoire of
</h2>
<h1 className="font-cinzel text-5xl font-bold text-midnight-darker tracking-wider">
  A. Developer
</h1>

Back Face — The Portal

The back face carries rotate-y-180 so it starts hidden. It uses the bg-midnight-darker dark-glass panel style with a border-spell/30 border and a shadow-[0_0_50px_rgba(45,212,191,0.15)] ambient glow. Its contents:
  • A faded <Sigil> icon at opacity-50
  • An <h3> reading “Beyond this cover lies The Craft
  • A paragraph in EB Garamond italic describing the portfolio
  • A CTA button that navigates to /about
The CTA uses a layered hover effect — a bg-spell/10 fill slides up from translate-y-full to translate-y-0 on group-hover, while the label colour transitions from teal to dark. The button’s onClick stops propagation and calls the useNavigate hook to push the /about route:
<button
  onClick={(e) => {
    e.stopPropagation();
    navigate("/about");
  }}
>
  Open the Book
</button>

Floating Rune Ambient Animation

Fixed to the viewport behind the card (-z-10, pointer-events-none) is an array of 15 floating rune characters. They are generated with [...Array(15)].map(...) and rendered as motion.div elements. Each rune:
  • Is randomly positioned using Math.random() * window.innerWidth for x and starts below the viewport at y: window.innerHeight + 100
  • Animates upward to y: -100 with a sinusoidal horizontal drift: `calc(${Math.random() * 100}vw + ${Math.sin(t) * 50}px)`
  • Cycles through ✧ ✦ ⚝ ☽ ☾ based on index % 5
  • Has a randomised duration between 15 and 35 seconds, a randomised delay up to 10 seconds, and repeat: Infinity
[...Array(15)].map((_, t) => (
  <motion.div
    key={t}
    className="absolute font-cursive text-spell text-2xl"
    initial={{ x: Math.random() * window.innerWidth, y: window.innerHeight + 100 }}
    animate={{
      y: -100,
      x: `calc(${Math.random() * 100}vw + ${Math.sin(t) * 50}px)`,
    }}
    transition={{
      duration: Math.random() * 20 + 15,
      repeat: Infinity,
      ease: "linear",
      delay: Math.random() * 10,
    }}
  >
    {["✧", "✦", "⚝", "☽", "☾"][t % 5]}
  </motion.div>
))
The overall opacity-20 on the wrapper keeps the runes atmospheric rather than distracting.

How to Customize

To update the practitioner name and subtitle on the cover, locate the two heading elements inside the front face of the card in assets/Home.js and replace their text content:
// assets/Home.js — front face heading block
<h2 className="font-cursive text-3xl text-midnight/60 mb-2">
  The Grimoire of          {/* ← Change subtitle here */}
</h2>
<h1 className="font-cinzel text-5xl font-bold text-midnight-darker tracking-wider">
  A. Developer             {/* ← Change your name here */}
</h1>
Font choices are controlled by the font-cursive (Pinyon Script), font-cinzel (Cinzel), and font-garamond (EB Garamond) Tailwind utility classes. These map to the Google Fonts loaded in index.html. Do not change the class names — update the font import URL instead.

Build docs developers (and LLMs) love