Skip to content

Design system — WalkRPG

Design system — WalkRPG

Foundation document for all UI decisions. Informs mobile implementation (phase 11+) and wiki component styling. Every wireframe page references this document for token names.


1. Color tokens

1.1 Region palette (canonical — from data/src/content/regions/*.ts)

These six colors are canon from phase 5b. Do not create replacements without a D-level decision via game-director.

TokenHexRegionCharacter
--color-region-plenny#c9a04aPlenny / CentreBureaucratic gold, parchment warmth
--color-region-frostlands#7fb8d4Frostlands / NorthIce-blue, crystalline
--color-region-passage-arc#9b7fc4Arc of Passage / NE-BridgeViolet, hybrid, contested
--color-region-mglica#6b8f7aMglica / EastFog-green, muted, dreaming
--color-region-beber#c47a4aBeber / WestOchre-rust, bestial, savanna
--color-region-targosie#d65a5aTargosie / SouthCoral-red, mercantile, urgent

1.2 Neutral base palette

Dark default. The neutral ramp is warm (slight golden cast) to echo the Plenny parchment tone without competing with region accents.

TokenHexUsage
--color-bg#0f0e0cApp background (near-black, warm)
--color-surface#1a1916Cards, panels, bottom sheet base
--color-surface-variant#252320Input fields, pressed states, table rows
--color-surface-elevated#302e2bModals, popovers, top-of-stack drawers
--color-on-surface#f0ece3Primary text on dark surfaces
--color-on-surface-muted#a09880Secondary text, hints, placeholders
--color-border#3a3730Dividers, strokes
--color-border-subtle#252320Inset card borders, barely visible

1.3 State colors

TokenHexUsage
--color-success#4caf7dStreak active, quest complete, accepted steps
--color-warning#e0a843Streak about to decay (1 day left), provisional state
--color-error#e05555Rejected steps, auth failure, destructive actions
--color-info#5b99c4Tooltips, informational banners
--color-disabled#4a4843Disabled buttons, locked content
--color-on-disabled#6b6760Text on disabled elements

1.4 Faction accent colors

One accent per faction, used for reputation tier badges, faction strip cells, and faction-gated content borders.

TokenHexFaction (EN handle)PL name
--color-faction-unfinished-guild#c9a04aUnfinished GuildCech Niedokończonych Wypraw
--color-faction-practical-academy#5b99c4Practical AcademyAkademia Praktyczna
--color-faction-quiet-lights#9b7fc4Quiet Lights BrotherhoodBractwo Cichych Świateł
--color-faction-free-merchantry#4caf7dFree MerchantryWolnokupiectwo
--color-faction-wild-path#c47a4aWild PathDziki Trakt

Note: Unfinished Guild shares #c9a04a with Plenny because the Guild IS Plenny’s dominant faction. On screens where both region and faction appear together, the region card uses the token by name (--color-region-plenny) and the faction badge uses its own (--color-faction-unfinished-guild). Visual overlap is intentional — tonal coherence.

1.5 Contrast audit (WCAG 2.2 AA)

Background for all checks: --color-bg = #0f0e0c.

Foreground tokenHexAgainst --color-bgAgainst --color-surfaceAA body (4.5:1)AA large (3:1)
--color-on-surface#f0ece3~16.8:1~14.2:1PASSPASS
--color-on-surface-muted#a09880~6.1:1~5.1:1PASSPASS
--color-region-plenny#c9a04a~6.9:1~5.8:1PASSPASS
--color-region-frostlands#7fb8d4~7.8:1~6.6:1PASSPASS
--color-region-passage-arc#9b7fc4~5.5:1~4.6:1PASSPASS
--color-region-mglica#6b8f7a~4.6:1~3.9:1PASS (just)PASS
--color-region-beber#c47a4a~4.9:1~4.1:1PASSPASS
--color-region-targosie#d65a5a~4.6:1~3.9:1PASS (just)PASS
--color-success#4caf7d~5.6:1~4.7:1PASSPASS
--color-warning#e0a843~7.5:1~6.3:1PASSPASS
--color-error#e05555~4.7:1~3.9:1PASS (just)PASS
--color-info#5b99c4~5.8:1~4.9:1PASSPASS

Warning for Mglica, Beber, Targosie region colors used as body text: these barely clear AA at 4.5:1. Use them only as accent strokes, badges, and large-text headings — not as body copy color on dark surfaces.

Light mode note: if a light mode is ever implemented, the full contrast table must be re-run against #f0ece3 backgrounds. The region accent palette was designed for dark-first — several colors will fail AA on white.


2. Typography scale

W-level decision: Typeface family is Literata (serif, variable font, Google Fonts, free OFL) for lore/display headings + Inter (sans-serif, variable font, Google Fonts, free OFL) for UI chrome. Both have full Polish diacritic support (ą ć ę ł ń ó ś ź ż and uppercase variants).

Why Literata for lore/display:

  • Variable font (one file, multiple weights via font-variation-settings).
  • Designed for dense reading at small sizes (e-reader heritage) — useful for map descriptions and quest text.
  • Cartographic / parchment character at display size without being a novelty face.
  • Google Fonts means no licensing cost at any scale.

Why Inter for chrome:

  • Universally legible at small sizes with Polish diacritics clean.
  • Designed for screen UI — consistent stem weights, generous x-height.
  • Variable font — single file.

CEO open question (D-level): If a licensed “more characterful” display face becomes desirable for marketing assets (e.g. app store screenshots, loading screen), that would require a D-level decision with game-director before it enters the design system. Literata is the working choice — solid and free.

2.1 Scale

TokenTypefaceSize (px)Line heightWeightRole
--type-displayLiterata32px1.2700Region titles, keystone names on tree, onboarding headers
--type-h1Literata24px1.25600Screen titles
--type-h2Inter18px1.3600Section headings within screens
--type-body-lgInter16px1.5400Quest description, node description popover body
--type-bodyInter14px1.5400Standard UI text, labels, tab names
--type-captionInter12px1.4400Hints, timestamps, tree node micro-labels

Minimum body font on-device: 14px. At 200% OS font scaling (WCAG 1.4.4), 14px becomes effectively 28px — layout must not overflow or clip at this size. See section 5 (a11y baseline) for compliance details.


3. Spacing scale

Base unit: 4px. All spacing values are multiples.

TokenpxUsage examples
--space-14pxIcon-to-label gap, micro-padding inside badges
--space-28pxInner padding of compact chips, badge inner horizontal
--space-312pxList item vertical padding, tab bar inner vertical
--space-416pxCard inner padding, modal horizontal margin
--space-624pxSection gap within a screen, between quest pill and streak ribbon
--space-832pxBetween major sections, top/bottom of modal
--space-1248pxMinimum tap target size (also minimum interactive zone height)
--space-1664pxBottom nav bar total height, large header zones

Touch target baseline: All interactive elements — buttons, tabs, node cells in tree, quest pills, faction strip items — must present a minimum 48dp hit area. Visual size may be smaller (e.g. tree nodes rendered as 24dp circles), but the invisible tap target wraps to 48dp. This applies to both iOS (pt) and Android (dp).


4. Iconography stance

W-level decision: System icon vendor per platform + a set of named custom lore icons (to be authored in phase 11 visual asset sprint).

4.1 System icons (chrome)

PlatformLibraryUsage
iOSSF Symbols 5Navigation, standard actions (back, share, settings, search, checkmark)
AndroidMaterial Symbols (outlined weight)Same roles on Android — matched icon semantics, not pixel-identical shapes

System icons handle: tab navigation glyphs, action buttons, disclosure chevrons, close/dismiss, check states, loading spinners.

4.2 Custom lore icons (named, to be authored phase 11)

13 custom icons named here as contracts. Visual design deferred to phase 11.

HandleDescriptionUsage context
icon.defining-image-fragmentCech ring motif (18th-century surveyor’s hand, watermark weight) overlaid on a fragment of moved coastline; coastline drawn twice — warm-brown current line plus ghost-blue alpha offset curve per D-012 double-printed-lines technique; warm parchment background (#f0ece3); no central figure, no magical glowBrand-kit primary mark — splash, loading screen, app icon, marketing thumbnail. Distinct from icon.cech-seal (faction badge / quest-issuer) and icon.compass-rose (navigation chrome); D-012 canon-locked
icon.cech-sealWax seal with ring motifUnfinished Guild faction badge, quest issuer marker
icon.leak-shardCrystallised magic fragmentCrafting currency, leak-related node modifiers
icon.footprintSingle stylized walker footprintStep count delta, energy unit icon
icon.compass-rose4-point compass with Cech ring accentNavigation fallback, map-related nodes
icon.faction-academyFlame-over-bookPractical Academy badge
icon.faction-quiet-lightsLantern with haloQuiet Lights Brotherhood badge
icon.faction-merchantryCoin with guild markFree Merchantry badge
icon.faction-wild-pathBare-foot track in grassWild Path badge
icon.keystone-lockPadlock with Cech ringLocked keystone state on tree
icon.notable-nodeHexagon with inner diamondNotable node type marker
icon.mastery-pickThree-pronged choice symbolMastery popover header
icon.streak-flameStylized walking flameStreak ribbon accent

5. Accessibility baseline (walking-specific)

Every screen and flow must satisfy all six checks. Deviations require a documented waiver per screen.

5.1 One-handed use while walking

Rule: All primary actions reachable with one thumb in the bottom 60% of the screen. Destructive or secondary actions may live in the top 40%. The tree viewer (which requires 2D navigation) is the highest-risk screen — see tree-viewer wireframe for mitigations.

Check: Primary CTA on every screen is at bottom, inside the safe zone (below the fold, above the system nav bar). Bottom nav tabs are the primary navigation affordance.

5.2 Glance legibility (2-second comprehension)

Rule: The most critical piece of information on each screen must be readable in a 2-second glance without focusing. This means: large primary numeral or status indicator, high-contrast, centered or top-anchored.

Implementation per screen:

  • Home: Streak count is the largest element after the region card header.
  • Tree: Available points count is persistent at top-right. Current allocation state (how many points spent) is visible without scrolling.
  • Post-walk sync: Step delta is the single dominant element (+N,NNN steps). Energy delta secondary.
  • Onboarding: One instruction per screen. No multi-step copy on a single view.

5.3 Tap target minimum (48dp)

All interactive elements in the product are 48dp minimum hit area. See spacing section for the token (--space-12). Tree nodes are the exception: at small zoom levels, nodes render smaller than 48dp visually. The hit target must still be 48dp; overlap is resolved by nearest-node selection at small scales with a disambiguation popover if two nodes are within 48dp of each other.

5.4 Color contrast (WCAG 2.2 AA)

  • Body text: 4.5:1 against background. (Met by --color-on-surface and --color-on-surface-muted — see audit table.)
  • Large text (≥18px regular, ≥14px bold): 3:1 minimum. (All region accent colors pass at large size.)
  • UI components (borders, focus rings, active states): 3:1 against adjacent surfaces.
  • Focus ring: 2dp solid --color-region-plenny (#c9a04a) against --color-surface yields ~5.8:1 — PASS.

5.5 Font scaling (200%)

Rule: No text must clip, truncate with ellipsis at primary-content level, or overflow container bounds at 200% OS font scale.

Implementation notes:

  • All flex/grid layouts use min-height not fixed height for text-bearing rows.
  • Button labels: single line only for actions up to 12 characters; longer actions wrap to two lines within the button (button height grows). PL labels average 30% longer than EN — design against PL lengths.
  • Tab bar labels: at 200% they will almost certainly overflow a 4-tab bar. Mitigation: at 200% scale, tab bar hides text labels and shows icons only (a fallback layout must be designed and tested). See bilingual layout section for tab label character budgets.
  • Tree node micro-labels hide at 200% — nodes use icon glyph only and tooltip popover on long-press.

5.6 Audio and haptic alternatives

Every primary visual feedback channel must have an audio or haptic companion:

Visual feedbackAudio/haptic alt
Streak updated (day counter increments)Haptic: medium impact + success tone
Step count delta appearedHaptic: light impact
Node allocatedHaptic: medium impact
Keystone unlockedHaptic: heavy impact + distinctive sound
Quest beat completedHaptic: success pattern + chime
Error / rejected stepsHaptic: error pattern
Onboarding step advanceHaptic: light tick

Audio and haptic are opt-out in settings, not opt-in. Players who cannot feel or hear can disable; default-on covers those who walk with eyes forward.


6. Bilingual layout rule

Player-facing strings exist in both en and pl. PL strings average 20-40% longer than EN equivalents (inflection, compound nouns). UI must be designed against PL string lengths as the constraint.

6.1 Character budget reference

ElementEN budgetPL budgetWorked example
Bottom tab label≤8 ch≤10 chEN: “Quests” (6) / PL: “Zadania” (7) — fits
Quest pill (active quest title)≤28 ch≤36 chEN: “Quest 001 — The First Road” (28) / PL: “Quest 001 — Pierwszy Trakt” (28) — both fit
Streak ribbon label≤20 ch≤26 chEN: “Day 7 — Tier 1 bonus” (20) / PL: Dzień 7 — Premia I stopnia (26) — design for 26
Region card title≤12 ch≤16 chEN: “Plenny” (6) / PL: “Plenny” (6) — same; some regions differ: EN “Frostlands” (10) / PL Krainy Mrozłu (13)
Button label (primary CTA)≤14 ch≤18 chEN: “Begin Journey” (13) / PL: Rozpocznij Wyprawę (18) — design at 18
Faction tier badge≤12 ch≤14 chEN: “Apprentice” (10) / PL: “Praktykant” (10) — fits; EN: “Stranger” (8) / PL: “Obcy” (4) — fine

6.2 Overflow handling

  • Text elements that can overflow must use ellipsis truncation with a full-text tooltip on long-press.
  • Primary elements (quest title, keystone name) must NOT truncate — they must wrap or the layout must expand to accommodate.
  • Never use overflow: hidden on content that carries gameplay state.

7. Dark vs light mode

W-level decision: Dark is the default. Light mode is optional, toggled in settings.

Rationale:

  1. Walking outdoors in daylight: high-contrast dark UI with bright region accent colors reads better in sunlight than a white background (which washes out). The region palette was designed for a dark background.
  2. OLED battery: most mid-to-high-end Android phones and all iPhone 12+ use OLED panels. Dark pixels draw near-zero current. Walking sessions can be long (30+ minutes). Battery impact is material.
  3. Tone: the Pratchett-warm + epic-stakes tone corresponds to parchment, ink, lamp-light — which maps naturally to a warm dark palette (near-black backgrounds, golden accents). A white-background UI would read clinical against the world’s character.
  4. Hardcore RPG audience (D-008): the PoE-inspired audience expects dark UIs. This is the genre convention for passive-tree style games.

Light mode (optional): A fully compliant light palette exists as an option for users with visual accessibility needs or personal preference. Light mode uses --color-bg: #f5f0e8 (warm parchment), --color-surface: #ede8de, --color-on-surface: #1a1816. The region accent palette retains its hex values but must be re-audited for contrast on the light background — several accents that pass on dark will fail on light (notably Mglica #6b8f7a and Targosie #d65a5a). Light mode contrast audit is a phase 11 deliverable, not phase 9.


This document is W-level autonomous. Typography family choice (Literata + Inter) and dark-first default are decisions within ui-designer authority. Licensing costs: both are OFL/free — no D-level escalation required.