A physical-world arbitrage problem
Professional card grading is a real economic decision wrapped in a slow, analogue process: pay a fee, wait weeks, and find out whether the card was worth submitting at all. PokeGrade is built around that decision for Pokémon cards specifically. Submit a card that comes back lower than expected and the grading fee is a straight loss, sometimes worse, since a low grade can mark a card down against its raw value. That's a computer-vision and judgement problem before it's anything else, and I wanted to see how far you could get automating the first call: is this card worth the cost of grading.

The output is a decision, not a number: submit, check in hand, or skip, with the limiting pillar named and the confidence stated.
What it measures, and what it doesn't
PokeGrade splits card condition into two categories that get treated very differently.

Centring is a hard pillar: it can be measured directly and deterministically from a photo, so the app does exactly that, no model judgement involved.

Surface, edges and corners are soft pillars. They resist a clean measurement and need a human-style judgement call, so PokeGrade hands them to a Claude Opus 4.8 adjudicator instead of pretending a formula can substitute for an eye.
Every grading call runs through an EV/verdict ledger, so the reasoning behind a grade is traceable, not just the output. That's the difference between a tool that estimates a grade and one that actually supports a submit-or-skip decision.

When the photo can't settle a pillar, the app says so and hands you a targeted in-hand checklist instead, with the expected-value maths laid out beside it.
The rule that matters most
A single flat photo cannot support a confident top grade, so PokeGrade is built to refuse one. It will not hand out a 10 on the strength of one image, no matter how clean the card looks. Knowing when a system should decline to answer turned out to be a harder and more useful design problem than getting the easy calls right, and it's the decision that actually makes the arbitrage call trustworthy. A tool that always gives you a number is easy to build and easy to be misled by.
Status
Live, tested against 71 cases, grading real submissions.
Stack
Next.js frontend, local FastAPI engine, Claude Opus 4.8 for the judgement calls.