Brand and design
Shuke / 述刻 — hi-fi design v1
The hi-fi gallery, the botgumi stages mapped onto it, the checks and the pending gates.
Static HTML/CSS/JS. No build step is needed to view anything here. Every screen and state is drawn at 393 × 852 pt (iPhone 15/16 Pro) in both UI languages (zh-Hans and en, ADR-001 D13), shares one token layer, and carries data-bind annotations to the API contract.
botgumi stages (ADR-0004)
This repo follows the botgumi template (.botgumi.json); its design process has five stages, each closed by a
human gate. Shuke's design was finished before those gates existed, so the stage files sit on top of the gallery
below without redrawing anything, and every gate is retroactive and pending: no gate issue has been opened, so
no screen is approved yet. design/check.mjs (botgumi's structural check) passes on this folder.
| # | Stage | Botgumi output | What exists here | Gate |
|---|---|---|---|---|
| 1 | Brand brief | brand/brief.md, brand/mark.svg |
brand/brief.md filled from the README and ADR-001; name, domain and mark are open |
pending |
| 2 | Design system | system/design-system.md, system/tokens.source.json |
system/design-system.md points at tokens.md and base.css; system/tokens.source.json mirrors tokens.css in the template's shape (generated, must be kept in step) |
pending |
| 3 | Lo-fi | lofi/screens.md, lofi/wireframes/ |
lofi/screens.md: every screen with a stable ID (S01…S34), its states and flows, generated from screens.json, the screen contract (botgumi ADR-0006). The lo-fi stage itself was skipped: the gallery is the wireframe set and the prototype (lofi/wireframes/README.md) |
skipped |
| 4 | Hi-fi | hifi/<ID>/screen.md, hifi/<ID>/bindings.md, boards |
hifi/<ID>/ per screen: contract, a board per state (the gallery files), tokens used, strings, and the data-binding map; every screen is at hifi |
pending, per screen |
| 5 | Screenshot direction | screenshots/direction.md |
screenshots/direction.md, not started |
pending |
screens.json is the screen contract (botgumi ADR-0006, D1): every screen, its stage and gate, its states with their
boards per locale, example data and binds, its calls, binding fields, tokens and strings. For now it is exported
from the gallery by tools/hifi_index.py, because tools/build.py still draws the boards; the pages under lofi/
and hifi/ and the screen pages of docs/manifest.json are generated from it by botgumi's botgumi-design index.
Checks (CI runs all of them in .github/workflows/design.yml, with botgumi's packages from GitHub Packages):
node design/check.mjs # token shape, screen list, wireframe per screen, hi-fi folders, boards per state, binding maps
node --test design/check.test.mjs # the check's own tests
python3 design/tools/tokens_source.py --check # system/tokens.source.json is in step with tokens.css
python3 design/tools/hifi_index.py --check # screens.json and lofi/wireframes/S*.md are in step with the gallery
pnpm design:check # all of the above, then botgumi-design check: the contract's rules, every board and example, tokens, stale pages
Gaps: the four required states (loading, empty, error, offline) are listed for every screen, but where the
gallery has no board of its own for one, hifi/<ID>/screen.md says so and quotes states.md; elevation, motion and font-stack tokens have no group in
tokens.source.json and stay in tokens.css. Each bound field has a typed source checked against
docs/api/openapi.yaml (botgumi ADR-0006 D2); the six that wait on CCR-14 are pending.
How to view
Through the docs site: pnpm docs:dev at the repo root, then http://127.0.0.1:4321/design/gallery/ (the gallery
below, served with its tokens, components and fixtures), http://127.0.0.1:4321/design/hifi/s01/ for a screen's
contract and binding map, and http://127.0.0.1:4321/api/reference.html for the rendered API. The hosted docs serve
the same paths. Or from disk:
- Open
screens/index.htmlin a browser (double-click works;file://is fine). This is the gallery: every screen/state as a live thumbnail, grouped by flow.- Language: 中文 / English swaps every screen. Deep link with
index.html?lang=en. - Theme: light / dark. Type: Dynamic Type 100 / 120 / 135 %. Show: data-bind outlines, reduced motion, increased contrast. Zoom: S / M / L.
- Language: 中文 / English swaps every screen. Deep link with
- Click a thumbnail to open the screen full size. The spec panel on the right lists the state description, API calls, local state, interaction notes, sibling states, and a link to the other language. Press b to outline every bound element with its source path.
- The paywall is interactive: open
screens/paywall/paywall--default.html(or.en.html), drag the 3/5/7 slider and switch plans. The projection, calendar, billing date and CTA update from the embedded/v1/paywall+ StoreKit JSON.
URL parameters work on any screen file: ?theme=dark&dt=1.2&motion=reduced&contrast=high&binds=1.
Index
| Deliverable | File | What it is |
|---|---|---|
| Gallery | screens/index.html |
102 zh-Hans + 101 en screens/states in 15 groups |
| Screens | screens/<group>/<screen>--<state>.html (zh-Hans), ….en.html (en) |
One file per screen per state per language |
| Screen manifest | screens/manifest.json |
Every file with title, description, API calls, local state, data binds |
| Tokens | tokens.css + tokens.md |
Colour (light/dark/high-contrast), type (iOS text styles), spacing, radii, elevation, motion, haptics |
| Token source (botgumi shape) | system/tokens.source.json |
Generated mirror of tokens.css for design/check.mjs and @botgumi/design-tokens; regenerate after any token change |
| Base components | base.css, base.js |
Shared components + viewer (theme / type / bindings / count-ups) |
| Strings | strings.json + copy.md |
Every client string keyed, en and zh-Hans (xcstrings-shaped JSON; copy.md is generated) |
| Example data | ../docs/api/examples/ en/, zh-Hans/, index.json |
API-shaped responses behind every number on screen (seed data), each validated against its operation by botgumi-design check |
| Flows | flows.md |
9 flows as Mermaid + step tables (screen, trigger, API, success, failure, exit) |
| States | states.md |
Screen × {loading, empty, error-retryable, error-fatal, offline, partial} |
| Data binding | data-binding.md |
Element → source → format → fallback for every screen, and the contract change requests |
| Onboarding | onboarding.md |
Rationale, questions, mapping to /v1/onboarding and the plan |
| Paywall | paywall.md |
Projection formula, calendar rules, honesty rules |
| Engagement | engagement.md |
Quest, XP, streak, levels, achievements, notifications, haptics/motion per moment, dark patterns not used |
| iOS handoff | ios-handoff.md |
SwiftUI component map, SF Symbols, localization, Dynamic Type, VoiceOver labels, hit targets |
| Generator | tools/ |
build.py + fixtures + string catalog + screen templates (stdlib Python) |
| Stage pages | screens.json, lofi/, hifi/, brand/, system/, screenshots/ |
The botgumi stage files (see the top of this page); screens.json is exported by tools/hifi_index.py, and lofi/screens.md and hifi/ are generated from it by pnpm design:index |
Screen groups
Onboarding (welcome, practice language, goal, scenario, self-level, commitment, notification priming) · Diagnostic (intro, read, mic purpose sheet, record × 6, processing × 5, result reveal) · Plan · Paywall × 6 · Home × 10 · Library × 6 · Read × 3 · Record round 1 × 7 · Processing × 7 · Feedback × 6 · Compress round 2 × 7 · Complete × 6 · Growth × 4 · Profile & settings × 8 (incl. languages) · Global × 5.
How iOS should consume this
- Tokens → code. Mirror
tokens.cssintoDesignSystem/Tokens.swift(Color.accentPrimary,Spacing.s4,Radius.card,Motion.base,Font.shuke(.headline)) and an asset catalog with Any / Dark / High-Contrast variants. Names map 1:1 (tokens.md). - Strings →
Localizable.xcstrings. Convertstrings.jsondirectly (same key,ensource,zh-Hanstranslation,**bold**markdown). Never hard-code a string or a unit. - Screens → views. Use the gallery for layout and states, and the spec panel for API calls.
data-binding.mdis the field-by-field contract for each view model. Components and system/custom decisions are inios-handoff.md. - Example data → previews/tests.
docs/api/examples/<locale>/*.jsondecode straight into the API models. Use them for#Previewand snapshot tests in both locales (zh-Hans persona 晓雯 practises zh-Hans + en; en persona Mia practises en). - States. Every screen must implement the cells in
states.md. Reviewers check against the gallery. - Contract gaps. Fields the screens need but the contract lacks are listed at the top of
data-binding.mdwith fallbacks. CCR-1…13 were applied in #8; CCR-14 is open. Each needs anopenapi.yamlPR. The design track does not edit the contract.
Regenerating
The committed HTML is the deliverable; viewing needs nothing. To change content or templates:
python3 design/tools/build.py # rewrites screens/, docs/api/examples/, strings.json, copy.md; runs structural checks
python3 design/tools/tokens_source.py # rewrites system/tokens.source.json from tokens.css (after a token change)
python3 design/tools/hifi_index.py # rewrites screens.json and lofi/wireframes/S*.md from the gallery
pnpm design:index # rewrites lofi/screens.md, hifi/S*/ and the screen pages in docs/manifest.json from screens.json
pnpm docs:build # rebuilds docs/public/
Run them in that order after a change. hifi_index.py keeps each screen's ID, stage and gate from the committed
screens.json, so an approved screen stays approved.
The build fails on unbalanced HTML, duplicate ids, lorem ipsum, a missing string key in either language, or any CJK text leaking into an English screen.
Visual language (kept from the prototype, polished)
Warm off-white canvas #FAF9F5 / #F5F2E9, ink #171717 cards for the moments that matter (today's quest, Change just one thing / 这次只改一件事, the before/after block), coral #FF6030 only for the primary action and live recording, lime #DFFC66 only for rewards and levels, violet / green / amber for topics and dimensions. Avenir Next + PingFang SC, pill + 16–20 pt radii, the concentric-ring record button. Removed per ADR-001: the 4th 迁移 step, fixed numbers, the 3-second gate, the desktop frame, unconditional praise.