Pickup-game matcher
Getting ten people onto a pitch means four group chats and a lost evening. YIGMA does it in one tap — a live feed of every pickup game in Baku, inside Telegram.
Role · Product, brand & design system · solo build
Scope · Landing + Mini App + Telegram bot + owner cabinet
State · Live in production



One scroll, one promise
The public page has to do two jobs at once: explain a Telegram Mini App to somebody who has never opened one, and prove that games are happening tonight. The counter in the hero is a live database query — when the number is small, it says so.
Three months, one person, one stylesheet.
Four sides, one column
A pickup-sports economy in 480 pixels
Player, host, venue owner and a Telegram bot — four jobs on one narrow surface, because a Mini App has no room for four.
Not just screens
I owned this end to end — the problem, the name, the brand, the design system, the code that shipped it and the analytics that judged it. Solo, over three months, in public.
01
Product & UX
Flows, information architecture and the four-step hosting wizard, across feed, game, profile and owner surfaces.
02
Brand & UI
The name, the Y-figure mark, the palette and the voice — then the pixel-level interface built on top of them.
03
Design system
A 9-step scale, 5 radii, 6 shadows and 37 hand-drawn icons, in one hand-rolled stylesheet with no framework.
04
Engineering
Next.js 15, Postgres, Drizzle and the Telegram Bot API — 25 screens and 50 endpoints, written and deployed.
A mark I drew myself
Yigma is Azerbaijani for the squad you assemble — what Russian calls «сборная». The name is a pun that works in both languages of the city, and the mark had to carry it in a single glyph that still reads at sixteen pixels. In Azerbaijani the G takes a breve; the Latin lockup drops it.
Logo concept
A person
The letter Y
A team
The mark
Yigma is the place where players come together. The mark folds three things into one — a person, a team, and the first letter of the name.
Lockups
One mark, every container
The same figure sits in the app icon, the favicon, the Telegram avatar and the empty states. Below thirty-two pixels the arms are what survive — which is why they are the widest part of the drawing.
From a link to a lineup
Three slides, then you are in
Open the bot, pick what you play, and the feed arrives already filtered to you — no sign-up form, no password, no empty state.
Motion, exactly once
The first slide runs a gyroscope parallax with a depth-of-field blur behind the headline — tilt the phone and the balls drift out of focus. It is the one place in the product where motion is allowed to show off.
Everywhere else motion is functional, and the whole thing is behind a prefers-reduced-motion guard.
And on the web
Real users turned out to be on WhatsApp and plain browsers, so Telegram could not be the only door: Google, a magic link and the Telegram widget all lead to the same account.


The feed is the product
Every game in the city, one scroll
Eleven activities, three lanes — open now, this week, good for beginners — and a map that speaks exactly the same colour language.





No chats.
Just the squad.
Four steps, no dead ends
Post a game in under a minute
What, when and where, who is coming, publish — with a live preview of the feed card at every step, so nobody posts blind.





One stylesheet, no framework
No Tailwind, no UI kit, no icon library. Tokens, thirty-seven hand-drawn icons and a single 480-pixel column — so the bot web view, the Mini App and the owner cabinet are unmistakably the same product.
Palette
Button
Every component is built on the same tokens the code uses — the eleven activity chips carry the real tint/ink pairs, the card is the feed card, the nav is the five-tab bar. A developer can open the library and read the exact value instead of guessing from a screenshot.
Typography
Yig. Play.
Find your crew for anything in Baku.
Radius, elevation & motion
Radius
Elevation
Motion
ease-out cubic-bezier(.2, .85, .25, 1)
ease-spring cubic-bezier(.5, 1.6, .4, 1)
Ten named keyframes — pulse, fade, slide, rise, pop, shimmer, join-flash, confetti, drift, float — all behind a prefers-reduced-motion guard.
No score, no fake Elo
Reputation you can actually earn
Pickup games have no recorded result, so a competitive rating would have been fiction. Stars are the honest average of peer reviews; reliability is smoothed attendance.
Rating
Peer stars and quick tags, collected after the game and shown on host cards and profiles. Nothing is derived from a scoreline, because there is no scoreline.
Reliability
The host marks who actually turned up. Bayesian smoothing means one missed evening does not brand a newcomer — and a long clean record is genuinely hard to fake.
Reliability
100 · (present + 4) / (present + noShow + 4)
The prior of 4 is what stops a single no-show from destroying a new player.

The other side of the pitch
Venues are the supply side. Owners get a four-tab cabinet — overview, requests, schedule, data — with working hours, closure calendars and booking confirmations.


A game on a request-mode court stays out of the public feed until the owner confirms it — so nobody joins a match whose pitch later disappears.
Ownership transfers through a one-time claim link. No support ticket, no manual database edit.
Logo upload, price per hour and a live KPI strip — all inside the same 480-pixel column as everything else.
The product also lives in a chat
Inline approve and decline buttons, deep links that open straight into a game, and a channel post for every published match. The bot is not a wrapper around the app — it is a second front end, translated per user.
Fifteen localised notification templates
Each one exists in Russian, Azerbaijani and English and is sent in the language the user picked — including for people who signed in on the web and never opened Telegram.

Two jobs, not two personas
The brief named exactly two problems. I did not run interviews, so these are written as design hypotheses rather than research — but every screen in the product is answerable to one of them.
Job 01
Already plays
“I have people to play with — but collecting them costs me an evening across four group chats.”
What the design answers with
- One-tap join, with the seat actually held
- Host approval queue for the games that need it
- A day-before reminder sent on the host’s behalf
- Reliability, so a repeat no-show is visible before you invite them
Job 02
Would play, has nobody to call
“I want in, but every game already has a closed circle — and I don’t know which venues are any good.”
What the design answers with
- A “good for beginners” lane in the feed
- Price, place and head count on the card, before committing
- A public profile with a record, so you are not anonymous
- Map mode, because the venue matters as much as the sport
Where the line dips is where the design earns its keep
The riskiest moment is not joining — it is the wait afterwards, when a game can quietly die. That is why the squad thread, the reminder and the live “needs three more” counter exist at all.
Taps a channel link or opens the bot
Scans the feed, filters by activity and day
One tap — seat held, host notified
Waits for the squad to fill, talks in the thread
Turns up and pays the venue on site
Leaves stars and tags for whoever came
“Is this another dead chat?”
“Is it near me, and what does it cost?”
“Am I actually in, or on a list?”
“Will this game even happen?”
“Will these people be any good?”
“Was that worth repeating?”
No signal that anything is happening
Sport, time, price and distance all at once
Silence after joining feels like nothing happened
Games quietly die between joining and playing
No signal about who is reliable
Nothing carries over to next week
Live open-games counter on the landing
Tinted cards, three lanes, price up front
Confetti, haptics, your face in the roster
Squad chat, “needs 3 more”, reminder
Reliability shown before you commit
Attendance marked, rating updated, saved
So the squad gets a thread
A per-game chat that both Telegram and web players share. It polls instead of holding a socket — Vercel functions are short-lived, so a persistent connection would have been the wrong tool — and it backs off from four seconds to ten once the room goes quiet.
Every message is deleted when the game is finalised: nothing to leak, nothing to store, nothing to pay for.

The app, mapped
Five surfaces branch off one core, each carrying only the screens that role lives in — and every one of them renders through the same tokens, in the same narrow column.
Player
- Feed · list & map
- Game page & roster
- Squad chat
- Profile, reviews, saved
Host
- Four-step wizard
- Approval queue
- Attendance marking
- Recurring weekly slots
Venue owner
- Cabinet overview
- Booking requests
- Schedule & closures
- Venue data & logo
Admin
- KPI console
- Venue moderation
- Force-cancel
- Demo mode
Telegram bot
- /start · /help · /lang
- Deep links into a game
- Inline approve & decline
- Channel post per game
Three things I changed my mind about
A solo project has no one to argue with, which makes it very easy to defend a bad idea. These are the calls where the first answer turned out to be wrong, and what replaced it.
01
From padel to everything
23 Apr · day two
A padel-matching app.
Eleven activities, from mini-football to mafia nights.
Padel is a rounding error in Baku; the volume is mini-football, basketball, quiz nights and weekend hiking. The entire eleven-tint colour system exists because of this one call, made on day two.
02
The dark direction, killed after 48 hours
24–26 May
Two same-day experiments — a dark editorial v3 and an italic-serif v3.1.
A revert to the light system, keeping only the new YIGMA brand.
The dark direction photographed well and lost legibility inside Telegram’s own chrome, on the phones people actually use. Throwing away two days was cheaper than spending a month defending it.
03
Desktop deliberately not redesigned
throughout
A multi-column desktop layout.
The 480-pixel column, centred on a backdrop and framed like a phone.
It is a Telegram Mini App. A real desktop grid meant per-section work for traffic that does not exist. Deciding what not to build is a design decision too.
How one person shipped this
Twenty-five screens, fifty endpoints and two thousand translated strings in twenty-three working days is not a story about typing fast. Every feature started as a written spec. The code was written with AI assistance; I set the direction, made the product calls, and reviewed everything that landed.
01
Written before built
Nine specs and five implementation plans, versioned next to the code. If a feature could not be described in a page — who it is for, what it does, what it must never do — it did not get built. That constraint shaped the product more than any tool did.
02
I was the review gate
The iOS ghost-click that shut a sheet the instant it opened. Two horizontal-scroll regressions headless Chrome physically cannot see. A day toggle that had quietly shrunk to a dot glyph, found by tapping it by accident. Nothing automated catches those — sitting with the thing on a real phone does.
03
Taste is not delegable
The name, the eleven-tint system, the refusal to fake a rating, the decision not to redesign desktop, the choice to publish no numbers I could not defend. Nothing decided those but judgement — which is the part of this job that does not get automated.
Designed, built and shipped
by one person.
Landing, Mini App, Telegram bot, owner cabinet and an experiment framework — running in production in Baku, in Russian, Azerbaijani and English.
oyunbot.vercel.app↗