Production work and the tools around it.

Split into the production systems I build for media work, and the utilities and experiments I build to think through problems.

Media Production

Production Systems

TypeScript code: transcript-to-clips pipeline using Remotion renderMedia and Zod schema validation

Podcast Automation Pipeline

React + Remotion render architecture that transforms transcript data into captioned clips and social variants with typed schema validation.

TypeScript code: retention signal mapping with edit decision types cut, keep, retime

Retention Signal Dashboard

Structured reporting layer that maps watch-time drop-offs to specific edit decisions for iterative episode optimization.

Playwright TypeScript test: crop-safe spec validating platform aspect ratios across Instagram, YouTube, TikTok

Crop Check QA Utility

Platform-safe area preview system with deterministic screenshot checks to catch layout breakage before publishing.

View Source
Zod schema code: ReelSchema with project, artist, ctaText, reelType, and timing validation

Genera-Reels Engine

Template-based short-form video rendering tool that consumes payload inputs and emits batch reels with repeatable output quality.

Private Repo
Remotion code: RemotionRoot registering StartingSoon, Intermission, stinger, and alpha-channel alert compositions for a Twitch stream

Twitch Stream Asset Pack

A Remotion render pipeline that programmatically generates a full broadcast kit for a Twitch channel — starting-soon and intermission scenes, animated follower / sub / raid alerts, a stinger transition, and info panels.

What it renders Show less
  • Scenes — Starting Soon, Intermission, and Offline screens at 1080p.
  • Alerts — follower, donation, sub, and raid animations exported with an alpha channel (VP9 / WebM) so they layer cleanly in OBS.
  • Stinger transition — a branded wipe between scenes.
  • Panels — About, Schedule, Socials, Donate, and Rules stills rendered to PNG.

Every asset is defined as code, so the whole pack re-renders on a single command when the brand changes. Built for the "crashdontfall" stream as a personal project — no public site, it outputs video and image files.

Remotion · React · TypeScript

Personal Project
Side Builds

Utilities & Experiments

TypeScript: calculateHelix pure function computing effective grade, curve drag, and a plain-English build-risk verdict across model railroad scales

Will My Helix Work?

A model railroad helix risk checker. It walks five risk dimensions for any helix design in O, S, HO, N, or Z scale and returns a plain-English verdict — from Looks Good to High Risk — before you cut wood.

What it checks Show less
  • Grade — rise per turn ÷ track length per turn, as a percentage.
  • Curve drag — added resistance from constant turning, using John Allen's scale-specific rule of thumb (32/R for HO, scaled per gauge).
  • Clearance — the vertical stack of track, roadbed, deck, open air, and safety margin between levels.
  • Footprint — outer diameter of the helix and the aisle space needed to reach inside for derailments.
  • Train type — heavy steam, long passenger, and small switchers behave differently from generic freight on the same grade.

All math runs in the browser — no server, no database, no account. Inputs serialize into the URL, so a design shares with a single link. Verdict thresholds are calibrated against published model railroad guidance, and the site ships with a glossary, FAQ, gear checklist, and three worked example builds.

Next.js 14 App Router · React · TypeScript · Tailwind CSS · Vercel

Live Site ↗ Private Repo
TypeScript: calculateBreakEven pure function computing profit per item, break-even units, and required sales per day and hour for an artist alley table

Artist Alley Break-Even Calculator

Tells anime convention vendors how many prints, charms, stickers, or commissions they need to sell to cover their table before they profit — with live sales-per-day and sales-per-hour targets.

What it figures out Show less
  • Break-even units — fixed costs divided by profit per item, rounded up.
  • Pace targets — the sales per day and per hour that target requires.
  • Product presets — Sticker, Charm, Print, and Commission, each editable after selection.
  • Reality checks — warns on zero/negative margin and on an unrealistic sales pace.
  • Share & reuse — Copy Summary button, large screenshot-friendly result card, and localStorage persistence.

Mobile-first one-page dashboard with a sticky desktop result panel. All math is client-side with divide-by-zero guards — no backend, no account, no tracking.

Vite · React · TypeScript · Tailwind CSS · Vercel

TypeScript: planSupplies function computing per-color paint volume, cost, and a total from a project's mini count

Paint Supply Planner

Detects the main colors in a reference image, then builds a miniature- painting supply list — how much of each paint you need and what it costs — before you buy.

What it does Show less
  • Color detection — upload a photo, screenshot, or reference and it pulls out the main colors.
  • Editable palette — adjust, add, or remove colors before the list is built; you stay in control.
  • Supply math — paint volume and cost per color scaled to how many minis you're painting.
  • Export — a clean total and CSV you can take to the store.

A calm, warm-paper tool feel. Runs entirely client-side with your inputs saved in the browser — no account, no backend.

Vite · React · TypeScript · localStorage · Vercel

JavaScript: buildLetter function summing deposit deductions, computing the refund due, and exporting through the browser print engine

DepositLetter

Helps self-managing landlords generate a professional, itemized security- deposit deduction letter with the math done correctly — the #1 way landlords lose small-claims disputes is getting this wrong.

What it does Show less
  • Itemized deductions — a dynamic repeater for each damage line item.
  • Live balance math — total deducted and refund due update as you type.
  • Print to PDF — uses the browser's native print engine via @media print, so there's zero PDF-library weight.
  • Privacy by design — letter contents never leave the browser; no accounts, no database.

A deliberately zero-backend build with edge security headers, a strict CSP, and a published privacy policy. Live at depositletter.com.

React 19 · Vite · @media print · Vercel

Node Express code: a route that streams a comic page from a CBZ archive, with notes on CBR conversion, PDF rendering, and thumbnailing

Self-Hosted Comic & Book Reader

A self-hosted reading library for comics, manga, PDFs, and EPUBs that runs on your own machine and streams to any browser on your home network — your files never leave your device.

What it does Show less
  • One library, many formats — CBR/CBZ comics, image folders, PDFs, and EPUB books in one place.
  • Comic converter — turns .cbr and image-folder series into standard CBZ automatically.
  • Real reader UX — 3D page-flip, pinch-zoom, right-to-left manga mode, bookmarks, and resume-where-you-left-off.
  • Read anywhere on your LAN — open it on your phone over WiFi or a private Tailscale tailnet; installable as an offline PWA.
  • Hardened — security headers, optional shared-secret token, rate-limited metadata proxy, generic error messages.

Express server that indexes your files, streams comic pages from CBZ, renders PDF pages, and generates thumbnails. No cloud, no accounts, no database. A personal project — runs locally, so there's no public site.

Node.js · Express · PWA · sharp · pdf-to-img

TypeScript code: normalizeCards function parsing MTG deck list text into typed Card objects

Keep7 Probability Simulator

Browser-based combinatorial analysis tool for opening-hand consistency and mulligan decision support.

View Source
TypeScript reducer code: gameReducer with PLAYER_HIT case, state guards, and bust detection

Blackjack State Engine

Reducer-driven game state machine built to enforce explicit transition rules and avoid hidden state drift bugs.

View Source

If a project here helped you, you can support future tools.