PROJ-STEPWEAV
Loaded
Project detail
stepweaver.dev

Problem

The main problem was never just "build a portfolio." A standard portfolio would have been easier, but it would also have been false to the way I work and the kinds of interfaces I like. I wanted a site that could hold projects, notes, experiments, and technical writing while also reflecting my actual taste: terminals, monospaced type, neon, cyberpunk, systems thinking, and deliberate interaction design. There was also a practical problem behind the rewrites. I wanted a way to publish what I was learning so the act of documenting it would reinforce the learning itself.

Context / users

stepweaver.dev is my portfolio, but it is also the project that best shows how I think. It started as a basic personal site, then evolved through several rewrites as my skills, tooling, and goals changed. What began as a simple web presence became a publishing system, a case-study platform, a command-driven interface, and a place to consolidate the technical and aesthetic ideas I actually care about. The result is not a generic portfolio template. It is a custom application built to feel like mine.

My role

I owned the project end to end across multiple iterations. That included the original static version, the move to a more component-driven frontend, the rebuild in Next.js, MDX-based publishing, later Notion CMS integration, terminal UX design, project architecture, route structure, content modeling, shared chat behavior, middleware, and deployment decisions. I also shaped the site’s visual and interaction language. I used AI to explore programming-theme palettes and variations, but the final composition, behavior, and overall direction were mine.

Solution

I treated the site as an evolving system instead of a one-time build. The earliest version was a simple HTML page. From there I rebuilt it with more modern frontend tooling, then moved to Next.js when I wanted first-class routing and publishing support. I added MDX so I could write in Markdown and publish directly to the site. I experimented with Obsidian as an authoring bridge, but when that proved awkward, I kept the content flow simpler and committed MDX directly. After using headless CMS patterns in other projects, I adapted a Notion integration I had already proven elsewhere and used that to support a more flexible content model. The terminal came later, not because the site needed a novelty feature, but because I genuinely like command-line interfaces and wanted the portfolio to expose that part of my taste and thinking.

  • Command-driven terminal with navigation, utilities, and mode-aware input handling
  • Reusable project-detail rendering from structured project data
  • Shared AI chat backend used by the terminal and the chat widget
  • Notion-backed codex and documentation content exposed through internal API routes, with shared `lib/codex/selectors` normalization across API, web, and terminal
  • Stateful flows for command history, weather selection, contact intake, and local UI preferences
  • Standard route-based navigation alongside terminal-based exploration
  • Consistent API trust boundary for mutable routes: origin checks, Zod validation, bot/timing signals, and KV-backed rate limits in production

Architecture

Architecturally, the project reflects layered iteration rather than a single greenfield design. The current application uses Next.js App Router as the base, with route groups separating default site chrome from console-style and embed-style pages so layout decisions live in composition—not imperative DOM hacks. Conventional route-driven pages sit alongside a terminal interaction surface. Structured project data feeds reusable case-study rendering with server-first shells where it matters. Shared hooks, a unified API security layer (`withProtectedRoute`), and internal API routes support content retrieval and chat behavior. Middleware handles CSP nonce generation and request hardening. Some of the architecture exists because the site needed those capabilities; some of it exists because this project has been a long-running place for me to absorb and apply what I learn. That history matters, because the current shape of the codebase is the result of real requirements accumulated over time, not a contrived exercise.

Engineering Details

  • Built on Next.js App Router with a clear split between routes, shared libraries, and terminal modules
  • Used dynamic imports for client-heavy interactive features to reduce initial load
  • Added CSP nonce middleware and explicit security headers; JSON API responses use a shared security header helper
  • Centralized protection for chat, contact, and other sensitive routes: `withProtectedRoute` orders method, origin/host, rate limit, parse, bot detection, schema validation, and sanitization
  • Production rate limiting requires Vercel KV; namespaced keys and hashed client identifiers avoid per-instance drift
  • Assistant chat links use an allowlisted `safeHref` path so markdown cannot render unsafe URL schemes
  • Notion signed image refresh tokens replace public block IDs for `/api/notion-image`
  • Centralized AI chat behavior behind one server route with provider fallback and prompt isolation
  • Kept the dice engine as a shared tested utility instead of embedding it in terminal UI code

Outcome

  • Built a portfolio that shows frontend engineering, API design, interaction design, and content architecture in one codebase
  • Created reusable infrastructure for new case studies
  • Gave the site room for experiments, writing, documentation, and tools without turning it into disconnected sections
  • Made the portfolio itself part of the work

Tradeoffs / Limits

  • Some important UI surfaces are still concentrated in large components, especially the generic project page and the terminal core
  • Test coverage is strongest around security primitives, rate limiting, and shared utilities—not every interactive UI path
  • Production operationally depends on KV and explicit origin allowlists; local dev is intentionally more permissive
  • Parts of the content model are built for growth, but some live sections are still sparse

Why It Matters

This project matters because it is the clearest expression of how I build when I am not trying to imitate what a portfolio is supposed to look like. Every major change came from a real need or a real preference: publish what I learn, simplify the writing workflow, adapt proven CMS patterns, expose projects more clearly, and make the interface feel like something I would actually enjoy using. The terminal, typography, colors, naming, and interaction details are not arbitrary styling choices. They are part of the point. λstepweaver is the most accurate visual and technical expression of my identity I have built so far.

Like what you see?

Feel free to reach out if you have questions about this project or want to chat about working together.

> stepweaver.devNext.js