Skip to content
Portfolio · 2026

Selected Work

A guided tour of things I've designed, built, and shipped.

→ Left / Right · Explore projects ↓ Down · Inspect the deep dive ESC · Bird's-eye overview

Use the arrows, your keyboard, or swipe.

Project 01

Affogato

A cozy focus timer where every minute on the clock earns beans to spend on voxel companions.

Astro React 19 zustand React Three Fiber drei

Affogato · Deep dive

The Challenge

[THE_CHALLENGE: describe the core problem Affogato solves and the key performance/architectural constraints — e.g. [TIMER_ACCURACY_CONSTRAINT], [PERSISTENCE_CONSTRAINT], [3D_BUDGET_CONSTRAINT]]

Engineering & Architecture

  • Stack choice: [STACK_RATIONALE: why [CORE_TECH_STACK] over the alternatives considered]
  • State management: [STATE_MANAGEMENT_DETAIL: store shape, selector strategy, and how the tick loop lives outside React]
  • Component ownership: [COMPONENT_OWNERSHIP_STRATEGY: boundary rules that keep the app extractable into a standalone build]

AI & Data Layer

[AI_DATA_LAYER: orchestration, data pipelines, or LLM/vector integration — or NOT_APPLICABLE]

Performance & Optimization

  • [ASSET_LOADING_OPTIMIZATION: how GLB models and the 3D chunk are loaded]
  • [RENDERING_OPTIMIZATION: frameloop policy, context budget, memoization strategy]
  • [BUNDLE_METRIC: eager vs lazy chunk sizes and what moved where]
Project 02

Evillevi Garden

A neobrutalist second brain where notes link, graphs render, and the design system is a living showcase.

Astro 6 Tailwind v4 React islands three.js uFuzzy D3

Evillevi Garden · Deep dive

The Challenge

[THE_CHALLENGE: describe the core problem the garden solves and the key performance/architectural constraints — e.g. [CONTENT_MODEL_CONSTRAINT], [ISLAND_HYDRATION_CONSTRAINT]]

Engineering & Architecture

  • Stack choice: [STACK_RATIONALE: why [CORE_TECH_STACK] for a content-first site with interactive islands]
  • State management: [STATE_MANAGEMENT_DETAIL: what stays server-rendered vs which islands own client state]
  • Component ownership: [COMPONENT_OWNERSHIP_STRATEGY: Astro kit vs React kit split and the design-token contract]

AI & Data Layer

[AI_DATA_LAYER: orchestration, data pipelines, or LLM/vector integration — or NOT_APPLICABLE]

Performance & Optimization

  • [ASSET_LOADING_OPTIMIZATION: content index generation and search payload strategy]
  • [RENDERING_OPTIMIZATION: 3D accent frameloop gating and reduced-motion behavior]
  • [BUNDLE_METRIC: per-island chunking results]
Project 03

gg³

Good game, G. Two ways to play chess across three levels.

Astro React Three Fiber TypeScript Supabase

gg³ · Deep dive

Two games, two rulebooks

Strato Chess separates planar captures from transfers between levels. Chess³ allows pieces to attack through three-dimensional space. Each has its own versioned movement policy, backed by explicit examples and documented conventions. A saved match keeps its original rules version.

A table you can turn

Three stacked boards and procedural Staunton pieces form the React Three Fiber scene. Rotate, zoom or isolate a level to inspect a position. HTML move controls and a selectable 2D board make every move available without a 3D click, including when WebGL is unavailable.

A shared position

Choose White, Random or Black, then share a private invite. Supabase anonymous authentication identifies each player. Edge Functions validate moves with the same pure TypeScript engine used for practice; a Postgres transaction compares the position version and records exactly one move. Participant-only reads and restricted writes protect the canonical board.

Realtime notifications trigger an authoritative snapshot refresh. Reconnect and page reload restore the position and move history. Matches end in checkmate, stalemate, resignation or a mutually agreed draw.

Read the rules and application conventions or take a seat.

Project 04

Karma POS

A complete café workflow where the register and kitchen stay useful—even when the network does not.

Astro 6 React 19 LocalStorage Vite Multi-station UX

Karma POS · Deep dive

The Challenge

A café POS has to serve several people at once: baristas need a fast catalog and checkout, managers need inventory and reporting, and the kitchen needs an uncluttered queue. Those workflows cannot simply disappear when connectivity becomes unreliable. Karma explores how a compact product can make order state, permissions, payment status, and synchronization visible without slowing down the counter.

Product & Architecture

  • Two-station workflow: the register creates and edits orders while a focused Comanda view moves tickets through queued, preparing, ready, and delivered states.
  • Role-aware operations: owner, manager, cashier, and kitchen roles expose different navigation and approval boundaries. The demo includes realistic PIN-based sessions rather than a single all-powerful user.
  • Local-first state: both stations share one versioned browser document. Storage events keep separate tabs aligned, while explicit online, pending, and conflict states make connectivity part of the interface.
  • Operational breadth: the POC covers modifiers, open checks, split payment, tips, cancellations, inventory movements, recipes, sales history, reports, users, and configuration.

Prototype Evolution

Karma began as a declarative Datacosm design prototype. Its templates were mechanically translated into native JSX, the CDN/Babel runtime was removed, and React became a normal bundled dependency in a multi-page Vite application. For this portfolio version, the same product logic is hosted as isolated Astro React islands: data is imported as an SSR-safe module, styling is scoped to the demo boundary, and the register and Comanda remain distinct routes with shared browser-local state.

Resilience & Tradeoffs

Offline mode keeps cash and transfer workflows moving and records pending operations for a later sync. Card payment deliberately fails while disconnected, demonstrating a product-level failure path instead of pretending every dependency is available. The current synchronization model is intentionally a POC: localStorage stands in for a durable local database and backend conflict resolution, authentication is demonstrative, and no real payment or printer integration is present.

Portfolio Integration

The embedded version preserves the original Spanish café interface and seeded menu while adding portfolio navigation, visible demo credentials, and a reset-to-seed action. The integration is a maintained copy rather than a shared package, leaving the standalone repository as the historical source and allowing the portfolio boundary to remain deployment-independent.