ClassLink · Frost · Data visualization spec

Chart color and treatment strategy

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.

Scope
Charts, KPI heroes, heatmaps
Status
Draft
Tokens
Page-local for now
Updated
2026-10-13

01 · Purpose

What it is for

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.

Role rampslight theme · 5 steps · same lightness steps as the approved blue ramp
All roles
Brand blue · approved
#DCEBF8#A9CDEE#6FAAD9#2F78B3#0A4D7F
Students
Teal · proposal
#E0EBEB#9AD5D4#52B5B5#018484#005656
Teachers
Violet · approved
#EEEBF8#D5CDED#B8ABE0#9986D3#7257C2
Students and teachers
Plum · proposal
#EEE6ED#E2B9DD#C78CC2#9C5496#6B2F67
Admins
Gold · proposal
#EDE8E0#DEC59A#C39D5A#966A02#624400
Other staff
Slate · proposal
#ECF2F8#C9D4DF#9AA9B8#5E6E80#2F3E50
Measure paletteproposal · for measures, not roles · validated with the dataviz palette script
Measure 1 · Time
Brand blue · same ramp as All roles
#DCEBF8#A9CDEE#6FAAD9#2F78B3#0A4D7F
Measure 2 · Resources
Moss · proposal
#EEF2E2#D3DFA8#B0C66A#7E9C22#566B14
Dark theme marks
Proposal · v.03 is light only
#6BA8E0 blue#9BB83A moss8.4:1 and 7.5:1 on #0C1118
Measure 3
None · use a facet

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.

Role-coded heatmapFrost heatmap look · ramp chosen by role · role named in text
All roles
Mon
Tue
Wed
Thu
Fri
Lincoln ES
92%
95%
90%
88%
70%
Washington ES
80%
84%
82%
78%
55%
Riverside ES
62%
70%
66%
60%
40%
Students
Mon
Tue
Wed
Thu
Fri
Lincoln ES
94%
97%
92%
90%
71%
Washington ES
82%
86%
84%
80%
56%
Riverside ES
63%
71%
67%
61%
41%
Students and teachers
Mon
Tue
Wed
Thu
Fri
Lincoln ES
78%
81%
76%
75%
60%
Washington ES
68%
71%
70%
66%
47%
Riverside ES
53%
60%
56%
51%
34%

02 · Treatments

Three treatments and when to use each

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.

Default

A · Quiet Frost

Learning time90%

Flat role fills, 4px rounded bar tops, light gridlines, brand blue for any single series. Maps directly to page-local tokens.

Single series only

B · Rail gradient

Learning time90%

Fill samples the rail hue range (blue → teal → green) at chart-safe lightness. Soft area fade under one line. Never on heatmap cells.

KPI heroes

C · Editorial numerals

90%
Learning time

Barlow Semi Condensed numerals carry the message. No gridlines, direct labels, one highlighted mark; the rest recede to step 2.

TreatmentUse forAvoid 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

Color and styling 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.

PartRuleTokenBasis
Roles and rampsEach role has one hue and one 5-step ramp. Hue says which role; darker always means more.--role-{name}-s1…s5Proposal
Role orderAll roles, Students, Teachers, Students and teachers, Admins, Other staff. Same order in legends, tabs and stacks.n/aProposal
Role huesBlue (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 aboveProposal
Single seriesOne series uses brand blue #0A4D7F. Do not use an accent color there.--role-all-s5Approved
MeasuresA 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-2Proposal
Measure countTwo 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/aProposal
Moss contrastMoss 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-s5Proposal
Role text labelEvery role-colored chart or table names the role in text (chip, tab or legend). Color is never the only cue.n/aProposal
Heatmap cell textPick dark ink or white per cell, whichever has higher contrast; target 4.5:1.--role-*-t1…t5Proposal
Heatmap zeroZero is a hatched cell, not step 1..hm-zeroApproved
MarksBars, 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/aProposal
Area sizeLarge areas (bars, fills) use the lighter steps or flat fills; small marks (lines, dots) can use the darker steps.n/aProposal
NeutralsGridline #E6ECF3, baseline #CBD6E2, axis text #44546A, track #E8EEF5. Gridlines lightest, axis labels darker, titles darkest.--chart-grid · --chart-baseline · --chart-axis · --chart-trackProposal
Bar shape4px rounded top (A), 6px (B/C). 1px white gap between stacked segments.n/aProposal
StatusStatus 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-finalApproved

04 · Watch for

Guardrails and notes

Guardrail

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.

Guardrail

Gradients (treatment B) are for single series only. Whether they need a flat fallback for print and export is deferred.

Guardrail

Teal, gold, slate and plum are new proposals. Violet and blue come from existing Frost pages.

Note

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.

Note

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.

Note

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

Do and don't

Do

One brand-blue series. Position separates the categories, so color doesn't have to.

Don't

A different hue per bar (the current CMC pattern) with no meaning behind the order.

06 · Implementation

Tokens and code

Define these on each page for now. Text tokens (-t1 to -t5) were chosen by contrast against each step.

page-local chart tokens.css
/* 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

How to know it landed

  • One treatment per chart. Each chart is A, B or C and matches the use table. No gradients on heatmap cells or multi-series charts.
  • Role colors never vary. A role has the same hue in every chart, tab and legend on every page.
  • Role is named. Every role-colored chart or table shows the role as text.
  • Contrast. Cell and label text is 4.5:1 or better; bars, lines and markers are 3:1 or better against the surface.
  • Measures use measure hues. A measure chart or hero value is blue or moss; a role chart never is moss, and no chart uses more than two measure hues.
  • Zero is hatched in every heatmap.
  • No legacy status colors. Search the page for #E40101, #E5840C, #F3B211, #26C06E, #03A52D and #28A745 as chart fills; none remain.
  • Status uses the badge spec and always has a text label.
  • Reskin only. A before and after screenshot shows identical layout, labels, data and interactions.

08 · Open questions

Decisions needed

Role hues

Teal, gold and slate accepted for Students, Admins and Other staff. Plum chosen for Students and teachers.

Decision: Decided · 2026-10-13

Three treatments kept

Keep A, B and C, each with its own use case.

Decision: Decided · 2026-10-13

Status colors in charts

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

Failure red vs badge danger

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

Should treatment B follow each product's rail?

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

Which rail does Insights use?

The rail spec lists ten products and none is Insights. The spec also says ten rails while the request mentioned eight.

Decision: Pending

Measure palette

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

Colorblind check

Simulate all six ramps, especially plum vs danger pink, teal vs blue, and gold vs slate.

Decision: Pending

Flat fallback for gradients

Whether treatment B needs a flat color for print and export.

Decision: Deferred

Semantic chart system and dark mode

Move tokens out of each page once direction is final, then define dark values.

Decision: Deferred

← Design crit overview