@filipgutica/design-system 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +53 -2
- package/language/DESIGN.md +210 -0
- package/language/components.html +1283 -0
- package/language/components.md +300 -0
- package/language/decisions.md +41 -0
- package/language/docs.html +111 -0
- package/language/product.html +74 -0
- package/language/reference.html +1038 -0
- package/language/themes/graphite-indigo/LICENSE +21 -0
- package/language/themes/graphite-indigo/README.md +21 -0
- package/language/themes/graphite-indigo/SOURCE.json +11 -0
- package/language/themes/graphite-indigo/THIRD_PARTY_NOTICES.md +5 -0
- package/language/themes/graphite-indigo/graphite-indigo.t3-theme.json +134 -0
- package/language/themes/graphite-indigo/package.json +40 -0
- package/language/themes/graphite-indigo/themes/graphite-indigo-dark-color-theme.json +707 -0
- package/language/themes/graphite-indigo/themes/graphite-indigo-light-color-theme.json +728 -0
- package/language/tokens.css +282 -0
- package/language/visualizations/build-count-report.mjs +167 -0
- package/language/visualizations/count-snapshots.md +51 -0
- package/language/visualizations/delivery.md +33 -0
- package/language/visualizations/report.css +40 -0
- package/language/visualizations.md +37 -0
- package/package.json +43 -4
- package/scripts/build-tokens.mjs +236 -0
- package/tokens/graphite-indigo.json +298 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Filip Gutica
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,54 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Design system
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Filip's design language for any framework: the spec, the tokens, the component catalogue, and the editor themes. It ships as the npm package `@filipgutica/design-system`.
|
|
4
|
+
|
|
5
|
+
- **Agents** get `language/` at `~/design-language` through filip-stack host config.
|
|
6
|
+
- **Vue apps** use [`@filipgutica/ui`](https://github.com/filipgutica/ui), which implements this design language.
|
|
7
|
+
- **Pages:** the catalogue and example pages are at <https://filipgutica.github.io/design-system/components.html>.
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
| Path | What it holds |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `language/` | The payload: `DESIGN.md`, `components.md`, `decisions.md`, `visualizations.md`, `tokens.css`, the catalogue (`components.html`), example pages, visualization helpers, and the Graphite Indigo editor theme |
|
|
14
|
+
| `tokens/graphite-indigo.json` | The Graphite Indigo token values |
|
|
15
|
+
| `scripts/build-tokens.mjs` | The token generator |
|
|
16
|
+
| `tests/` | Guard tests for the payload and the tokens |
|
|
17
|
+
|
|
18
|
+
`language/tokens.css` is a hand copy of the token values. The generator does not write it yet. Its command line still reads ui's `src/theme.css` and writes ui's files, so run it in ui until the JSON takes in the values that only `theme.css` defines. Until then, `tests/token-agreement.test.mjs` holds `tokens.css` to the JSON wherever both define a value.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npm install @filipgutica/design-system
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Read files from `node_modules/@filipgutica/design-system/language/`. For example, link `language/tokens.css` from a standalone HTML page.
|
|
27
|
+
|
|
28
|
+
## Develop
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
corepack enable
|
|
32
|
+
pnpm install --frozen-lockfile
|
|
33
|
+
pnpm verify
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`pnpm verify` runs the tests, `pnpm pack --dry-run`, and `publint`.
|
|
37
|
+
|
|
38
|
+
## Release
|
|
39
|
+
|
|
40
|
+
semantic-release publishes from `main` with npm provenance, as in ui:
|
|
41
|
+
|
|
42
|
+
- `fix` releases a patch.
|
|
43
|
+
- `feat` releases a minor.
|
|
44
|
+
- A breaking change releases a major.
|
|
45
|
+
|
|
46
|
+
Commits follow Conventional Commits, and CI checks them with commitlint. Do not edit the version by hand.
|
|
47
|
+
|
|
48
|
+
## History
|
|
49
|
+
|
|
50
|
+
`language/` came from `host-config/design-language/` in [filip-stack](https://github.com/filipgutica/filip-stack), with its history. The token JSON and generator came from [ui](https://github.com/filipgutica/ui).
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
MIT. The editor theme in `language/themes/graphite-indigo/` derives from Visual Studio Code's default themes; see its `LICENSE` and `THIRD_PARTY_NOTICES.md`.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Design language
|
|
2
|
+
|
|
3
|
+
A shared visual language for personal products, documentation, tools, mockups, and inline explainers. Claude and Codex follow this file. Take inspiration from the clarity and restraint of [Linear](https://linear.app/), [Codex](https://openai.com/codex/), [Director](https://director.sh/), and [T3 Code](https://t3.codes/): clear hierarchy, a balanced page frame, and real product evidence. Adapt their principles to the task; use original copy and assets.
|
|
4
|
+
|
|
5
|
+
## Scope and precedence
|
|
6
|
+
|
|
7
|
+
1. The user's current request wins.
|
|
8
|
+
2. A repository's own design system owns its tokens and components.
|
|
9
|
+
3. Other personal work follows this language. Use a consistent palette, type family, and component vocabulary across projects.
|
|
10
|
+
|
|
11
|
+
Interaction, flows, states, interface copy, and accessibility checks follow the `interface-design` skill (`~/.agents/skills/interface-design`). This file owns visual hierarchy and composition.
|
|
12
|
+
|
|
13
|
+
## Two layers
|
|
14
|
+
|
|
15
|
+
The language has a reusable core and a replaceable identity layer.
|
|
16
|
+
|
|
17
|
+
| Layer | What it holds | A new project |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Core | Tokens, depth, controls and their states, focus, motion, accessibility, and forced colors | Adopts it as is |
|
|
20
|
+
| Identity | The terminal folio look of the personal sites: the `~/name` header, the project registry, mono display headings, `##` section marks, and terminal plates | Replaces it with its own |
|
|
21
|
+
|
|
22
|
+
A new project keeps `tokens.css` unchanged and sets the identity inputs (`--project`, `--project-dark`, `--font-sans`, `--font-mono`, and `--accent-text` when the hue needs it) on `:root` in its own stylesheet. [Component specs](components.md) mark each component Core or Identity, and [decisions](decisions.md) record why each choice was made and which options were rejected. Read both before you build or change a component.
|
|
23
|
+
|
|
24
|
+
## Apply the right format
|
|
25
|
+
|
|
26
|
+
Choose the format before styling. A public product page and an application screen need different density.
|
|
27
|
+
|
|
28
|
+
| Format | Composition | First useful content |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| Product page | Centered wide frame, compact top navigation, expressive heading, left-aligned copy | Product purpose, one primary action, real product image |
|
|
31
|
+
| Documentation or CLI tool | Centered frame containing navigation and article; compact heading and readable prose | Setup command or the information needed for the task |
|
|
32
|
+
| Lesson or long-form article | Documentation frame; prose at `--measure`, figures may use the full article width | The question the lesson answers, a short contents list, then the first idea |
|
|
33
|
+
| Application | Task-sized navigation and content panes; compact controls and rows | Working content and its relevant actions |
|
|
34
|
+
| Inline visualization | Fit the conversation width and inherit the host appearance | The comparison, explanation, or interaction itself |
|
|
35
|
+
|
|
36
|
+
For data-driven charts, filterable reports, or portable HTML artifacts, read [Data visualizations](visualizations.md). It owns measurement consistency, reusable count rendering, filter checks, and inline/standalone delivery. Project-specific source queries stay in the owning project.
|
|
37
|
+
|
|
38
|
+
Center the **container**, not every sentence. Align header, content, images, and footer to deliberate shared edges. Bound prose with `--measure`; let useful images, tables, and component previews use the available frame.
|
|
39
|
+
|
|
40
|
+
## Files and examples
|
|
41
|
+
|
|
42
|
+
- `tokens.css`: a standalone snapshot of the values (the Graphite Indigo theme) owned by `@filipgutica/ui`. The identity inputs sit in one block at the top. Each line's `ui:` comment names the library variable for that token. Update it when the package values change.
|
|
43
|
+
- `components.md`: one spec for each component, with anatomy, tokens, states, keyboard and screen-reader behavior, motion, and forced colors. Read it for any component work.
|
|
44
|
+
- `components.html`: every component in each of its states, in plain HTML and CSS on `tokens.css`. Copy component markup and styles from there.
|
|
45
|
+
- `decisions.md`: the choices behind the components, and the options they replaced.
|
|
46
|
+
- `reference.html`: an application example, and a Foundations catalogue (`#foundations`) of every token: type, color with contrast, spacing, shape, borders, elevation, focus, and motion.
|
|
47
|
+
- `docs.html`: a balanced documentation shell and compact setup command.
|
|
48
|
+
- `product.html`: a restrained product-page hierarchy with illustrative product evidence.
|
|
49
|
+
- `DESIGN.md`: selection rules and acceptance criteria. It names tokens rather than repeating their values.
|
|
50
|
+
|
|
51
|
+
Personal sites import `@filipgutica/ui/themes/graphite-indigo.css` and the shared site helpers. The UI package owns the values and generation procedure.
|
|
52
|
+
|
|
53
|
+
Token names depend on where the page runs. This file uses the `tokens.css` names.
|
|
54
|
+
|
|
55
|
+
| Context | Variable names to write |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| Standalone HTML | The `tokens.css` names. Import or inline `tokens.css`, and copy component styles from `components.html`. |
|
|
58
|
+
| Site on `@filipgutica/ui` | The library variable in the `ui:` comment beside each `tokens.css` line, such as `--color-muted` for `--text-muted`. Some names are unchanged, such as `--text-sm`. When a comment names several, use the first. A `tokens.css` name that its comment does not list is undefined on a library site, and `var()` falls back without an error. The library draws the base focus ring only inside `.fg-site-docs`; elsewhere, write it yourself, exactly `outline: var(--focus-width) solid var(--color-focus); outline-offset: var(--focus-offset)`. |
|
|
59
|
+
| Other repository | That repository's own tokens and components, matched to these roles by meaning. |
|
|
60
|
+
| Inline visual | The host's supplied CSS variables and font, with no separate page shell. |
|
|
61
|
+
|
|
62
|
+
## Core
|
|
63
|
+
|
|
64
|
+
### Character
|
|
65
|
+
|
|
66
|
+
Controls use quiet depth and familiar shapes: borderless surfaces with one tight shadow at rest that sink when pressed or filled in.
|
|
67
|
+
|
|
68
|
+
- **Quiet surfaces, clear hierarchy.** Neutral paper and graphite backgrounds, with color reserved for the project hue, links, and meaningful states. Contrast, type, alignment, and proximity carry the structure.
|
|
69
|
+
- **Purposeful space.** Compact elements within a group, larger gaps between groups. Every gap should help a reader understand a relationship.
|
|
70
|
+
- **Evidence before decoration.** Show the actual product, command, or example. Use restrained framing so the evidence remains the focal point.
|
|
71
|
+
- **Fewer competing choices.** Make the next useful action obvious and group secondary destinations separately.
|
|
72
|
+
- **Precise and readable.** Consistent edges, measured prose, tabular numbers, comfortable line height, and meaningful text contrast.
|
|
73
|
+
|
|
74
|
+
### Typography
|
|
75
|
+
|
|
76
|
+
- Use `--font-sans` for prose, h3 and below, labels, and controls, and `--font-mono` for code, identifiers, and keys. The identity layer decides where else mono appears.
|
|
77
|
+
- Controls and dense application content use `--text-md`; secondary text uses `--text-sm`. Paragraphs and substantial article text use `--text-reading` with `--leading`. Bound reading text with `--measure` and introductory copy to a slightly shorter line.
|
|
78
|
+
- Documentation titles use `--text-3xl`; section headings use `--text-xl` and sit above their content. Application titles use `--text-2xl` or smaller, and application section headings use `--font-sans` at `--text-xl` or smaller.
|
|
79
|
+
- Use `--weight-regular`, `--weight-medium`, and `--weight-semibold`. Keep the source text's case; never transform it. Sentence case and restrained tracking make hierarchy easier to scan.
|
|
80
|
+
- Use `--text-muted` for secondary information and metadata, and `--text` for essential labels and instructions.
|
|
81
|
+
|
|
82
|
+
### Theme and color
|
|
83
|
+
|
|
84
|
+
- Inline visuals inherit the host theme. They do **not** need an independent theme switch.
|
|
85
|
+
- Standalone pages follow the OS by default. A visible theme control is optional: include it when the user requests one, the product already has one, or choosing/comparing themes serves the task. Token inspection and UI-library documentation are valid uses; a simple chart or explainer usually is not.
|
|
86
|
+
- Existing products retain their theme preferences and persistence contracts. Where a standalone choice is needed, System removes the override and explicit Light/Dark choices set it. Wrap storage access in try/catch.
|
|
87
|
+
- Use neutral `--bg`, `--surface`, and `--surface-raised` (paper in light, graphite in dark) to separate regions. Use `--text` and `--text-muted` for the main hierarchy.
|
|
88
|
+
- Each project sets one hue, and `--accent` follows it. The hue fills the one primary action in each decision group, and marks identity and selection: current items, the selected tab's text, and checked or selected controls. It is never a fill for secondary buttons, cards, or wells. Check it at 3:1 for marks and bars, and at 4.5:1 wherever it colours text, on every surface it sits on. `--accent-text` on an `--accent` fill must reach 4.5:1 for each hue; a hue that misses does not colour text or carry a label there.
|
|
89
|
+
- `--link` identifies links; underline prose links. `--focus` is the accent (`--accent`) and outlines keyboard focus on every role but fields, which turn their edge the accent instead (see [focus](components.md#rules-for-every-control)). Where color marks a checked or selected state, use `--accent` as a fill, tint, or mark; `--link` never marks one, and a focus ring marks only focus, never selection.
|
|
90
|
+
- Navigation and selection: the current page, the selected tab, and a selected list row take the same quiet lifted fill, tinted with the accent, with accent text where it reaches 4.5:1 on that fill (another readable colour otherwise), and no underline or bar; an in-page location takes a short accent pip without a fill. Keep raised-control hover and keyboard focus separate from these states. [Component specs](components.md#navigation-list) give the values.
|
|
91
|
+
- Status colors mean state and have a text or icon label. Status surfaces are soft tints of their status color (the `--*-soft` tokens). Outside badges, the danger button label, and field error text, status foreground colors go on icons; numbers and labels beside them stay in `--text` or `--text-muted`. Keep restrained syntax colors separate from the action palette.
|
|
92
|
+
- Verify light and dark appearance where supported, regardless of whether a switch is visible. Check text contrast rather than assuming a muted token is accessible at every size.
|
|
93
|
+
|
|
94
|
+
### Layout and spacing
|
|
95
|
+
|
|
96
|
+
- Use the `--space-*` rhythm and flex/grid `gap`. Use smaller gaps within a group and larger gaps between groups. Documentation sections use `--space-12`, stepping down to `--space-8` on phones. Product sections use `--space-24` total separation, stepping down to `--space-16` at tablet width. Give each section gap one owner so adjoining padding does not double it.
|
|
97
|
+
- Size type, spacing, and controls in rem through the `--text-*`, `--space-*`, and `--control-*` tokens, so text and controls follow the reader's font-size setting. A literal that sizes text, padding, a gap, or a line height is rem too (pixels ÷ 16). Keep hairlines, focus rings, shadows, and breakpoints in px.
|
|
98
|
+
- Product pages use `--page-wide`; documentation uses `--page-max`, optionally combined with a thin navigation column. Center the combined shell, not only the article inside an edge-pinned sidebar.
|
|
99
|
+
- Tool and docs introductions stay compact. Preserve the direct route to install commands and useful captures.
|
|
100
|
+
- Use two named breakpoints. Write desktop styles first, then override them at these widths:
|
|
101
|
+
|
|
102
|
+
| Name | Media query | What changes |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| Tablet | `@media (max-width: 800px)` | Multi-column layouts become one content column. Touch controls use `--control-lg`. |
|
|
105
|
+
| Phone | `@media (max-width: 640px)` | Side gutters drop from `--space-6` to `--space-4`, and section gaps take their phone step. |
|
|
106
|
+
|
|
107
|
+
Use `@media (min-width: 801px)` only for a rule that applies to desktop alone. One documented exception: the tool-home hero (`.fg-site-hero` in `@filipgutica/ui`) splits at `@media (min-width: 1024px)`, with the title across the top, the lede on the left, and the install block and facts on the right. Below 1024px it stacks in source order. `@filipgutica/ui` also ships 680px rules for its own site header, prose title and definitions (`max-width: 680px`, with `min-width: 681px` for frame padding); they belong to the library, so pages add no viewport breakpoint beyond the table and the hero split. A pane that must collapse at its own width uses a container query, as the detail column in `reference.html` does.
|
|
108
|
+
- Navigation can become a drawer or a native scrolling section strip. A sticky side rail taller than the window scrolls its link list, not the element that draws its divider, so an overlay scrollbar sits clear of the line; `UiSiteNav` does this. Keep wide code, tables, and charts scrolling inside their containers.
|
|
109
|
+
- Keep main headings, actions, and product evidence visible on load. Scrolling should reveal more content without being required to make existing content appear.
|
|
110
|
+
|
|
111
|
+
### Surfaces
|
|
112
|
+
|
|
113
|
+
- Start with headings, content, and whitespace. Use a `--border-subtle` divider where it clarifies a boundary.
|
|
114
|
+
- Each surface role has one recipe:
|
|
115
|
+
|
|
116
|
+
| Role | Use for | Fill | Border | Radius | Shadow |
|
|
117
|
+
| --- | --- | --- | --- | --- | --- |
|
|
118
|
+
| Page | The canvas and example stages | `--bg` | None | None | None |
|
|
119
|
+
| Well | Source code, screenshots, figures, and inset previews other than example stages | `--surface` | Source code: transparent 1px; figures: `--border-subtle` | `--radius-lg` | Source code: `--shadow-surface`; figures: none |
|
|
120
|
+
| Panel | Cards, forms, charts, and detail views | `--surface-raised` | Transparent 1px | `--radius-lg` | `--shadow-surface` |
|
|
121
|
+
| Field | Inputs, selects, textareas, and search fields | `--field-bg`; disabled: `--field` | `--field-edge` | `--radius-field` | `--field-shadow`; disabled: none |
|
|
122
|
+
| Track | Segmented and switch tracks, and selected radio cards | `--field` | Transparent 1px | Tracks: `--radius-md`; radio cards: `--radius-lg` | `--shadow-sink` |
|
|
123
|
+
| Floating layer | Menus, popovers, pickers, and dialogs | `--surface-raised` | Transparent 1px; the shadow's ring draws the edge | `--radius-lg` | `--shadow-popover` |
|
|
124
|
+
|
|
125
|
+
- Borders stay 1px and transparent on buttons, quiet actions, tracks, panels, and radio cards, so forced colors can draw them. Fields keep `--field-edge`. `--border` keeps unchecked checkbox and radio edges visible. The toggle card is a named exception: a visible `--border-subtle` edge and no rest raise. Invalid fields show a `--danger` edge, except in forced colors, where the system edge wins. Figures, example frames, and dividers use `--border-subtle`.
|
|
126
|
+
- Radii: `--radius-sm` for inline elements and checkboxes; `--radius-field` for fields, navigation rows, tabs, and toggle cards; `--radius-md` (a pill) for buttons and segmented controls; `--radius-lg` for wells, example frames, plates, panels, radio cards, alerts, and floating layers; `--radius-pill` for badges and switch tracks. Inner menu rows take the panel radius minus `--space-1`.
|
|
127
|
+
- Avoid nesting panels. Cards are for a few parallel self-contained options that a reader compares. Running prose belongs in open sections. Product screenshots need one frame, not a frame around a frame.
|
|
128
|
+
- [Depth](#depth) gives each role its shadow. Stable hover states keep normal content quiet.
|
|
129
|
+
|
|
130
|
+
### Depth
|
|
131
|
+
|
|
132
|
+
Each depth tier has one token. [`tokens.css`](tokens.css) holds every shadow value, including the dark ones. Pages and components use the tokens and write no shadow of their own. Only zero-blur lines in a token colour are exempt: focus rings and dividers. A focused field's inset line is a token too (`--field-shadow-focus`, `--field-shadow-focus-invalid`).
|
|
133
|
+
|
|
134
|
+
| Tier | Token | Use for |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| Control | `--shadow-raise` | Idle buttons, unselected radio cards, switch knobs, and segmented thumbs |
|
|
137
|
+
| Container | `--shadow-surface` | Panels, cards, source code (not inside an example frame), command plates, and terminal captures |
|
|
138
|
+
| Pressed or well | `--shadow-sink` | Tracks, pressed buttons, selected radio cards, and fields in dark (through `--field-shadow`; light fields take none) |
|
|
139
|
+
| Selected row | `--shadow-nav-current` | The current navigation row, the selected tab, and a selected list row |
|
|
140
|
+
| Floating | `--shadow-popover` | Menus, popovers, pickers, and dialogs |
|
|
141
|
+
|
|
142
|
+
- Idle controls and containers take no outer light highlight and no blur wider than 2px. In dark mode, controls take a faint inset top edge and containers a faint 1px ring, so no halo shows.
|
|
143
|
+
- A pressed button sinks and moves 1px down; see [Button](components.md#button).
|
|
144
|
+
|
|
145
|
+
### Components
|
|
146
|
+
|
|
147
|
+
[`components.md`](components.md) specifies each component and [`components.html`](components.html) shows its states. These composition rules apply across them:
|
|
148
|
+
|
|
149
|
+
- Build each control from the owning library's component or class, and style a link that acts as a button with the button's classes. A page adds layout only: size, spacing, and position. A local copy of a control drifts from the library, even when it uses the same tokens.
|
|
150
|
+
- One clearly primary action per visible decision group, filled with the hue. Other actions are secondary, ghost, or text buttons.
|
|
151
|
+
- Use a segmented control for two to five short options that apply at once, a select for longer lists, and radio cards for options that need descriptions.
|
|
152
|
+
- Callouts carry a real caveat, not decorative emphasis.
|
|
153
|
+
- Lists and properties: align short labels, values, and metadata. Use definition lists for terms and short meanings; use tables for actual comparisons.
|
|
154
|
+
- Figures: number them when the prose refers to any of them, and then number them all. Place a figure beside the paragraph that explains it, once the terms it uses have been introduced.
|
|
155
|
+
- Source code sits in a theme-matched well with syntax colours; multiline samples may have a small descriptive header and Copy action. Put useful setup context above a command; omit repeated language labels.
|
|
156
|
+
- Examples: show a live component on a stage above its code, in one frame, with Copy in the code's corner. The stage sits on the page background. See [code block with a live example](components.md#with-a-live-example).
|
|
157
|
+
- A screenshot opens at full size when clicked; use a native accessible trigger and restore its focus on close.
|
|
158
|
+
|
|
159
|
+
### Interaction and motion
|
|
160
|
+
|
|
161
|
+
- Show visible focus and accessible names. A visual simplification must preserve useful controls, caveats, and keyboard paths.
|
|
162
|
+
- Every focusable element but a field draws one ring, `outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset)`, with no glow, over its own raise or sink shadow. The `tokens.css` base sets it. `--focus` is the accent, which reaches 3:1 on `--bg`, `--surface`, and `--surface-raised` in both themes; a dark plate sets `--focus: var(--project-dark)`. Do not give a role its own ring colour. Fields (input, select, textarea, search) draw no ring: focus turns the edge `--accent` with a 2px inset line (`--field-shadow-focus`), and the fill stays. [Component specs](components.md#rules-for-every-control) give the values. Use an inset offset (`calc(var(--focus-width) * -1)`) only where a scrolling or clipping parent would cut the ring, or inside a segmented control; add a comment that names the reason. Keep the focus default in `@layer base`, so a component's own focus rule can refine it. Pointer hover never draws the outline.
|
|
163
|
+
- Keep product navigation distinct from in-page section links. Current-page and current-section indicators serve different purposes. Open sibling project links in the same tab; indicate a new tab only when the link opens one.
|
|
164
|
+
- Use `--duration-fast` for hover/press and `--duration` for menus/panels. Animate opacity or transform only where it explains a state change. A component spec may set its own timing, as the segmented control's glide does.
|
|
165
|
+
- Keep content visible without reveal effects, entrance sequences, or continuous decorative animation. Honor reduced motion, including anchor scrolling.
|
|
166
|
+
- An interactive figure first renders as complete static content, so it reads the same without JavaScript; enhancement adds controls, not information. Give each state a text label and announce live results politely. A lesson needs one interactive figure at most; keep the rest static.
|
|
167
|
+
- Data views account for loading, empty, error, and recovery states. Heuristics guide design; browser evidence validates the result.
|
|
168
|
+
|
|
169
|
+
### Copy and density
|
|
170
|
+
|
|
171
|
+
- Lead with a plain description and a useful action. Keep one idea per short paragraph. Product pages can explain value without unsupported superlatives or invented statistics.
|
|
172
|
+
- Say each point once. Put exact payloads, logs, or long reference text behind a useful disclosure when appropriate.
|
|
173
|
+
- Keep table cells short. Put rules, thresholds, and caveats next to what they govern.
|
|
174
|
+
- Label illustrative data and demo outcomes clearly. Credit upstream creators when presenting a derivative product.
|
|
175
|
+
- Use monochrome line icons sparingly; give an icon a purpose beyond filling space.
|
|
176
|
+
|
|
177
|
+
## Identity layer: terminal folio
|
|
178
|
+
|
|
179
|
+
The personal sites are terminal tools that read Markdown and paths, so their identity comes from that world. A new project replaces this section with its own identity and keeps the core.
|
|
180
|
+
|
|
181
|
+
- **Mono identity.** `--font-mono` (IBM Plex Mono) sets identity, the page titles and section headings of documentation, CLI tool, article, and product pages, navigation rails, metadata, captions, and the footer. `@filipgutica/ui` self-hosts IBM Plex; elsewhere the tokens fall back to the system stack.
|
|
182
|
+
- **Headings.** Documentation, CLI tool, article, and product page titles are mono; application titles are `--font-sans`. Page-level section headings (h2) on documentation, CLI tool, article, and product pages are mono, start with a `##` mark in `--accent` (decorative, so screen readers skip it), and have a `--border-subtle` rule above the section. Application and inline-visualization section headings, and every h3 or lower, are plain `--font-sans` with no mark. Product pages and tool homes may use a mono `--text-display` title, stepping down to `--text-display-sm` on phones; keep a short heading measure, place supporting copy and the primary action nearby, and let the first product image enter the initial desktop viewport.
|
|
183
|
+
- **Hue marks.** The hue also draws the `~/` header mark, the `##` mark on documentation, CLI tool, article, and product section headings, step numbers, and the `$` prompt.
|
|
184
|
+
- **Header.** Personal product sites share a compact static header: a mono `~/name` identity with the `~/` in `--accent`, a project switcher, useful page links, appearance controls, and a solid `--text` rule below. Use the shared project registry for names, order, and destinations. Keep a gallery's existing application navigation structure.
|
|
185
|
+
- **Appearance.** Personal pages share the built-in System/Light/Dark choice, through the header's picker. An explicitly selected custom gallery theme overrides that choice until the reader selects a built-in appearance. Preserve installed themes.
|
|
186
|
+
- **Terminal plates.** Commands sit on a dark plate tinted with the project hue (`--command-bg`), in both themes. A shell command gets a `$` prompt in `--project-dark`, drawn by CSS so it never enters copied or accessible text. Short commands use a headerless compact row with an accessible Copy control. Terminal captures keep the neutral `--terminal` plate, with a mono status-line caption below the screen; tabs on a capture switch to mono.
|
|
187
|
+
- **Steps.** A real sequence is an ordered list with mono numbers in `--accent` on a ruled leading column, an h3 title per step, and an optional result note on the last step.
|
|
188
|
+
|
|
189
|
+
## Avoid recurring clutter
|
|
190
|
+
|
|
191
|
+
- Decorative eyebrows, numbered markers on unordered content, and badge rows that repeat the title.
|
|
192
|
+
- Multiple cards around ordinary prose, ornamental grids, glows, gradients, pill-shaped cards, and hover lifts.
|
|
193
|
+
- Tinted wells or panels used for decoration. The hue-tinted command plate is the one tinted surface, because it carries the project's identity.
|
|
194
|
+
- Display typography on dense tool screens, or tiny application typography on a product landing page.
|
|
195
|
+
- The `##` mark on every section of an application screen, where it repeats down the page and competes with the data.
|
|
196
|
+
- Large blank gaps that push the action or evidence away from the introduction.
|
|
197
|
+
- Centered long paragraphs, excessively faint text, and horizontal page overflow.
|
|
198
|
+
- Theme controls added automatically to inline charts and explainers.
|
|
199
|
+
|
|
200
|
+
## Acceptance
|
|
201
|
+
|
|
202
|
+
- [ ] The format matches the reader's task, and the next useful action is clear.
|
|
203
|
+
- [ ] Header, content, imagery, and footer have deliberate shared edges; wide-screen margins feel balanced.
|
|
204
|
+
- [ ] Typography distinguishes title, section, body, and metadata without competing focal points.
|
|
205
|
+
- [ ] Product evidence is real or clearly illustrative; factual caveats and attribution remain present.
|
|
206
|
+
- [ ] Both supported themes are readable, with theme controls only where useful.
|
|
207
|
+
- [ ] At 390, 720, and 1280 px wide there is no horizontal page scroll, and the page's own viewport media queries use only `max-width: 640px`, `max-width: 800px`, `min-width: 801px`, and the documented `min-width: 1024px` hero split.
|
|
208
|
+
- [ ] Keyboard, focus, touch, deep links, and reduced motion work across relevant states.
|
|
209
|
+
- [ ] Every control is the owning system's component or class, never a local copy built from its tokens; spacing uses its tokens; each panel and visual effect has a purpose.
|
|
210
|
+
- [ ] Control states match between `components.html`, the example pages, and the owning library: hover, press, focus, disabled, busy, invalid, and forced colors.
|