A · Quiet Frost
Flat role fills, 4px rounded bar tops, light gridlines, brand blue for any single series. Maps directly to page-local tokens.
ClassLink · Frost · Data visualization spec
One color system and three treatments for every chart, KPI hero and heatmap in the reskin. Colors and styling only; no layout or UX changes.
01 · Purpose
The chart audit found 23 captured screens across Analytics+, Insights, CMC and Roster Server using about five greens for "good," four ambers, an 8-color rainbow bar palette, and no chart tokens. The Frost shell is modern but the plots inside it are not. This spec gives every chart one source of color and tells you which of three treatments to use.
No third hue passes the colorblind check against the six role hues and three status hues. A third measure gets its own chart or tile, not a new color. Measure text stays in ink tokens; a 54px hero value may wear the measure hue.
02 · Treatments
Use one treatment per chart. A is the default. B and C can sit on the same page as A, each in its own place.
Flat role fills, 4px rounded bar tops, light gridlines, brand blue for any single series. Maps directly to page-local tokens.
Fill samples the rail hue range (blue → teal → green) at chart-safe lightness. Soft area fade under one line. Never on heatmap cells.
Barlow Semi Condensed numerals carry the message. No gridlines, direct labels, one highlighted mark; the rest recede to step 2.
| Treatment | Use for | Avoid for |
|---|---|---|
| A · Quiet Frost Default for every chart | Column and stacked-role columns, horizontal bars, line charts, heatmaps, table-embedded bars. Examples: Analytics+ Failed Logins, OS / Browser, Costs, Students by Grade; Roster Server and CMC dashboard columns; Insights app-analysis lines and portfolio bars. | Nothing. This is the baseline the other two sit on. |
| B · Rail gradient Single-series fills only | Progress capsules, one-line area fills, rings and gauges, KPI hero card backgrounds. Examples: Screen Time progress lines, Screen Time ring scorecards, Login Summary hero card. | Heatmap cells, role-stacked bars, anything with two or more categories, any chart where the value is read from the color itself. |
| C · Editorial numerals KPI heroes and lightly-labeled charts | Big-number tiles and KPI strips, Insights headline heroes, small charts with one highlighted mark. Examples: Analytics+ Overview tiles, Roster Server stat tiles, Insights Cost / Instructional / Assessments strips. | Dense charts, heatmaps, or any chart where readers need axes to read exact values. |
03 · Rules
"Approved" means it comes from an approved Frost source (heatmap ramp, status badges, school-comparison ramps). "Proposal" is new in this work and needs review.
| Part | Rule | Token | Basis |
|---|---|---|---|
| Roles and ramps | Each role has one hue and one 5-step ramp. Hue says which role; darker always means more. | --role-{name}-s1…s5 | Proposal |
| Role order | All roles, Students, Teachers, Students and teachers, Admins, Other staff. Same order in legends, tabs and stacks. | n/a | Proposal |
| Role hues | Blue (All), teal (Students), violet (Teachers), plum (Students and teachers), gold (Admins), slate (Other). Green and pink are not used for roles: Frost badges give them success and danger meaning. | ramps above | Proposal |
| Single series | One series uses brand blue #0A4D7F. Do not use an accent color there. | --role-all-s5 | Approved |
| Measures | A measure (Time, Digital Resources, Logins) is not a role. The first measure on a page uses brand blue; a second measure shown beside it uses moss #7E9C22. Measure hues never appear in a role chart and role hues never appear in a measure chart. | --measure-1 · --measure-2 | Proposal |
| Measure count | Two measure hues, no more. A third measure gets its own chart or tile. Both hues pass CVD ΔE 8 against every role and status hue; nothing else in the warm, cyan or pink range does. | n/a | Proposal |
| Moss contrast | Moss step 4 is 3.0:1 on the page surface, enough for bars, hero values and 2px lines. Thin lines, dots and any text use step 5 #566B14. Hover darkens to step 5; lightening would drop under 3:1. | --measure-2-s4 · --measure-2-s5 | Proposal |
| Role text label | Every role-colored chart or table names the role in text (chip, tab or legend). Color is never the only cue. | n/a | Proposal |
| Heatmap cell text | Pick dark ink or white per cell, whichever has higher contrast; target 4.5:1. | --role-*-t1…t5 | Proposal |
| Heatmap zero | Zero is a hatched cell, not step 1. | .hm-zero | Approved |
| Marks | Bars, lines and markers need 3:1 against the surface. Thin lines and small marks use step 4 or 5, never 1 to 3. Violet step 4 is 3.13:1, so use step 5 for thin violet lines. | n/a | Proposal |
| Area size | Large areas (bars, fills) use the lighter steps or flat fills; small marks (lines, dots) can use the darker steps. | n/a | Proposal |
| Neutrals | Gridline #E6ECF3, baseline #CBD6E2, axis text #44546A, track #E8EEF5. Gridlines lightest, axis labels darker, titles darkest. | --chart-grid · --chart-baseline · --chart-axis · --chart-track | Proposal |
| Bar shape | 4px rounded top (A), 6px (B/C). 1px white gap between stacked segments. | n/a | Proposal |
| Status | Status marks use the Frost badge spec: success #007F31, warning #B05500, danger #D90065, info #0072BD, neutral #4B5562, muted #736E67, always with a label. Bright legacy status colors are not used as chart fills. | Frost-status-badges-final | Approved |
04 · Watch for
Plum (Students and teachers) sits near Frost's pink danger color. Keep plum out of status marks, and run a colorblind simulation on all six ramps before sign-off. Not done yet.
Gradients (treatment B) are for single series only. Whether they need a flat fallback for print and export is deferred.
Teal, gold, slate and plum are new proposals. Violet and blue come from existing Frost pages.
The Storybook Colors page shows the legacy brand set (primary blue, secondary blue, decorative green and gold) next to bright status colors with 50 to 900 ramps. It says green and gold are decorative-only and that status uses the accessible inks. Chart status marks therefore follow the badge spec inks, and green is kept out of role colors. The Storybook hex values were read from screenshots, not from tokens, so they are approximate.
The approved left-nav rail spec has ten rails running blue-green through violet to rose, plus a gray internal rail. None is gold. The Admins gold ramp matches the hue of the Storybook decorative gold, not any rail, and plum sits at about the hue of the CMC rail's top stop.
Research basis: Datawrapper's color guides and Okabe-Ito were read directly. Carbon, Atlassian, ColorBrewer and Lisa Charlotte Muth's article were taken from search summaries. The FT's palette was not verified. Dark mode is out of scope for this draft.
05 · Compare
One brand-blue series. Position separates the categories, so color doesn't have to.
A different hue per bar (the current CMC pattern) with no meaning behind the order.
06 · Implementation
Define these on each page for now. Text tokens (-t1 to -t5) were chosen by contrast against each step.
/* Page-local chart tokens. Light theme only. Not part of v.03; move into a semantic chart system later. */
:root{
--role-all-s1:#DCEBF8;
--role-all-s2:#A9CDEE;
--role-all-s3:#6FAAD9;
--role-all-s4:#2F78B3;
--role-all-s5:#0A4D7F;
--role-all-t1:#10243C;
--role-all-t2:#10243C;
--role-all-t3:#10243C;
--role-all-t4:#FFFFFF;
--role-all-t5:#FFFFFF;
--role-students-s1:#E0EBEB;
--role-students-s2:#9AD5D4;
--role-students-s3:#52B5B5;
--role-students-s4:#018484;
--role-students-s5:#005656;
--role-students-t1:#10243C;
--role-students-t2:#10243C;
--role-students-t3:#10243C;
--role-students-t4:#FFFFFF;
--role-students-t5:#FFFFFF;
--role-teachers-s1:#EEEBF8;
--role-teachers-s2:#D5CDED;
--role-teachers-s3:#B8ABE0;
--role-teachers-s4:#9986D3;
--role-teachers-s5:#7257C2;
--role-teachers-t1:#10243C;
--role-teachers-t2:#10243C;
--role-teachers-t3:#10243C;
--role-teachers-t4:#10243C;
--role-teachers-t5:#FFFFFF;
--role-both-s1:#EEE6ED;
--role-both-s2:#E2B9DD;
--role-both-s3:#C78CC2;
--role-both-s4:#9C5496;
--role-both-s5:#6B2F67;
--role-both-t1:#10243C;
--role-both-t2:#10243C;
--role-both-t3:#10243C;
--role-both-t4:#FFFFFF;
--role-both-t5:#FFFFFF;
--role-admins-s1:#EDE8E0;
--role-admins-s2:#DEC59A;
--role-admins-s3:#C39D5A;
--role-admins-s4:#966A02;
--role-admins-s5:#624400;
--role-admins-t1:#10243C;
--role-admins-t2:#10243C;
--role-admins-t3:#10243C;
--role-admins-t4:#FFFFFF;
--role-admins-t5:#FFFFFF;
--role-other-s1:#ECF2F8;
--role-other-s2:#C9D4DF;
--role-other-s3:#9AA9B8;
--role-other-s4:#5E6E80;
--role-other-s5:#2F3E50;
--role-other-t1:#10243C;
--role-other-t2:#10243C;
--role-other-t3:#10243C;
--role-other-t4:#FFFFFF;
--role-other-t5:#FFFFFF;
/* Measure palette (proposal). Measure 1 reuses the blue ramp. */
--measure-1-s4:#2F78B3; --measure-1-s5:#0A4D7F; --measure-1-hover:#215E92;
--measure-2-s1:#EEF2E2; --measure-2-s2:#D3DFA8; --measure-2-s3:#B0C66A; --measure-2-s4:#7E9C22; --measure-2-s5:#566B14; --measure-2-hover:#566B14;
/* dark proposal: --measure-1-s4:#6BA8E0; --measure-1-hover:#7DBAF3; --measure-2-s4:#9BB83A; --measure-2-hover:#B5D14F; */
--chart-grid:#E6ECF3; --chart-baseline:#CBD6E2; --chart-axis:#44546A; --chart-track:#E8EEF5;
--chart-grad-rail:linear-gradient(90deg,#2F78B3,#2E92A3 55%,#3AA58F); /* B only, single series */
}
.hm-zero{background:repeating-linear-gradient(45deg,#fff 0 4px,#EEF2F7 4px 5px);border:1px solid var(--chart-grid)}
07 · Acceptance
08 · Open questions
Teal, gold and slate accepted for Students, Admins and Other staff. Plum chosen for Students and teachers.
Decision: Decided · 2026-10-13
Keep A, B and C, each with its own use case.
Decision: Decided · 2026-10-13
Insights' red-to-green student strip and Screen Time bands used legacy status colors. They need a mapping onto the Frost badge spec, for example which badge color each band uses.
Decision: Pending
Storybook keeps a red failure/destructive token (--destructive) and a separate pink critical, plus alert and pending. The final badge spec has six states, with pink as danger. Which set do chart status marks follow, and does destructive red ever appear in a chart?
Decision: Pending
B currently uses a fixed blue to teal to green. The ten approved rails are per product, so B could sample the product's own rail instead. That would make Analytics+ charts rose and magenta, close to danger pink. Recommendation: keep B fixed for now.
Decision: Pending
The rail spec lists ten products and none is Insights. The spec also says ten rails while the request mentioned eight.
Decision: Pending
Moss #7E9C22 proposed as the one non-role hue, with brand blue as measure 1. Validator (OKLab, light surface): worst CVD ΔE 8.9 against gold, worst normal ΔE 13.6 against gold, 3.0:1 on #F8FAFC. Dark #9BB83A: worst CVD 10.0 against success. Every warm, cyan and pink candidate failed against warning, gold, blue or danger. The earlier Logins fuchsia #993C8C sits at ΔE 4.2 from plum under CVD, so Logins stays blue. Confirm moss, or accept a one-hue palette plus facets.
Decision: Pending
Simulate all six ramps, especially plum vs danger pink, teal vs blue, and gold vs slate.
Decision: Pending
Whether treatment B needs a flat color for print and export.
Decision: Deferred
Move tokens out of each page once direction is final, then define dark values.
Decision: Deferred