Personal Portfolio (Placeholder)
The Next.js + Tailwind build powering this site.
Implementation notes for the portfolio you're browsing — design system, content pipeline, animation layer, and MDX authoring workflow.

Quick Stats
Links
Personal Portfolio
You're reading this on the site it describes. The write-up covers the design decisions, tech choices, and content pipeline that power what you're seeing right now.
My previous portfolio was a rigid single-page build that made adding experiments painful. This iteration puts extensibility first: every piece of content lives in an MDX file, every component inherits from a shared design system, and the whole thing generates statically at build time.
Design system
The site is dark-only, built on the Rose Pine palette. Committing to a single mode eliminates the conditional branching that makes theming tedious and lets the colour choices be deliberately atmospheric rather than merely accessible.

Colour palette
| Token | Hex | Role |
|---|---|---|
love | #eb6f92 | Primary accent, headings |
gold | #f6c177 | Secondary accent, CTAs |
pine | #31748f | Tertiary accent, links |
foam | #9ccfd8 | Highlights |
iris | #c4a7e7 | Decorative |
surface | #1f1d2e | Card backgrounds |
overlay | #26233a | Layered elements |
Typography
Three fonts, three roles:
Space Grotesk— display headings, brand mark.Readex Pro— body text, paragraphs.Roboto Mono— code, ASCII art, monospace contexts.
All loaded via next/font/google with variable mode for font-family CSS custom property injection.
Stack
- App shell: Next.js 16 App Router with React Server Components, streaming layouts, and
generateMetadatahelpers per route. - Design: Tailwind CSS v4 + shadcn-inspired UI primitives, gradient overlays, and canvas background layers (animated gears, matrix rain).
- Content: MDX files in
content/projectsandcontent/extras, validated with Zod at load time and rendered vianext-mdx-remote. - Media: Raw assets → Sharp WebP pipeline →
assets.jsonmanifests — images reference manifest entries, missing files fall back to a gear placeholder. - SEO: Structured data (JSON-LD), dynamic OG images (Edge runtime,
@vercel/og), sitemap, and RSS feed.
Content pipeline
The Zod schema is the single source of truth for what frontmatter is valid. Missing required fields throw at startup — no silent failures rendering half-empty pages.
MDX component map
Every MDX file has access to the full set of custom components:
<Image>/<Gallery>— responsive media with blur placeholders.<Video>/<AudioPlayer>— hosted asset embeds with consistent framing.<Embed>— YouTube and arbitrary iframe embeds.<LinkButton>— gradient CTAs to repos, demos, or contact.<RelatedContent>— cross-links to other entries by slug and type.<Callout>,<Quote>,<Code>,<Markdown>— narrative building blocks.
Animation layer
The site uses three distinct animation systems:
- Framer Motion — entry animations (
fadeUp), carousel transitions, staggered card reveals. - CSS keyframes —
pulse-glowon CTA buttons, the ambientbody::afterradial gradients. - Canvas / rAF — matrix rain effect (
c-matrix-layer.tsx), gear rotation overlay (gear-layer.tsx), skills marquee.
The canvas layers sit at z-0 behind a z-10 content wrapper, keeping decoration fully separate from interactive elements.
OG image generation
Each project and extra gets a dynamic OG image generated at the Edge:
/api/og/projects/[slug] → 800×400 branded card
/api/og → default fallback
Deployment
The site deploys to Vercel. Static generation means the hosting bill is essentially zero — Edge functions only fire for OG image requests.
A portfolio is never finished. It's a living record of who you are right now, and an invitation to become someone different.
Have thoughts?
Curious what others see or think
Feel free to reach out or leave feedback
Share FeedbackPrefer email? joshuatjhie@pm.me