Web · 2025
Portfolio UI Systems
Design tokens, animation primitives and motion budgets as reusable code

- Year
- 2025
- Status
- shipped
- Discipline
- Web
- My role
- Design system and front-end architecture
The brief
The component and motion layer this portfolio is built on: token-driven theming, glass surfaces, scroll-aware navigation, reusable animation primitives and multilingual content wiring, all extracted so a new page costs hours instead of days.
Problem
Every previous version of this portfolio carried its own copy of the same button, the same card and the same reveal animation. Changing one detail meant editing a dozen files, and reduced-motion was written per page by hand, so it was inconsistently applied. The site was also getting slower with every version, since each new section brought its own dependencies.
My role
Solo. I own the whole system: the design tokens in CSS, the layout shell, the motion primitives, the reduced-motion contract and the theme bootstrap that applies the stored palette before first paint.
Process
- Moved every colour, radius, type step and shadow into Tailwind v4 theme tokens, so no component contains a raw hex value
- Extracted animation work into named primitives (reveal, split text, marquee, counter, page transition) that each ship their own reduced-motion fallback
- Centralised GSAP registration and motion constants so easings and durations are never typed inline
- Split the shell so heavy 3D and motion code loads only where it is used, behind a WebGL guard with a real fallback
- Documented the rules in the repo so the next contributor adds a page instead of a special case
- Audited the bundle per route, so a page that only needs text never downloads the 3D or GSAP layer
Result
A reusable system rather than a pile of pages: tokens control the theme, the motion primitives carry their own accessibility contract, and the 3D layer is opt-in per section. I measure this one in cost per page, and the honest version is that adding a new section is now a small component plus a data entry, where earlier versions meant copying and adapting an entire page. The trade is real though: a design system is more code than any single page needs, and the rules only pay off if they are followed. That is why the conventions live in the repo as a document rather than in my head, so the fourth contribution is as consistent as the first. A design system only earns its keep once it is boring to use, which is the state this one is finally in.
What it had to do
- Token-driven theming with light and dark modes
- Motion primitives reused across every page
- Reduced-motion paths built into the primitives, not bolted on
Stack
- Next.js
- Tailwind CSS
- Framer Motion
- GSAP
- TypeScript
