The Work History page visualises professional experience as a pendulum swinging through time. A gold rod with a weighted sphere is anchored at the top-center of the page and rotates from −30° to +30° as the visitor scrolls from the top to the bottom of the section. Timeline entries alternate left and right of the central axis, each connected to the pendulum path by a short gold horizontal line. The effect transforms a conventional work history list into a kinetic, meditative experience.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/fortune-seeker/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Work History page lives at route/work and is titled “The Pendulum Swing”. Its opening quote — “Time is merely a construct, but experience leaves a mark.” — frames career experience as something felt rather than merely listed. The page uses Framer Motion’s useScroll hook (via the project’s De utility) to track scroll progress against the page container ref, then maps that progress to a rotation value using useTransform.
The scroll-linked rotation uses
useScroll with offset: ["start end", "end start"] targeting the page’s root div ref. This means the pendulum starts swinging when the top of the section enters the viewport bottom, and finishes when the section bottom exits the viewport top — giving the full scroll range to the pendulum.Layout & Components
Pendulum pivot
A small
64×64 gold ring sits absolutely at top: 0, left: 50% as the pivot point. Inside it is a 8×8 gold dot. The pivot is z-index: 20 to always appear in front of the timeline entries.Pendulum rod & sphere
A
motion.div anchored at top: 4px, left: 50% with origin-top transform origin. It contains a 2px-wide gold gradient rod 400px tall and a 64×64 sphere at its base. The sphere has a pulsing inner dot with animate-pulse. The rotate style is bound to the Framer Motion useTransform value.Timeline entries (×3)
Each entry is a
motion.div with whileInView: { opacity: 1, x: 0 } from opacity: 0, x: ±50 (left entries start from the left, right entries from the right). Each entry occupies w-5/12 and uses text-right pr-12 (left) or text-left pl-12 (right). A short h-[1px] gold horizontal connector bridges the entry to the center axis.useScroll + useTransform
useScroll monitors the scrollYProgress of the page container. useTransform maps the [0, 1] progress range to [-30, 30] degrees of rotation. The rotation value is passed directly as style={{ rotate: rotationValue }} on the pendulum motion.div.Data Structure
Work entries are defined in a flat array. Add, reorder, or remove entries freely — the timeline layout and alternating alignment are computed from the array index:Animations
Scroll-linked pendulum rotation
Scroll-linked pendulum rotation
useScroll is called with { target: containerRef, offset: ["start end", "end start"] }. The returned scrollYProgress motion value runs from 0 to 1 as the page scrolls. useTransform(scrollYProgress, [0, 1], [-30, 30]) maps that range to a rotation in degrees. The value is bound to the pendulum arm’s style prop, so it updates on every scroll frame without React re-renders.Pendulum sphere pulse
Pendulum sphere pulse
The gold dot at the center of the sphere uses
animate-pulse (a Tailwind utility). It has no Framer Motion involvement — the 1 s CSS keyframe opacity pulse is sufficient and avoids over-engineering a decorative element.Timeline entry whileInView
Timeline entry whileInView
Each entry’s
motion.div starts off-screen horizontally (x: -50 for left entries, x: 50 for right entries) and at opacity: 0. When the entry enters the viewport (with margin: "-100px" guard), it transitions to x: 0, opacity: 1 over 0.8 s with once: true. This prevents re-animation on scroll-back.Page title entrance
Page title entrance
The page title and quote share a single
motion.div entrance: initial: { opacity: 0, y: 20 }, animate: { opacity: 1, y: 0 }. Unlike the timeline entries, this fires immediately on mount, not on scroll.Customization
Add more work entries
Push new objects into the
workHistory array. Each entry automatically receives a left or right alignment based on its even/odd index. With more than five entries, consider reducing the per-entry mb-32 bottom margin to mb-20 so the page doesn’t become excessively tall.Adjust pendulum swing range
The
useTransform output range is [-30, 30]. To make the pendulum swing more dramatically, widen to [-45, 45]. For a more subtle sway on a short timeline, narrow to [-15, 15]. The input range remains [0, 1] matching scrollYProgress.Extend the rod length
The pendulum rod
div is h-[400px]. Increase this if you add more timeline entries so the sphere reaches further down toward the final entry. Keep the sphere’s absolute positioning (bottom: 0) so it remains anchored to the rod tip.Rename job titles
The mystical job titles (“Senior Alchemist”, “Spellweaver”) are in the
title field. Replace them with real titles or keep the theme — the company and desc fields hold the grounding factual information. The year field accepts any string, so “Q2 2020 – Q4 2022” is valid if you prefer precision.