# Levantry
Hebrew + Levantine Arabic flashcards, at levantry.app.
A private, offline-first, mobile-first flashcard app for drilling **Hebrew and
Levantine Arabic at the same time**. A card only counts as correct when both
languages are recalled correctly.
Built as an installable PWA: React + TypeScript + Vite, IndexedDB via Dexie,
Zustand for state, Framer Motion for the card gestures.
## Running it
```bash
npm install
npm run dev # development server
npm run build # production build into dist/
npm run preview # serve the production build
npm test # unit tests for the study engine and validation
npm run serve # build, then serve the app and the sync server together
```
### Putting it on your phone
`npm run build`, serve `dist/` over HTTPS (or `
localhost`), open it in
Chrome on Android and choose **Add to home screen**. After the first load it
works with no network: cards, progress, statistics and device voices are all
local.
## Syncing the phone with the laptop
The app is still local-first: every device studies from its own IndexedDB and
works with no network at all. Sync is an optional extra that lets two devices
agree, and it runs on your own machine — there is no cloud account.
On the laptop:
```bash
npm run serve
```
That builds the app and starts the sync server, which serves both the app and
the API from one address. It prints a token and the addresses it is reachable
on:
```text
token 3f9c… Say the following in everyday spoken Palestinian Levantine Arabic, in the
> accent of a native speaker from Jerusalem…
That instruction is `GEMINI_ARABIC_STYLE`, and it counts as part of the voice:
editing it re-records every Arabic clip. A Modern Standard Arabic voice is
never asked for, and the vocabulary itself is never rewritten towards MSA.
The Azure path is shelved rather than removed — `ARABIC_TTS_PROVIDER=azure`
brings it back, which is how the two accents get compared. Every voice is set
through the en …