Colophon
This site is its own case study. 100+ components, 4 theme modes, 3 languages, streaming AI chat, and a design token system that enforces itself. Here's how it's built.
By the numbers
Architecture
Framework
Next.js 15 App Router with React 19 and TypeScript 6. Server components by default, client components where interactivity demands it. ISR revalidation on all pages.
Hosting
Vercel serverless. Edge middleware for security headers. Sentry for error tracking. Vercel Analytics for performance.
CMS
Sanity CMS for structured content. Blog posts as MDX files with auto-generated TypeScript metadata. Dual pipeline — local-first with CMS sync.
Database
MongoDB for contact submissions and GDPR-compliant data management. PostgreSQL for structured queries.
Design system
Tokens
~200 CSS custom properties covering typography, color, spacing, grid, motion, and radius. No JSON intermediate — tokens defined directly in CSS and consumed by CSS Modules. Enforced by Stylelint + Rhythmguard.
Styling
CSS Modules exclusively. Logical properties throughout (margin-inline, padding-block). Tailwind available as a secondary utility layer. No inline styles except dynamic backgroundImage.
Typography
Syne for headings, Satoshi for body. Fluid sizing via clamp() — no breakpoint-based font scales. Display: 5–8rem, body: 0.75–1.25rem.
Themes
Four modes: light, dark, high-contrast black, high-contrast white. Switched via CSS class selectors on the root element. Cookie-persisted.
Component architecture
Every component follows the same structure: functional component, CSS Module, Storybook story, Vitest + axe-core test, and barrel export. No exceptions.
Primitives
Built on Radix UI (Accordion, Checkbox, Dialog, Select, Tabs, Tooltip) for accessible behavior. Styled with CSS Modules, not the Radix theme layer.
Layout
Container, Stack, Grid, FlexBox, Spacer, Section, Center. Responsive grid: 4 → 8 → 12 columns.
Storybook
Storybook 10 with a11y addon, Vitest integration, and MCP addon. Every component has stories. WIP badge until a11y + visual + translation verification passes.
Testing
Vitest for unit tests. axe-core for accessibility. Playwright for visual regression. Every component test includes an accessibility assertion.
Animation
GSAP
Primary animation engine. ScrollTrigger for scroll-driven animations. useGSAP hook for React integration. Named easing curves in the token system.
Framer Motion
React-specific transitions and AnimatePresence for enter/exit animations. Page transitions and layout animations.
Lenis
Smooth scrolling with momentum. Respects prefers-reduced-motion. Integrated via SmoothScrollProvider in the layout chain.
Internationalization
English, Finnish, and Swedish — full coverage across all UI strings, form labels, error messages, and content. Powered by i18next + react-i18next with browser language detection and cookie persistence. 100% translation coverage is a shipping requirement.
AI integration
Donny
Studio guide chatbot for design systems intake. Streaming responses via Vercel AI SDK. Rate-limited, prompt-injection-guarded, with structured tool calling for project showcase and navigation.
MCP
8 Model Context Protocol integrations: Figma, GitHub, TypeScript LSP, Sentry, Vercel, Context7, Sanity, and Akaunting. The site is agent-aware from the ground up.
Security
Strict Content Security Policy in production. HSTS with 2-year max-age and preload. Input sanitized via mongo-sanitize and isomorphic-dompurify. Rate limiting on AI chat and contact endpoints. GDPR-compliant with automated weekly data cleanup. Permissions-Policy disables camera, microphone, and geolocation.
Open-source tools used on this site
This site uses Rhythmguard for design token enforcement at lint time, and was bootstrapped with Project Spine for agent-native operating context. Both are open-source tools we built and maintain.