Skip to content
ع
All projects

Ma'an

A private space for couples, played on one phone or two.

Ma'an: A private space for couples, played on one phone or two.
Role
Solo: product and engineering
Year
2026
Status
Live
Category
Web

An Arabic, adults-only site for married couples with illustrated guides and games: challenge cards, a choice wheel, a desire match, and a paced evening path. Each partner sets limits in secret and only what both accept is shown. No accounts.

Overview

Ma'an is built around one rule: nothing appears unless both partners accepted it. Before the first game each partner sets their limits privately, and every card, challenge and guide is filtered against both sets before it is shown.

Couples can play on one phone, passing it between them, or link two phones with a short code and play in real time. There are no names, emails or profiles; preferences stay in the browser and shared sessions expire after 24 hours of inactivity.

Content is managed from a small admin, so new guides and challenges can be added, tagged, or hidden without touching the site.

Built with

  • Next.js 16
  • React 19
  • TypeScript
  • Convex
  • Tailwind CSS 4
  • Biome
  • node:test

Links

Challenges

One partner's limits must never reach the other

Problem

In a two-phone session each partner's no is private. If the server sent both sets of limits to both phones and filtered there, the other partner's refusals would be one devtools tab away.

Solution

Both limit sets are combined on the server in Convex, and phones only ever receive the already-filtered pool. What each phone may see is decided in a single function, so there is one place to audit instead of every query.

Real-time sessions with no accounts

Problem

Linking two phones normally means logging both people in. Here there is no account, so the session itself has to be the credential, and a guessable one would let a stranger join.

Solution

Each phone holds a random player key and every function finds the session through that key, so a wrong key gets nothing back. Invites are short-lived, and a scheduled job deletes sessions once they expire.

Results

  • Six games that run on one phone or across two in real time.
  • Only mutually accepted content is ever shown; refusals stay private.
  • No accounts, and shared session data is deleted when it expires.