ClassLink · Frost · Status family investigation

Status family system — proposal v1

A first pass at resolving everything status-family-findings.html surfaced: fewer tiers, one job per tier, and a home for the three real states — Paused, Unconfigured, Read-only — that nothing accounted for. Built on what’s already canonical, not a rewrite from zero.

Status tiers
6 (down from 9)
Based on
status-family-findings.html
Status
Draft · for review
Owner
Jacky Powell
Updated
2026-10-21

01 · The core insight

Status and severity are two different questions

Alert and Critical never attached to a real-world word anywhere we looked — not because they’re bad colors, but because they’re answering a different question than the other seven tokens. Status asks "what state is this specific thing in" (a file, a connection, a sync job) — that’s Success / Info / Warning / Error / Neutral / Pending. Severity asks "how urgent is this problem," which is a notification/incident concept (the way PagerDuty or Datadog separate incident severity from a service’s status). Frost put both questions in one bucket. This proposal splits them: a 6-tier status family for anything attached to an object, and a small separate severity scale (below) for system-wide banners — which finally gives Alert and Critical a real job.

02 · The status family

Six tiers, one job each

Every tier keeps a canonical HSL value already proven in Brand & Semantic or the live components — nothing here is an invented color. Icon per tier matches what was already used consistently wherever that concept appeared.

Success

#03A52E
Word“Synced,” “Connected,” “Active” — any domain word is fine as long as it means “this completed / is healthy.”
WhenAn action completed, or the system/connection is healthy right now.
WhereAny status role: solid pill, dot, icon + word, or surface chip.
WhyGreen = done/healthy is near-universal (IBM Carbon, Atlassian, GOV.UK, Material all agree). Already used this way everywhere we found it — kept unchanged.

Before / after

No change
Synced

Already wired this way everywhere we looked — kept unchanged.

Info

#0A4D7F
Word“Info,” “Scheduled” — reserve for genuinely neutral, no-action-needed messages.
WhenSomething the person should see, but doesn’t need to act on and isn’t a problem.
WhereBadges, inline banners, tooltips.
WhyBlue = neutral/FYI in every system we checked. Stop using it for permission states like Read-only — that’s not information, it’s a restriction (see Neutral).

Before / after

Today
Read-only

components–data-table––default, live — info-blue stretched onto a permission state.

→
Proposed
Read-only

Moves to Neutral, with its own icon — a restriction, not information.

Warning

#E4830C
WordDefault: “Warning.” “Degraded” or “Needs attention” are both fine substitutes — the finding wasn’t that the word is wrong, it’s that no one had picked a default yet.
WhenSomething needs attention but hasn’t failed. The thing still basically works.
WhereBadges, banners, table status columns.
WhyAmber = caution, consistently applied already. This is the one tier that was already working end to end — only the missing “pick one default word” needed deciding.

Before / after

Already in use, three ways
WarningDegradedNeeds attention

Same amber, same icon, three words already live in different products — this proposal just names “Warning” the default for new work.

Error

#E40101
WordDefault: “Failed.” (“Error,” “Rejected,” “Declined” etc. for specific domains.)
WhenSomething broke, was rejected, or needs the person to act now.
WhereBadges, banners, inline messages.
WhyMerges alert + critical + failure/destructive into the one red tier that’s ever actually been used for a status. True red, not critical’s magenta — red is the cross-system convention for error (IBM, Atlassian, GOV.UK, Material). “Destructive” stays a separate, button-only action color — it was never really a status.

Before / after

Today
Failed

components––status-indicator, live — wired to --critical (hsl 332 100% 43%).

→
Proposed
Failed

Same icon, same word — re-wired to the hue every trusted system uses for error.

Neutral

#F2F2F2 · #666666
WordDefault: “Unavailable.” Also covers Paused, Unconfigured, Read-only — same color, different icon (see below).
WhenNothing is wrong, but nothing is actively happening either: off, disabled, restricted, or not yet set up.
WhereBadges, table status columns.
WhyMerges neutral + muted into the value that’s already canonical in Brand & Semantic, and finally gives Paused, Unconfigured and Read-only a real home instead of being invented ad hoc per product.

Sketched in section 03 below — Neutral covers four icons off one color.

Pending

#746F67
WordDefault: “Processing.”
WhenAn action is actively in progress and will resolve into one of the other five states.
WhereBadges, table status columns.
WhyKept as its own tier — “actively working on it” behaves differently from “inactive” (Neutral) and deserves to look different, the way Atlassian’s “In progress” is its own color, not a shade of grey. One concrete change: animate the icon. A static loader glyph doesn’t read as “in progress” — it read as a settings/options icon in every source we checked.

Before / after

Today
Processing

components––status-indicator, live — the glyph never moves, reads like a settings icon.

→
Proposed
Processing

Same color, same icon — just add motion. (The icon on the right is genuinely animating.)

03 · Neutral, one color, several meanings

Where Paused, Unconfigured and Read-only finally live

Rather than inventing a new color per nuance, Neutral carries the "nothing’s wrong, nothing’s active" meaning, and the icon tells you the specific reason — the same pattern Atlassian and GOV.UK use for their default/grey tag family.

Unavailable / disabled

“Unavailable,” “Disabled”

Paused

“Paused” — the real OneData state with no home today

Not yet configured

“Unconfigured” — also unaccounted for today

Restricted / read-only

“Read-only” — currently force-fit onto Info

Before / after

Today · two values
UnavailableUnavailable

The “neutral” token carried a warm-beige value in one standalone file, and near-white grey in the live component — two colors, one supposed meaning.

→
Proposed
Unavailable

One value: the near-white grey already canonical in Brand & Semantic and the live component.

Today · one token, two jobs
UnavailableProcessing

“muted” did two unrelated jobs — Unavailable in one file, Processing in another — with two different actual color values behind the one token.

→
Proposed
UnavailableProcessing

Each job gets the tier that actually fits: Unavailable → Neutral, Processing → Pending (and finally animates).

Today
No shared treatment — each product draws its own icon

Paused and Unconfigured are real OneData states today, invented ad hoc with no token behind them.

→
Proposed
PausedUnconfigured

Same Neutral grey, a different icon per reason — now part of the system instead of a one-off.

04 · A separate severity scale

For system-level banners, not per-item status

This is sketched, not fully specified — flagged below as its own decision. The idea: an escalating scale for things like maintenance notices or outage banners — a job nothing else was doing. Critical keeps its existing hue; Alert's legacy brick read too heavy next to Warning, so it gets a fresh violet instead.

Alert vs. Warning

An alert is a broad notification or state of readiness that informs you of a potential event or condition, whereas a warning is a specific, urgent notice that a hazardous or dangerous event is already happening or strictly imminent.

NoticeScheduled maintenance
AlertDegraded for some users
WarningDegraded for most users
CriticalFull outage

Before / after

Today
Alert
Critical

Bare swatches with no real-world word ever attached — this is all either token does in the status-families spec today.

→
Proposed

Critical keeps its hue. Alert trades its old brick for a violet that reads clearly next to Warning instead of heavier than it — both finally doing a real job: system-wide banners, not per-item status.

05 · What changes from today

Migration, token by token

TodayProposedWhy
alertretired as a status token; its old brick hue retires tooNever had a real-world word attached to it in any source audited. The severity scale below needed a second rung after Notice, but the legacy brick read heavier than Warning sitting right next to it — so that rung gets a new violet instead of the old hue.
criticalbecomes “Error,” hue changes from magenta to redThe live Status component already wires the word “Failed” to this token — we’re making that the rule, not the exception, and switching to the hue every trusted system actually uses for error.
failure / --destructive (as a status)folded into “Error” for status use; --destructive remains, but only for destructive actions (delete buttons)Having a token for “failure” that no live status component actually used was the core conflict in the findings. One red status tier, one separate action color.
neutralfolded into “Neutral,” value changes to the canonical 0 0% 95%The warm-beige value only ever existed in one standalone file. The live component and the canonical registry already agree on near-white grey — we’re keeping the canonical one.
mutedfolded into “Neutral” (Processing moves to the Pending tier instead)“muted” was doing two unrelated jobs — Unavailable in one file, Processing in another — with two different actual color values. Splitting those jobs onto Neutral and Pending removes the conflict.
pendingkept, unchanged color, now animatedAlready correct in every source — the only change is giving the loader icon motion so it reads as active.

06 · What we kept, because it already works

Not a rewrite

Every canonical HSL value

Success, Info, Warning, and Pending’s colors are untouched — they were already consistent everywhere and already match Brand & Semantic.

Icon-plus-word, never color alone

Every source we audited already pairs a Lucide icon with a visible word — satisfies WCAG 1.4.1 (don’t rely on color alone) without any change needed.

The four role patterns

Solid pill, emphasis dot + word, icon + word, and surface chip from status-families-spec all still apply — this proposal changes which six colors fill them in, not the patterns themselves.

07 · Why these choices

Grounded in precedent, not just preference

Fewer tiers, less cognitive load

Nielsen Norman Group and most mature enterprise systems (IBM Carbon, Salesforce Lightning) settle on 4–6 status colors. Nine was already more than any of them.

Red means error, everywhere

IBM, Atlassian, GOV.UK and Material all converge on true red for error/danger. Critical’s magenta was an outlier with no precedent backing it as a status color.

One grey family, many icons

Atlassian’s default/grey tag and GOV.UK’s grey tag both carry several specific meanings off one neutral color — exactly the Neutral tier here.

In-progress deserves motion

Atlassian’s "In progress" status and most CI/deploy tools (GitHub Actions, Vercel) use an animated indicator specifically so "pending" doesn’t read as "stuck."

08 · Open questions

Your call

Does Critical’s hue actually change?

Recommended: yes, to true red, since it becomes the status "Error" tier. Alternative: keep the magenta for Critical and let it stay a severity-only color, with Error getting a fresh third red.

Option B
CriticalFailed

Critical keeps its magenta as a severity-only color; Error gets a third, different red. Three reds in the system instead of one.

→
Option A · recommended
Failed

Critical repoints to true red and becomes the status “Error.” One red, used one way.

Decision: Pending

Is the severity scale worth building now?

It’s sketched here mainly to give Alert and Critical a legitimate reason to exist. Could be its own follow-up project instead of part of this pass.

Today
Alert
Critical

Bare swatches with no real-world word ever attached — this is all either token does in the status-families spec today.

→
Proposed

Critical keeps its hue. Alert trades its old brick for a violet that reads clearly next to Warning instead of heavier than it — both finally doing a real job: system-wide banners, not per-item status.

Decision: Pending

Confirm the six default words

Synced/Failed/Processing etc. are starting points, not final copy — content design should sign off.

The six defaults, rendered
Synced Failed Processing Warning Info Unavailable

Starting points, not final copy — confirm or swap any word before content design signs off.

Decision: Pending

Who owns rolling this out across ClassLink’s products?

OneData and OneSync are what we audited, but the real scope is every ClassLink product currently being reskinned — most still run entirely on Font Awesome icons and no Frost tokens. This system solves the design side; adoption is a separate, larger effort that has to happen product by product.

Today
Font Awesome icons, no Frost token

OneData and OneSync are the two we audited, but every product currently being reskinned renders status this way today — this proposal hasn’t touched any of them yet.

→
Proposed
FailedUnavailableProcessing

This system’s badges — rolled out product by product as each one goes through the reskin, not a one-time OneData/OneSync fix.

Decision: Pending

Should we audit every product before rolling out?

This proposal is built from the OneData/OneSync audit plus outside precedent — it hasn’t been run against the status patterns in the rest of the reskin yet. Worth expanding the audit first to see if the six tiers actually hold, before any product starts migrating to this system.

Audited so far
OneDataOneSync

This proposal is grounded in two products’ worth of real patterns, plus outside precedent.

→
Proposed audit
Every other product in the reskin — not yet checked

Confirms the six tiers (and the Neutral icon set) actually hold up everywhere, or surfaces a status concept this pass didn’t anticipate — before any product starts migrating to it.

Decision: Pending

Keep “Emphasis dot + word,” or drop it?

Faina flagged the dot for removal — fewer role patterns means less inconsistency, and every one of the six tiers already has a real icon, so nothing would be orphaned the way “alert” and “failure” used to be. But dropping it costs density: Icon + word is heavier than a dot, and becomes the only inline pattern left for the busiest table rows and compact lists. A middle path: keep the dot, but scope it — use it only in the most dense contexts (dense table rows, compact inline lists) where Icon + word would crowd the row, and keep Icon + word as the default everywhere else.

Decision: Pending

Raised in design review with Faina, 2026-10-22.