Repository navigation
Colour System
This page lists every colour in fiscalclock's palette, the role each colour plays in the light and dark themes, how the dark theme is switched on, and the measured contrast of every pair that carries text or meaning.
Last reviewed: 1 Nov 2026
fiscalclock uses a small set of greys, one accent colour (a deep teal) and four status colours. Pages never pick a colour by its value; they ask for a role, such as "body text" or "page background", and the theme supplies the value. Every pair of colours that carries text or meaning is measured against the accessibility rules on each build, in both themes, so a colour change cannot quietly make text unreadable. Terms such as token, primitive and contrast ratio are defined below and in the Design-Glossary.
| Term | Meaning |
|---|---|
| hex value | A colour written as # plus six hexadecimal digits: two each for red, green and blue. |
| palette | The full list of raw colours. Each palette colour is a primitive: a named value with no meaning attached, such as palette.teal.700. |
| semantic token | A colour named for its job, such as color.text.default. It points at a palette colour, and it points at a different one in each theme. See Design-Tokens. |
| theme | A complete set of semantic colours. fiscalclock has two, light and dark, and both are first-class (DD-005). |
| accent | The one colour used to draw attention: links, the current item, the open end of an interval. |
| contrast ratio | How different two colours are in brightness, as defined below. |
Primitives are numbered by lightness: low numbers are light, high numbers are dark. The same palette serves both themes. Use semantic tokens in pages and assets; a page that uses palette.teal.700 directly will not change with the theme (design/tokens/README.md). Values are copied from the generated tokens.light.json.
| Primitive | Hex | Used by |
|---|---|---|
palette.neutral.0 |
#ffffff |
color.bg.raised (light), color.text.on-accent (light) |
palette.neutral.25 |
#fdfdfc |
color.bg.default (light), color.diagram.surface (light) |
palette.neutral.100 |
#f2f2f0 |
color.bg.subtle (light), color.code.bg (light), color.diagram.period-fill (light) |
palette.neutral.150 |
#ececea |
color.text.default (dark), color.code.text (dark), color.diagram.ink (dark), color.logo.ink (dark) |
palette.neutral.200 |
#ddddd9 |
color.border.default (light) |
palette.neutral.400 |
#a5a5a1 |
color.text.muted (dark), color.code.comment (dark), color.diagram.ink-muted (dark) |
palette.neutral.500 |
#7d7d79 |
color.border.strong (light), color.diagram.rule (light) |
palette.neutral.550 |
#71716d |
color.border.strong (dark), color.diagram.rule (dark) |
palette.neutral.600 |
#555552 |
color.text.muted (light), color.code.comment (light), color.diagram.ink-muted (light) |
palette.neutral.800 |
#2d2d2b |
color.border.default (dark) |
palette.neutral.850 |
#222221 |
color.bg.raised (dark), color.diagram.period-fill (dark) |
palette.neutral.900 |
#1a1a19 |
color.bg.subtle (dark), color.text.default (light), color.code.bg (dark), color.code.text (light), color.diagram.ink (light), color.logo.ink (light) |
palette.neutral.950 |
#121212 |
color.bg.default (dark), color.text.on-accent (dark), color.diagram.surface (dark) |
palette.teal.50 |
#e7f3f2 |
color.bg.accent-subtle (light) |
palette.teal.200 |
#8ed8d1 |
color.accent.hover (dark) |
palette.teal.300 |
#5cc6be |
color.accent.default (dark), color.focus.ring (dark), color.code.keyword (dark), color.diagram.extra-week (dark), color.logo.open-end (dark) |
palette.teal.700 |
#0b6b69 |
color.accent.default (light), color.focus.ring (light), color.code.keyword (light), color.diagram.extra-week (light), color.logo.open-end (light) |
palette.teal.800 |
#08524f |
color.accent.hover (light) |
palette.teal.950 |
#102726 |
color.bg.accent-subtle (dark) |
palette.green.300 |
#73cc93 |
color.status.success (dark) |
palette.green.700 |
#1c6e3d |
color.status.success (light) |
palette.amber.300 |
#e9b65c |
color.status.warning (dark), color.diagram.reference-date (dark) |
palette.amber.700 |
#8c5600 |
color.status.warning (light), color.diagram.reference-date (light) |
palette.red.300 |
#ff8a80 |
color.status.danger (dark) |
palette.red.700 |
#b4261f |
color.status.danger (light) |
palette.blue.300 |
#8cb2f0 |
color.status.info (dark), color.code.string (dark), color.diagram.calendar-b (dark) |
palette.blue.700 |
#1f55a0 |
color.status.info (light), color.code.string (light), color.diagram.calendar-b (light) |
Each hue has a dark step (700 or 800) for the light theme and a light step (200 or 300) for the dark theme; teal also has 50 and 950 for tinted backgrounds. A single value cannot serve both: saturated colours lose contrast on dark backgrounds, so the dark theme needs its own lighter version (accessibility research, section 6).
Each row gives the value in each theme, the palette colour it points at, and its purpose as written in the token's $description (semantic.light.tokens.json, semantic.dark.tokens.json). The CSS name of each token is --fc- plus the name with dots replaced by hyphens, for example --fc-color-text-default (Design-Tokens).
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.bg.default |
#fdfdfc (palette.neutral.25) |
#121212 (palette.neutral.950) |
Page background. |
color.bg.subtle |
#f2f2f0 (palette.neutral.100) |
#1a1a19 (palette.neutral.900) |
Sidebars, code blocks, table headers. |
color.bg.raised |
#ffffff (palette.neutral.0) |
#222221 (palette.neutral.850) |
Menus and popovers, which sit above the page. |
color.bg.accent-subtle |
#e7f3f2 (palette.teal.50) |
#102726 (palette.teal.950) |
Tinted background for the current item and highlighted rows. |
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.text.default |
#1a1a19 (palette.neutral.900) |
#ececea (palette.neutral.150) |
Body text and headings. |
color.text.muted |
#555552 (palette.neutral.600) |
#a5a5a1 (palette.neutral.400) |
Secondary text: captions, metadata, table labels. |
color.text.on-accent |
#ffffff (palette.neutral.0) |
#121212 (palette.neutral.950) |
Text on an accent-filled button. |
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.border.default |
#ddddd9 (palette.neutral.200) |
#2d2d2b (palette.neutral.800) |
Decorative dividers that carry no meaning on their own. |
color.border.strong |
#7d7d79 (palette.neutral.500) |
#71716d (palette.neutral.550) |
Borders that identify a control or carry meaning; at least 3:1. |
color.accent.default |
#0b6b69 (palette.teal.700) |
#5cc6be (palette.teal.300) |
The one accent: links, the current item, the open end of an interval. |
color.accent.hover |
#08524f (palette.teal.800) |
#8ed8d1 (palette.teal.200) |
Accent under the pointer. |
color.focus.ring |
#0b6b69 (palette.teal.700) |
#5cc6be (palette.teal.300) |
Keyboard focus outline, drawn 2 px wide with a 2 px offset. |
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.status.success |
#1c6e3d (palette.green.700) |
#73cc93 (palette.green.300) |
Success text and icons. |
color.status.warning |
#8c5600 (palette.amber.700) |
#e9b65c (palette.amber.300) |
Warning text and icons. |
color.status.danger |
#b4261f (palette.red.700) |
#ff8a80 (palette.red.300) |
Error text and icons. |
color.status.info |
#1f55a0 (palette.blue.700) |
#8cb2f0 (palette.blue.300) |
Informational text and icons. |
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.code.bg |
#f2f2f0 (palette.neutral.100) |
#1a1a19 (palette.neutral.900) |
Code block background. |
color.code.text |
#1a1a19 (palette.neutral.900) |
#ececea (palette.neutral.150) |
Code text. |
color.code.keyword |
#0b6b69 (palette.teal.700) |
#5cc6be (palette.teal.300) |
Keywords and imports. |
color.code.string |
#1f55a0 (palette.blue.700) |
#8cb2f0 (palette.blue.300) |
String literals, including dates. |
color.code.comment |
#555552 (palette.neutral.600) |
#a5a5a1 (palette.neutral.400) |
Comments. |
These roles follow the diagram grammar in the domain-visuals research; Diagrams-and-Data-Visuals explains how to draw with them.
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.diagram.surface |
#fdfdfc (palette.neutral.25) |
#121212 (palette.neutral.950) |
Diagram background. |
color.diagram.ink |
#1a1a19 (palette.neutral.900) |
#ececea (palette.neutral.150) |
Labels, quarter boundaries, start and end markers. |
color.diagram.ink-muted |
#555552 (palette.neutral.600) |
#a5a5a1 (palette.neutral.400) |
Secondary labels and week ticks. |
color.diagram.rule |
#7d7d79 (palette.neutral.500) |
#71716d (palette.neutral.550) |
Period separators; at least 3:1 against the surface. |
color.diagram.period-fill |
#f2f2f0 (palette.neutral.100) |
#222221 (palette.neutral.850) |
Fill for alternate periods; never the only cue. |
color.diagram.extra-week |
#0b6b69 (palette.teal.700) |
#5cc6be (palette.teal.300) |
Hatch and outline of an extra (53rd) week; always also labelled. |
color.diagram.calendar-b |
#1f55a0 (palette.blue.700) |
#8cb2f0 (palette.blue.300) |
The second calendar in a comparison; drawn dashed. |
color.diagram.reference-date |
#8c5600 (palette.amber.700) |
#e9b65c (palette.amber.300) |
A caller-supplied reference date; always labelled with its ISO date. |
| Token | Light | Dark | What it is for |
|---|---|---|---|
color.logo.ink |
#1a1a19 (palette.neutral.900) |
#ececea (palette.neutral.150) |
The closed bracket and the wordmark. |
color.logo.open-end |
#0b6b69 (palette.teal.700) |
#5cc6be (palette.teal.300) |
The open parenthesis: the excluded end. |
See Logo-Guidelines for how the logo uses these two colours.
- One accent. The admired documentation sites share "neutral surfaces, one restrained accent" (peer analysis, synthesis). In a study of 450 websites, highly colourful designs were judged less favourably, most of all by participants with a PhD, which is close to fiscalclock's technical and finance audience (trust research, section 2.3).
-
Deep teal. The accent came with brand direction C, "Interval", which the owner chose on 1 Nov 2026 (DD-013). In the logo it marks the open end of
[ ), the excluded end of an interval, which is the library's core rule (Brand-Foundation). - Status colours are not accents. Green, amber, red and blue appear only where they mean success, warning, danger or information, in code highlighting, or where a diagram needs a second calendar or a reference date.
| Theme | Background | Body text | Ratio |
|---|---|---|---|
| Light |
color.bg.default #fdfdfc
|
color.text.default #1a1a19
|
17.11:1 |
| Dark |
color.bg.default #121212
|
color.text.default #ececea
|
15.83:1 |
- The admired sites avoid pure white text on pure black, and the reverse, for body copy (peer analysis, synthesis point 3).
- The claim that white on black "glows" for readers with astigmatism (halation) is widely repeated but weakly evidenced: the research found no controlled study. Material Design's Android guide and web.dev both advise dark grey rather than black backgrounds, as design guidance rather than research (accessibility research, section 6).
- Contrast stays far above the 7:1 enhanced level either way, so softening the extremes costs nothing measurable.
- Light-theme text is
#1a1a19, the same value as the dark theme'scolor.bg.subtle, so the palette has one value fewer (DD-015). - Two light-theme roles do use pure white:
color.bg.raised, so menus stand slightly above the off-white page, andcolor.text.on-accent.
WCAG 2.2 success criterion 1.4.1 says colour must not be "the only visual means of conveying information" (WCAG 2.2). In practice:
| Where | Colour | The other cue that is always present |
|---|---|---|
| Links in prose | color.accent.default |
An underline (DD-027). Link colour against body text is only 2.75:1 in light and 1.72:1 in dark, below the 3:1 that colour-only links would need (technique G183). Check: python -I design/scripts/contrast.py "#0b6b69" "#1a1a19" and python -I design/scripts/contrast.py "#5cc6be" "#ececea". |
| Status messages | color.status.* |
An icon and a word such as "Warning" (Docs-Components). |
| Extra week in a diagram | color.diagram.extra-week |
A hatch pattern and a text label. |
| Second calendar in a comparison | color.diagram.calendar-b |
Dashed lines and a row label. |
| Reference date | color.diagram.reference-date |
A labelled line carrying the ISO date. |
| Alternate periods | color.diagram.period-fill |
Separators and text labels. |
| Current item in navigation | color.bg.accent-subtle |
Proposed: a bar or weight change as well; the navigation component is not designed yet. |
Accessibility covers colour-vision deficiency and forced-colours mode.
The page follows the reader's operating-system setting by default. A data-theme attribute on <html> overrides it in either direction, so a theme switch always wins (DD-018). The generated tokens.css has three blocks; this excerpt shows one token:
:root {
color-scheme: light;
--fc-color-bg-default: var(--fc-palette-neutral-25);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
color-scheme: dark;
--fc-color-bg-default: var(--fc-palette-neutral-950);
}
}
:root[data-theme="dark"] {
color-scheme: dark;
--fc-color-bg-default: var(--fc-palette-neutral-950);
}| Reader's system |
data-theme on <html>
|
Theme shown |
|---|---|---|
| Light | none | Light |
| Dark | none | Dark |
| Either | "light" |
Light |
| Either | "dark" |
Dark |
-
color-schemetells the browser to draw its own scrollbars and form controls to match (token research, section 4.2). - A site should set the attribute before the first paint and add
<meta name="color-scheme" content="light dark">, to avoid a flash of the wrong theme (design/tokens/README.md). - The selector blocks were chosen over the CSS
light-dark()function because they work for every kind of token, not only colours, and match every docs framework surveyed (DD-018). - Proposed: a three-way control (system, light, dark), as Claude Docs, Vercel and Resend Docs offer (peer analysis, synthesis point 2). No site exists yet (DD-009).
A contrast ratio compares the brightness of two colours. WCAG 2.2 first converts each colour to its relative luminance, a number from 0 (black) to 1 (white) in which green counts most and blue least. The ratio is (lighter + 0.05) ÷ (darker + 0.05). It runs from 1:1, two identical colours, to 21:1, black on white (WCAG 2.2 definition).
| Minimum | Applies to | WCAG 2.2 criterion |
|---|---|---|
| 4.5:1 | Normal-size text: body text, links, captions, code, labels in diagrams | 1.4.3, level AA |
| 3:1 | Large text: at least 24 px, or at least 18.67 px bold | 1.4.3, level AA |
| 3:1 | Things that are not text but carry meaning: control borders, focus indicators, diagram lines and marks | 1.4.11, level AA |
A ratio is never rounded up: 4.499:1 fails 4.5:1. The project script decides on the exact value and prints it truncated to two decimals (accessibility research).
This table is copied from design/tokens/generated/contrast.md, which python -I design/scripts/build_tokens.py generates from contrast-checks.json. The build fails if any pair falls below its minimum. If this table and the generated file differ, the generated file is right.
| Pair | WCAG 2.2 criterion | Minimum | Light | Dark |
|---|---|---|---|---|
color.text.default on color.bg.default
|
1.4.3 text | 4.5:1 |
#1a1a19 on #fdfdfc: 17.11:1 |
#ececea on #121212: 15.83:1 |
color.text.default on color.bg.subtle
|
1.4.3 text | 4.5:1 |
#1a1a19 on #f2f2f0: 15.53:1 |
#ececea on #1a1a19: 14.72:1 |
color.text.default on color.bg.raised
|
1.4.3 text | 4.5:1 |
#1a1a19 on #ffffff: 17.41:1 |
#ececea on #222221: 13.46:1 |
color.text.default on color.bg.accent-subtle
|
1.4.3 text | 4.5:1 |
#1a1a19 on #e7f3f2: 15.34:1 |
#ececea on #102726: 13.24:1 |
color.text.muted on color.bg.default
|
1.4.3 text | 4.5:1 |
#555552 on #fdfdfc: 7.34:1 |
#a5a5a1 on #121212: 7.57:1 |
color.text.muted on color.bg.subtle
|
1.4.3 text | 4.5:1 |
#555552 on #f2f2f0: 6.67:1 |
#a5a5a1 on #1a1a19: 7.04:1 |
color.text.muted on color.bg.raised
|
1.4.3 text | 4.5:1 |
#555552 on #ffffff: 7.47:1 |
#a5a5a1 on #222221: 6.44:1 |
color.text.muted on color.bg.accent-subtle
|
1.4.3 text | 4.5:1 |
#555552 on #e7f3f2: 6.58:1 |
#a5a5a1 on #102726: 6.33:1 |
color.accent.default on color.bg.default
|
1.4.3 link text | 4.5:1 |
#0b6b69 on #fdfdfc: 6.21:1 |
#5cc6be on #121212: 9.16:1 |
color.accent.default on color.bg.subtle
|
1.4.3 link text | 4.5:1 |
#0b6b69 on #f2f2f0: 5.64:1 |
#5cc6be on #1a1a19: 8.52:1 |
color.accent.default on color.bg.raised
|
1.4.3 link text | 4.5:1 |
#0b6b69 on #ffffff: 6.32:1 |
#5cc6be on #222221: 7.79:1 |
color.accent.default on color.bg.accent-subtle
|
1.4.3 link text | 4.5:1 |
#0b6b69 on #e7f3f2: 5.57:1 |
#5cc6be on #102726: 7.66:1 |
color.accent.hover on color.bg.default
|
1.4.3 link text | 4.5:1 |
#08524f on #fdfdfc: 8.85:1 |
#8ed8d1 on #121212: 11.50:1 |
color.text.on-accent on color.accent.default
|
1.4.3 button text | 4.5:1 |
#ffffff on #0b6b69: 6.32:1 |
#121212 on #5cc6be: 9.16:1 |
color.text.on-accent on color.accent.hover
|
1.4.3 button text | 4.5:1 |
#ffffff on #08524f: 9.01:1 |
#121212 on #8ed8d1: 11.50:1 |
color.border.strong on color.bg.default
|
1.4.11 control border | 3:1 |
#7d7d79 on #fdfdfc: 4.06:1 |
#71716d on #121212: 3.82:1 |
color.border.strong on color.bg.subtle
|
1.4.11 control border | 3:1 |
#7d7d79 on #f2f2f0: 3.68:1 |
#71716d on #1a1a19: 3.55:1 |
color.border.strong on color.bg.raised
|
1.4.11 control border | 3:1 |
#7d7d79 on #ffffff: 4.13:1 |
#71716d on #222221: 3.24:1 |
color.focus.ring on color.bg.default
|
1.4.11 focus indicator | 3:1 |
#0b6b69 on #fdfdfc: 6.21:1 |
#5cc6be on #121212: 9.16:1 |
color.focus.ring on color.bg.subtle
|
1.4.11 focus indicator | 3:1 |
#0b6b69 on #f2f2f0: 5.64:1 |
#5cc6be on #1a1a19: 8.52:1 |
color.focus.ring on color.bg.raised
|
1.4.11 focus indicator | 3:1 |
#0b6b69 on #ffffff: 6.32:1 |
#5cc6be on #222221: 7.79:1 |
color.status.success on color.bg.default
|
1.4.3 text | 4.5:1 |
#1c6e3d on #fdfdfc: 6.16:1 |
#73cc93 on #121212: 9.62:1 |
color.status.warning on color.bg.default
|
1.4.3 text | 4.5:1 |
#8c5600 on #fdfdfc: 5.98:1 |
#e9b65c on #121212: 10.08:1 |
color.status.danger on color.bg.default
|
1.4.3 text | 4.5:1 |
#b4261f on #fdfdfc: 6.37:1 |
#ff8a80 on #121212: 8.20:1 |
color.status.info on color.bg.default
|
1.4.3 text | 4.5:1 |
#1f55a0 on #fdfdfc: 7.20:1 |
#8cb2f0 on #121212: 8.69:1 |
color.status.success on color.bg.subtle
|
1.4.3 text | 4.5:1 |
#1c6e3d on #f2f2f0: 5.59:1 |
#73cc93 on #1a1a19: 8.94:1 |
color.status.warning on color.bg.subtle
|
1.4.3 text | 4.5:1 |
#8c5600 on #f2f2f0: 5.43:1 |
#e9b65c on #1a1a19: 9.38:1 |
color.status.danger on color.bg.subtle
|
1.4.3 text | 4.5:1 |
#b4261f on #f2f2f0: 5.78:1 |
#ff8a80 on #1a1a19: 7.62:1 |
color.status.info on color.bg.subtle
|
1.4.3 text | 4.5:1 |
#1f55a0 on #f2f2f0: 6.53:1 |
#8cb2f0 on #1a1a19: 8.07:1 |
color.code.text on color.code.bg
|
1.4.3 text | 4.5:1 |
#1a1a19 on #f2f2f0: 15.53:1 |
#ececea on #1a1a19: 14.72:1 |
color.code.keyword on color.code.bg
|
1.4.3 text | 4.5:1 |
#0b6b69 on #f2f2f0: 5.64:1 |
#5cc6be on #1a1a19: 8.52:1 |
color.code.string on color.code.bg
|
1.4.3 text | 4.5:1 |
#1f55a0 on #f2f2f0: 6.53:1 |
#8cb2f0 on #1a1a19: 8.07:1 |
color.code.comment on color.code.bg
|
1.4.3 text | 4.5:1 |
#555552 on #f2f2f0: 6.67:1 |
#a5a5a1 on #1a1a19: 7.04:1 |
color.diagram.ink on color.diagram.surface
|
1.4.3 diagram labels | 4.5:1 |
#1a1a19 on #fdfdfc: 17.11:1 |
#ececea on #121212: 15.83:1 |
color.diagram.ink on color.diagram.period-fill
|
1.4.3 diagram labels | 4.5:1 |
#1a1a19 on #f2f2f0: 15.53:1 |
#ececea on #222221: 13.46:1 |
color.diagram.ink-muted on color.diagram.surface
|
1.4.3 diagram labels | 4.5:1 |
#555552 on #fdfdfc: 7.34:1 |
#a5a5a1 on #121212: 7.57:1 |
color.diagram.ink-muted on color.diagram.period-fill
|
1.4.3 diagram labels | 4.5:1 |
#555552 on #f2f2f0: 6.67:1 |
#a5a5a1 on #222221: 6.44:1 |
color.diagram.rule on color.diagram.surface
|
1.4.11 diagram line | 3:1 |
#7d7d79 on #fdfdfc: 4.06:1 |
#71716d on #121212: 3.82:1 |
color.diagram.rule on color.diagram.period-fill
|
1.4.11 diagram line | 3:1 |
#7d7d79 on #f2f2f0: 3.68:1 |
#71716d on #222221: 3.24:1 |
color.diagram.extra-week on color.diagram.surface
|
1.4.11 diagram mark | 3:1 |
#0b6b69 on #fdfdfc: 6.21:1 |
#5cc6be on #121212: 9.16:1 |
color.diagram.extra-week on color.diagram.period-fill
|
1.4.11 diagram mark | 3:1 |
#0b6b69 on #f2f2f0: 5.64:1 |
#5cc6be on #222221: 7.79:1 |
color.diagram.calendar-b on color.diagram.surface
|
1.4.3 diagram labels | 4.5:1 |
#1f55a0 on #fdfdfc: 7.20:1 |
#8cb2f0 on #121212: 8.69:1 |
color.diagram.reference-date on color.diagram.surface
|
1.4.3 diagram labels | 4.5:1 |
#8c5600 on #fdfdfc: 5.98:1 |
#e9b65c on #121212: 10.08:1 |
color.logo.ink on color.bg.default
|
Logo (exempt; checked anyway) | 4.5:1 |
#1a1a19 on #fdfdfc: 17.11:1 |
#ececea on #121212: 15.83:1 |
color.logo.open-end on color.bg.default
|
Logo (exempt; checked anyway) | 3:1 |
#0b6b69 on #fdfdfc: 6.21:1 |
#5cc6be on #121212: 9.16:1 |
| Pair | Why it is not in the report |
|---|---|
color.border.default on any background |
Decorative only, by definition; its ratio is about 1.33:1 in light and 1.35:1 in dark. Anything that identifies a control or carries meaning uses color.border.strong. Check: python -I design/scripts/contrast.py "#ddddd9" "#fdfdfc". |
color.diagram.period-fill on color.diagram.surface
|
A fill is never the only cue; separators drawn in color.diagram.rule and text labels carry the meaning. |
To check any pair yourself, run python -I design/scripts/contrast.py "<foreground>" "<background>" from the repository root. It prints the ratio and a pass or fail for each WCAG level.
- Edit the token file in
design/tokens/and runpython -I design/scripts/build_tokens.py. The build reruns every contrast check; fix a failure by changing the colour, never by removing the check. - Record the change and its reason in
design/DECISIONS.md. - Update this page's tables and run
python -I design/scripts/check_brand.py --wiki <path to the wiki clone>, which fails if a page shows a hex value that is not in the palette. - If a brand colour changed, regenerate the logo and card files (Asset-Inventory).
Full steps are on Design-Tokens.
- Design-System, Design-Tokens, Typography, Accessibility, Diagrams-and-Data-Visuals, Logo-Guidelines, Design-Glossary, Design-Decisions
- Token files:
design/tokens/; generated contrast report:design/tokens/generated/contrast.md - Scripts:
design/scripts/contrast.py,design/scripts/build_tokens.py,design/scripts/check_brand.py - Research: accessibility, peer analysis, trust and credibility, design tokens
- Decision log:
design/DECISIONS.md(DD-005, DD-013, DD-015, DD-018) - WCAG 2.2
fiscalclock is licensed under MIT OR Apache-2.0 (MIT, Apache-2.0). Last reviewed: 31 Oct 2026. Found an error on this page? Report it with the documentation form.