Kiosk-X design system
One brand across every surface. Kiosk X is a category-agnostic, manufacturer-agnostic gamified vending network — the buying experience is identical whether the machine sells snacks, tech, or a 21+ category, and whether the hardware is a Reyeah/JD board or anything else. This page is the canonical definition of that brand; every surface consumes the same tokens:
| Surface | How it consumes the tokens |
|---|---|
| Vending kiosk screen (patched Reyeah/JD APK) | CI brand pass (reyeah-jd-vending-kiosk/scripts/localize_en.py BRAND_COLORS) writes the android token section into the APK theme; launcher icon overlay |
| Emulator (kiosk + operator frames) | /emulator CSS mirrors these tokens 1:1 |
| Hosted operator view | /operator links /design/tokens.css directly |
| Operator console (web + Android) | builds from /design/tokens.json (kiosk-x-operator) |
Hosted kiosk storefront (/kiosk/ui, ZHZN WebView) |
{c:*} token substitution + the same coral/amber chrome |
| Shopper phone pages (spin, scratch, draws, fortune, ads, live) | app/phone_theme.py — same palette, kx-* components |
| Guides / docs / QR pages | brand gradients + charcoal neutrals |
Machine-readable sources (consume these, never copy values by hand):
- JSON —
/design/tokens.json - CSS custom properties (
--kx-*) + shared keyframes —/design/tokens.css
Token provenance (v2.0.0): the Kiosk-X Figma
(Kiosk Web UI mQcUnikYgRdZzhmYJsGhHI — marketing site, Kiosk OS page, merch
checkout) and its shipped CSS (Intelliverse-X-User-Webfrontend
merch-theme.css, kiosk-x app/phone_theme.py): charcoal #151515 surfaces,
1px #333333 hairlines, one coral accent #f05a47 on cream #fff9e9 ink, amber
#f5c66c for money and warnings, Sora body / Montserrat Alternates display /
Poppins CTAs.
v2.0.0 — brand v2. The v1 deep-space navy / neon cyan / purple set (extracted from intelli-verse-x.ai and the vending APK overlay) is retired on every surface. Token keys are unchanged —
purple-*,cyan-*,pink-500survive as aliases of the coral ramp — so no consumer breaks; only values moved. The APKBRAND_COLORSmirror and the operator-console token sync pick the newandroidsection up on their next build.
1. Palette
Brand
| Token | Value | Use |
|---|---|---|
coral-500 (alias purple-500) |
#f05a47 |
Primary. APK colorPrimary, buttons, prices, selection, active nav |
coral-700 (alias purple-700) |
#c9412f |
Deep coral. APK colorPrimaryDark (status bar), pressed states, gradient tails |
coral-300 (alias cyan-400) |
#ff8a75 |
Highlight. APK colorAccent, links, focus rings, beams |
cyan-300 |
#ffb3a5 |
Light coral tint. Overlines, hover text |
amber-500 (alias pink-500) |
#f5c66c |
Money, streaks, 18+ tier, gradient tails |
amber-300 |
#ffdd99 |
Amber highlight |
cream |
#fff9e9 |
Ink on coral fills, wordmark |
ink |
#151515 |
Text on coral / amber fills |
Semantic
| Token | Value | Use |
|---|---|---|
green-400 |
#3ecf93 |
Online, verified, shipped, positive |
teal-500 / teal-600 |
#2fb27f / #25955f |
Healthy stock bars, success |
amber-500 |
#f5c66c |
Low stock, warnings, streaks, 18+ tier |
rose-400 |
#ff6b6b |
Faults, out of stock, offline, refunds |
Charcoal neutrals
| Token | Value | Use |
|---|---|---|
bg |
#151515 |
Page background |
panel |
#1c1c1c |
Cards, panels |
surface |
#202020 |
Product tiles, inputs |
surface-2 |
#262626 |
Secondary buttons, chips |
kiosk-shell |
#0a0a0a |
Device frames |
line |
#333333 |
Hairline borders |
line-bright |
#3d3d3d |
Borders on raised tiles |
line-glow |
#444444 |
Screen bezels |
text |
#fafafa |
Primary text |
muted |
#b8b8b8 |
Secondary text |
Contrast: text on bg is ≈17:1; muted on panel ≈8:1 — keep body copy at
or above these pairings. Ink on a coral fill is cream, never text on coral-300.
2. Gradients
Coral is the brand; gradients stay inside the coral/amber ramp so surfaces read as one product, never a rainbow.
| Token | Value | Use |
|---|---|---|
brand |
90deg, coral-300 → coral-500 55% → amber-500 |
Wordmark & display text (background-clip: text) |
action |
90deg, coral-500 → coral-700 |
Primary buttons |
hero |
135deg, coral-700 → coral-500 |
Money/sales hero cards |
price |
90deg, coral-300 → coral-500 |
Price text on product tiles |
age-18 |
90deg, amber-500 → coral-500 |
18+ tier chip |
age-21 |
90deg, coral-700 → coral-500 |
21+ tier chip |
screen |
radial #202020 → #191919 → #151515 |
Attract-screen ambient depth |
3. Typography
Sora for body and UI (400–800), Montserrat Alternates for display /
headings (600–900), Poppins for CTA labels — the Figma type stack, served by
the typography.google-font link. Mono for wire logs and machine serials:
ui-monospace, Menlo, monospace.
| Style | Spec | Example |
|---|---|---|
| Display | 42px / 900 / -1px, brand gradient | the KIOSK X wordmark |
| H1 | 30px / 800 / -0.4px | page titles |
| Stat | 32px / 900 | money numbers ("$247.50") |
| H2 | 20px / 800 | section heads |
| Body | 15px / 400 / 1.55 | copy |
| Label | 12px / 600 | field labels, sublines |
| Overline | 11px / 700 / 5px tracking / uppercase, coral-300 |
"SCAN · PLAY · WIN" |
| Micro | 10px / 600 | chips, wire annotations |
Android (operator console / APK): map Display→displayMedium, H1→headlineMedium,
Stat→headlineLarge, Body→bodyLarge with the same weights.
4. Spacing & radii
4px base unit. Scale: xs 4 · sm 8 · md 12 · lg 16 · xl 24 · 2xl 28.
Touch targets ≥ 48px on kiosk and operator surfaces (gloved hands, arm's length).
Radii scale: sm 8 · md 12 · lg 14 · xl 16 · screen 14 · device 22 · pill 999,
plus two semantic tokens every surface must use: radius.button = 12px and
radius.card = 16px (--kx-radius-button / --kx-radius-card in
tokens.css). Device frames 22px; chips/pills fully rounded.
v1.0.1 reconciliation — this doc previously specified buttons 9px / cards 14px while the operator console and the native app had both shipped 12px / 16px. The shipped values win: 12/16 is now the contract, the vending emulator and hosted operator view were restyled to match, and the semantic tokens above exist so no surface hard-codes these again. Branding evals should score against 12/16.
5. Iconography
- Emoji glyphs are the icon set — playful, category-agnostic, zero-download, render identically on the RK3288 kiosk board and every phone: 🥤 drinks · 🍿 snacks · 🎧 tech · 💄 beauty · ⚡ energy · 🍺 alcohol · 💨 vape · 🎁 fallback.
- Logo: the Figma wordmark — "Kiosk" in
text/cream, "X" incoral-500; for icon sizes a "KX" monogram, 900 weight, on acoral-500tile (10-12px radius). The APK launcher icon set (overlays/launcher_icons) uses the same monogram. Accepted deviation: the launcher icon backgrounds (vending APK and operator app) are#0b0d17, not tokenbg #151515. The difference is imperceptible at icon sizes, it is consistent across both apps, and regenerating means re-shipping binary assets through the single-owner APK pipeline — so#0b0d17stays until the next icon refresh. - QR codes: brand-customized per destination (
app/qr.py, one generator for every surface): rounded modules in the destination product's primary color on a white field, error-correction H, and that product's app-icon mark on a white center plate. Brand map — QuestX (free-product play + prize-mechanic QRs: indigo#4f46e5modules, purple-Q icon), ContentX (advertise-here QRs + the getAd house poster: magenta#a21cafmodules, CX icon), Intelliverse X (Game World / multiplayer join QRs: purple#7c3aedmodules — the APKcolorPrimaryDark— with the X-mark tile), KX ink (operator-view and operator-app QRs). Logo marks ship inapp/brand_assets/and are served at/brand/{brand}.pngfor client-rendered codes (game screen, emulator). Every profile is machine-decode tested (tests/test_branded_qr.py).
6. Component styling
| Component | Recipe |
|---|---|
| Primary button | gradient.action, cream 700 Poppins text, radius.button (12px); hover: brightness 1.12 + coral glow |
| Secondary button | surface-2 fill, line border, radius.button (12px); hover: coral-300 border + coral glow |
| Card | panel fill, line border, radius.card (16px) |
| Product tile | surface fill, line-bright border, 12px radius; hover: lift -3px, scale 1.03, coral shadow |
| Stat hero | gradient.hero fill, white text, 16px radius |
| Stock bar | 6px tall, 3px radius, line track; fill teal-500 / amber-500 (≤ threshold) / rose-400 (0 or faulted) |
| Alert pill | pill radius; amber rgba(245,198,108,.15) / rose rgba(255,107,107,.15) tints |
| Age chip | pill; 18+ gradient.age-18, 21+ gradient.age-21, white 800 text |
| Status dot | 8px circle; online green-400 with 8px glow, offline rose-400 |
| Toast | panel fill, coral-500 border, coral glow, bottom-center |
7. Motion — the gamified feel
Kiosk X screens are alive: ambient motion at idle, springy feedback on touch, celebration on success. Timings and easings:
- Tap feedback 150ms, hover 180ms, pop-ins 400ms.
- Springy entrances use
cubic-bezier(.2,1.6,.4,1)(--kx-ease-pop). - Signature keyframes (shipped in
tokens.cssaskx-*):glowpulse(wordmark glow, 2.6s),drift(blurred brand-color orbs, 9-13s),floaty(category emoji),popin(reward chips),blink(CTA pulse, 1.6s),confetti(70-piece brand-colored burst on purchase),buzz(tray shake on dispense),scanbeam(coral sweep on the age-check card). - The age gate is a branded moment, not a compliance wall: playful copy
("Quick age check … straight back to the fun"), scanbeam animation,
popinverified state. - Honor
prefers-reduced-motion: drop drift/floaty/glowpulse, keep state changes.
8. Voice
Playful, gamified, category-agnostic. "Scan · Play · Win." Never stern: "Quick age check" not "AGE VERIFICATION REQUIRED"; "Enjoy! Grab your item below — scan the QR to play & win" not "Transaction complete".
9. Consuming the tokens
Web (operator view, console, docs):
<link rel="stylesheet" href="https://api.kiosk-x.ai/design/tokens.css">
<style>
body { background: var(--kx-bg); color: var(--kx-text); font-family: var(--kx-font-body); }
.buy { background: var(--kx-gradient-action); }
</style>
Build-time (operator console web/Android): fetch
https://api.kiosk-x.ai/design/tokens.json and generate your Tailwind theme /
Compose ColorScheme from it. The android section is the exact APK mapping:
colorPrimary #f05a47 · colorPrimaryDark #c9412f · colorAccent #ff8a75.
Vending APK: the CI brand pass already applies the android section —
change tokens here first, then mirror in localize_en.py BRAND_COLORS.
The tokens are versioned (version in the JSON, X-Kiosk-X-Design-Version
response header). Breaking renames bump the major version.