Skip to main content

Documentation Index

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

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

Constellation is the primary visual on the Skills (/skills) page. It renders an aspect-[4/3] panel containing eight technology nodes displayed as glowing turquoise stars connected by constellation lines that animate into view when the component enters the viewport. The component takes no props — the skill data and connection graph are hardcoded inside the component.

Skill Nodes

Eight technologies are mapped to X/Y percentage positions within the panel:
IDLabelX%Y%Level
reactReact50503 (large)
tsTypeScript30203 (large)
jsJavaScript70203 (large)
nextNext.js20602 (medium)
nodeNode.js80602 (medium)
cssTailwind50853 (large)
framerFramer Motion35752 (medium)
graphqlGraphQL65751 (small)
Node sizes based on level:
  • Level 3w-3 h-3 — core technologies
  • Level 2w-2 h-2 — strong secondaries
  • Level 1w-1.5 h-1.5 — proficient

Connection Lines

Eight constellation lines connect related technologies:
TypeScript → React
JavaScript → React
React      → Tailwind
React      → Next.js
React      → Node.js
Tailwind   → Framer Motion
Node.js    → GraphQL
TypeScript → Next.js
Lines are rendered as motion.line elements in an SVG overlay (viewBox="0 0 100 100", preserveAspectRatio="none") so percentage coordinates map directly to SVG units.

Animation System

Viewport entry gating (useInView)

A custom useInView hook wraps the IntersectionObserver API. It attaches to the component’s root ref with { once: true, margin: "-100px" }, setting inView = true once the panel scrolls 100 px into the viewport. All animations are gated on inView:
// Lines only draw once the section is visible
animate: inView ? { pathLength: 1 } : { pathLength: 0 }

Line draw-in

initial:    { pathLength: 0 }
animate:    { pathLength: 1 }  // when inView
transition: { duration: 1.5, delay: 0.5 + index * 0.1, ease: "easeInOut" }
Lines draw sequentially, each starting 100 ms after the previous.

Node entrance

initial:    { scale: 0, opacity: 0 }
animate:    { scale: 1, opacity: 1 }  // when inView
transition: { duration: 0.5, delay: 0.2 + index * 0.1 }

Node glow

Each star has bg-turquoise shadow-[0_0_15px_rgba(64,224,208,0.8)] and an inner animate-pulse opacity-50 white div for a gentle heartbeat effect.

Hover Tooltip

Hovering a node reveals a tooltip via opacity: 0 → group-hover:opacity-100:
┌─────────────────────────────┐
│  React                      │
│  ● ● ●   (proficiency dots) │
└─────────────────────────────┘
The tooltip renders as a bg-ink/90 border border-turquoise/30 card with backdrop-blur-sm. Proficiency is shown as three dots — filled bg-turquoise up to level, empty bg-turquoise/20 beyond. Each node also includes an invisible w-8 h-8 rounded-full cursor-pointer hit-area element positioned at the node centre to increase the clickable/hoverable target size.

Background

The panel has a bg-midnight/30 base with 50 randomly positioned w-0.5 h-0.5 white dot “background stars” at 30% opacity. Each uses an inline animation: flicker keyframe with a randomised 2–5 s duration for a subtle starfield shimmer.
import { Constellation } from './components/Constellation';

// Used directly on the /skills page — no props required
<Constellation />
Because useInView is called with once: true, the animation only fires once on the first scroll into view. Scrolling back up and down will not re-trigger the draw-in sequence.

Page Context

The Constellation is accompanied by an explanatory paragraph that fades in 1.5 s after the page mounts:
“Hover over the celestial bodies to reveal proficiency. The brightest stars represent my core incantations, while the connecting lines show how these technologies weave together to form complete digital ecosystems.”

Build docs developers (and LLMs) love