job-lab: I needed judgment, not more job links.
A local-first job-search desk for a senior designer applying from India: private, with a public demo.
The first idea was a job board, but I was the user, and I never ran out of job links. I ran out of hours: checking which roles were real, whether remote included India, what to say, who to write to, and whether the market was teaching me anything back.
Private desk, public demo
The real desk is private and stays behind a login. The public demo runs on fictional data, so you can try every screen. Try it at job.kousikdutta.com/?demo=1 (opens in a new tab).
Volume was never the problem.
Most job products optimize for volume. That fails a senior designer in India looking for roles worth a careful application.
| User problem | Design response | Engineering response |
|---|---|---|
| Remote does not always mean remote from India | Split remote, hybrid, onsite, and city roles instead of flattening them into one list | Normalize location text into workplace, city points, and eligibility flags before anything renders |
| A match score alone does not tell me what to do | Rename the score Worth your hour and tie it to the next action | Combine role fit, freshness, application readiness, resume evidence, and human-route signals |
| Most ATS advice is vague or dishonest | Suggest rewrites only where the resume lacks truthful evidence | Compare posting language against the resume, portfolio projects, and saved profile data |
| Networking turns into spam fast | Design outreach as a decision, not a send-more button | Build templates from the role, the company, hiring-team clues, and portfolio proof |
I designed it, directed the build, and tested it.
Each design decision becomes a typed model, a component, and a test.
The architecture is the strategy.
Three layers: sources become one clean job object, a decision layer scores fit, effort, readiness, and access to a real person, and the interface turns those signals into action.
The board is for triage.
Board. Search, filters, the role list, and an India-first map, so you can triage the market without opening ten tabs.
The map got pushback, and it deserved it. The first version was decoration, and its India boundary was not acceptable, so I replaced it with an accepted world political map.
- Decorative geography
- Unclear political boundary
- Remote roles plotted as if they had a city
- No link to the ranked list
- Accepted political map context
- India first, because that is the market
- Remote work counted separately
- Dots, city cards, and jobs all agree
Toggle the signals and watch the call move.
Try the Worth your hour model
Worth a look, but fix the resume gate before opening the ATS.
On a phone, the job changes.
Desktop is for comparison. A phone is a different job, so it gets a different composition.
Each product need, and how desktop and the phone meet it.
| Product need | Desktop behavior | Mobile behavior |
|---|---|---|
| Choose what to do next | The wide layout keeps several destinations and their context visible | Today leads with the most useful actions and five daily destinations |
| Scan the market | List, map, city summary, and filters share one view | Board goes list-first; filters collapse and the map becomes secondary context |
| Move across the workflow | Every top-level destination stays in the header | A safe-area bottom bar holds daily tasks; More opens Advisor, Portfolio, Pay, Negotiate, and Settings |
| Open a role and return | Detail and list share the split-view space | Detail becomes its own overlay: the content behind it goes inert, context is kept, and Back to roles is always there |
The apply packet earns its keep.
Job detail. A posting stops being a link and becomes a decision, before the apply click.
A normal job card ends at the apply link. job-lab starts there, and slows you down before the external click, because that is where an application is won.
| Packet module | Design decision | Engineering detail |
|---|---|---|
| Resume match | Show missing evidence and honest rewrites, never fake ATS hacks | Compare JD terms, seniority, and proof points against the stored resume text |
| Portfolio proof | Ask for the two projects that answer this posting, not five random links | Match job keywords to saved project themes and generate a short pitch angle |
| Who to contact | Replace “go network” with a specific route to a person | Use public company and team clues, with a manual review every time |
| Write to them | Specific enough to be useful, restrained enough to be ethical | Built from role context, profile data, and the portfolio URL, not generic AI prose |
Try packet readiness
Profile fit and seniority match the posting.
Paste your resume once in Settings.
Two case studies map to the role.
Find one person before outreach.
Name, email, and portfolio URL are ready.
See every screen, failure state, and test
Every screen has one job.
Today and autopilot. It shows the most useful next moves and caps the day at a small number of quality applications.
Failure is a designed state too.
Local-first products still fail. Each failure gets its own state instead of one generic empty card.
Each failure state, what the interface says, and how it recovers.
| State | What the interface says | Recovery behavior |
|---|---|---|
| Required board data fails | The Board is unavailable; local applications and contacts were not changed | Retry the failed source without clearing private local state |
| Optional evidence is malformed | The Board still works; the affected Advisor or company evidence names what is missing | Reload that feed and keep the rest of the product usable |
| Search or filters return zero roles | The roles still exist, this view just has no matches | Clear search and filters in one action |
| Resume, profile, or portfolio proof is missing | The relevant packet module is blocked and names the missing evidence | Send the user to the field that enables matching, outreach, or autofill |
| A form or storage write fails | The error stays on the action instead of implying success | Fix the field, retry the write, or reset only the affected local data |
Accessibility changed the structure.
The ranked list doubles as a readable alternative to the map.
| User need | Implementation evidence | Validation |
|---|---|---|
| Navigate without a pointer | Named buttons, keyboard map points, tab semantics, and logical focus order | Keyboard review across every primary view and all job-detail tabs |
| Keep context through overlays | Focus trap, inert covered content, explicit close and back actions, focus restoration | Mobile detail and More-sheet open and close paths at 320 and 390 pixels |
| Read both visual themes | Semantic tokens for text, muted labels, status tones, focus and action contrast | Light and dark contrast, persistence, and first-paint theme checks |
| Zoom and reflow | Compact cards and local table patterns avoid page-level two-way scrolling | 320-pixel viewport and 200%-equivalent reflow coverage |
| Understand errors and state | Errors name the failed action, keep trustworthy work, and offer a recovery control | Core-data, malformed-feed, empty-result, invalid-form, and storage-state tests |
I tested it against real ATS platforms.
I tested against Greenhouse, Lever, Ashby, Workday, SmartRecruiters, iCIMS, Workable, and generic employer forms. Autofill can prepare you, but it doesn’t pretend every ATS behaves the same, and it never auto-submits.
Browser tests cover the whole product at 390 × 844 and 320 × 720. A production smoke test after deployment found no horizontal overflow and zero page errors.
What this proves, and what it doesn’t yet.
I designed and directed this alone, with Claude Code writing the code. It shows end-to-end ownership of a working deployed system, not team leadership, and it is too early for placement or conversion numbers. The next layer measures time to decision, packet completion, reply and interview rates, and whether the daily cap cuts weak applications without cutting opportunities.
Blunt feedback made it better.
The useful feedback was blunt: the map looked bad, the India treatment was wrong, mobile felt like a squeezed desktop, and a pretty happy path was not enough.
The board isn’t the product. The product is the system that tells you what to do next.



































