A swipe-based English vocabulary game. Shows a word and a definition — swipe right if they match, left if they don't. 20 questions, 15 seconds each, 10 points per correct answer.
This repository contains two things: a component design system (Storybook) and an interactive prototype (Vite app) that runs the full game loop in a mobile phone frame in the browser.
| URL | |
|---|---|
| Prototype | https://lexify-prototype.netlify.app |
| Storybook | https://lexify-storybook.netlify.app |
npm installnpm run devOpens at http://localhost:5173. Shows the full game flow — Home → How to Play → Game → Result — inside a rendered iPhone frame. Supports drag, touch, and keyboard (← →) input.
npm run storybookOpens at http://localhost:6006. Documents brand tokens, components, and all screens as isolated stories inside a mobile frame.
src/
tokens/
tokens.css # CSS custom properties — colors, type, spacing, motion
components/
Button/ # Primary, ghost variants
Badge/ # Status chips
Logo/ # App icon mark
MobileFrame/ # iPhone mockup used in Storybook
ProgressBar/ # Round progress bar
StatCard/ # Score stat card
SwipeCard/ # Draggable vocabulary card component
prototype/
App.jsx # Screen router + localStorage persistence
prototype.css # All prototype styles
hooks/
useGame.js # Game state — questions, score, answers, timer logic
screens/
HomeScreen.jsx
HowToPlayScreen.jsx
GameScreen.jsx # Drag/touch/keyboard input + 15s timer
ResultScreen.jsx
data/
words.js # 32 bundled vocabulary words
stories/
00-Brand.stories.jsx
01-Colors.stories.jsx
02-Typography.stories.jsx
03-Button.stories.jsx
04-Badge.stories.jsx
05-ProgressBar.stories.jsx
06-SwipeCard.stories.jsx
07-Screen-Home.stories.jsx
08-Screen-HowToPlay.stories.jsx
09-Screen-Game.stories.jsx
10-Screen-Result.stories.jsx
docs/
design.md # Full product and design brief
- 20 questions per round, drawn from 32 bundled words
- 50 / 50 split between correct-match and mismatch questions, shuffled each round
- Swipe right = "this definition matches the word"
- Swipe left = "this definition does not match"
- +10 points for each correct answer — max score 200
- 15-second timer per question — auto-submits wrong if it expires
- Best score and last score persist in
localStorage
| Layer | Choice |
|---|---|
| Framework | React 19 |
| Bundler | Vite 5 |
| Design system docs | Storybook 8 |
| Styling | CSS custom properties (no framework) |
| Fonts | Space Grotesk (display) + Inter (body) via Google Fonts |
| Persistence | localStorage |
| State | React hooks only (useGame, useState, useEffect) |
| No backend | fully offline, no auth, no API calls |
All visual constants live in src/tokens/tokens.css as CSS custom properties and are shared between the prototype and Storybook.
Key values:
| Token | Value |
|---|---|
--color-bg |
#0C0C16 |
--color-primary |
#7C6FFC |
--color-success |
#34D399 |
--color-error |
#F87171 |
--font-display |
Space Grotesk 800 |
--font-body |
Inter |