Mushroom Alien Games — Design System
Version 01.2608.0003 (WIP — not yet reviewed or locked)
Derived from: Brand Reference 01.2608.0001, mag_colour.svg, Creative Direction 01.2608.0001
Supersedes: 01.2608.0002 — primary figure/ground inverted (dark background, light text). See Migration note.
Scope: Layer 1 (site-wide). Layer 2 (per-game) mechanism is in SITE_ARCHITECTURE.md.
© 2026 Willem van Wyk
Positioning filter
“Mushroom Alien Games makes small, elegant tabletop games. Simple rules on the surface, complex gameplay underneath.”
“Natural-history archive, except something is wrong.” — the fast test drawn from Creative Direction 01.2608.0001. Save that brief in full as documents/Mushroom_Alien_CREATIVE_DIRECTION_01.2608.0001.md, referenced here rather than duplicated — this file stays tokens and rules, not philosophy, per the existing progressive-disclosure pattern between this doc, SITE_ARCHITECTURE.md, and BUILD_BRIEF.md.
Test every visual decision against both. If a choice is showy on the surface and shallow underneath, or reads as generic archive/vintage with nothing quietly wrong underneath it, it fails — regardless of how good it looks in isolation.
Colour tokens — LOCKED (roles inverted from 0002)
Hex values retained where possible — this is a role change, not a repaint. One new token added for a gap the inversion exposed.
:root {
--ink: #06373C; /* was --teal's role. Now PRIMARY PAGE BACKGROUND. */
--substrate: #F2ECDE; /* now PRIMARY BODY TEXT on dark, and light-surface accent */
--panel: #EAE2CE; /* specimen-card surface, floats on --ink */
--cream-faded: #B7AE94; /* NEW. Muted/secondary text directly on --ink. */
--teal-faded: #4A6A6D; /* kept, but now scoped to use INSIDE .panel only — see below */
--orange: #C85915; /* unchanged role: UI/large-text/labels only, never body text */
--rule: #C9BFA6; /* unchanged role: hairline dividers, borders */
}
Token names are kept from 0002 for continuity with the locked SVG asset and Phase 1’s already-implemented CSS. --ink is introduced as the name for the background role that --teal’s hex value now plays; renaming --teal itself throughout the codebase is possible but not done here; it would touch every already-built Phase 1 selector for a role change that doesn’t touch the hex value. Flag if you’d rather force the rename for clarity.
Role table — what actually changed
| Token | 0002 role | 0003 role |
|---|---|---|
--teal / --ink |
Primary text colour, on cream | Primary page background |
--substrate |
Primary page background | Primary body text colour, on dark |
--panel |
Card surface, on cream page | Card surface, now floats on the dark --ink page — reads as a specimen card in an archive drawer |
--teal-faded |
Secondary/muted text, on cream, anywhere | Secondary/muted text, but only inside .panel cards — fails outright directly on --ink, see contrast table |
--cream-faded |
(did not exist) | New. Secondary/muted text directly on --ink |
--orange |
Accent, UI/large-text only | Unchanged. Reads more as a “warning mark” against dark — matches Creative Direction’s framing of orange as punctuation, not wallpaper |
--rule |
Hairline divider | Unchanged. Also passes as text-on-dark if ever needed, but kept separate from --cream-faded so divider and text roles don’t conflate |
Contrast check (WCAG 2.1) — recomputed for the inverted scheme
Computed directly via sRGB relative luminance, same method as 0002’s table. Verified against 0002’s own published numbers first (Substrate-on-Teal reproduced at 11.01:1, Orange-on-Teal at 3.02:1) before trusting the new pairs below.
| Pair | Ratio | AA body (4.5:1) | AA large/UI (3:1) |
|---|---|---|---|
| Substrate on Ink (primary body text on dark bg) | 11.01:1 | Pass | Pass |
| Panel on Ink (card surface vs page bg) | 10.05:1 | Pass | Pass |
| Teal-faded on Ink | 2.21:1 | Fail | Fail |
| Cream-faded on Ink (new token, muted text on dark) | 5.86:1 | Pass | Pass |
| Orange on Ink | 3.02:1 | Fail | Pass |
| Rule on Ink | 7.09:1 | Pass | Pass |
| Ink on Panel (text inside a card) | 10.05:1 | Pass | Pass |
| Teal-faded on Panel (muted text inside a card) | 4.55:1 | Pass | Pass — tightest margin in the system, spot-check on preview |
The load-bearing finding: --teal-faded was 0002’s muted-text colour, used freely on the cream page. It fails completely once it’s sitting directly on --ink — 2.21:1, below even the non-text UI floor of 3:1. It is not usable for secondary text on the new primary background. --cream-faded is the specific replacement for that job. --teal-faded still works, but only where it already passed before: inside .panel cards.
Confidence: High, computed not eyeballed. Evidence: standard WCAG 2.1 relative-luminance formula, same approach as 0002’s own method note.
Colour vision deficiency
0002’s teal-vs-orange CVD simulation still applies unchanged — the hue relationship between those two tokens hasn’t moved, only which one occupies the background role. Practical rule unchanged: never let teal-vs-orange alone carry meaning; pair colour with an icon or shape.
Typography
Faces, weights, and pairing unchanged from 0002.
Wordmark size: increase the header wordmark’s set size from Phase 1’s current implementation. Creative Direction’s note that “typography should occasionally become graphic in itself… a large sentence may be more powerful than an illustration” applies directly to the header lockup. Flag the exact size landed on rather than picking one silently, and confirm the sticky-bar mini-mark doesn’t scale up disproportionately as a side effect.
Spacing scale
Unchanged from 0002.
Components
Structure unchanged (.fig-label, .caption, hr.hairline, .panel, sticky header, version stamp footer) — only colour values need re-pointing per the role table above.
Concretely, wherever Phase 1’s CSS currently has:
body { background: var(--substrate); color: var(--teal); }
it becomes:
body { background: var(--ink); color: var(--substrate); }
Secondary/muted text sitting directly on the page (nav links, .hook, .eyebrow, footer meta, captions outside panels) switches from var(--teal-faded) to var(--cream-faded). Anything living inside a .panel keeps using var(--teal-faded) — that pairing was already vetted and still holds.
.fig-label stays orange — already vetted on --ink (3.02:1, UI/large-text size, which is what fig-labels are).
.panel itself is unchanged structurally — cream surface, teal-family text inside — it’s now the one place in the system that still looks like 0002’s light-mode logic, deliberately, because that’s the specimen-card effect.
.field-texture — site-wide background layer (_layouts/default.html), one <div> behind all page content. Built from two independently-sized SVG tiles layered via CSS multiple backgrounds on the same element (not two divs), so their repeat periods don’t share a common alignment and the combined pattern doesn’t visibly repeat within normal scroll distance:
field-texture-mycelium.svg(640×640,--rulehex) — three spore-burst clusters of varied scale (5/4/3 rays), each at least 50px clear of the tile edge.field-texture-constellation.svg(727×727,--cream-fadedhex) — 4 distinct curves (varied curvature direction, length, and quadrant position, each ≥50px clear of every edge) plus 24 scattered dots.
background-image: url(assets/img/brand/field-texture-mycelium.svg), url(assets/img/brand/field-texture-constellation.svg);
background-repeat: repeat, repeat;
background-size: 640px 640px, 727px 727px;
background-position: 0 0, 137px 205px;
The 90px 140px offset on the second layer is deliberate misalignment (not a round multiple of either tile size). Per-element opacity in both SVGs was tuned down from an earlier single-tile version to compensate for the roughly doubled apparent density of layering two patterns — see asset inventory for current values. position: absolute (not fixed) so the whole layer scrolls with the page rather than staying pinned.
Hard rules
Unchanged, with one confirmation:
- No pure white (
#FFF) or pure black (#000) anywhere —--ink(#06373C) is not pure black, confirmed by the same method as 0002. - No parallax, WebGL, scroll-jacking, autoplay
- One orange element per viewport is usually enough
- “Mycelium” appears at most once or twice site-wide — motif, not gimmick
- No em dashes or en dashes in any copy, checked programmatically
- UK spelling throughout
Photography direction
Clarified, not replaced: the warm-daylight, cream/linen direction describes the tonal quality of the photographed subject and surfaces (props, table, materials) — not the page chrome around it, which is now --ink. Creative Direction’s suggestion to frame photography as documentation (e.g. “FIG. 04 · SALT & STONE PLAYTEST · MELBOURNE / 2026”) fits this naturally: a warm-toned photograph sits inside a .panel card, floating on the dark archive page.
Asset inventory
Unchanged from 0002, with one addition:
| Asset | Status | Action |
|---|---|---|
| Full lockup (badge + wordmark), 2-colour | Have — mag_colour.svg |
Unchanged |
| Badge-only crop (favicon/avatar) | Have — mag_badge.svg |
Unchanged |
| Single-colour variants (all-teal, all-cream) | Done — mag_badge-light.svg, mag_colour-light.svg (assets/img/brand/) |
Not a strict monochrome: the primary shape’s fill was recoloured from #06373C to --substrate’s hex (#F2ECDE); the orange accent path (#C85915) was left unchanged. Built to solve a real problem — the original teal fill is byte-identical to --ink, so it went fully invisible in header/sticky-bar/footer once those backgrounds moved to --ink this session. Used only in those three dark-bg placements; the original files are unchanged and still used inside .panel contexts (unaffected, still cream). |
| Salt & Stone hero photography | Missing | Unchanged — placeholder stays until Phase 4 |
| Field texture, mycelium layer (site-wide repeating background) | Done — field-texture-mycelium.svg (assets/img/brand/) |
Sparse organic SVG tile (640×640) — three spore-burst clusters of varied scale (5/4/3 rays), no two identical. Colour is the literal hex of --rule (an external SVG loaded via background-image can’t read CSS custom properties) — re-point manually if that token’s hex value ever changes. |
| Field texture, constellation layer (site-wide repeating background) | Done — field-texture-constellation.svg (assets/img/brand/) |
Sparse organic SVG tile (727×727 — deliberately coprime with the mycelium tile’s 640px so the two repeat periods share no small common alignment) — 4 distinct curves (varied curvature direction, length, and quadrant position, each ≥50px clear of every edge) plus 24 scattered dots. Colour is the literal hex of --cream-faded, same caveat as above. Layered with the mycelium tile via CSS multiple backgrounds at an offset position (not stacked as a second div) — see Components entry. |
Badge crop legibility on --ink background |
Re-checked, resolved via the light variants above | The original badge/lockup’s internal detail lines are negative-space cutouts (nonzero-winding holes) within one compound path, not separate light paths — confirmed by inspecting the SVG source before recolouring. A single fill swap on that path (to --substrate) was therefore sufficient: light silhouette, dark detail lines showing the page through the holes, no path restructuring needed. Not visually rendered in this session (no browser tooling in this container) — confirm on preview. |
Open flags — not decided in this revision
- Second dark tone. Creative Direction mentions “very dark near-black or forest tone for certain applications” (plural). This revision introduces only one,
--ink, used everywhere. A second, deeper tone (e.g. for footer separation) is not added here — if wanted later, it needs its own contrast pass before use, not an eyeballed value. - Generation number. This is versioned as a
rrrrrevision withinGG=01, not aGGbump — the layer mechanism, component set, and typefaces are all intact; only token roles shifted. Worth your own second look: VERSIONING_REFERENCE.md lists “major redesign” as aGGtrigger, and a full figure/ground inversion arguably qualifies. Flagging, not deciding. - Where this lands in BUILD_BRIEF. This revises already-built Phase 1 CSS before Phase 2 starts. Worth deciding whether it’s folded into Phase 1’s own Definition of Done (re-opened, not yet signed off) or run as a standalone interim session between Phase 1 and Phase 2. Recommend the former — it’s the same foundation layer, not new scope.
Two-layer identity — summary
Unchanged from 0002: Layer 1 = this document, applies site-wide. Layer 2 = per-game, contained to that game’s own page(s), never leaks into Layer 1 — including the new dark background. Salt & Stone stays on its own ochre/cream system per SITE_ARCHITECTURE.md and is unaffected by this revision. Adding a new game does not change this document.