DESIGN SYSTEM
BFSUAPA Design System
Choose layouts and components from the content, look up type, spacing and motion values, and check phone display and keyboard use before handing off.
How to use this document
When building a page, choose the layout and components from the content first, then use the existing colour, type and spacing variables, and finally check phones, keyboard use and the light and dark themes. This page is for web design and development; for copy editing, see the Style guide; for logos and printed material, see the Brand guidelines.
A "token" is the name of a design variable; for example, --ink is the body text colour. Reusing variables lets many pages adapt to theme changes at once. Values follow the current definitions in the repository's src/app/globals.css; if the design notes disagree, check the implementation against the design requirements first, then change both together.
Choosing a presentation from the content
| What you need to present | Preferred approach |
|---|---|
| An article meant to be read through | Paragraphs, section headings and images that match the text |
| Steps that happen in order | An ordered list or timeline that keeps every step |
| A few options to compare | A table or static grid that states what is being compared |
| Several photos from the same event | A photo set in narrative order, with captions kept |
| Content the reader needs to act on | Existing buttons, links or forms, with clear results and error messages |
Give each area a clear focus; do not add cards, motion or colour in place of organising the content. Do not put important steps in an area that has to be scrolled sideways to discover. The component list and values follow below.
Colour, type and spacing values
Colour
The full seven-continent and four-ocean colour system is in the Colour system. Only the neutrals and core structure are listed here.
| Variable | Light | Dark | Meaning |
|---|---|---|---|
--paper | #ffffff | #0d1117 | Background; off-white, cream or yellowed tones are not allowed |
--ink | #111318 | #f5f7fa | Body / primary text |
--deep | #0d1117 | #080b10 | Dark surface |
--muted | #626b78 | #a8b1be | Secondary text |
--on-accent | #ffffff | #0d1117 | Text on accent-coloured surfaces |
--line | ink 19% mix | ink 18% mix | The only default divider |
--focus | #1f5aa8 | #87aae0 | Focus outline |
Core brand colour: BFSUAPA Red --torch-red (#e14b3f); seven continents --continent-*; four oceans --ocean-* (for the 10-step scales and pairing rules, see the colour system). The web interface uses the --accent-* accent colours; the brand palettes are for visual content that needs a clear theme. For choosing colours and checking contrast, see the Colour system.
Not allowed: gradients, warm washes, paper textures, decorative greys; off-white, cream or yellowed backgrounds.
Type
| Variable | Use |
|---|---|
--font-display | Display and interface headings (Noto Sans Variable + CJK) |
--font-cjk | Chinese body text (Noto Sans SC Variable, PingFang, Microsoft YaHei) |
--font-world | Translations in other languages (Noto fonts chosen per language) |
- Heading line height 1.12–1.28; body line height 1.65–1.8.
- Headings use
text-wrap: balance; paragraphs usetext-wrap: pretty. - Chinese is never set in italics.
Spacing
Spacing starts at 0.5rem and steps up along this scale:
0.5 → 0.75 → 1 → 1.5 → 2.25 → 3.5 → 5.5 (in rem)
- When using
clamp(), make sure the result is readable at both 390px and wide desktop.
Corners and borders
- Panels and cards always have square corners (
border-radius: 0). - Only circular controls may be round (such as the
999pxradius on the theme and language toggles). - Inline code may use a small radius (4px).
- Dividers are always 1px
--line; adjacent dividers share an edge rather than stacking borders.
Motion
| Variable | Value | Use |
|---|---|---|
--motion-fast | 150ms | Quick feedback (hover, press) |
--motion-base | 200ms | Standard transitions (colour, movement) |
--motion-slow | 220ms | Panels opening, complex entrances |
--motion-ease | cubic-bezier(0.22, 1, 0.36, 1) | Shared easing curve |
Choosing existing components by purpose
Articles on the site are organised as semantic blocks. Each block first makes sure the information is complete and readable, then adds limited, controlled interaction.
Component list
| Component | When to use it |
|---|---|
EditorialSection | A new section within an article |
EditorialQuote | A line of source text, or a confirmed quotation, worth pausing on |
EditorialTimeline | Recruitment steps, event schedules, timelines |
EditorialCardSlider | Parallel items that can each be read alone; many items do not require side-scrolling |
EditorialFigure | A single cover, an in-text image or a credited image |
EditorialPhotoSet | Two to four documentary photos in the same passage |
EditorialImageSequence | Long images, infographics and images in sequence |
EditorialMediaFeature | One source image + one passage of substantial reading |
EditorialAside | Sources, editor's notes, short fact-check notes |
EditorialDefinitionList | Compact, verified terms or facts |
EditorialReveal | Block entrance primitive (not a content type) |
Statistical visualisations reuse the data visualisation guidelines (data-viz.md): data cards, horizontal ranking bars, donut/share charts, rose charts, word clouds and timelines. All must use colour-blind-safe colours (blue + orange + gold) and meet the "legends labelled in text, readable offline and in screenshots" constraint.
Layout decisions
- Body text: paragraphs, sections and image sequences, with continuous reading first.
- Two to four items of equal weight: a static semantic grid, fully visible on the first screen.
- Five or more items of equal weight: consider a list or groups first; use side-scrolling cards only when each item can be read alone and nothing necessary is hidden.
- Time and steps: a timeline, not forced into a wall of cards.
- One image:
EditorialFigure; two to four documentary photos:EditorialPhotoSet; long images:EditorialImageSequence. - Important text inside images: OCR it and check it by hand, move it into adjacent body text, a timeline or cards, and keep the image as source material.
- Decorative images from the original WeChat posts, Xiumi templates and duplicate screenshots stay out of the reading flow.
Component registry
The component catalogue is in src/design-system/editorial-registry.json. Before adding a new story pattern, query it with pnpm design:context <intent...>. A new component must have: Chinese and English copy, a narrow-screen layout, a keyboard path, empty-content handling, alternative text, and light and dark theme checks.
Desktop and phone layout
- Editorial feel: a restrained grid, generous white space, a single 1px
--linedivider. - Adjacent dividers share an edge; no stacked borders, transforms or clipping pseudo-elements.
- Panels have square corners (only controls may be round).
Responsive breakpoints:
| Breakpoint | Requirement |
|---|---|
| ≥1024px | Asymmetric but deliberate columns |
| 768px | Protect the reading line length first, then think about visual arrangement |
| 390px | Stack in source order; touch targets ≥44px; reading column ≥18ch |
- Use horizontal scrolling only for clearly labelled tracks with keyboard controls; key reading content must never be hidden in a track.
Motion and reduced motion
- Motion serves function only: revealing state changes, keeping the reader's place, responding to actions.
- Use only
transformandopacity. EditorialRevealis the default entrance primitive: content is visible before JS loads, it observes once, moves no more than 0.65rem and never replays.- No auto-playing carousels, parallax, WebGL, blurred hover galleries, scrambled text, scroll-jacking or layout-shifting entrances.
- Under
prefers-reduced-motion, turn off non-essential transitions and use instant navigation. - Every interaction needs a static, keyboard-readable state; animation must never be the only way to understand the content.
Keyboard, image and assistive reading checks
- Use semantic
article,figure,figcaptionandsectionelements and a proper heading hierarchy. - Interactive galleries must be keyboard reachable, and screen readers should be able to tell which item is current without announcing too often.
- Respect dark mode, visible focus and image dimensions (to avoid layout shift).
- Lazy-load images below the first screen; components run with local resources only: no external web fonts, remote example images, analytics SDKs or animation libraries.
Do one real check before handing off
- Open the page on a phone and a desktop and check that text, tables and images are complete and nothing overflows sideways by accident.
- Switch between light and dark themes and check the actual contrast of text, borders, buttons and focus outlines.
- Use only the keyboard to reach links, buttons and forms; confirm that focus is visible, the order makes sense and the result of each action is clear.
- Turn on reduced motion and confirm that the content is still complete and readable and navigation does not depend on animation.
- Check image alternative text, the heading hierarchy, empty content and error states; finally, confirm that the source files, the implementation and the documentation agree.
Which files to check during development
| File | Purpose |
|---|---|
src/app/globals.css | Current colour, type and motion variables |
design.md | Overall design context |
docs/editorial-blocks.md | How to use the editorial components |
src/design-system/editorial-registry.json | Catalogue of existing components and their uses |
For specific colours, see the Colour system; to see how things look, see Design examples; or return to all guidelines.
