SHADE.OSshaderahman.dev/projects

Built things

Projects

Fewer entries, written properly. Each one says what it does, what was hard, and what I would do differently.

  • EcoStep

    Home energy upgrades are worth thousands in rebates that almost nobody claims, because working out which ones you qualify for means reading your own appliance labels and utility bills. EcoStep reads them for you.

    A model was retired mid-build
    The production Gemini model the vision pipelines ran on was retired while the project was still being built. I replaced it with a 4-model automatic fallback chain and a 9-category error taxonomy across both pipelines, appliance-label OCR and utility-bill parsing, which took single-model outages off the table entirely.
    Five engines, six routes
    Rebate matching, affordability simulation, outage-resilience planning, group-buying, and proactive coaching, across 6 REST API routes. Benchmarked at 9,600+ evaluations per second, averaging 0.104ms per call, with 8 of 8 unit tests passing.
    What was broken
    Three classes of app-wide UI bug: a dark-mode toggle that was silently ignored, 17 invalid Tailwind color tokens, and 17 controls that failed contrast. I fixed all three, added a motion layer across 6 components, and shipped with zero TypeScript errors across 13 routes.
    • Next.js
    • React
    • TypeScript
    • Tailwind CSS
    • Supabase
    • Gemini API
    • Vercel

    Built at BloomKnights 2026. The reliability work was not planned. It was a response to the Gemini model disappearing underneath us partway through, which turned out to be the most useful thing in the project. Anything depending on one model has a single point of failure that a hackathon timeline will happily expose.

    Built with Abeni Rodriguez, Emma Stefanini

    Source on GitHubWriteup on Devpost

  • Bolo

    Writing a professional email in a second language is slow, and most tools either translate too literally or flatten the English you already wrote correctly. Bolo takes text, speech, or a screenshot of an email and returns a drafted English reply.

    The measured result
    Drafting time dropped from 30 minutes to 4 across 50+ generated emails, an 87% reduction.
    Code-switching without losing intent
    People writing in a second language mix English words, phrases, and whole sentences into their native text. Prompt flows that passed 35 generation tests preserve those rather than round-tripping them back out through translation.
    What an adversarial QA pass found
    21 verified bugs, fixed, with 126 tests passing afterwards. The fixes were prompt-injection detection, Unicode-aware OCR cleanup, runtime API validation, stale async guards, and an empty-response fallback.
    • Next.js
    • React
    • TypeScript
    • Tailwind CSS
    • Tesseract.js
    • Gemini API
    • OpenAI API
    • Vercel

    The OCR path was the fiddly one. Screenshots of emails arrive at every possible resolution and Tesseract will confidently return Unicode garbage for a low-quality crop, so a cleanup pass sits between it and the model.

    Try BoloSource on GitHub

  • Cooked!

    Recipe sites want you to already have the ingredients. Cooked! goes the other way: type in what is actually in your fridge and it ranks recipes by how much of each one you can make right now.

    Ranking, not just matching
    A tiered ingredient-matching algorithm with coverage-based scoring ranks 12+ recipes per query, rather than dumping back everything that happens to contain one ingredient you own.
    Cutting redundant calls
    In-memory caching and API error handling reduced redundant external API calls by 73.6% across overlapping query benchmarks.
    People type messily
    Nobody enters ingredients consistently. '2 cups', '2c', and 'two cups' all show up. Real-time validation, unit normalization, and unit suggestions resolve that before anything reaches the matcher.
    • Python
    • Flask
    • Next.js
    • TypeScript
    • REST APIs
    • TheMealDB API
    • Gemini API

    Built at HackUSF 2026 with Natalie Reese. I worked mainly on the backend: the Flask service, the matching and scoring, the caching, and the input normalization, plus the wiring between the frontend and backend, and the UI/UX. Natalie built the frontend UI and handled integration and deployment.

    Built with Natalie Reese

    Source on GitHubWriteup on Devpost

  • annabelle.sfx

    A birthday present for my best friend. A mobile-first soundboard styled after a Stream Deck: sixteen tactile keys in a 4×4 grid, one sound each, no build step and no dependencies.

    No framework, deliberately
    Vanilla HTML, CSS, and JavaScript. Nothing to install, nothing to build. It registers a service worker and installs as a PWA, so it keeps working with no connection at all, which matters for something meant to be opened on a phone at a party.
    iOS is the hard part
    Safari suspends the Web Audio context until a real user gesture unlocks it, then suspends it again when the page is backgrounded. app.js carries a dedicated recovery path for that, and the repo ships a separate diagnostics page for testing on the phone itself rather than in a desktop simulator.
    Swappable without touching code
    The sixteen keys are built from a manifest.json that maps files to slots, with an optional colour shade per key. Changing the whole sound set means editing one JSON file and reloading.
    • JavaScript
    • HTML
    • CSS
    • Web Audio API
    • PWA

    Not a serious project, and I am keeping it here anyway. It is the only thing on this page built for exactly one person.

    Source on GitHub

  • Network Connectivity Analyzer

    Given a network and a list of connections that fail one after another, how connected does the network stay at each step? This answers that in O(log n) average time per operation.

    Running the problem backwards
    Union-Find only merges. It has no way to split a set, so sequential edge removal is the one thing it cannot do directly. Reverse-deletion sidesteps that: replay the removals backwards as insertions, rebuilding the graph bottom-up and tracking size-weighted component merges at each step to recover the connectivity score at every stage.
    Where the log n comes from
    Union-Find with both path compression and union by rank. Either alone is worse; together they give the O(log n) average.
    • Java
    • Algorithms

    Coursework, and the first time an algorithm felt like a genuine trick rather than a procedure to memorise. The insight that you can run a destruction problem backwards as a construction problem is not obvious until someone shows you.

    Source in my coursework repo

  • Gaming CPU Project

    A team build of a RISC-V CPU system-on-chip that runs video games on an FPGA, run through IEEE at UCF. Hardware is the half of computer engineering a software portfolio usually leaves out.

    The design
    A 5-stage pipeline with VM/0 fetch, built as a team through the university's IEEE chapter.
    My part
    Coding, debugging, synthesis, and implementing hardware modules: the ordinary work of getting RTL to behave on real hardware rather than only in simulation.
    • Verilog
    • FPGA
    • RISC-V
    • RTL Design

    Ran from September to December 2025. Not an active project any more, but it is the reason the hardware side of the degree stopped being abstract.

    IEEE at UCF

  • Card Game Simulator

    A card game simulator in C that reads a deck from a plain text file, deals it out, and tracks every player's hand. Written while learning what linked lists are actually for.

    Where the work was
    Sorted insertion, pile reversal, and transfers between the draw, player, and discard piles, all on hand-rolled linked lists, with dynamic memory allocation and file I/O underneath.
    • C