CASE STUDY · PLAYABLE

Building the thing nobody asked for

Rooftop+ started as a weekly chore: seventeen dealership websites, checked by hand. It became the pipeline dashboard my three-person team lives in. This case study is playable. In a moment, you'll be doing my old job.

In plain terms: I found a slow, error-prone chore and built the tool that removed it. That instinct for structure is what I bring to every build.

Role UI/UX • Front-end • AI pair-programming
Scope Internal pipeline tool • 3 roles • 17 rooftops
Stack HTML • CSS • vanilla JS • GitHub + Netlify
Timeline Late 2025 → ongoing

01 · The Job

First, do my old job.

By 2025 I'd been at the company two years, and that's the year the model pages were handed to me. An inherited codebase, a build process I was still learning, and I was slow at it. Not all of the 2025 model pages got finished, and the dealerships noticed. "Where's our page? Why hasn't it been built?" That sting is where this project starts.

But before any pages could be built, someone had to know a car existed. Here's what that looked like. A new model just arrived at one of our seventeen rooftops. Find it.

skip →
redwood-rooftops · 17 sites open

↑ Click a rooftop. Any rooftop.

Somewhere in these seventeen sites is one new model.

02 · The Wall

"Can we get a feed?" "No."

The obvious fix existed. Dealership websites run on inventory feeds; the data was right there, powering the very pages I was checking by hand. So we asked if we could be added to one. The answer was no. We asked again later. No. Every route to the data came back closed, and the weekly chore stayed a chore.

Months later, mid-build with momentum running hot, I went at the wall directly: find the one person at the site vendor who could actually hand over feed access. Not one feed, it turned out. Seventeen, one per rooftop.

MonInventory feed access: quick question
WedRe: Inventory feed access: quick question
FriFwd: Re: Inventory feed access · "try support?"
TueRe: Fwd: Re: Inventory feed access · "not my team"
+8more of these

The chase worked. Seventeen feeds landed, which raised one last question: where do they live? That's the twist. The answer had been sitting in-house the whole time: a hosting server the company already ran, quietly capable of serving all seventeen feeds at stable URLs. I pointed my scan script at them and it came alive. The last problem was solved years before I asked the first question.

03 · The Build

Three months of "what if I just built it?"

The idea sat in the back of my head for months before I wrote a line. What tipped it: I realized I'd already answered the hard questions without noticing. I'd shipped this very portfolio on GitHub and Netlify, so hosting a static app was a solved problem. The only open question was the code, and I answered that with AI as a pair programmer: I drove the product decisions, the interaction design, and the data model; it helped me move at the speed of my ideas instead of the speed of my syntax.

Hosting

Already solved

GitHub + Netlify, no build step. One HTML file, hand-written CSS, vanilla JS modules.

Code

AI as pair programmer

Design vision mine, syntax shared. Three months of evenings: data model first, then queues, roles, polish.

Data

Seventeen feeds, one scan

One feed per rooftop, hosted on a server we already owned, plugged into a scan script. Every lot checked in one click.

04 · The Product

Remember the seventeen tabs? Watch this.

This button replaced section 01 of this page.

Rooftop+ opens to My Work. Not a dashboard, not a settings page: your queue. Every role gets their own: the builder sees pages ready to build, the SEO writer sees pages that need copy, the AEO writer sees the answer-engine layer. Tasks group by brand, clicking one opens a full-width focus mode with next steps and one-click actions, and owners assign themselves the moment someone touches a task. The design bet of the whole app: nobody should have to ask "what should I be doing?"

The second bet came straight from the 2025 sting. The reason missed pages hurt is that a car on the lot with no page is invisible money. So the shared board sorts by consequence, not by date.

Live · Team Pipeline. The red tier is "on the lot, no page": the exact miss that used to sting, now impossible to not see. Full size ↗

And because a three-person team shipping hundreds of pages a year deserves to see it: Wins. Counters, a brand trophy shelf, a leaderboard computed from real task ownership. The chore got automated; the pride got a page.

Live · the Wins page. Every number on it is computed from the pipeline, not typed in. Full size ↗

05 · Outcome

Demo day.

I gave the first build to Bob, my manager, and James, our SEO writer. They loved it. Bob's words: "This is a great idea!" I appreciated that, but I'd known it was a good idea for months, for one specific reason:

It wasn't something people were asking for.
It was something we needed.

01

The chore became a click

Seventeen websites checked by hand became one scan across seventeen feeds we finally won access to.

02

The sheet retired

Statuses, owners, and notes live in the pipeline now: glanceable, not emailable.

03

Nothing sits unseen

The 2025 miss became a design rule: on-lot models with no page go to the top, in red.

Three months in, still fine-tuning. The pages this pipeline feeds have a system of their own: that's the vehicle page system case study, and it's the other half of this story: 2025 taught me to build pages faster; this app made sure I always know which page to build next.

About this demo: the embedded app is the real product with one swap. "Redwood Motors Group," its rooftops, team, and data are fictional, and names here are changed. The production build runs privately with live feeds, Google sign-in, and real-time sync.

Have a site that's drifted like this?

Most businesses do. The fix is structure, not a reskin.