Focused Review
Shabana token decisions
A clearer page for the colour alignment discussion: what is already canonical, what needs Shabana's decision, and what is just implementation cleanup.
What Matters
The long audit table was mixing three different things. This page separates them so the team can discuss the right thing at the right level.
34Canonical primitives Shabana wants
36Canonical dark semantic tokens
14Actual design decisions needed
Light mode is intentionally excluded: Shabana's light-mode semantic colours are yet to be worked on, so this page only treats dark mode as canonical.
Decisions Needed From Shabana
These are the only items that need design input before we can make dark mode strict against the 34-token primitive palette. Everything else below is cleanup work once these decisions are clear.
| Area | Semantic token | Current | Closest approved target | Decision needed |
|---|---|---|---|---|
| Canvas surface | ui.background.page | neutral975 / #030F1A | slate900 / #092D46 | Should the app canvas move to Slate-900, or should Neutral-975 be added to the approved palette? |
| Tint surface | ui.background.success | green900 / #236C18 | green800 / #268717 | Should dark success surfaces keep the deeper Green-900, or move to approved Green-800? |
| Tint surface | ui.background.error | red900 / #470E00 | red800 / #7A1800 | Should dark error surfaces keep the deeper Red-900, or move to approved Red-800? |
| Tint surface | ui.background.warning | yellow900 / #332D00 | yellow800 / #695C00 | Should dark warning surfaces keep the deeper Yellow-900, or move to approved Yellow-800? |
| Secondary content | ui.text.secondary | neutral300 / #C9D1D9 | slate300 / #CEDBE4 | Can secondary text move from neutral grey to slate-tinted copy? |
| Inverse content | ui.text.inverse | neutral900 / #0D1117 | slate900 / #092D46 | Should inverse text become slate-tinted instead of neutral black? |
| Brand content | ui.text.brand | blue400 / #8CA1EE | blue300 / #B9C4EE | Should brand text use Blue-300, or the stronger approved Blue-500? |
| Warning content | ui.text.warning | yellow300 / #FFEF75 | yellow400 / #FFE940 | Can warning text move to approved Yellow-400? |
| Secondary content | ui.icon.secondary | neutral300 / #C9D1D9 | slate300 / #CEDBE4 | Can secondary icons move from neutral grey to slate-tinted icons? |
| Inverse content | ui.icon.inverse | neutral900 / #0D1117 | slate900 / #092D46 | Should inverse icons become slate-tinted instead of neutral black? |
| Brand content | ui.icon.brand | blue400 / #8CA1EE | blue300 / #B9C4EE | Should brand icons use Blue-300, or the stronger approved Blue-500? |
| Feedback | ui.feedback.warning | yellow300 / #FFEF75 | yellow400 / #FFE940 | Can warning indicators move to approved Yellow-400? |
| Feedback | ui.feedback.pending | yellow200 / #FFF5AB | yellow400 / #FFE940 | Should pending share Yellow-400 with warning, or get a distinct approved primitive? |
| Feedback | ui.feedback.info | blue400 / #8CA1EE | blue300 / #B9C4EE | Should info indicators use Blue-300, or the stronger approved Blue-500? |
Implementation Cleanup After Decisions
This is not a list for Shabana to review line by line. These are engineering migration buckets created by the palette consolidation.
Primitive Migration Buckets
| Bucket | Size | What it contains | Migration direction |
|---|---|---|---|
| Slate / Neutral depth | 18 primitives | Extra light/dark neutrals and slate steps used by light mode, overlays, inverse text, and dark canvas. | Decide whether the approved palette needs a deeper app-canvas primitive, otherwise migrate to Slate-900 / Slate-300 / Neutral-500 / Neutral-700. |
| Blue / Sky | 7 primitives | Older brand/info blues plus Sky aliases. | Collapse to Blue-300, Blue-500, Blue-600, Blue-800, or Blue-900. |
| Green | 5 primitives | Legacy success and light-mode success stops. | Collapse to Green-100, Green-300, Green-500, Green-700, or Green-800. |
| Red | 5 primitives | Intermediate and deep error stops. | Collapse to Red-100, Red-400, Red-700, or Red-800. |
| Yellow / Gold | 10 primitives | Legacy warning, pending, and premium gold stops. | Decide whether premium gold remains product-specific; otherwise collapse into Yellow-100, Yellow-400, Yellow-700, Yellow-800. |
| Extended accents | 15 primitives | Extra peach, rose, lavender, indigo, azure, salmon, cyan, magenta, and terracotta variants. | Keep only Violet, Cyan, Coral, and Terracotta as canonical unless Shabana approves a broader accent set. |
| Base / overlays / glass | 21 primitives | White/black, alpha overlays, glass gradients, pending overlays, and one track helper. | Do not treat these as palette colours; either promote as semantic effects or migrate callers to surface/overlay semantics. |
Legacy Semantic Alias Buckets
| Bucket | Size | What it contains | Migration direction |
|---|---|---|---|
| Background aliases | 12 aliases | pageNavy, surfaceSubtle, surface, surfaceSecondary, inverseSecondary, disabled/inset/glass/info aliases. | Migrate usage to page, pageSubtle, raised, inverse, or feedback.info. |
| Text aliases | 3 aliases | onColor, onFill, info. | Migrate usage to primary/inverse or feedback.info depending on context. |
| Icon aliases | 8 aliases | tertiary, disabled, onColor, onFill, success/error/warning/info. | Migrate usage to secondary, primary, or feedback status semantics. |
| Border aliases | 3 aliases | disabled, warning, info. | Migrate usage to subtle or feedback status semantics. |
| Interactive aliases | 3 aliases | primaryActive, secondaryBorder, disabledText. | Migrate usage to selected, primary, or text.disabled. |
| Base / overlay aliases | 6 aliases | base.black and overlay light/medium/dark/black/transparent. | Migrate usage to background.page unless a real overlay semantic is needed. |
Why the old table felt too long
It listed every compatibility primitive and every legacy semantic alias as if each one needed a separate design conversation. Most do not. The design conversation is the 14-row decision table above; the rest is engineering migration once those answers are confirmed.
Canonical Tables
These are the approved sets the team should align to for this dark-mode pass.
Canonical Primitive Tokens
| Family | Token | Value | Role |
|---|---|---|---|
| Slate | slate100 | #F5F9FB | Light inverse surface |
| Slate | slate300 | #CEDBE4 | Light border / disabled surface |
| Slate | slate500 | #7992A6 | Low-emphasis light content |
| Slate | slate800 | #25445B | Strong slate accent |
| Slate | slate900 | #092D46 | Hero surface / brand background |
| Blue | blue100 | #EEF0F7 | Info background |
| Blue | blue300 | #B9C4EE | Soft brand support |
| Blue | blue500 | #5D7DF4 | Brand support |
| Blue | blue600 | #1E4FDD | Primary CTA |
| Blue | blue800 | #1334AE | Small-text CTA |
| Blue | blue900 | #142871 | Dark brand depth |
| Green | green100 | #ECFBEA | Success background |
| Green | green300 | #AFFAA3 | Positive support |
| Green | green400 | #82FF6F | Positive data |
| Green | green500 | #31F613 | Success/live |
| Green | green700 | #27A414 | Positive number contrast |
| Green | green800 | #268717 | Success contrast |
| Red | red100 | #FFE7E0 | Error background |
| Red | red400 | #FF6C47 | Error/destructive |
| Red | red700 | #AD2300 | Negative number contrast |
| Red | red800 | #7A1800 | Error contrast |
| Yellow | yellow100 | #FFFBE0 | Warning background |
| Yellow | yellow400 | #FFE940 | Neutral data reference |
| Yellow | yellow700 | #9E8C00 | Warning contrast |
| Yellow | yellow800 | #695C00 | Warning depth |
| Extended | extendedViolet | #DD97F2 | Third data series |
| Extended | extendedCyan | #3A9AA8 | Fourth data series |
| Extended | extendedCoral | #F1A297 | Reduced accent |
| Extended | extendedTerracotta | #A67B4B | Reduced accent |
| Neutral | neutral100 | #E6EDF3 | Primary dark text |
| Neutral | neutral400 | #8B949E | Tertiary text |
| Neutral | neutral500 | #57606A | Disabled / strong border |
| Neutral | neutral700 | #30363D | Default dark border |
| Neutral | neutral800 | #1C2128 | Subtle dark divider |
Canonical Semantic Dark Groups
| Group | Count | Scope |
|---|---|---|
| Surfaces | 7 tokens | Page, raised, page-subtle, inverse, success, error, warning surfaces. |
| Text | 9 tokens | Primary, secondary, tertiary, disabled, inverse, brand, success, error, warning text. |
| Actions | 5 tokens | Primary, secondary, selected, destructive, disabled action colours. |
| Borders | 6 tokens | Subtle, default, strong, focus, error, success borders. |
| Icons | 4 tokens | Primary, secondary, inverse, brand icons. |
| Feedback | 5 tokens | Success, error, warning, pending, info indicators. |