# afrix-mobile

The AfriX **design canvas** — 27 artboards on one pan/zoom surface, generated
from the same token system the web front end ships.

**This repository is not an application.** There is no React Native, Flutter,
Android or iOS project here, and nothing in it compiles to a phone. It is the
design deliverable that the mobile app would be built *from*, and it is kept in
a repository because it is generated by scripts that deserve review and history
like any other source.

The running front end is [`web-frontend`](https://africaone.dev/afrix1/web-frontend).

## What is in here

| Path | What it is |
| --- | --- |
| `build.py` | Generates every `.dc.html` artboard from one shared token block. The design system lives here, not in the output. |
| `reseed.py` | Folds the artboards and `canvas.json` back into the published canvas file, reporting what changed. |
| `*.dc.html` | 27 artboards — 21 mobile at 390×844, 6 web at 1440×1024, 768×1024 and 390×844. Generated; do not hand-edit. |
| `canvas.json` | Artboard positions on the canvas. Edited by hand. |
| `afrix-mobile-concept.html` | The published canvas: the editor and the whole design in one file. Generated by `reseed.py`. |
| `img/` | Five portraits with `credits.json` naming photographer and licence for each. |
| `fetch_portraits.py` | Refetches those portraits from Unsplash. Reads an access key from `.unsplash-key` or `$UNSPLASH_ACCESS_KEY`, and never prints it. The key is not in this repository and must not be. |

## Rebuilding

```
python3 build.py && python3 reseed.py
```

`build.py` writes the artboards; `reseed.py` folds them into
`afrix-mobile-concept.html`. Run both — an artboard regenerated without the
reseed leaves the published canvas showing the previous design, which is the
one way this pair fails quietly.

Open `afrix-mobile-concept.html` in a browser to view the canvas, or any single
`.dc.html` to check one artboard in isolation at its real pixel size.

## The design it carries

Screens: feed, feed composing in place, compose, the take in progress, the two
microphone-unavailable states, post detail, thread, profile, explore, search,
notifications, messages, stories, the story viewer, settings, sign-in, sign-up,
and three state studies — skeleton, offline with a queued post, and data-saver.
Plus the Arabic feed at `dir="rtl"`, which is a screen rather than a note
because the one thing that must **not** mirror is the continent glyph.

Six web artboards carry the same product at 1440, 768 and 390, where the web
app becomes the mobile shell exactly.

Both concepts are held against the specification, which is the authority when
they disagree:

- **Concept spec v4.2** — decisions, tokens, contracts, per-screen definition of done
- **Build plan** — how the front end is built from it, and what CI refuses

## Conventions worth knowing before editing `build.py`

- **The continent glyph is a 7×8 ASCII map**, not a bitmask. 56 cells overflow
  the 32 bits JavaScript's bitwise operators use, so `1 << 55` is silently
  wrong. The shape is written where it can be read and corrected.
- **`%` is doubled in any string passed through `%`-formatting** and left
  single in any string that is not. Both directions have shipped bugs here;
  `width:100%%` in an unformatted template reached the CSS literally.
- **A `str.replace` whose anchor does not exist does nothing and raises
  nothing.** Every edit to a generated file should be grepped afterwards to
  prove it landed. This is the single most common defect in this repository's
  history.
