# The Sports Deal — prototypes

Static, throwaway prototypes for **The Sports Deal**, a members-only sports
transfer marketplace where clubs search professional profiles — players,
coaches, referees, agents. Arabic-first with English, Saudi market.

The prototypes exist to settle **screens, states and decisions before code**.
The real front end is a separate Next.js app using shadcn/ui on Tailwind; a
prototype answers a question, gets reviewed, gets locked, and its findings are
written back as user stories. Then it stops mattering.

## The zero-build promise

There is no build step, no bundler, no package manager, no runtime dependency.
Every prototype is plain HTML, CSS and one small vanilla script, and it must
work in both of these ways or it is broken:

1. **Double-clicked from disk** — `file://`, no server, no network.
2. **Served by Cloudflare Pages** from the repository root.

So: relative paths only, no imports that need a server, no framework, nothing
that assumes a base URL.

## Opening it

Double-click `index.html`. That is the whole story for reading and reviewing.

If you want a real origin — `fetch()` of `prototypes.json` is blocked over
`file://`, and query strings survive better — serve the repo root:

```bash
cd sports-deal-prototypes
python3 -m http.server 8080
# then open http://localhost:8080/
```

Nothing in the repo requires the server; it only removes the `file://`
restrictions.

## How Cloudflare Pages serves it

The repository deploys to Cloudflare Pages via **direct upload**, not Cloudflare's
git integration (decided 16 Sep 2026; GitHub Pages is not used either). A GitHub
Actions workflow (`.github/workflows/deploy-pages.yml`) runs
`cloudflare/wrangler-action@v3` on every push to `main`, checks out the repo and
uploads the repository root as-is to the `sports-deal-prototypes` Pages project
— no build job, no generator. The site root is this `index.html`, and
`P1-market-journey/` is served at `/P1-market-journey/`. `.nojekyll` is harmless
there and stays so the tree also works on any static host that runs Jekyll.

The workflow needs two repo secrets: `CLOUDFLARE_API_TOKEN` (a token scoped to
Cloudflare Pages — Edit on the account) and `CLOUDFLARE_ACCOUNT_ID`.

## Design tokens and the Next.js repo

`shared/tokens.css` is **the source of truth for design tokens** and this repo
owns it. It is plain CSS custom properties — no Tailwind directives, no
`@theme`, no imports — so the same file can be copied verbatim into the web app
at `sports-deal-web/src/styles/tokens.css` and imported from `globals.css`
alongside the Tailwind and shadcn setup. The flow is one-directional:

```
sports-deal-prototypes/shared/tokens.css   →   sports-deal-web/src/styles/tokens.css
            (edit here)                                 (copy, never edit)
```

The colour values are the current shadcn/ui **neutral** base colours in the
OKLCH form the v4-era registry uses, taken from the shadcn registry itself, so
a shadcn component dropped into a prototype looks like a shadcn component. The
chart and sidebar variables are carried along for the same reason.

On top of them this project adds:

- `--font-sans` / `--font-mono` — an Arabic-capable stack.
- Availability status colours — free agent, open to offers, available for loan,
  contracted, unknown — each with a matching foreground.
- Verification tier colours — low, mid, high — each with a matching foreground.

One caveat worth knowing: shadcn's v4 neutral registry no longer ships a
`--destructive-foreground`. This file defines one anyway, because the kit needs
readable text on a destructive button. If it is ever copied into a repo that
defines its own, that repo's wins.

`shared/base.css` is a **prototyping kit, not a design system**. It mimics the
shadcn look closely enough to judge a layout, using only the token variables,
and it is never shipped.

## Layout

```
index.html          the list of prototypes (hand-maintained, renders everywhere)
prototypes.json     the machine-readable twin of that list
shared/             tokens.css, base.css, fonts.css, proto.js — the only shared code
TEMPLATE/           copy this to start a prototype; its README is the full how-to
P<n>-<slug>/        one folder per prototype ticket
```

Every prototype is one folder: `index.html`, `screens.md`, `findings.md`,
`screenshots/`. Sub-screens are extra HTML files inside that same folder. There
is no other structure and no per-prototype dependency.

## Arabic, RTL and locale

Every prototype is Arabic by default — `<html lang="ar" dir="rtl">` — with an
English toggle in the header. Copy is authored inline on the element:

```html
<span data-ar="لاعب حر" data-en="Free agent">لاعب حر</span>
```

`shared/proto.js` swaps the text, flips `lang`/`dir`, and remembers the choice
in the URL (`?locale=en`) and in `localStorage`. There is deliberately no JSON
message catalogue: a prototype is read side by side with its copy.

Layout uses **logical CSS properties only** — `margin-inline-start`,
`padding-inline-end`, `inset-inline-start`, `text-align: start`. `left` and
`right` never appear. RTL then costs nothing.

## States

A screen declares its named states in the markup and `?state=` switches between
them; the header carries a switcher built from the declared names. The
vocabulary is `default`, `loading`, `empty`, `error`, `partial`,
`no-permission`. Locale, theme and viewport are toggles, not states.

Full detail, including the screenshot naming convention, is in
[`TEMPLATE/README.md`](TEMPLATE/README.md).

## Write-back contract

A prototype's findings land in exactly one of three places, and `findings.md`
has a copy-paste section for each:

- **(a) A new user story** appended to the owning epic's `## Stories` block in
  the sibling planning manifest `gh-project/manifest.json`, in the form
  `- **As a <actor>**, I <do>, so that <outcome>.` followed by an indented
  `- Accept: <criteria>.` line. Stories are append-only and never reordered.
- **(b) A note on an existing story**, as a `story_notes` entry on that epic
  keyed by the story's position.
- **(c) A rule for the code repo**, recorded into its `.ai/rules/` under the
  matching glob.

Two standing rules: a finding without a screenshot as evidence is not written
back, and requirement ids from any parked requirement document must never
appear anywhere — restate the requirement in the project's own words or leave
it out.

## Review states

```
draft  →  in-review  →  locked  →  superseded
```

Each prototype names one reviewer and a timebox in days, both in
`prototypes.json`. **A locked prototype is never edited** — not even for a
typo. It records what was decided on that date. If the answer changes, a new
`P<n>` supersedes it and the old entry is marked `superseded`.

## A note on the product name

The Arabic brand string in the prototype shells — الصفقة الرياضية — is a
placeholder. It has not been signed off; replace it everywhere once it is.
