Skip to content
karim.semaan(open to work)
WorkExperienceAboutSkillsContactResume ↓
← All work
SEM BM preview
Full-stackLive2026

SEM BM

Byzantine-chant learning games

Relaunched a legacy FileMaker curriculum as a live bilingual web app: 29 playable exercises across 9 game mechanics, with every note synthesized at runtime so no audio files ship.

Echo the ChantRound 1 · Best 0

Press Begin chant to hear the melody, then echo it back.

Opens the live app.

Open live app ↗︎

SEM BM relaunches a legacy FileMaker music curriculum as a live web app for a school of ecclesiastic music. Nine game mechanics (sequence-order, link-match, interval logic, scale sight-reading, a timed Tetris mode, memory, maze, guess, reading) cover 29 exercises in 4 chapters, all built on Byzantine 7-note scale arithmetic; a seeded Fisher-Yates shuffle makes any run replayable from its recorded seed. Every tone is synthesized at runtime via the Web Audio API (sine oscillators, soft attack/release envelope, anchored on Ni = C4), so no audio files ship. Reference grids carry both Western solfege (Do/Re/Mi) and Byzantine (Ni/Pa/Vou) labels; tapping either plays the same canonical note. Accessibility is baseline, not retrofit: skip link, visible focus outlines, prefers-reduced-motion support, and aria labels sourced from the shared note-label map that also drives the English/Arabic RTL UI. Supabase Postgres with RLS, email plus Google auth, and Storage back it; guest progress persists in localStorage and max-merges with server progress. ~68 TS/TSX files (~9,900 LOC) over 12 SQL migrations.

  • Next.js 15
  • React 19
  • TypeScript
  • Tailwind CSS v4
  • Supabase
  • Web Audio API
  • Vercel
Exercises
29
Game mechanics
9
Languages
EN + Arabic (RTL)
Source
68 files · ~9,900 LOC

What I'd improve

The synth uses 12-TET piano frequencies as an explicit placeholder; authentic Byzantine intonation is the Chrysanthine 72-EDO system, so the next step is real morae-based intervals or recorded chant takes behind the same playNote API. Also open: the Chapter 2 key glyphs are programmatic placeholders pending authentic notation artwork, and guest progress is not yet back-filled into Supabase when a player signs in mid-session.

Open live↗︎
Want something like this? Get in touch →

Measured:30/30 chatbot evals·20-case Bastion eval·Serving·Calibration Lab

© 2026 Karim SemaanBuilt with Next.js, Tailwind & Supabase.LinkedIn ↗︎GitHub ↗︎