Every Arabic word grows from a three-letter root (جذر) poured into a pattern (وزن). Wazn shows a learner that structure instead of asking them to memorise past it.
React · Vite · FastAPI · K2 Think
Search عَامِل (ʿāmil, "worker") and Wazn takes it apart:
- Root — ع م ل, the idea of work
- Pattern — فَاعِل, the active participle: the one doing the root action
- So — one who works → worker
That same root in other patterns gives مَعْمَل (factory), مُسْتَعْمِل (consumer), اِسْتِعْمَال (use), عَمَل (job). Wazn draws them as one tree, because that is what they are: one family, one root.
Learn the root and the pattern, and you haven't learned one word — you've learned the shape of dozens.
The morphology is verifiable, not generated. The tree, the letter-by-letter breakdown, and the word family all come from a hand-curated knowledge base. GET /api/analyze runs no language model — every response carries "source": "deterministic" and a trace of how it got there. A learner is never shown a hallucinated root.
The model earns its place elsewhere. On a separate /api/insights endpoint, K2 Think writes the explanation, the practice questions, and an example sentence — then a guardrail agent checks that output back against the knowledge base before it's shown. Every K2 step falls back to a template if it fails.
Splitting the endpoints is the point: the trustworthy path stays fast, and the generative path can take its time.
Click any leaf and the companion panel follows it. Three tabs.
![]() |
![]() |
| Quiz. Recall the family from the root alone, with the tree's labels hidden. | Insights. Which module found the word, which agent wrote the explanation, whether the grounding checks passed. |
Start the backend first, then launch the frontend in a separate terminal. Requires Python ≥ 3.10.
cd backend && pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000cd frontend && npm install
npm run devOpen http://localhost:5173 and search عامل.
CORS errors in the browser mean your frontend origin is missing from the allowlist in backend/app/main.py.
search ──▶ GET /api/analyze ──▶ deterministic, no LLM
lookup · morphology · tree · quiz · guardrail
Insights ─▶ GET /api/insights ─▶ K2 Think, with fallbacks
explanation · quiz · sentence · guardrail · evaluation
backend/ is FastAPI: content is plain JSON in data/, loaded once at startup — no database. frontend/ is React + Vite: two views, no router, and a numbered CSS cascade where the order is load-bearing.




