this site

a portfolio is the artifact a hiring manager scans for ten seconds before deciding to read. so the constraint isn't "build a portfolio" — it's "prove the taste in ten seconds, prove the engineering in the next ten."

0.0

01 — problem

i interview every two years and i was tired of having to talk people through the same screenshots of the same projects. i wanted a site that did three things: be skim-readable in ten seconds for the hiring manager, be inspectable by an AI agent for the company that ships an AI agent for candidate review (this is now a real thing), and not look like every other developer portfolio generated in 2026.

the second constraint mattered more than i expected. the wave of AI-generated developer portfolios in 2025 collapsed the median into a recognizable pattern: hero with purple-to-blue gradient, "unleash" or "elevate" in the headline, a 4×3 icon wall of every technology touched, and a proficiency radar chart. the tell isn't any single element — it's the conjunction. so the design brief became a bans list before it became a feature list.

02 — approach

frontend:next 16 (turbopack), react 19, tailwind 4, shadcn/ui·api:hono on vercel edge, tRPC, drizzle, neon serverless·ai:mastra, anthropic claude, vercel ai sdk, langfuse·agent surfaces:model context protocol (mcp), /.well-known/agent-card.json (a2a), llms.txt·infra:vercel · turbo remote cache, cloudflare r2, sentry, infisical

every layer is something an AI agent can read directly — the openapi spec via /reference, the prose via /llms.txt, the tool catalog via /mcp.

the case-study infrastructure you're reading came out of a single constraint: every project page should look like a careful editorial decision, not a template. that meant building a small library of components instead of one mega-template, then dogfooding it on the portfolio itself before using it on real apps. you're inside the dogfood right now.

scalar for /reference
chosen
  • reads the same openapi.json hono already emits
  • warm-machine-themed cleanly via css custom properties
  • keyboard-navigable, no jquery
  • agent-readable: scalar exposes the spec at the same origin
swagger ui
  • 2008 chrome — the brand of "this is a backend"
  • theming is a fight
  • keyboard nav is incomplete
  • the page weighs 2mb of jquery and css resets

picked scalar because it lets the openapi spec _be_ the documentation without dressing it up as enterprise software. the spec is the source; scalar is just a viewer.

a single warm-machine palette
chosen
  • oklch tokens, monospace data, tinted neutrals — one direction
  • identity registers in the first paint
  • every component shares the same five border / text / surface tokens
vs-code-shell theme picker
  • first iteration shipped a 16-theme chooser in the corner
  • diluted the identity — the visitor was looking at the picker, not the work
  • every theme was a compromise; none felt finished

killed the theme picker after a friend said "cool palette switcher." that wasn't the takeaway i wanted.

rendering diagram…
agent-readable surface area

the 2026-native primitives

three protocols ship behind well-known paths so an AI agent can introspect the site without scraping. each is a single file, generated from the same data model the human pages render.

  • /llms.txt — markdown summary of the site for llm context windows; lists the case studies, the stack, the contact path. one route handler, ~140 lines.
  • /.well-known/agent-card.json — A2A descriptor: the agent's name, capabilities, contact endpoint. fixed schema, served as a static-ish JSON.
  • /mcp — model context protocol server hosted on the hono api. tools are read-only catalog queries (list_projects, get_project_by_slug, list_skills). zero write tools — there's nothing to mutate from outside.
building an ai-chat portfolio that doesn't feel like ai slop

rebuilt the chat with the same warm-machine palette as the rest of the site, killed the gradient send button (rust accent only on the active state), wrote the empty-state copy as a real question ("what do you want to know about my work?" → not "ask me anything"), and lowered the avatar density. the bans list i ran against:

  • no purple-to-blue gradient anywhere (banned at the css-token layer)
  • no "elevate, seamless, unleash, next-gen" in any headline
  • no "ask me anything" / "learn more" placeholder copy
  • no avatar bubbles wider than 32px
  • no emoji in the assistant's replies (configured at the system prompt)
  • no skill radar charts, no proficiency bars, no tech-stack icon walls
  • no centered hero with a glow effect
  • no model name shown in chrome — the model is implementation, not branding
what i tried firstdefault vercel ai sdk chat ui — purple gradient send button, generic empty state, "ask me anything" placeholder.
why it failedthe chat looked exactly like every other AI integration in 2025. the visitor stopped reading after the third familiar pattern. the chat was supposed to be a feature; it was reading as a stamp.
the playground demo had to feel like a real tool, not a marketing widget

stripped the chrome. the playground sits in the page as a flat text editor with the same monospace font as the rest of the page, no card frame, no animated label. the "try it" affordance is one line of rust mono above it. the value is in the thing itself.

what i tried firstembedded the zod playground inside a card with a "try it" pill and a play-button.
why it failedit read as an interactive product demo, the genre. the playground is a real thing i use to debug schemas; the case study should signal that, not dress it up.
try itthis is the same /reference page the openapi tools serve. live data; no fixture.

[ inline /playground zod widget — pending Track 3; visit

/reference

for the live tool catalog ]

03 — result

47
openapi endpoints
18
api packages
3
agent-readable surfaces
llms · a2a · mcp
1
design direction across every page

continuous deploy on vercel · sentry tracing on every route · turbo remote cache shared across worktrees · zero gradient text · zero skill radars · zero icon walls.

⌘Kterminal