I build production-grade web products where interface quality, browser behavior, and real implementation detail matter. My work sits at the intersection of frontend engineering, browser extension architecture, AI-assisted systems, and cross-platform debugging — especially when a polished UI still has to survive real device constraints, service worker lifecycles, and production deployment realities.
- Browser-platform engineering: I build Chrome Manifest V3 extensions, service-worker-driven workflows, isolated UI injection, and frontend systems that have to work inside real browser constraints.
- AI-integrated product systems: I use models as part of the product stack to support workflow quality, reasoning, and UX — not as a substitute for real implementation or human evidence.
- Cross-platform debugging: I solve browser- and device-specific issues on physical hardware using Safari Web Inspector, ngrok, and live debugging workflows across iPhone, Safari, WebGL, and media/runtime edge cases.
- Release-minded frontend systems: I ship with TypeScript, testing, CI, and production behavior in mind — treating maintainability, debuggability, and deployment quality as part of the product.
| Domain | Technologies | Focus |
|---|---|---|
| Frontend | React, Next.js, TypeScript, Tailwind CSS | Component systems, state flow, performance-minded architecture |
| Backend & Data | Node.js, Express, MongoDB, Firebase Auth | REST APIs, authentication, data modeling |
| Browser Platform | Chrome MV3, Service Workers, Shadow DOM, MutationObserver, Web APIs | Extension lifecycle, DOM orchestration, isolated UI injection |
| AI & Media | Gemini, MediaPipe, Google Cloud TTS | Product workflows, multimodal analysis, voice features |
| Mobile & Debugging | Safari Web Inspector, ngrok, iPhone camera handling | Real-device debugging, mobile QA, runtime troubleshooting |
| Ops & Quality | Vitest, Jest, ESLint, GitHub Actions | Automated tests, CI discipline, release-minded workflows |
SigSent - The Human Signal Lab
A full-stack pre-send email testing product. Users create email variants, generate tokenized reviewer links, capture human-response signals, compare outcomes, and refine copy before launch — with a Gemini-powered assistant grounded in real campaign data rather than generic completions.
The product is structured around human evidence, not AI-generated predictions. It is a structured experimentation workflow for measuring trust, clarity, and action intent before an email is sent.
Stack: React, TypeScript, Tailwind CSS, Node.js, Express, MongoDB, Firebase Auth, Gemini API, Google Cloud TTS, MediaPipe
Architecture:
- Signal Lab workflow: Tests with 2–5 variants, tokenized public review links, behavioral event capture, survey collection, and fixed comparison rules that gate release guidance behind 3–5 completed responses per variant — structured as a cohesive product, not isolated features
- Public reviewer sessions: Secure token handling, expiration, stateful session tracking, and event capture without requiring reviewer authentication
- On-device processing: Optional MediaPipe FaceLandmarker for client-side facial-reaction capture within the broader workspace
- Cross-platform constraints: Browser- and device-specific work across Safari, iPhone, and client-side runtime handling, including multimodal input
CI/CD: GitHub Actions — lint, typecheck, tests, and build on every PR.
Status: Live product, actively developed · source is private
PDX Matchday — Published Chrome Extension with Safari Support
(formerly Portland Timbers Matchday) A Manifest V3 extension that shows upcoming Portland Timbers matches with a live countdown, TV/streaming info, and a fan confidence poll — expanding to cover Portland Thorns matches too, as the first client of a planned multi-surface matchday platform.
The Architecture: chrome.storage.local for state, alarm-based hourly refresh, runtime messaging between popup and service worker, and a three-tier data resolution strategy (Matchday API, which resolves ESPN server-side → cache → bundled fallback). Fan confidence poll uses Firebase anonymous auth and Cloud Functions. Safari support is handled through Xcode conversion with no polyfills required.
The Result: Published on the Chrome Web Store, with Safari support built into the codebase and workflow. 163 passing Jest and Vitest tests across 12 suites (extension client + backend API), GitHub Actions CI, and Codecov coverage reporting.
Oregon Lawn Barbers — Client Site
End-to-end design and build for a Portland-area landscaping company: 8 service-area pages across Oregon and Washington, a quote form with validated photo-upload intake, and GA4 measurement for consent-aware traffic tracking. Conversion-focused, responsive, and deployed on Vercel with Next.js, TypeScript, and Tailwind.
Good Old Tee — Pre-Launch Brand Platform
Live pre-launch web presence for an independent apparel brand, capturing early demand ahead of launch.
The Architecture: Next.js, TypeScript, and Tailwind CSS, with consent-aware email signup, GA4 measurement, and 5 commerce policy pages (privacy, cookie, terms, shipping, returns).
The Result: Live and collecting signups ahead of the product drop.
OfferEngine — Zero-Backend Coupon Utility
A client-side coupon generator for configurable discount codes, QR output, and persistent storage with no backend required.
The Architecture: Next.js 15 (App Router) + TypeScript + Tailwind. Coupon codes use crypto.getRandomValues for suffix generation. QR rendering via qrcode.react. localStorage persistence across sessions. Input validation for discount ranges, code length, and expiration dates.
The Result: Deployed on Vercel with 105 passing Vitest unit tests across 4 suites, ESLint, TypeScript type-checking, and GitHub Actions CI.
PerkPop — MV3 DOM Injection, Published Chrome Extension
(formerly Search Cashback Injector) A Manifest V3 Chrome extension that detects supported merchant domains in Google Search results and injects inline cashback banners next to matching results.
The Architecture: TypeScript + Vite build. Content script handles result link detection and domain normalization; background service worker resolves offers via a configuration-driven merchant registry with chrome.storage.local caching and JSON fallback data. Injected UI uses Shadow DOM for full style isolation from the host page.
The Result: Published on the Chrome Web Store as a technical prototype — current offer data is mock/fallback only, no real cashback payouts. 68 passing Vitest tests reaching 98% statement coverage, with GitHub Actions CI.
I treat AI tooling as an architectural constraint, not a substitute for engineering judgment.
That means:
- generated code should fit the actual system, not generic defaults
- repo-specific rules and conventions should keep implementation aligned with the product
- core projects should validate through linting, tests, and CI where the workflow calls for it
- browser behavior, runtime detail, and production reality matter just as much as clean code in the editor
I care about understanding what is actually running — especially when the debugging gets messy.



