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 Work page reframes employment history as a row of ritual candles. Each candle’s height corresponds to the seniority and impact of that role — the tallest flame for the most recent position, shorter flames for earlier ones. Clicking a candle selects it and causes a glass-panel detail card to animate into view below, recounting the company name, role title, and accomplishments in flavour-text prose.

Work History Entries

assets/Work.js holds an internal array of three entries. Each object has six fields:
FieldTypePurpose
idstringUnique key used for React reconciliation and active-state tracking
yearstringDate range displayed as the candle caption (only the start year is shown)
companystringOrganisation name rendered in the detail panel heading
rolestringJob title rendered in the detail panel subheading
descriptionstringAccomplishment prose shown in the detail panel body
candleHeightnumberPixel height of the wax-column portion of the candle
The three entries from the source are:

High Sorcerer (Senior Frontend) — Ethereal Systems

Years: 2023 – PresentCandle Height: 140pxDescription: “Leading a coven of 5 junior developers. Architected the new React-based spellbook that increased casting speed (page load) by 40%. Implemented dark rituals (Redux Saga) for complex state management.”

Data Alchemist — Void Analytics

Years: 2020 – 2023Candle Height: 100pxDescription: “Transmuted raw user data into beautiful, interactive D3.js visualizations. Banished numerous memory leak demons from the legacy Angular application.”

Apprentice Weaver — Mystic Web Agency

Years: 2018 – 2020Candle Height: 70pxDescription: “Crafted responsive landing pages using ancient HTML/CSS incantations. Learned the sacred arts of accessibility and cross-browser compatibility.”

Candle Heights

The candleHeight value (in pixels) controls how tall the wax-column div renders inside the <Candle> component. The three values — 140px, 100px, 70px — create a descending visual hierarchy from most recent to earliest role, reinforcing career progression at a glance.

Interaction Model

1

Default State

The first entry is selected by default: useState(entries[0].id). Its candle is already active and its detail panel is visible when the page loads.
2

Click to Illuminate

Each <Candle> component receives an onClick callback that calls setActiveId(entry.id), replacing the currently active entry. The candle component itself renders differently when isActive is true — the flame div plays the .animate-flicker CSS animation and the wax column switches from bg-parchment/40 to bg-parchment.
3

AnimatePresence Transition

The detail panel is wrapped in an AnimatePresence with mode="wait". When the active entry changes the outgoing panel exits before the incoming panel enters, preventing a cross-fade overlap:
<motion.div
  key={activeEntry.id}
  initial={{ opacity: 0, filter: "blur(10px)", y: 20 }}
  animate={{ opacity: 1, filter: "blur(0px)", y: 0 }}
  exit={{ opacity: 0, filter: "blur(10px)", y: -20 }}
  transition={{ duration: 0.5 }}
>
The key prop is set to activeEntry.id so React treats each entry as a distinct element and triggers mount/unmount animations correctly.

The Candle Component

The <Candle> component (imported from components/Candle.js) accepts four props:
PropTypeDefaultPurpose
labelstringCaption text rendered below the wax column (the start year)
heightnumber120Pixel height of the wax-column div
isActivebooleanWhen true, enables the flame animation and full-opacity wax colour
onClickfunctionCalled when the user clicks anywhere on the candle wrapper
The flame is a CSS-only element — a motion.div positioned at the top of the column. When isActive is true it receives bg-spell shadow-[0_0_20px_rgba(45,212,191,0.8)] animate-flicker and a blurred white inner highlight. When inactive the flame div uses bg-spell/20 with no shadow and no animation. Below the flame a thin wick line (w-0.5 h-3 bg-midnight-darker) connects flame to wax:
// components/Candle.js — simplified structure
export function Candle({ label, height = 120, isActive, onClick }) {
  return (
    <div className="flex flex-col items-center gap-4 cursor-pointer group" onClick={onClick}>
      <div className="relative flex flex-col items-center justify-end" style={{ height: height + 40 }}>
        {/* Flame */}
        <motion.div
          className={`absolute top-0 w-4 h-8 rounded-[50%_50%_20%_20%] origin-bottom transition-all duration-500 ${
            isActive
              ? "bg-spell shadow-[0_0_20px_rgba(45,212,191,0.8)] animate-flicker"
              : "bg-spell/20 shadow-none"
          }`}
        />
        {/* Wick */}
        <div className="w-0.5 h-3 bg-midnight-darker absolute top-7 z-10" />
        {/* Wax column */}
        <div
          className={`w-10 rounded-t-sm transition-colors duration-500 relative overflow-hidden ${
            isActive ? "bg-parchment" : "bg-parchment/40"
          }`}
          style={{ height }}
        />
      </div>
      {/* Year label */}
      <span
        className={`font-cinzel text-sm tracking-widest transition-colors duration-300 ${
          isActive ? "text-spell text-glow" : "text-parchment/40 group-hover:text-parchment/80"
        }`}
      >
        {label}
      </span>
    </div>
  );
}
The candle row is laid out with flex justify-center items-end gap-12 md:gap-24 so all candles align at their bases on a shared absolute gradient baseline:
{/* Baseline rule beneath all candles */}
<div className="absolute bottom-6 left-0 w-full h-px bg-gradient-to-r from-transparent via-spell/30 to-transparent" />
Each candle’s label receives entry.year.split(" ")[0] — just the start year — as its caption.

Detail Panel

The glass panel below the candle row uses max-w-2xl h-64 and the glass-panel utility. Inside it, centred content shows:
  • company in Cinzel text-3xl text-spell
  • role in Pinyon Script text-2xl text-parchment/80
  • A decorative w-12 h-px bg-spell/30 divider rule
  • description in EB Garamond text-lg text-parchment leading-relaxed
A blurred bg-spell/5 opacity-50 absolute div behind the content creates a soft inner glow without obscuring the text.

How to Customize

Edit the entries array at the top of assets/Work.js. Add, remove, or reorder entries as needed:
// assets/Work.js
const entries = [
  {
    id: "coven-1",                         // Must be unique
    year: "2023 - Present",
    company: "Ethereal Systems",
    role: "High Sorcerer (Senior Frontend)",
    description:
      "Leading a coven of 5 junior developers. Architected the new React-based spellbook...",
    candleHeight: 140,                     // Pixels — taller = more prominent
  },
  // … add more entries
];
Set candleHeight proportionally to reflect the weight of each role. A good rule of thumb: give your current role the tallest candle (120–160px) and reduce by 30–40px per previous role. The minimum recommended height is 50px — any shorter and the flame div will look cramped against the wax column.
The page initialises with the first entry in the array selected by default. If you reorder the array, the first entry in the new order will be active on page load.

Build docs developers (and LLMs) love