Brand and design · Hi-fi screens · Hi-fi screens

Hi-fi: S17 Library · Library

Contract, a board per state (loading, list, language-en, filtered, filter-empty, error, empty, offline), tokens and strings.

Generated by botgumi-design index from ../../screens.json. Edit that file, not this page.

Stage: hifi · Key: library/library · Data-binding map: bindings.md

Drawn in the gallery: Library. Each board is the committed HTML in screens/, drawn on the example data in docs/api/examples/.

Contract

  • loading: Skeleton rows. No import button in v1 (config.flags.import_enabled = false).
  • list: All languages + topics: unseen / in progress / completed (best score) / locked tier. A language tag shows on each row when more than one practice language exists. No import button in v1 (config.flags.import_enabled = false).
  • language-en: Language filter = English (GET /v1/articles?language=en). No import button in v1 (config.flags.import_enabled = false).
  • filtered: Topic filter = Product. No import button in v1 (config.flags.import_enabled = false).
  • filter-empty: Topic with 0 articles → empty state + clear filter. No import button in v1 (config.flags.import_enabled = false).
  • error: Retryable load failure. No import button in v1 (config.flags.import_enabled = false).

Flows: F3 Free practice from the library.

Reads and calls:

  • GET /v1/topics (Accept-Language)
  • GET /v1/articles?language=&topic=&status=&cursor=
  • POST /v1/sessions {article_id, kind: free}

Local state:

  • local:library.filter.language
  • local:library.filter.topic
  • local:library.filter.status

Boards

One row per state. A state without boards of its own says what shows it.

State Board Example data
loading zh-Hans · en
list zh-Hans · en articles.json (zh-Hans · en)
language-en zh-Hans articles.json (zh-Hans)
filtered zh-Hans · en articles.json (zh-Hans · en)
filter-empty zh-Hans · en
error zh-Hans · en
empty no board of its own: From states.md (Library): library--filter-empty
offline no board of its own: From states.md (Library): cached first page + banner; filters on cached data only

The boards

Each state as drawn (393 × 852), one board per locale. Open a board on its own for its spec panel.

loading

list

language-en

filtered

filter-empty

error

Tokens used

By path in ../../system/tokens.source.json.

Token Where
color.accentPrimary .btn--primary
color.accentPrimaryPressed .btn--primary
color.bgCanvas .device, .large, .navbar, .screen …
color.bgInverse .chip, .tag--ink
color.bgInverseRaised .skel
color.bgSunken .btn, .segmented, .skel, .state-illo …
color.bgSurface .btn--secondary, .chip, .list, .segmented
color.lineHairline .btn--secondary, .btn--sm, .chip, .list-row …
color.lineInverse .topic-ink
color.lineStrong .btn--secondary, .tag--line
color.textDisabled .btn
color.textOnAccent .btn--primary
color.textOnInverse .chip, .tag--ink
color.textOnInverseSecondary .chip, .count
color.textPrimary .btn--secondary, .chip, .device, .home-indicator …
color.textSecondary .c-secondary, .segmented, .state-illo, .tag
color.textTertiary .c-tertiary, .chip, .count, .list-row …
color.topicCoral .topic-coral
color.topicGreen .tag--green, .topic-green
color.topicGreenSoft .tag--green
color.topicViolet .tag--violet, .topic-violet
color.topicVioletSoft .tag--violet
radius.button .btn
radius.md .list
radius.pill .btn--sm, .chip
radius.sm .topic-tile
radius.xs .tag
space.gutter .chip-row, .large, .navbar, .pad
space.s6 .has-tabbar, .screen
space.safeBottom .has-tabbar, .screen, .tabbar
space.safeTop .device, .screen
space.sizeCtaHeight .btn, .screen
space.sizeNavbarHeight .navbar
space.sizeTabbarHeight .has-tabbar, .screen, .tabbar
typography.callout .t-callout
typography.caption1 .t-caption
typography.footnote .t-footnote
typography.largeTitle .t-large-title
typography.subheadline .t-subhead
typography.title3 .t-title3

Strings

app.name, band.clear, common.all, common.difficulty, common.error_code_retryable, common.retry, common.today, growth.title, home.level.a11y, lang.all, lang.en, lang.zh-Hans, library.empty.body, library.empty.cta, library.empty.title, library.error.body, library.error.title, library.filter.language.a11y, library.filter.status.a11y, library.filter.status.completed, library.filter.status.unseen, library.filter.topic.a11y, library.footer.tier3, library.row.locked, library.row.status.best, library.row.status.in_progress, library.row.status.unseen, library.subtitle, library.title, notif.daily.title, paywall.calendar.legend.today, paywall.calendar.rest, paywall.projection.score, processing.unreliable.reason_label, read.tag.daily, tab.growth, tab.home, tab.library, tab.nav.a11y

Notes for the app tracks

Motion, haptics, Dynamic Type and VoiceOver: engagement.md, tokens.md §6–7 and ios-handoff.md. Open a board with ?theme=dark&dt=1.35&binds=1 to see dark mode, the largest tested type size and every bound element.

Tracking-plan events: no tracking plan page exists yet; ADR-001 D12 names the events.

Tokens with no group in system/tokens.source.json yet (they stay in tokens.css): --dt, --elevation-1, --font-family-reading, --font-family-text, --font-weight-bold, --font-weight-medium, --font-weight-regular, --font-weight-semibold, --motion-duration-fast, --motion-duration-instant, --motion-ease-standard, --type-tracking-tight.