Lab · shipped · July 25, 2026
Infinia Optimiser
Hypothesis
A focused, single-card rewards tool - designed in Figma before any code - can outperform generic multi-card trackers for someone who actually knows the quirks of their program.
Outcome
MVP working in under a week. Designing fully in Figma first made the Claude Code build faster and more accurate. Forcing zero recurring cost produced better architecture, not worse - on-device PDF parsing, Firebase free tier only.
HDFC Infinia rewards are powerful but genuinely hard to track manually. Rules change often - caps, categories, exclusions shift with little notice. Every “should I buy this voucher or that one” decision was manual math in my head. I built this for an audience of one: me.
The gap
Existing tools - SaveSage, Realise Club - are multi-card generalists. They made rewards tracking feel like a product, not a spreadsheet. But they’re not tuned to Infinia’s specific voucher routing, retention math, or statement format.
My actual problem was simpler and harder: I wanted to hit my Rs. 18L annual retention target without guesswork, and I wanted the tool to tell me where to route each purchase before I made it - not after.
How I approached it
Analysis first. Mapped every Infinia purchase decision that needed covering: brand vouchers (Amazon, Amazon Pay, Flipkart, others), rent, utilities. Worked through the core design gap with Claude - caps can’t be known mid-cycle from statements alone. Landed on a two-layer ledger: confirmed data from parsed statements, provisional data from in-app logging, with freshness indicators on every number so you always know what you’re looking at.
Full Figma spec before any code. Five screens: Home, Shopping, Statements, Rules, Profile. Real components, real variables, not throwaway mockups. Locked the design system name (“Obsidian Ledger”) before opening a terminal.
Engineered for zero recurring cost. Firebase Spark (free tier) only - no Blaze plan. Statement PDFs decrypted and parsed on-device via pdf.js, never uploaded to cloud storage. The parser is tuned to the exact HDFC Infinia statement layout - no LLM call needed for parsing in v0.1. Skipped a fancier extraction pipeline to keep the app genuinely free to run.
Key decisions
Visual system - Obsidian Ledger. Dark obsidian/graphite base, cyan accents, vermilion for alerts. Data-forward, with a pace sparkline as the signature element. JetBrains Mono for numbers, Google Sans Flex for labels and body. The card itself rendered as a brushed-metal card, recoloured into the Obsidian palette but true to the real Infinia card.
Home screen hero = live progress toward the Rs. 18L milestone. Fee-waiver marker at Rs. 10L sits as a waypoint on the same bar. Spend trajectory below flags “Rs. 40K BEHIND PACE” the moment it’s true - no digging required. The two-layer ledger (confirmed vs. provisional) puts freshness indicators on every number so you always know what the statement has confirmed vs. what you’ve manually logged.
The shopping router is the core of the product. Enter an amount, pick a category, get every route ranked by reward points - not just the winner. Each route shows its caveat up front (“1,933 RP of voucher headroom left this month”). “See the math” on every card: accelerated portion, base portion, fees, total value - never just a blended final number. “Log this purchase” is pinned at the end of that flow, the one moment the app asks you to confirm anything.
Privacy-first by design. Only extracted, structured data touches Firestore. The raw PDF never leaves the device. No server-side parsing, no cloud storage. “Your statements never leave this device” is the first line of copy you see on sign-in.
Stack: React (mobile web), Firebase Auth + Firestore (free tier), pdf.js for on-device decryption and parsing.
The screens

Sign in. Low-poly navy facets - same material language as the physical card. Google sign-in only, one less thing to build or secure. Trust-building copy right on the entry screen, not buried in a settings page: “Your statements never leave this device.”

Home - before your first statement. No empty dashboard, no placeholder charts. Just the card and one clear action: upload a statement. The milestone tracking has nothing to show until there’s real data behind it.

Import a statement. Tap to choose the PDF, enter the password once, and it decrypts and parses on-device. The four-step progress line - unlocking, reading, parsing, ready - makes the otherwise invisible parsing work visible while it happens.

Home, populated. Card render up top, milestone bar with the fee-waiver waypoint at Rs. 10L, spend trajectory flagging pace in real time. Everything you need to know about your year, above the fold.

Shopping - entry. Amount field and category chips. CTA stays disabled until both are set. Recent lookups underneath so a repeat check is one tap, not a re-type.

Shopping - ready. Same screen once filled in - amount entered, category selected, CTA live in cyan. No separate loading step, no modal.

Ranked routes. Every route shown, not just the winner - including what you’d lose if you picked a worse one. Cap headroom surfaced per route, not on a separate screen.

Route detail. Full breakdown: accelerated portion, base portion, fees, total value. Cap impact after this purchase, with the exact reset date. Milestone impact: does this count toward Rs. 18L, and what’s your progress after? “Log this purchase” pinned at the bottom - the one moment the app asks you to confirm anything.
What I learned
Designing fully in Figma before writing any code made the Claude Code build faster and more precise - the model had real constraints to work within, not a vague brief. Cost constraints (wanting Rs. 0 recurring spend) forced better architecture: on-device parsing is more private and more robust than a cloud pipeline. Building for an audience of one removed almost all scope-creep temptation.
Mid-cycle data gaps - not knowing your cap usage until the statement arrives - are a real UX problem, not an edge case. The two-layer ledger with freshness indicators is the most design-interesting part of the whole product.
What’s next
An optional LLM-based statement extraction path for edge cases the client-side parser can’t handle - probably a small Cloudflare Worker calling the Claude API, only if needed. Possible expansion beyond Infinia if the system proves out. Native mobile app only if mobile web starts feeling limiting.