Skip to main content

Documentation Index

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

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

The About page ditches the conventional bio layout in favour of a hardware metaphor: a fully rendered iPod click-wheel device. The click wheel sits on the left side of the screen; a large text panel on the right displays the current section. Clicking the forward and back controls on the wheel cycles through four sections — Origin Story, How I Got Here, Hobbies, and Philosophy — each cross-fading in and out on the iPod’s screen, complete with a progress bar showing position in the sequence.

Visual overview

The page is centred and split horizontally on desktop. On the left, a CSS-rendered iPod body — rounded pill shape, grey gradient, inset highlights — houses a circular click wheel with MENU at the top and directional arrows for previous and next. The centre button is a large circular hit area. On the right, an aqua-glass panel shows the headline “The Story So Far” and a secondary label prompting the user to navigate via the click wheel. The iPod screen itself, styled as a miniature LCD, shows the current section title, its paragraph of content, and an (n of 4) counter with a fill bar.

iPod screen

Displays the active section title, full content paragraph, and a progress indicator. Content transitions use Framer Motion AnimatePresence with opacity and y cross-fades on section change.

Click wheel

A decorative ring with directional controls. The forward arrow (bottom of wheel) and back arrow (left of wheel) cycle sections. The ring rotates +90° or −90° in a spring animation on each press.

The four content sections

The sections are stored in an array of objects in the About route component inside assets/main.js:
#TitleContent summary
1Origin StoryBorn in the era of dial-up, learned to code from Geocities source. Still misses <marquee>.
2How I Got HereHTML/CSS → jQuery → survived Angular vs React → now comfortably in the React ecosystem.
3HobbiesVintage Apple products, early-2000s web design archives, recreating glossy Aqua buttons in CSS.
4PhilosophySoftware should be functional and delightful — gloss, soft animations, thoughtful interactions matter.

Component structure

// Simplified About page structure — iPod click wheel
import { motion, AnimatePresence } from 'framer-motion';
import { useState } from 'react';

const sections = [
  {
    id:      'origin',
    title:   'Origin Story',
    content: 'Born in the era of dial-up, I learned to code by inspecting Geocities source code...',
  },
  {
    id:      'journey',
    title:   'How I Got Here',
    content: 'Started with HTML/CSS, moved to jQuery, survived the Angular vs React wars...',
  },
  {
    id:      'hobbies',
    title:   'Hobbies',
    content: 'When not coding, I collect vintage Apple products, curate early-2000s web design archives...',
  },
  {
    id:        'philosophy',
    title:     'Philosophy',
    content:   'Software should be functional, yes, but it should also be delightful...',
  },
];

export default function About() {
  const [index, setIndex]  = useState(0);
  const [rotation, setRotation] = useState(0);

  const next = () => {
    setIndex((i) => (i + 1) % sections.length);
    setRotation((r) => r + 90);
  };

  const prev = () => {
    setIndex((i) => (i - 1 + sections.length) % sections.length);
    setRotation((r) => r - 90);
  };

  return (
    <div className="ipod-layout">
      {/* Left: iPod device */}
      <div className="ipod-body">
        {/* Miniature LCD screen */}
        <div className="ipod-screen">
          <h3>{sections[index].title}</h3>
          <AnimatePresence mode="wait">
            <motion.p
              key={index}
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -10 }}
              transition={{ duration: 0.2 }}
            >
              {sections[index].content}
            </motion.p>
          </AnimatePresence>
          <span>{index + 1} of {sections.length}</span>
          {/* Progress fill bar */}
        </div>

        {/* Click wheel */}
        <div className="click-wheel">
          <motion.div
            animate={{ rotate: rotation }}
            transition={{ type: 'spring', stiffness: 200, damping: 20 }}
            className="wheel-ring"
          />
          {/* MENU label, prev/next arrows, centre button */}
          <button onClick={prev}></button>
          <button onClick={next}></button>
        </div>
      </div>

      {/* Right: prose panel */}
      <div className="aqua-glass about-prose">
        <h2>The Story So Far</h2>
        <p>Use the click wheel (or just click the arrows) to navigate through my background.</p>
      </div>
    </div>
  );
}

Customization

Section content lives in the sections array in the About route component in assets/main.js. The compiled bundle is minified, so locate the array by searching for the string "Origin Story" and edit the four content strings around it. If you are running the Vite dev source, edit the array directly in the About component file:
// In assets/main.js — locate the sections array (search for "Origin Story")
const sections = [
  { id: 'origin',     title: 'Origin Story',    content: 'Your text here.' },
  { id: 'journey',    title: 'How I Got Here',  content: 'Your text here.' },
  { id: 'hobbies',    title: 'Hobbies',         content: 'Your text here.' },
  { id: 'philosophy', title: 'Philosophy',      content: 'Your text here.' },
];
Keep each content string to two or three sentences. The iPod screen area is small and the text scrolls within the LCD panel — very long paragraphs will be cut off unless the user scrolls the screen element.

Key interactions

InteractionBehaviour
Click forward arrowindex advances by 1 (wraps); rotation increases by 90°; screen content cross-fades out/in
Click back arrowindex decreases by 1 (wraps); rotation decreases by 90°; screen content cross-fades
Wheel rotationThe decorative ring motion.div animates to the new rotation value with spring stiffness 200
Screen transitionAnimatePresence mode="wait" — old content exits (opacity 1→0, y 0→−10) before new content enters (opacity 0→1, y 10→0)
Progress barWidth animates to (index + 1) / total * 100% on each navigation step
The iPod device is rendered entirely in CSS — no image assets are required. The rounded body, inset highlights, and LCD bezel are all achieved with border-radius, box-shadow, and gradient backgrounds. The wheel ring is a separate motion.div layered on top so it can rotate independently of the static MENU label and arrow buttons.

Build docs developers (and LLMs) love