Skip to content

invzfnc/save-lah

Repository files navigation

SaveLah

Malaysian youth aren't broke because they don't know how to save. They're broke because knowing isn't enough at 1am when SaverEats is one tap away. SaveLah steps in at exactly that moment — not with another budgeting dashboard, but with a behavioural pause built directly into the payment flow.

Built for the GXBank Youth Resilience Challenge, targeting university students and fresh graduates caught in the BNPL debt trap.

Live demo Pitch deck Pitch video


The Problem

Consumer debt among Malaysian youth has reached a critical threshold. BNPL usage generated RM 9.3 billion in the first half of 2025 alone, with 40% of transactions originating from users under 30. In 2024, 877 individuals under 25 were declared bankrupt. Financial literacy campaigns have not moved these numbers. The gap isn't knowledge — it's behaviour at the moment of temptation.

The Insight

Every financial wellness app assumes the problem is information. They track, categorise, visualise, and educate. But users already know they spend too much on food delivery at midnight. What they need isn't a better graph of their bad decisions after the fact — they need friction before the tap goes through.

SaveLah relocates the intervention from the post-mortem to the moment of intent.

The Solution

When a user initiates a payment that crosses a behavioural threshold — late night, over budget, third purchase in the same category today — SaveLah intercepts it before authorisation. An AI teammate calls it out in plain language, referencing their actual goal and actual numbers. The user can hold the purchase for later reflection, or proceed with full awareness. Either way, the unconscious tap becomes a conscious choice.

Every cash-in automatically routes a configurable slice to a savings goal before the user can spend it. A daily streak creates a loss-aversion anchor that makes breaking the habit feel costly. A monthly Wrapped summary makes the invisible visible.


Features

Feature What it does Why it works
Quarantine Intercepts flagged payments before the PIN screen Creates a mandatory pause between impulse and action — the gap where better decisions live
Scold Mode AI-generated callout referencing the user's real goal and real numbers Personalised friction is harder to dismiss than a generic warning
Compliment Mode AI celebration when the user resists or hits a milestone Positive reinforcement closes the behavioural loop
Auto-Save Configurable % of every cash-in routed to savings before it touches the main balance Automates the hardest part — starting — by making saving the default, not the exception
Save Streak Daily habit counter with loss-aversion mechanics Prospect theory: losing a 12-day streak hurts more than the pleasure of one skipped saving day
SaveLah Wrapped Monthly story-card summary of savings and blocked impulses Makes progress tangible and shareable — social proof for the habit
Squad Save Streak-sharing with friends Accountability compounds when it's visible to people whose opinion matters

AI Integration

SaveLah uses Google Gemini 2.5 Flash-Lite for two real-time text generation features: Scold Mode and Compliment Mode. Both run through server-side Next.js Route Handlers and stream responses as SSE.

The implementation uses a hybrid scripted-and-live architecture designed so the demo never breaks regardless of network conditions:

  1. A pre-written message renders instantly the moment quarantine fires — no loading state, no spinner
  2. The Gemini API call fires in parallel with an 8-second timeout
  3. When the first token arrives, the UI crossfades from the scripted message to the live one and shows a Live AI badge
  4. If the call fails or times out, the scripted message stays — no error, no broken experience

The prompts are constrained by safety rules: Scold Mode only references financial data (amounts, budget percentages, goal progress, time of day). It never references body, identity, lifestyle, or mental health. All framing uses "we" — SaveLah is a teammate, not a judge.


Design System

The visual language is built on a six-stop forest green palette (#0D1F12 through #DAF1DE) with a three-layer surface system (bg, bg-surface, bg-inset). All colour values are CSS custom properties so light and dark themes share a single component tree.

Typography pairs Lato for UI copy (weights 400/700/900) with DM Mono for all numeric and currency displays, creating a clear visual distinction between information and data.

The app supports both light and dark themes, detected from OS preference on first load and persisted to localStorage.


Tech Stack

Layer Choice Rationale
Framework Next.js 15, App Router, TypeScript (strict) Server components for AI route handlers, client components for state-heavy UI
Styling Tailwind CSS v3 + CSS custom properties Tailwind for layout velocity; CSS vars for theme-responsive colour without duplication
State Zustand v5 + persist middleware Minimal API, localStorage persistence, zero boilerplate for a prototype
Animation Framer Motion v11 Spring physics for sheet animations; layout animations for list mutations
AI Gemini 2.5 Flash-Lite via @google/genai Fast first token, free tier sufficient for demo, server-side only
Icons lucide-react Consistent stroke weight across the design system

Getting Started

Live demo available: https://save-lah.vercel.app

Prerequisites: Node.js 18.18 or later and a free Gemini API key from https://aistudio.google.com/apikey

npm install
cp .env.local.example .env.local   # paste your GEMINI_API_KEY
npm run dev                         # http://localhost:3000

The app opens in onboarding. After completing setup, the demo persona is pre-loaded: RM 837.50 balance, 12-day streak, food spending primed at 95% of the weekly limit, and a New Laptop savings goal at 7.8% progress.

To reset the demo to its clean initial state at any point: Settings > Reset Demo.


Demo Flow

A complete walkthrough takes under 90 seconds:

  1. Home — balance card, streak at 12 days, food guardrail bar at 95%
  2. Pay — SaverEats, RM 89, tap Authorize
  3. Quarantine fires — AI scold references the late-night timing, the food budget, and the laptop goal simultaneously
  4. Hold it for me — item parked in the Cooling Off list
  5. Resist — Compliment Mode celebrates the decision
  6. Wrapped — swipe through the April story cards

Project Structure

save-lah/
├── app/
│   ├── api/
│   │   ├── scold/route.ts        # Streaming Gemini scold endpoint
│   │   └── compliment/route.ts   # Streaming Gemini compliment endpoint
│   ├── home/                     # Dashboard
│   ├── pay/                      # Payment flow + quarantine trigger
│   ├── quarantine/               # Cooling Off list
│   ├── savings/                  # Goal progress + auto-save config
│   ├── wrapped/                  # Monthly story-card summary
│   ├── squad/                    # Social streak sharing
│   ├── settings/                 # User configuration
│   └── onboarding/               # First-run setup flow
├── components/                   # Shared UI components
├── lib/
│   ├── store.ts                  # Zustand state + actions
│   ├── anomaly.ts                # Rules-based transaction flagging
│   ├── ai-client.ts              # Client-side SSE streaming wrapper
│   ├── gemini.ts                 # Server-side Gemini client
│   ├── prompts.ts                # Scold and compliment prompt builders
│   └── fallbacks.ts              # Scripted message banks
└── types/                        # Shared TypeScript types

Team

Built for the GXBank Youth Resilience Challenge, by team Hack 'n Fly.


SaveLah is a hackathon prototype. No real banking integration. All transactions are simulated. Not affiliated with GX Bank Berhad.

All rights reserved by the team.

About

Financial knowledge is not enough, we need actual actions. SaveLah intercepts impulsive spending, using AI-powered nudges, automate saving, and habit-forming mechanics. (also a Spotify wrapped style summary!)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors