MegaSquad

Multi-sport pick’ems for your friend group. Thirteen leagues across five sports, picks that auto-lock at tip-off, and standings that settle the trash talk. I built the front end; my brother built the API.

Leagues supported
13five sports, 20 competitions
Games in one season
285scored, reconciled, settled
Ways it answers back
3213 hits, 12 misses, 7 scoldings
Poll interval
30 sidle after 5 min
The problem

The group chat is a bad database

TL;DR

My brother and I got tired of running our pick’em on a spreadsheet and chasing everyone in the group chat before kickoff. MegaSquad is that job handed to software: picks lock themselves and standings settle themselves.

Run by hand, a pick’em is mostly admin. Somebody has to collect everyone’s picks before kickoff, score them afterwards, and settle it when two people remember the same result differently. MegaSquad is that arrangement with a source of truth: squads, leagues, weekly picks that lock the moment a game starts, and standings nobody can argue with.

A MegaSquad league page: nine members ranked by record with the viewer first at 7-3, beside a This Week panel showing five settled games and four won picks.
Ten games in. Nine members, and a leader
The craft

Cards become tickets

TL;DR

Making picks isn’t a separate screen. The schedule you were reading turns into the thing you fill in. The cards tear along a perforation and stay exactly where they were.

The obvious build is a picking page: leave the schedule, go somewhere else, come back. That loses your place and makes choosing feel like paperwork. So picking happens in place: the same cards, transformed. A dashed tear line opens down the middle, notches punch through both edges, and the card you were reading becomes the ticket you hand in.

It only reads as a transformation because nothing moves. An earlier attempt put the controls in a right-hand rail, which reserved its width the moment picking started and shoved every card sideways, 602px to 422px. The tickets stopped looking like the cards becoming something and started looking like a re-render.

MegaSquad in picking mode: a sticky bar reading 5 of 16 with Cancel and Save Picks, a segmented progress strip showing five team crests, an active slot and ten question marks, and schedule cards rendered as perforated tickets with dashed tear lines, punched notches and lock-in countdowns.
Picking: the schedule, torn into tickets

The bar above tracks the week without you counting: a segment per game, a crest for every team you’ve taken, a question mark for the ones you haven’t, and a padlock once a game locks. It scrolls horizontally on a phone rather than wrapping, so the week stays one line you can read at a glance.

Picking mode on a phone: the sticky bar and its scrolling crest row above a single column of perforated ticket cards.
390 pt
The hard thing

Showing you where the season got away from you

TL;DR

A win-loss record tells you nothing about where it went wrong, so every row opens into the weeks, with each team you picked badged green for a win and red for a loss.

A record of 182–103 tells you almost nothing. The interesting question is where it went wrong. So standings expand into a per-week breakdown, and each week shows the actual team logos you picked, badged correct or incorrect.

63.9% across 285 games. The playoffs alone go 11 of 13: Wild Card 5 of 6, Divisional 3 of 4, Conference 2 of 2, the Super Bowl called. Divisional is the round that slipped, and now it has a name.
One season, read at a glance
An expanded MegaSquad standings row at 182-103 and 63.9% correct, opening into per-week results (Super Bowl 1 of 1, Conference 2 of 2, Divisional 3 of 4, Wild Card 5 of 6) with Week 18 open below them, showing sixteen team crests each outlined green for a correct pick or red for a wrong one.
A season, opened week by week

None of those numbers are stored twice. The record, the win percentage, the per-week tallies, and the completed-game count all derive from the same picks, which is why they reconcile exactly, and why they can’t drift apart.

The delight

Every settled pick answers back

TL;DR

Settled picks talk back, pulling from a set of phrases for a hit and another for a miss, so the same outcome never reads quite the same way twice.

Getting a pick right returns “Bullseye!”, or “Nailed It!”, or “A Prophet!” Getting one wrong returns “Narp.”, “Whiff.”, or “Gross, dude.” State is encoded three ways at once (border color, a result pill, and the score), so an entire week reads without parsing anything.

MegaSquad's NCAA tournament Round 1 schedule: matchup cards with team logos, seeds, and final scores, each outlined red or green and topped with a result pill: a short phrase of praise for a hit, of commiseration for a miss.
Round 1, settled

All three signals survive the narrow layout. The schedule has exactly one breakpoint, so every phone width takes the same path: the card stacks, and the pill keeps its place.

The same NCAA tournament schedule on a phone: matchup cards stacked vertically with the result pill centered above each pair of teams.
390 pt

When no league is in season, a sleeping squid offers sports trivia instead. It’s the kind of thing nobody asks for in a spec.

MegaSquad's empty state: a cartoon squid asleep, the message “No games found for Week 1, Season 2026,” and a sports trivia card with a Get Another Fact button.
No league in season
Working to someone else's contract

Two languages, one product

TL;DR

Half of this app is my brother’s and I can’t change it. Building on someone else’s system means behaving like a guest: ask for only what you need, and stop asking once nobody is looking.

The API is my brother’s, in Python. That makes the front end a consumer of a contract it doesn’t control, which is its own discipline: the app polls invitations every 30 seconds but stops after five minutes of inactivity, so a tab left open for three days isn’t quietly hammering his server.