Brand portal

Color

One primary, a small set of accents, one neutral ramp. The purple marks what you can act on; greys do almost all the work.

Core colors

Four values carry the identity.

  • Brand Purple

    #471eff

    --brand-primary

    The primary. Every call to action, link, focus ring and selected state. This is the 1club purple — nothing else is.

  • Ink

    #212121

    --ink

    The near-black. Dark brand surfaces, and the strongest text on light backgrounds.

  • Mist

    #e7fefd

    --mist

    The pale cyan that pairs with Ink. Text and icons on dark brand surfaces.

  • White

    #ffffff

    --canvas

    The page. Also the text colour on Brand Purple.

Brand Purple is a signal, not a decoration — if it appears somewhere the user cannot act, it is misused. On a club’s own surfaces their colour replaces it.

Accent colors

Two sets, two jobs: brand accents give a surface mood, feedback colours mean one thing each.

Brand accents

  • Lavender

    #a294ea

    Closest to the primary — identity and brand surfaces.

  • Sand

    #ebd69f

    Warm and editorial. Pairs with photography in the ritual register.

  • Rose

    #d9adc4

    Soft counterweight to the cooler accents.

  • Mint

    #bfe0dc

    Calm, quiet surfaces — content and copy.

  • Blue

    #b3c7e6

    Structure and motion; the most neutral of the accents.

  • Sage

    #c2d8a1

    Grounded and organic. Wide surfaces and banners.

Never mix a saturated colour into this set — one loud tile makes the other five look broken.

Feedback

  • Success

    #10b981

    Confirmed, paid, active.

  • Warning

    #f59e0b

    Pending, expiring, needs attention.

  • Danger

    #ef4444

    Failed, cancelled, destructive actions.

Never branded. A club whose brand colour is red still gets our red for errors.

Greys

One ramp, ten steps. Text, borders, surfaces and dark mode all come from here.

50

#fafafa

100

#f4f4f5

200

#e4e4e7

300

#d4d4d8

400

#a1a1aa

500

#71717a

600

#52525b

700

#3f3f46

800

#27272a

900

#18181b

On light

  • 50–200 — surfaces, hovers, cards
  • 200–300 — borders and dividers
  • 500–600 — secondary text
  • 800–900 — primary text

On dark

  • 900 — page background
  • 800 — cards and raised surfaces
  • 700 — borders (or white at 12%)
  • 400 — secondary text · 50 — primary text

Neutral, never blue-tinted. On white, 500 is the lightest step that clears WCAG AA for text.

Unresolved — decisions pending

Everything above is brand guidance. Everything below is a holding area — duplicated tokens and open questions, none of it a rule yet. It should shrink to nothing.

ItemWhere it standsDecision needed
--platform-purple (#6949e3)Decided against as a brand colour — but it is not a stray duplicate. It is the focus-ring and selected-state colour in ~17 shared components (ModernInput, ModernTabs, booking pills, event dialogs, account rows).Retiring it is a migration, not a deletion. Cheapest path: set --platform-purple to #471eff so all 17 usages become brand purple at once, then rename the token later.
Three app primariesnetwork #471eff · portal #1f1f1f · kiosk #2563eb. The portal neutral is intentional (org branding overrides it); the kiosk blue is an untouched Tailwind default.Point the kiosk at the org brand colour, falling back to #471eff — it stands in a club’s reception, where the club’s colour matters most.
Three --foreground near-blacksnetwork #333333 · portal #082a24 (a leftover dark green) · kiosk #171717. Three authoring sessions, not three decisions.Collapse to Ink / grey-900. Confirm nothing depends on the green.
Four near-identical light greys#f7f7f6 (portal sidebar) · #f6f7f8 (portal card) · #f5f5f5 (portal muted) · #f4f4f5 (network muted). Visually indistinguishable.Map all four onto grey-50/100. Highest-value cleanup on this page; nothing depends on the differences.
--brand-navy = --brand-darkBoth are #051915 in shared globals — two names for one colour. --brand-light (#0a3d35) and --brand-slate (#64748b) are declared there too; their usage is unaudited.Audit the five --brand-* primitives, keep what is used, delete the aliases.
--brand-sky (#e5e5e5)Named like a colour, is a neutral grey.Rename or fold into the grey ramp.
Status tokens are scope-bound--status-confirmed / --status-pending / --status-cancelled are set on .shared-branding-theme, so they are unset anywhere outside that wrapper — components reaching for them in a plain page context get nothing.Promote to :root, or document the wrapper as required.
Two dark moodsThe portal’s dark surfaces are blue-tinted slate (#1f2937, #374151); the network’s are true neutral (#1e1e1e, #1a1a1a).Standardise on the neutral ramp above.
Computed contrast is coarse--primary-foreground is never configured — it is derived from the org primary’s luminance with a single 0.5 threshold, returning #121212 or #ffffff.Accept, or add a mid-range case for brand colours that land near the boundary.
network-theme.css · portal-theme.css · public-kiosk/src/app/globals.css · public-web-shared/src/styles/globals.css · branding-theme.css · utils/public-web-branding.ts