Guess the word. Then guess five more. Stay frosty. ๐ง
brrrdle is a mobile-first, accessible, production-minded word game that blends two beloved formats:
ogmode โ classic single-puzzle, Wordle-style play.gomode โ chained five-puzzle, Hurdle-style play where solved answers pre-fill carry-over rows into the next puzzle.
It ships with guest progress, optional cloud accounts, post-game definitions, emoji sharing, an in-app economy, and Progressive Web App foundations โ all wrapped in a dark-first UI with icy brrr accents.
Project status: v1 launch scope plus approved addenda through Phase 18 (answer-difficulty tiers, Word Explorer / Go / Settings polish, and the daily-overlap fix) are implemented; Phase 19 (enhanced statistics visualizations, a configurable Go puzzle count, full resume-most-recent-game activation, advanced polish, and a light theming foundation) is planned and awaiting approval. Production deployment requires explicit release approval after PR review โ do not trigger a production deploy without it.
- ๐ฉ Exact Wordle tile coloring, including correct duplicate-letter accounting, from a single canonical source of truth.
- ๐
gochained sessions of five puzzles with carry-over pre-fills between rounds. - ๐ง Hard Mode for
ogandgo, in both daily and practice contexts. - ๐ Daily puzzles fixed at 5 letters; Practice supports word lengths 2 through 35.
- โจ๏ธ Physical keyboard + on-screen keyboard input with clear loading, empty, error, and invalid-guess states.
- โญ XP, levels, and coins earned through play.
- ๐ Consumables โ Reveal One Letter and Remove Incorrect Letters.
- ๐ธ Pay-to-Continue in daily and practice, scaled by word length and completion.
- ๐ Per-mode statistics (
ogvsgo) tracked from day one.
- ๐ Local curated word lists for every length 2โ35 (hundreds of thousands of real English words).
- ๐๏ธ Answer-difficulty tiers (Casual / Standard / Expert) that subset the answer pool only โ valid guesses stay identical across tiers.
- ๐ Post-game definitions with a graceful lookup chain: bundled data โ Dictionary API โ Wiktionary โ an always-available Search Google button.
- ๐งญ Word Explorer tab for browsing and inspecting the dictionary.
- ๐ค Guest play with full local progress, coins, levels, stats, settings, and history.
- โ๏ธ Optional Supabase accounts with email verification, cloud sync, and a guest-to-account transfer prompt.
- ๐ฆ๐จโฌ Classic emoji sharing generated from canonical tile states.
- ๐ Ranked Practice Multiplayer with a transparent Elo model documented in
docs/ranked-multiplayer.md. - ๐ฑ PWA shell with offline caching where reasonable.
- ๐ Toggleable sound effects and a Feedback tab.
- ๐ก๏ธ Protected admin route (
/api/admin-refresh) for word-list refresh, gated by Supabase auth + anadminrole.
- Faithful, not fragile. Tile coloring, Hard Mode, and sharing all consume one canonical engine โ never re-implemented per surface.
- Accessible by default. Targets WCAG AA: semantic controls, visible focus, keyboard-only navigation, reduced-motion support, and readable contrast.
- Offline-friendly data. Word lists are bundled locally, so daily play stays fast and resilient.
- Governed & auditable. Every change follows a written constitution, a phased plan, and per-phase progress reports.
# 1. Install dependencies from the lockfile (reproducible)
npm ci
# 2. Start the dev server
npm run devThen open the printed local URL (Vite defaults to http://localhost:5173).
Use
npm installonly when you intentionally change dependencies; otherwise prefernpm ci.
cp .env.example .env.local
# then fill in your public Supabase project URL + anon key (see "Environment variables" below)Guest mode is fully playable without any Supabase configuration.
| Layer | Technology |
|---|---|
| UI framework | React 19 + TypeScript |
| Build tooling | Vite 8 (@vitejs/plugin-react) |
| Styling | Tailwind CSS v4 (@tailwindcss/vite) |
| Testing | Vitest |
| Linting | ESLint + typescript-eslint + React Hooks/Refresh plugins |
| Accounts / sync | Supabase (@supabase/supabase-js) |
| Hosting (game) | Vercel (serverless API routes + cron) |
| Hosting (docs) | GitHub Pages + Jekyll (docs/) |
| PWA | Service worker + web manifest |
| Script | Description |
|---|---|
npm run dev |
Start the Vite dev server with HMR. |
npm run build |
Type-check (tsc -b) and produce the production bundle in dist/. |
npm run preview |
Serve the built dist/ locally to smoke-check production output. |
npm run test |
Run the Vitest unit-test suite once. |
npm run lint |
Lint the project with ESLint. |
npm run lint
npm run test
npm run build
npx tsc -p tsconfig.api.json --noEmit # type-check the serverless API projectCopy .env.example to .env.local and provide public Supabase values only:
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-public-anon-key
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_ANON_KEY=your-public-anon-keyVITE_*values are public and shipped in the browser bundle โ use only the public project URL and anon key.SUPABASE_URL/SUPABASE_ANON_KEYare server-side aliases used by/api/admin-refresh; they should point to the same public URL and anon key.- Never commit secrets, service-role keys, JWT signing secrets, database passwords, or any privileged credentials.
See docs/supabase.md for schema, Row-Level Security, account sync, and admin-role guidance. The browser client uses only the public project URL and anon key; admin roles must be assigned through a secure Supabase dashboard or server-side process โ never from browser code.
The protected refresh endpoint is POST /api/admin-refresh. It requires a Supabase bearer token for a user whose app_metadata.role is admin (or whose app_metadata.roles contains admin):
| Caller | Response |
|---|---|
| Unauthenticated | 401 |
| Authenticated, non-admin | 403 |
| Authenticated admin | Refresh acknowledgement |
- Game: Vercel, using
npm run buildand thedist/output configured invercel.json. - Blog / docs: GitHub Pages + Jekyll from
docs/.
See docs/deployment.md for deployment and verification checklists (environment-variable warnings, PWA asset checks, and production smoke checks).
brrrdle registers a service worker and ships a web manifest so it can be installed and remain usable offline where reasonable. Word-list handling is optimized so daily mode loads quickly and gameplay stays smooth.
brrrdle/
โโโ api/ # Vercel serverless functions and server-only helpers
โ โโโ _lib/ # Word-list persistence adapters (Vercel Blob)
โ โโโ cron/ # Scheduled word-list refresh endpoint
โ โโโ word-lists/ # Public word-list manifest endpoint
โ โโโ admin-refresh.ts # Protected admin refresh route
โโโ docs/ # GitHub Pages / Jekyll documentation site
โโโ progress/ # Phase progress CSV, template, and step reports
โโโ public/ # Static PWA assets, icons, manifest, service worker
โโโ src/ # React application and shared TypeScript modules
โ โโโ account/ # Supabase auth, guest storage, sync, settings UI
โ โโโ admin/ # Admin authorization helpers and admin panel
โ โโโ app/ # App shell, routing, navigation
โ โ โโโ games/ # Playable og/go route panels
โ โโโ data/ # Word-list loading, validation, refresh, cache, daily selection
โ โ โโโ bundled/ # Historical bundled fallback word-list seed
โ โโโ definitions/ # Post-game definition lookup and rendering
โ โโโ feedback/ # Feedback tab UI
โ โโโ game/ # UI-independent game engine and gameplay helpers
โ โ โโโ go/ # Go-mode session state logic
โ โ โโโ input/ # Keyboard normalization and input hook
โ โ โโโ og/ # Og-mode session state logic
โ โ โโโ storage/ # Daily in-progress session local-storage helpers
โ โโโ latest/ # Local curated per-length word-list JSONs (lengths 2โ35)
โ โโโ lib/ # Cross-feature, non-game-specific utilities
โ โโโ progression/ # XP, levels, coins, consumables, Pay-to-Continue
โ โโโ pwa/ # Service worker registration
โ โโโ sound/ # Toggleable Web Audio sound effects
โ โโโ stats/ # Statistics model and dashboard UI
โ โโโ test/ # Shared test helpers and testing docs
โ โโโ types/ # Shared ambient/type-only declarations
โ โโโ ui/ # Reusable UI primitives and layout controls
โ โโโ wordExplorer/ # Word Explorer data helpers and tab UI
โโโ supabase/ # Supabase migrations and setup assets
โโโ .env.example # Placeholder environment-variable documentation
โโโ eslint.config.js # ESLint configuration
โโโ index.html # Vite HTML entry point
โโโ package.json # npm scripts and dependency manifest
โโโ tsconfig*.json # TypeScript project references and compiler configs
โโโ vercel.json # Vercel build and cron configuration
โโโ vite.config.ts # Vite + React + Tailwind configuration
brrrdle is built under a strict, written governance model. When in doubt, these documents win โ in this order:
CONSTITUTION.mdโ binding rules for scope, review gates, verification, security, and conduct.BRRRDLE-SPEC.mdโ the product specification.BRRRDLE-OVERVIEW.mdโ the approved project plan.AGENT-IMPLEMENTATION-PLAN.mdโ root shim for the active lightweight plan and the archived full historical plan.CHANGELOG.mdโ root shim for historical and Phase 24 changelog locations.planning/โ current planning hub, specs, history, and testing strategy.progress/โ per-phase progress reports andPROGRESS.csv.
The agent workflow is model-agnostic โ any sufficiently capable coding model (e.g., Claude Opus 4.8) can drive it.
This project follows a phase-gated, verification-first workflow:
- Read the governance docs first โ
CONSTITUTION.md, thenBRRRDLE-SPEC.md, thenAGENT-IMPLEMENTATION-PLAN.mdand the relevant planning files it links to. - Make small, cohesive, reviewable changes tied to the current phase. Avoid speculative refactors and out-of-scope features.
- Preserve canonical logic โ never duplicate tile-coloring or Hard Mode rules; consume the shared engine.
- Verify before you finish โ run
npm run lint,npm run test,npm run build, andnpx tsc -p tsconfig.api.json --noEmit. - Never weaken or remove tests to make a phase pass, and never commit secrets.
- Update the changelog and progress artifacts when a phase requires it, then halt for review at the relevant gate.
- Accessibility: WCAG AA targets โ semantic controls, visible focus, keyboard-only navigation, dialog accessibility, status announcements, readable contrast, and reduced-motion support.
- Security: no committed secrets; no service-role privileges in browser code; Row-Level Security for user data; server-side admin authorization; imported word/definition data treated as untrusted; safe external-link behavior for new tabs.
Built with โ๏ธ and care. Stay frosty.