Thoughtful games to reduce anxiety. A collection of creative, accessible web games designed for relaxation and reflection. No ads, no accounts, no distractions.
Watermelon bowling - Roll strikes with physics-based gameplay Action • Medium difficulty
Daily word puzzle - Guess words about global progress and hope Puzzle • Easy • Daily
Chat with wisdom figures - Converse with 61 historical thinkers (AI-powered) Wisdom • Easy • Therapeutic
Ethical voting game - Make tough choices and see how others voted Thought • Medium • Community
Last words reflection - Share your final message, see humanity's collective word cloud Thought • Easy • Philosophical
- Zero Friction - No accounts, no logins, just play
- Accessible First - WCAG 2.1 AA+, neurodivergent-friendly
- Anxiety Reduction - Games designed to calm, not stress
- Pixelated Aesthetic - Retro charm with modern polish
- Invisible AI - Smart experiences without "AI" labels
Built-in accessibility controls accessible via button in corner:
- Visual: Reduce motion, contrast modes (normal/high/extra-high), animation speed
- Colorblind: Deuteranopia, protanopia, tritanopia, monochrome filters
- Audio: Mute toggle, volume control
- Interaction: Pause animations on demand
- Quick Presets: Calm Mode, Focus Mode, Sensory-Friendly Mode
- Performance: 90+ Lighthouse scores, optimized builds
- Real-time Data: Supabase for live game data and community features
- Modern Stack: Next.js 15, React 19, TypeScript, Tailwind CSS v4
- Fast Deployment: Auto-deploy via Vercel on push to main
| Layer | Technology |
|---|---|
| Framework | Next.js 15.5.4 (App Router + Turbopack) |
| Runtime | Node.js v24.10.0 |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS v4 with custom CSS variables |
| Database | Supabase (PostgreSQL with RLS) |
| AI | Google Gemini 2.0 Flash (primary), OpenAI (fallback) |
| Deployment | Vercel (auto-deploy) |
| Analytics | Vercel Speed Insights |
- Node.js: v24.10.0+ (uses
.nvmrc) - npm: v11.6.0+
- Supabase: Account for database (optional for frontend-only work)
# Use correct Node version
nvm use
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Edit .env.local with your Supabase keys
# Run dev server
npm run devVisit http://localhost:3000
Create .env.local:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
# AI Services (optional - for Timeless Minds game)
GOOGLE_GEMINI_API_KEY=your_key
OPENAI_API_KEY=your_key
# Site Config
NEXT_PUBLIC_SITE_NAME=VeryGoodMelon.Fun
NEXT_PUBLIC_SITE_URL=http://localhost:3000# Production build
npm run build
# Start production server locally
npm run start
# Deploy (auto-deploys on push to main)
git push origin mainverygoodmelon.fun/
├── app/ # Next.js App Router
│ ├── games/ # Game pages
│ │ ├── bowling/ # The Striker
│ │ ├── hope-daily/ # The Optimist
│ │ ├── timeless-minds/ # The Sage
│ │ ├── hard-choices/ # The Dilemma
│ │ └── last-words/ # The Final Word
│ ├── about/ # About page
│ ├── globals.css # Global styles + accessibility CSS
│ ├── layout.tsx # Root layout with Quicksand font
│ └── page.tsx # Homepage with game cards
├── components/
│ ├── accessibility/ # Accessibility panel
│ ├── games/ # Game components
│ │ ├── Bowling.tsx
│ │ ├── HopeDaily.tsx
│ │ ├── TimelessMinds.tsx
│ │ ├── HardChoices.tsx
│ │ └── LastWords.tsx
│ └── ui/ # Reusable UI components
│ ├── Header.tsx
│ ├── Footer.tsx
│ ├── Card.tsx
│ └── AccessibilityButton.tsx
├── lib/
│ ├── games/
│ │ └── config.ts # Central game configuration (SSOT)
│ ├── hooks/
│ │ ├── useAccessibility.ts # Accessibility state management
│ │ └── useAuth.ts # Supabase auth (future)
│ ├── supabase/ # Supabase client setup
│ └── utils/ # Helper functions
├── supabase/
│ └── migrations/ # Database migrations
├── types/
│ ├── accessibility.ts # Accessibility types & presets
│ └── database.ts # Supabase generated types
├── public/
│ ├── logo.png # Pixelated watermelon logo
│ └── games/ # Game assets (card SVGs)
└── README.md # You are here
--background: #fafafa; /* Light grey */
--foreground: #1a1a1a; /* Dark text */
--primary: #2d3748; /* Charcoal */
--accent: #e63946; /* Coral red (watermelon) */
--success: #74c69d; /* Light green (rind) */
--melon-green: #1a4d2e; /* Dark green */
--card-bg: #ffffff; /* White cards */- Font: Quicksand (Google Fonts, optimized)
- Weights: 400 (normal), 500 (medium), 600 (semibold), 700 (bold)
- Line Height: 1.6 for readability
- Pixelated Aesthetic: Crisp pixel art via
image-rendering: pixelated - Minimal UI: Every element has meaning
- Fast Transitions: 75ms for snappy feel
- Generous Spacing: Never cramped
- Soft Shadows: Subtle depth without harshness
- WCAG 2.1 AA+ - Exceeds baseline requirements
- Keyboard Navigation - All features accessible without mouse
- Screen Readers - Semantic HTML + ARIA labels throughout
- Color Contrast - 4.5:1 minimum for text
- Focus Indicators - Clear, visible focus states
- Predictable Patterns - Consistent UI/UX
- Optional Controls - Animation, sound, motion toggles
- No Time Pressure - Play at your own pace
- Undo/Reset - Always available
- Simple Instructions - Clear, direct language
- Calm Sensory Experience - No flashing, loud sounds, or jarring effects
Before shipping features:
- Keyboard-only navigation works
- Screen reader announces content correctly
- Reduced motion preference respected
- Mobile tested (iOS Safari + Android Chrome)
- Lighthouse accessibility score 90+
Ask these questions FIRST:
- ❓ Will users feel less anxious after playing?
- ❓ Will they smile, relax, or feel it was worth their time?
- ❓ Does it add genuine value (relaxation, growth, motivation)?
- ❓ Will they return naturally, not compulsively?
- ❓ More than a clone with different graphics?
- ❓ What's the unique twist?
- ❓ What value does it add to the world?
- ❓ Keyboard-only playable?
- ❓ Screen reader compatible?
- ❓ Sensory controls included?
- ❓ No timing requirements?
If ANY answer is "no" → Don't build it or fix it first.
-
Create migration (if database needed):
# Create migration file supabase migration new game_name_schema # Apply migration supabase db push # Regenerate types supabase gen types typescript --project-id PROJECT_ID > types/database.ts
-
Create game card SVG:
- Size: 1024x1792 (playing card aspect ratio)
- Style: Pixelated/minimalist matching logo
- Save to:
public/games/game-slug/card.svg
-
Create game page:
mkdir -p app/games/game-slug # Create page.tsx with metadata -
Create game component:
# Add to components/games/GameName.tsx -
Add to config:
// lib/games/config.ts { id: 'game-id', slug: 'game-slug', title: 'The Game Title', description: 'Short description', cardImage: '/games/game-slug/card.svg', difficulty: 'easy' | 'medium' | 'hard', category: 'Action' | 'Puzzle' | 'Wisdom' | 'Thought' | 'Creative', accentColor: 'accent' | 'success' | 'warning' | 'purple', isShowcase: true, tags: ['tag1', 'tag2'], order: 6, }
-
Test thoroughly:
- Keyboard navigation
- Screen reader
- Mobile devices
- Accessibility panel interactions
- Build succeeds:
npm run build
Stores user submissions for The Final Word game:
CREATE TABLE last_words (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
words TEXT NOT NULL CHECK (char_length(words) <= 500),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);Daily word puzzles and commentary for The Optimist.
Chat history for The Sage game.
Voting data for The Dilemma game.
All tables have RLS enabled:
- Read: Anyone can read
- Insert: Anyone can insert (anonymous submissions)
- Update/Delete: Restricted or disabled
# Clear Next.js cache
rm -rf .next && npm run dev# Regenerate Supabase types
supabase gen types typescript --project-id ihaqvdcckjccxhfabgwd > types/database.tsThis is a known Turbopack bug with Google Fonts. Build with webpack works fine:
npm run build # Uses webpack, fonts work correctly# List migrations
supabase db list
# Push migrations to prod
supabase db push
# Reset local dev database
supabase db reset- Performance: 90+
- Accessibility: 95+
- Best Practices: 95+
- SEO: 100
- Image Optimization: Next.js Image component with priority loading
- Font Optimization: Google Fonts with
font-display: swap - Code Splitting: Automatic route-based splitting
- CSS Extraction: Tailwind v4 with minimal output
- Static Generation: Pre-rendered pages where possible
This is a personal project, but if you have ideas:
- Open an issue for discussion
- Fork & PR for small fixes
- Follow the design philosophy (see
.claude/CLAUDE.md)
- TypeScript strict mode
- ESLint + Prettier
- Semantic HTML
- Accessibility-first
- Comments explain "why", not "what"
MIT License - See LICENSE file
- Inspired by: neal.fun - for proving simple web games can be profound
- Design Philosophy: Minimal, accessible, thoughtful
- Built by: Shakeel Bhamani
- Logo: Pixelated watermelon with Palestinian flag colors
- Live Site: verygoodmelon.fun
- GitHub: shaktech786/verygoodmelon.fun
- LinkedIn: shakeelbhamani
- Website: shak-tech.com
Made with purpose. Every pixel has meaning. 🍉