Case study
Scam Shield
A fraud check for small shop owners, built in two weeks for the Google Cloud AI Builder Cup: paste a conversation or a payment-slip screenshot and get a STOP, VERIFY or SAFE verdict, the reasons, and what to do next.

At a glance
- Role
- UI/UX designer and front-end engineer
- Status
- Shipped on time and live on Google Cloud Run, submitted to the Google Cloud AI Builder Cup 2026
- Platform
- Mobile-first web app, deployed on Google Cloud Run
- Tools
- Figma · Claude Code · VS Code · Git
- Tech stack
- Next.js 16 (static export) · React 19 · TypeScript · FastAPI · Python · Gemini 2.5 Flash on Vertex AI · Google Cloud Run
Design system
Calm pastel trust-blue with navy text, and red, amber and green used strictly as verdict colors, measured for contrast rather than claimed for the system as a whole.
Stop Red
#9E2828
Stop verdict text, on #FFF1F1
Verify Amber
#805200
Verify verdict text, on #FFF6DF
Safe Green
#17613F
Safe verdict text, on #EAF7EF
Action Blue
#416D9F
Primary buttons and links
Primary Text
#142B49
Headings and body text, on white
Typography
Inter
- Display
- 700 · 32/40px — page title
- Title
- 700 · 22/30px — verdict word, section titles
- Heading
- 600 · 18/26px — card titles
- Body
- 400 · 18/28px
- Body Small
- 400 · 16/24px — secondary body
- Label
- 600 · 16/24px — field labels
- Caption
- 400 · 14/20px — hints, metadata
- Overline
- 600 · 13/18px — tags
Components

VerdictCard

Button

Field
Sections
Section 1
The Problem
Shop owners have seconds to decide whether to hand over goods or money, and scammers change tactics every time they're refused. Small merchants get fake payment slips, spoofed bank texts, phishing links, refund tricks and "customer" enquiries that push risky files, with no security team and a customer waiting at the counter. The project was shaped by a real case: a cake business was messaged on LinkedIn with a link to a fake meeting page, and when the owner refused to download it and asked to move to WhatsApp, the attacker switched approach and sent a disguised file with a two-hour payment deadline. A checker that reads one message at a time misses that kind of pattern; the owner doesn't need a threat report, she needs one word, the reasons, and what to do next. Existing checkers such as ARKA ScamCheck and Trend Micro ScamCheck are built for everyday consumers; Scam Shield is built for the merchant deciding whether to release goods or pay.
Section 2
Approach
Built the front end and the whole design system in two weeks for the Google Cloud AI Builder Cup 2026, working alongside Sumala, who built the backend, security and evaluation. I owned everything the shop owner sees.
- 7 design-system boards in Figma: colour palette, typography, spacing and large controls, surfaces and accessibility, a component library of native Figma components, and composed examples.
- 22 screen designs across 11 flows, each at 1440px desktop and 390px mobile: the check screen in its empty, filled-thread and image-only states, checking, the STOP/VERIFY/SAFE results, a long-thread STOP result, Your records, and two boards of supporting states for waiting, validation and service recovery.
- Every screen designed mobile-first, for someone standing at a counter with a phone in one hand: plain language instead of jargon like VBS or punycode, colour never used alone (every verdict pairs its colour with a word and an icon), calm pale-blue surfaces with red, amber and green kept strictly for verdicts, and room for longer Sinhala text to wrap instead of being cut off.
- Shipped the front end myself as a Next.js app built to static files and served by the FastAPI backend from the same Cloud Run container, plus the slides and the under-3-minute demo video for submission.
Section 3
Key Design Decisions
The result screen had to be understood in about three seconds, and four decisions did most of that work.
- SAFE never means "genuine." The system can only find red flags, not prove a slip or sender is real, so the best result reads "No red flags found" and tells the owner to confirm the payment in their banking app, and a payment-slip image always carries a note that a slip is not proof money arrived.
- Show what we saw and what to look for. The verdict is set in code; Gemini only adds limited evidence and writes the explanation, and that only builds trust if people can see it — every finding card shows where it came from (a known scam pattern, the shop's own records, a pattern across the conversation, or "AI noticed"), its severity, and an Observed/Expected pair in plain words. AI-only findings are labelled tentative and written as a clue, never as proof.
- Build a conversation, not a single message. The key signal is escalation, so the check screen builds an ordered thread of up to 20 items with a From them/From me toggle, and the owner's own replies let the system notice they pushed harder after you said no, which surfaces as a banner on the result.
- A check that can't finish never becomes SAFE. Image checks can take over a minute, so waiting is a designed screen that says what to avoid, not a spinner on a button, and network errors, rate limits, a missing business profile, a rejected image and a fallback explanation each get their own state, always saying plainly that no verdict was returned and keeping the thread so the owner can retry without rebuilding it.
Section 4
How It Works
Scam Shield combines fixed security rules, knowledge of the shop's own business, and Gemini. The verdict is decided in code, so it comes with evidence rather than a guess.
- A screenshot or payment slip is read into facts first (type, amount, date, reference, what it's asking the reader to do); Gemini only reads at this step, it never judges.
- Deterministic rules check lookalike and shortened links, risky or disguised file names, fake installers, urgency paired with a payment request, untraceable payment methods, advance fees, sign-in lures and payment-slip arithmetic.
- The message is compared against the shop's own suppliers' known domains, phones, bank accounts, normal amounts and usual channels, so a "we changed our bank account" message is judged against the shop's own history, not just against known scam patterns.
- A Gemini analyst reads the whole conversation for tactics no rule knows, but every finding must quote the conversation exactly, and code discards any finding whose quote isn't really there.
- One evidence-correlation engine tracks escalation across the thread, scores every piece of evidence, and sets the verdict: STOP needs a critical finding or a score of 60 or more together with at least one rule or business-context finding, VERIFY covers a score of 25 to 59 or any single high-severity rule, and SAFE means nothing was found.
- AI-only evidence is capped at 30 points, can lift a result to VERIFY at most, and can never lower a verdict or remove a finding. Gemini then writes the plain-English explanation, but never for a SAFE result, and a fixed template takes over if it fails its guardrails or times out.
Section 5
Front-End Build
The front end is a Next.js app exported to static files and served by the FastAPI backend from the same Cloud Run container, so there's one deployment and no cross-origin setup. The browser sends the whole conversation with every check, and the server stores nothing between requests.
- The UI never computes a verdict: it shows exactly the state the backend returns.
- Figma variables map one-to-one to CSS variables in tokens.css, including the three verdict colours and five severity levels.
- Static-export limits shaped the whole build: no API routes, server actions or dynamic result routes, so results live in client state, and trailingSlash stays on so reloading a route like /check still works.
- Images are checked in the browser first, with type, size and HEIC handled before upload and a clear message for each problem, and requests get a 120-second timeout since a multi-image check can take over a minute, with the thread surviving errors and reloads.
- labels.ts keeps the vocabulary in one place, turning API values like fake_page into words an owner actually understands.
- Code is organised by job: components/ for the UI parts (VerdictCard, EvidenceCard, ActionsList, ImageReadCard, SupplierCard), features/ for the check, result and records screens, and lib/ for the API client, thread building and image handling.
Section 6
Components & Accessibility
Controls are at least 60px tall, focus is a 3px ring with a 3px offset, and contrast was measured for each exact colour pair rather than claimed for the system as a whole (exact hex values are in the design system above).
- STOP: 6.85:1 contrast, "Do not open, click or pay."
- VERIFY: 6.24:1 contrast, "Check before you act."
- SAFE: 6.76:1 contrast, "No red flags found."
- Core pairs: primary text at 14.27:1 on white, secondary text at 7.29:1, and white on the action blue at 5.37:1.
- The component library covers buttons, text inputs, the conversation input with its direction toggle, image upload, verdict banners, evidence items tagged Rule or AI, tool-check rows, escalation and fallback banners, supplier cards and surfaces, every one a native Figma component with variants.
Section 7
Testing & Outcome
Scam Shield shipped on time and is live on Cloud Run. Results are from the live evaluation on 10 October 2026: 88 synthetic messages, part of them written by a teammate who never read the rules, split into a dev half used to find and fix problems and a holdout half never looked at while fixing.
- Caught 17 of 20 scams on the held-out half, up from 12 to 13 of 20 on the first deployed version, an improvement made using only the dev half, which suggests the fixes generalised rather than memorised the test set.
- 1 of 7 harmless-but-pushy messages were wrongly flagged on the held-out half.
- Median time per text check was 5.0 seconds (95th percentile 6.6s) with Gemini 2.5 Flash and thinking disabled; a harmless message typically returned in about 2 seconds. Gemini 3.8 Flash was tried too, but a one-word request took 11 to 14 seconds in testing, too slow for a counter-top check.
- These are small samples, so a difference of one or two cases is within normal variation, and the tool finds red flags only: it can't confirm that anything is genuine.
- Built in two weeks, 4 to 18 October 2026: wireframes and the design system first, then the front-end plan written against the live backend with every result state designed before building, then the Next.js build connected to the live API, then the deck and demo video for the 18 October submission deadline.
- Next: test with real shop owners on their own phones, support Sinhala at scale, and read document content safely, which the prototype deliberately doesn't do yet.
Links
More projects

Sri Charge
A design-led EV charging & booking platform for Sri Lanka, built to end the queue.

Kandy 1st Court
A full-stack booking platform for Sri Lanka's first dedicated pickleball court, built end-to-end by directing Claude Code, not by hand-coding or blind-accepting it.

This Portfolio
This very site: a personal portfolio designed and built end-to-end with Claude Code assisting, one real feature at a time.

MUNE TASKS
A local-first AI project planner that turns a description into a phased, trackable to-do list in about 20 seconds.

MUNE Splits
A local-first expense splitter that works out who owes whom in the fewest possible payments.

MUNE UX
A local-first UX-to-dev pipeline that takes a vague idea through 17 guided stages to a shipped release, and traces every task back to a real user need.