PhotoX design system

Matchday: forest green and gold, condensed headlines, cards with real depth. Photographs stay the loudest thing on the page.

1 · Brand

${icon(camera)}PhotoX

Wordmark in Big Shoulders 900, uppercase. The mark is the camera glyph from our own icon set on a gold tile.

Positioning. Find and buy your photos from every school match, race and festival in South Africa.

A claim a parent understands on the touchline, not a tagline.

Direction. Chosen from three rendered options after industry research: Darkroom (Lightroom-style dark chrome), Gallery (Pic-Time premium white) and Matchday. Matchday won: it reads as South African sport at a glance, and cards with a coloured rail make the product panels feel like a product, not a spreadsheet.

Scene. Saturday 09:40 in July at Paarl Gimnasium: hard low winter sun, a parent on the touchline with a flask and a phone, wanting the try photo before the bus leaves.

2 · Colour

Committed, two colours: forest green (hue 158) on the rail, headings’ numbers and primary buttons; gold (hue 88) on the single primary action per screen. Contrast figures are measured with scripts/contrast.py.

--bgapp ground · .97 .006 158
--surfacecard · white
--surface-2.955 · step 2
--surface-3.925 · step 3
--ink14.6 : 1 on bg
--ink-29.9 : 1
--muted6.5 : 1
--muted-24.5 : 1 · large only
--primary7.5 : 1 · green .42 .105 158
--primary-stronghover / active
--primary-softselection, focus ring
--accent11 : 1 · gold, the action
--drench10 : 1 · sidebar and bands
--drench-26.4 : 1 muted text
--success9.1 : 1 · hue 150
--warning7.6 : 1 · hue 75
--danger7.7 : 1 · hue 25
--info8.1 : 1 · hue 265
Chart ramp

3 · Status vocabulary

One pill per state, used identically by every role. Colour is never the only indicator: the label always says the word.

4 · Typography

Big Shoulders Display for every headline, uppercase, like a matchday programme. Public Sans for everything you read. JetBrains Mono for bibs, IDs, timestamps and money.

display · fluid
Your athlete. Every photo.
h1 marketing
Every school match, race and festival
h2 marketing
Paarl Interskole 2026 · 1 840 photos live
lead

Upload a selfie or type a bib number. Facial and number recognition find every photo of one athlete across an entire event in seconds.

h1 product · 28
Sales & payouts
h2 product · 22

1st XV: Paarl Gim v Paarl Boys’ High

h3 product · 18

Pipeline: 1 540 of 1 840 faces indexed

body · 15

Photographers keep 80% of every sale. Payouts run every Thursday by PayFast split payment to the verified bank account on file. VAT at 15% is shown on every statement.

small · 13

Photos remain the property of the photographer. Purchased downloads are licensed for personal use.

mono · numbers

Bib 2431 · No. 7 · PX-0101-0100 · R 1 234,50 · 08 Aug 2026 15:34

5 · Space, radius, elevation

Spacing · 4 px base

--s-1 … --s-7. Sections use --section (clamp 4–7.5 rem).

Radius · three, locked

ctl 12
card 18
lg 24

Chunky and rounded. Pills for tabs, roles and status.

Elevation · one soft step

Card → floating layer → modal. Every card rests on a soft shadow; no card borders.

Density: control 42, row 46, card padding 24. Rules between rows inside cards; cards divide by shadow. Headings uppercase, weight 800.

6 · Controls

Buttons

Inputs

${icon(hash)}
Printed on the front of your race vest.
${icon(alert,14)} Add the part after the @, for example gmail.com.
${icon(upload,28)}

Drop up to 5 000 files or click to choose

JPEG, HEIC, CR3, ARW · originals stay private · watermarked previews generated automatically

7 · Surfaces & data

Table

2 selected

Tabs

Notices

${icon(check-circle,18)}Payout PO-2026-36 paid · R 7 152,00
${icon(alert,18)}3 files failed processing. Retry or replace.
${icon(x,18)}Card declined by issuer.

Key–value

Gateway
PayFast · split
Commission
20% · R 15,80
Photographer net
R 63,20

List rows & popover

    8 · Domain components

    The three things only PhotoX has: the watermarked tile, the face and number boxes on a preview, and the processing pipeline.

    Confidence

    ${conf(97)}
    ${conf(82)}
    ${conf(61)}

    Sponsor slot

    Processing pipeline

    9 · Feedback & states

    ${icon(wifi-off,16)} You’re offline. Your cart is saved on this device; checkout will resume when you reconnect.
    ${icon(lock,32)}

    You don’t have access to this gallery yet

    This photographer account is pending review. We reply within one working day.

    Added to cart · high-res · R 79,00
    Email would be sent to marisa.kotze@gmail.com
    Payment declined. Try another card.
    Step 3 of 10

    The photographer sees the sale

    The order you just placed is already in Johan’s sales, with commission split.

    10 · Iconography

    Lucide, 1.75 stroke, inlined from icons.js. One family, never emoji.

    11 · Bans we enforce

    • No coloured side-stripe borders on cards, alerts or list items.
    • No gradient text, no glassmorphism, no purple-blue gradients.
    • No hero-metric template, no three equal cards as a section’s answer, no eyebrow above every section, no numbered section scaffolding.
    • No dark mode. Green stays on the rail and key numbers; gold only on the one primary action per screen.
    • No emoji as icons, no second icon family, no icon fonts.
    • No fake screenshots built from divs. No stock handshakes or lightbulbs.
    • No text on a photograph without a scrim. No scale transforms on hover.
    • No placeholder text, no dead links, no inert controls: every button navigates, mutates, opens a layer or explains itself in a toast.