F · Foundation
Tokens
Everything the system is allowed to use, as CSS custom properties on :root in
css/classic/tokens.css. The dark theme overrides a subset; nothing else in the system contains a literal
value. Names follow --qf-{group}-{name}[-{step}].
Ten families, each with steps 25 → 900 and a main alias. Steps 25/50 are surfaces, 100/200
light accents, 300/400 borders and hover, 500 the default, 600–900 text and dark chrome. Toggle the theme to
see the dark overrides: info and primary swap ends so that the same step keeps the
same role.
Semantic aliases
Components reference roles, not ramps, wherever a role exists. These are the names that dark mode actually overrides; most components never touch a ramp directly.
Typography
Avenir Next at three weights (500, 600 and 700, each with its italic), with Twemoji Mozilla for emoji; nothing
lighter is loaded. The default is sm (0.875rem, 14px at the desktop root size) at weight 500; it accounts for 62% of all text sites, so it is the value you get
with no attributes at all.
| Size | Sample | Token |
|---|---|---|
| h1 · 1.5rem / 900 | Inbox overview | --qf-text-h1 |
| h2 · 1.25rem / 900 | Assigned to you | --qf-text-h2 |
| h3 · 1rem / 900 | Recent documents | --qf-text-h3 |
| h4–h6 · 0.875rem / 700 | Section heading | --qf-text-h4 |
| xl · 1.25rem · 20px | The quick brown fox jumps over the lazy dog | --qf-text-xl |
| lg · 1.125rem · 18px | The quick brown fox jumps over the lazy dog | --qf-text-lg |
| md · 1rem · 16px | The quick brown fox jumps over the lazy dog | --qf-text-md |
| sm · 0.875rem · 14px (default) | The quick brown fox jumps over the lazy dog | --qf-text-sm |
| xs · 0.75rem · 12px | The quick brown fox jumps over the lazy dog | --qf-text-xs |
| overline | Section label | uppercase · tracked |
| Weight | Sample | Use |
|---|---|---|
| regular · 500 | Body copy and field values | body (default) |
| medium · 500 | Labels, buttons, list titles | labels |
| semibold · 600 | Emphasis inside body copy | emphasis |
| bold · 700 | Titles, dialog headers, page headings | titles, display |
Spacing
A 0.25rem (4px) base, in rem so it scales with the root size (16px desktop, 20px tablet and mobile). Named steps map to the style guide: tight, standard, field group, card content, section, page.
| Token | Value | Role | Scale |
|---|---|---|---|
--qf-space-1 |
0.25rem · 4px | tight | |
--qf-space-2 |
0.5rem · 8px | standard | |
--qf-space-3 |
0.75rem · 12px | field group | |
--qf-space-4 |
1rem · 16px | card | |
--qf-space-5 |
1.25rem · 20px | ||
--qf-space-6 |
1.5rem · 24px | section | |
--qf-space-8 |
2rem · 32px | page | |
--qf-space-10 |
2.5rem · 40px | ||
--qf-space-12 |
3rem · 48px | ||
--qf-space-16 |
4rem · 64px |
Radius
Role aliases (control, card, menu, dialog) are what
components use.
alerts, tabs
control
card
menu
dialog
Elevation
Six steps. Cards rest at xs and lift to sm on hover; menus and popovers use
lg; dialogs use 2xl.
Sizing
| Token | Value | Used by |
|---|---|---|
--qf-control-height |
2rem (32px) | Button, Field, Select, DatePicker |
--qf-control-height-sm |
2rem (32px) | Small controls, toolbar buttons, pagination |
--qf-control-height-xs |
1.75rem (28px) | Chip delete, inline icon buttons |
--qf-icon-size |
1.25rem (20px) | Icon default |
--qf-icon-size-sm / -xs |
1rem / 0.875rem (16px / 14px) | Inline and chip icons |
--qf-avatar-3xs … -2xl |
16 · 20 · 24 · 32 · 40 · 48 · 56 · 64 | Avatar |
--qf-row-padding-y |
0.125rem (2px) | List rows, table cells |
--qf-nav-width |
13.5rem (216px), hidden when collapsed; user-resizable 10.5rem to 25rem | App shell |
--qf-appbar-height |
2rem (32px) | App shell |
Motion & layering
| Token | Value | Use |
|---|---|---|
--qf-duration-instant |
80ms | Press feedback |
--qf-duration-fast |
150ms | Hover, color, tooltip |
--qf-duration-normal |
220ms | Dialog, popover, nav collapse |
--qf-duration-slow |
320ms | Drawer slide, progress |
--qf-ease-standard / -enter / -exit |
cubic-bezier | Symmetric, decelerate, accelerate |
--qf-z-sticky |
100 | Sticky headers and toolbars |
--qf-z-appbar / -drawer |
200 / 300 | Shell chrome |
--qf-z-overlay |
1000 + 10·depth | Dialog stack |
--qf-z-popover / -toast / -tooltip |
1300 / 1400 / 1500 | Floating layers above every dialog |
--qf-bp-tablet / -desktop |
834px / 1200px | Reference only; media queries repeat the numbers |
… glyphs compiled into sprites/icons.svg as
<symbol>s by build-sprite.mjs from icons.txt. The sprite holds
every Tabler icon the system uses, a Tabler equivalent for every Blueprint icon the
classic app uses, and the classic app's own glyphs (folders, tasks, collections, workflow templates) ported
from its SVG bundles as custom/ symbols. sprites/classic-map.json maps each legacy
name to its symbol. Click a glyph to copy its markup.
# 1. add the Tabler name to design/sprites/icons.txt (kebab-case; "-filled" picks the filled set) echo "rocket" >> design/sprites/icons.txt # 2. rebuild node design/sprites/build-sprite.mjs # 3. use it <svg class="qf-icon"><use href="sprites/icons.svg#rocket"/></svg>
Themes
The theme is a token override: data-theme="dark" on
<html> redefines the color and shadow tokens inside the same tokens.css, so
every part follows without a rule of its own. There is one skin, classic, and it is the whole stylesheet
set: css/classic/ reproduces the GWT QAction app: 13px text on a #FAFAFA page, the
navy #10477E band with chip tabs, the pale left menu with bold #000F9F entries, a cyan hover and a green
selection mark, 24px bold buttons with 2px corners, #0B568D framed panels, grids and menus with a #B8DEFA
header row, orange row hover and periwinkle selection, and 5px-radius dialogs with a 20px navy header. No
rule contains a [data-skin] selector: the values live in tokens.css and the
geometry tokens cannot express in the layer files. Pages carry data-skin="classic" on
<html> for scripts.
Office
tokens-office.css
The QEditor editors' tokens (spec §2.1 F9–F19), in tokens-office.css, imported
right after tokens.css. App accents derive only from the QFlow palette (owner decision Q8)
and are set by [data-app]; every app is also named by its glyph and label, so color is
never the only cue. The classic skin paints the ribbon tab row with the app's chrome color. Hex stays in --qf-palette-*; the measured contrast of
each accent is recorded next to it in the file.
| Metric | Value | Use |
|---|---|---|
--qf-office-titlebar-height | 3rem · classic 2.5rem | the window header that carries the title bar |
--qf-ribbon-tabs-height | 2.5rem | tab row |
--qf-ribbon-compact-height | 2.5rem | Compact ribbon (single line, the default) |
--qf-ribbon-full-height | 5.75rem | Full ribbon: three 1.5rem rows and a group label |
--qf-command-height-sm | md | lg | 1.5 · 2 · 4.125rem | command buttons (sm is the 24px minimum target) |
--qf-command-icon-sm | md | lg | 1 · 1.25 · 2rem | office glyphs (one 20-grid sprite, scaled) |
--qf-statusbar-height | 1.75rem | status bar |
--qf-pane-width (min, max) | 20rem (16, 32) | task panes |
--qf-thumb-rail-width | 13rem | slide thumbnail rail |
--qf-formula-bar-height · --qf-namebox-width | 2rem · 7rem | formula bar |
--qf-grid-row-height · --qf-grid-row-header-width | 1.25rem · 2.5rem | sheet grid |
--qf-office-bp-search · wide · medium · narrow | 84 · 64 · 48 · 36rem | container-query widths on .qf-office-app |