The Skills page — headed “Familiar Skills” with the subtitle “The constellations of my craft” — renders the developer’s technology stack as an interactive star map. Nine skill nodes are scattered across a container at fixed percentage coordinates, connected by eleven SVG lines that animate from zero length to full length when the section scrolls into view. Each node is a silver dot with a label beneath it; hovering over a node reveals a turquoise glow halo. The whole graph sits on a dotted grid background that reinforces the astronomical theme.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/sorcerer/llms.txt
Use this file to discover all available pages before exploring further.
The Constellation
Node and Edge System
Each node represents a single skill. It is positioned absolutely within a relative container usingleft and top CSS properties expressed as percentages, so the constellation scales with the viewport without any JavaScript resizing logic. The visible mark is a 12×12 px silver dot (bg-slate-200 rounded-full) with the skill name rendered in small text directly below it. On hover, a turquoise ring (ring-2 ring-teal-400) expands around the dot to create the glow halo effect.
Edges are <line> elements drawn inside a full-size <svg> that is absolutely positioned behind all the node dots. Each line’s x1 / y1 / x2 / y2 coordinates are derived from the x and y percentage values of the two nodes it connects, converted to pixel positions at render time so the SVG geometry always matches the DOM layout.
Dotted Grid Background
The containing element uses an inline CSSbackgroundImage to produce the star-chart grid:
1 px silver dot at every 40 px interval across the full container, creating a subtle lattice that looks like a field of background stars without adding any DOM nodes.
Skills Data
The two data structures that drive the constellation are thenodes array and the edges array, both defined inside the SkillsPage component:
x and y are unitless numbers that the component appends a % sign to when writing CSS. An x of 20 therefore means left: 20% of the container width.
Animation
useInView Trigger
The entire SVG edges group is wrapped in a Framer Motion motion.g controlled by a useInView hook. The hook watches a ref attached to the container and fires once — once: true — with a root margin of -100px so the animation does not start until the graph is 100 px inside the viewport:
SVG Line Draw-on Animation
Each<line> element is replaced with a <motion.line> that animates its pathLength from 0 to 1. Because SVG <line> elements do not natively support pathLength, the implementation uses strokeDasharray and strokeDashoffset under the hood — Framer Motion handles this automatically when you pass pathLength as a motion value:
| Property | Value | Effect |
|---|---|---|
pathLength | 0 → 1 | Line draws from start node to end node |
duration | 1.5 s | Each edge takes 1.5 s to fully appear |
delay | i × 0.2 | Edges stagger: edge 0 at 0 s, edge 10 at 2 s |
once | true | Animation plays once and stays in final state |
Node Spring Scale
Each skill dot scales in with a spring transition after the edges begin drawing, reinforcing the sense that the constellation is assembling itself:Adding Skills
Add a new node to the nodes array
Open the
SkillsPage component, locate the nodes array, and append a new object. Choose an id that is unique across all existing nodes, a human-readable label, and x / y values that place the node in an unoccupied area of the graph:Add edges connecting the new node
In the
edges array just below nodes, add one or more two-element arrays that pair your new node’s id with the id of an existing node. Edges are undirected — ["rust", "node"] and ["node", "rust"] are equivalent:Verify x and y are within bounds
The
x and y values are percentages of the constellation container’s width and height respectively. Keep both values between 5 and 92 to avoid nodes being clipped by the container edge or overlapping the label of an adjacent node. The dotted grid spans the full container, so any position within those bounds will look natural against the background.