Skip to content

Canadian Palette

Candy pastels in the top half, deep indigo and slate in the bottom. The clearest light/dark split in the collection.

Live preview

Everything below is the real component. Change the controls, tab through it, and turn on Inspector Mode to read any value off the screen.

20 colours
Drawn by Dmitri Litvinov for Flat UI Colors 2.Original
Click any swatch to copy its value.

01 · Text colours

A palette ships hues, not a text ramp. These five are solved against the page background rather than mixed by percentage — "secondary" means 8:1 on every one of the fourteen palettes, so the pages stay comparable and none of them ships a ramp that fails. Disabled sits below the floor deliberately; it is the one role WCAG exempts.

PrimaryHeadings and high emphasis#f4f5f6Derived · near-white holding 8% of Storm Petrel's hue — this palette ships no neutral pale enough for body copy15.07:1
SecondaryBody copy#b2b6b9Derived · solved to 8:1 on the page8.06:1
TertiarySupporting detail#91969bDerived · solved to 5.5:15.52:1
MutedCaptions, metadata, placeholders#81878cDerived · solved to 4.5:1 — the floor for body text4.53:1
DisabledInactive — formally exempt from contrast#5a6168Derived · solved to 2.6:1, deliberately below the floor2.62:1

02 · Surfaces and backgrounds

Anchored on Imperial Primer, the darkest colour in the set. The rest of the ladder is computed, because no palette ships two darks that happen to sit 16% apart — and depth read from surface lightness is the only kind that survives greyscale, high-contrast mode and a phone in sunlight.

Page backgroundThe furthest-back plane#17202aDerived · 32% toward black from Imperial Primer
SurfaceCards, panels, the default plane#1d2734Derived · 16% toward black from Imperial Primer
Surface elevatedMenus, dialogs, anything raised#222f3eRow 4, Col 5 · Imperial Primer
Surface hoverPointer over a row or a card#313e4cDerived · 7% toward white from the elevated surface
BorderDividers and default edges#3a434eDerived · solved to 1.5:1 on the surface — visible, not loud1.50:1
Border strongInputs, checkboxes, anything you can click#697078Derived · solved to 3:1 — the floor for a control boundary3.01:1

03 · Semantic colours

Primary is the palette’s opening colour — designers lead with their signature. The status roles are the nearest hue this palette carries to each target, which is the honest version of a choice usually made by eye. Hover prefers a darker sibling the designer actually drew; active is always computed. Where a role sits far from its ideal hue, the row says so.

PrimaryRow 1, Col 2 · Casandora Yellow — the palette's opening colour
base#feca57
hover#ff9f43
active#c19a42

Label on the fill: the page colour at 10.81:1 · Hover is a palette colour.

SuccessRow 1, Col 5 · Wild Caribbean Green
base#1dd1a1
hover#10ac84
active#169f7a

Label on the fill: the page colour at 8.37:1 · Hover is a palette colour.

InfoRow 3, Col 2 · Joust Blue
base#54a0ff
hover#2e86de
active#407ac2

Label on the fill: the page colour at 6.15:1 · Hover is a palette colour.

WarningRow 1, Col 3 · Pastel Red
base#ff6b6b
hover#ee5253
active#c25151

Label on the fill: the page colour at 5.93:1 · Hover is a palette colour.

DangerRow 2, Col 1 · Lián Hóng Lotus Pink — 57° off the ideal danger hue, the nearest this palette carries
base#f368e0
hover#d65cc5
active#b94faa

Label on the fill: the page colour at 6.16:1 · Hover is derived.

AccentRow 3, Col 3 · Nasu Purple
base#5f27cd
hover#341f97
active#481e9c

Label on the fill: white at 7.90:1 · Hover is a palette colour.

04 · Component examples

The moment the palette stops being a picture. Filled, outlined and text buttons across five roles, four field states, and the selection controls — a colour that read as confident in a swatch grid often cannot hold a five-character label, and there is no way to discover that except by putting the label on it.

Buttons

filledPrimarySuccessInfoWarningDangerDisabled
outlinedPrimarySuccessInfoWarningDangerDisabled
textPrimarySuccessInfoWarningDangerDisabled

Input fields

DefaultInput text
FocusInput text
FilledInput text
DisabledInput text

Checkbox, radio and switch

CheckedUncheckedDisabled
SelectedUnselectedDisabledOnOff

05 · Chart colours

Eight hues spread around the circle, each required to clear 3:1 against the page — under WCAG 1.4.11 a chart mark is a meaningful graphic, so a series nobody can see is not a style choice. This set is kept separate from the semantic roles on purpose: a series that happens to be red must not read as a failure.

#ff6b6b#feca57#10ac84#01a3a4#48dbfb#c8d6e5#ff9ff3#ee5253
Direct24%Organic18%Social14%Referral12%Email10%Paid search9%Affiliate8%Other5%

Eight hues spread around the circle, every one of them measured at 3:1 or better against this page — a chart mark is a meaningful graphic, not decoration. None of them carries a status meaning, which is the entire reason this set is separate from the one above.

06 · Alerts and notifications

The four status roles doing the job they exist for, each with an icon and a word alongside the fill. Run these through a greyscale filter — if you can still tell the error from the success, colour was reinforcing the message rather than carrying it.

Success. Your changes have been saved.
Info. This is an informational message.
Warning. Please check your input carefully.
Error. Something went wrong. Try again.

Every one of these carries an icon and a word as well as a fill. Remove the colour and the four are still distinguishable — which is the test, because for a good number of readers the colour was never there.

07 · Elevation

The one part of the system that is not derived from the palette and never should be. Shadows are black at rising alpha on every palette on earth; on a page this dark they barely register, which is why the surface ladder in section 02 is what actually carries depth.

Level 0FlatPage, and anything not raised
Level 1RaisedCards at rest
Level 2HoverA card under the pointer
Level 3OverlayMenus and popovers
Level 4ModalDialogs and drawers

Black at rising alpha, on every palette. A shadow is the absence of light, so tinting it with the brand hue is how a dark theme starts looking bruised. On very dark pages the shadow does almost nothing and the surface ladder above is what carries depth.

Do

Take the hues, rebuild the rampTwenty flat values is a mood board, not a system. Lift the hues you want, generate a perceptually even ramp from each, and put those in the semantic tier — that is what makes the palette themeable, auditable and extensible.
Use it where colour carries no valenceCharts, tags, avatars, calendar categories. These are the jobs a decorative palette is genuinely good at, because nothing here has to mean "this failed" to someone who cannot see it.
Imperial PrimerLight Blue Ballerina
Reach for Imperial Primer and Light Blue Ballerina before the middleThe ends do the structural work. Imperial Primer #222f3e is the darkest value here — 13.60:1 on white — and Light Blue Ballerina #c8d6e5 the lightest, at 14.21:1 on black. A palette's usable contrast lives at its extremes, and the extremes are the two swatches people skip.

Don't

Do not map these onto success, warning and dangerA status colour has to clear 4.5:1 against the surface it sits on, in both themes, next to an icon and a word. These were drawn to look good in a grid. The two requirements overlap by accident, never by design.
Do not paste the hex into a componentA literal hex cannot be themed, cannot be audited, and cannot be found later. Every one of these values belongs behind a custom property, exactly like the values in our own token tiers.
Do not call a colour accessible without naming the surface4 of these 20 can set body text on a white page and 16 can on a black one — and none manage both. The two sets are nearly disjoint by arithmetic, not by taste. Pick the surface first and the palette divides itself.

Accessibility

Not a checklist to run at the end. These are the requirements the component was built from.

1.4.1Use of ColorA1.4.3Contrast (Minimum)AA1.4.11Non-text ContrastAA

Contrast

  • 4 of 20 colours clear 4.5:1 against white and can carry body text on a light page. 16 clear it against black. None do both.
  • Those two sets are nearly disjoint for a reason, not by accident: a colour’s contrast with white multiplied by its contrast with black is always exactly 21. Clearing 4.5:1 on one surface leaves at most 4.67:1 on the other.
  • 8 of 20 reach 3:1 on white, which is the bar for large text, icons, borders and chart marks — a much larger set, and the one most of this palette is genuinely for.
  • White and black are the bounds, not our surfaces. Against a real canvas the numbers move, and alpha moves them again — composite first or the ratio is fiction.

Keyboard

TabMoves through the swatches; each one is a button that copies its value.
⌘IInspector Mode reports the live contrast of anything on this page.

Screen readers

  • A colour has no accessible meaning. If a chart series is identified only by its fill, the series does not exist for a screen reader — label it directly or provide the table.
  • Colour names like “Jigglypuff” or “Wet Asphalt” are identifiers, not descriptions. Never use one as the only label for a state.

Focus & touch

  • Swatches take the standard focus ring, offset outwards. An inset ring would have to sit on the colour being demonstrated and would fail contrast on roughly half of these values.
  • Swatches are 88px tall and at least 152px wide, comfortably past the 44px minimum, so the copy affordance is reachable on a phone without a precise tap.
AttributeApplied toNotes
aria-labelEach swatchNames the colour and its value, because the swatch itself announces as nothing — a background colour is invisible to a screen reader.
forced-colors: activeMedia queryWindows High Contrast Mode discards this palette wholesale. Anything that was only distinguishable by fill becomes identical.

Code

Example usage

What this palette is for, and what it is not for.

tsx
1// A borrowed palette is categorical data, not a set of semantics.2// Bind it to series, not to states.3const CA_SERIES = [4  'var(--flat-ca-wild-caribbean-green)', // Wild Caribbean Green5  'var(--flat-ca-jade-dust)', // Jade Dust6  'var(--flat-ca-jigglypuff)', // Jigglypuff7  'var(--flat-ca-megaman)', // Megaman8  'var(--flat-ca-casandora-yellow)', // Casandora Yellow9  'var(--flat-ca-light-blue-ballerina)', // Light Blue Ballerina10]1112<Chart series={data} colors={CA_SERIES} />1314// Text on any of them uses the measured pair, never a guess.15// Jigglypuff takes #000000 at 11.51:1.16<span style={{17  background: 'var(--flat-ca-jigglypuff)',18  color: '#000000',19}}>20  Jigglypuff21</span>

CSS

The twenty plus the 37 they were expanded into. 12 of those are literal palette colours; the rest are computed, and each carries the arithmetic that produced it.

css
/* ---- The twenty, verbatim. Namespaced, so a borrowed value can never
        be mistaken for one of ours. ---------------------------------------- */
/* Canadian Palette — Dmitri Litvinov, Flat UI Colors 2 */
:root {
  --flat-ca-jigglypuff: #ff9ff3;
  --flat-ca-casandora-yellow: #feca57;
  --flat-ca-pastel-red: #ff6b6b;
  --flat-ca-megaman: #48dbfb;
  --flat-ca-wild-caribbean-green: #1dd1a1;
  --flat-ca-li-n-h-ng-lotus-pink: #f368e0;
  --flat-ca-double-dragon-skin: #ff9f43;
  --flat-ca-amour: #ee5253;
  --flat-ca-cyanite: #0abde3;
  --flat-ca-dark-mountain-meadow: #10ac84;
  --flat-ca-jade-dust: #00d2d3;
  --flat-ca-joust-blue: #54a0ff;
  --flat-ca-nasu-purple: #5f27cd;
  --flat-ca-light-blue-ballerina: #c8d6e5;
  --flat-ca-fuel-town: #576574;
  --flat-ca-aqua-velvet: #01a3a4;
  --flat-ca-bleu-de-france: #2e86de;
  --flat-ca-bluebell: #341f97;
  --flat-ca-storm-petrel: #8395a7;
  --flat-ca-imperial-primer: #222f3e;
}

/* ---- The system derived from them. This is the half a palette does not
        ship, and the half a product cannot be built without. -------------- */
/* Canadian Palette — a dark theme derived from the twenty.
   Dmitri Litvinov, Flat UI Colors 2. Values marked "taken" are the palette's own;
   everything else is computed from them by the rules on this page. */
:root {
  /* surfaces */
  --ca-page: #17202a;                     /* derived */
  --ca-surface: #1d2734;                  /* derived */
  --ca-elevated: #222f3e;                 /* taken */
  --ca-hover: #313e4c;                    /* derived */
  --ca-border: #3a434e;                   /* derived */
  --ca-border-strong: #697078;            /* derived */

  /* text */
  --ca-text: #f4f5f6;                     /* 15.1:1 on the page */
  --ca-text-secondary: #b2b6b9;           /* 8.1:1 on the page */
  --ca-text-tertiary: #91969b;            /* 5.5:1 on the page */
  --ca-text-muted: #81878c;               /* 4.5:1 on the page */
  --ca-text-disabled: #5a6168;            /* 2.6:1 on the page */

  /* semantic */
  --ca-primary: #feca57;                  /* taken */
  --ca-primary-hover: #ff9f43;            /* taken */
  --ca-primary-active: #c19a42;           /* derived */
  --ca-primary-on: #17202a;               /* 10.8:1 on the fill */
  --ca-success: #1dd1a1;                  /* taken */
  --ca-success-hover: #10ac84;            /* taken */
  --ca-success-active: #169f7a;           /* derived */
  --ca-success-on: #17202a;               /* 8.4:1 on the fill */
  --ca-info: #54a0ff;                     /* taken */
  --ca-info-hover: #2e86de;               /* taken */
  --ca-info-active: #407ac2;              /* derived */
  --ca-info-on: #17202a;                  /* 6.1:1 on the fill */
  --ca-warning: #ff6b6b;                  /* taken */
  --ca-warning-hover: #ee5253;            /* taken */
  --ca-warning-active: #c25151;           /* derived */
  --ca-warning-on: #17202a;               /* 5.9:1 on the fill */
  --ca-danger: #f368e0;                   /* taken */
  --ca-danger-hover: #d65cc5;             /* derived */
  --ca-danger-active: #b94faa;            /* derived */
  --ca-danger-on: #17202a;                /* 6.2:1 on the fill */
  --ca-accent: #5f27cd;                   /* taken */
  --ca-accent-hover: #341f97;             /* taken */
  --ca-accent-active: #481e9c;            /* derived */
  --ca-accent-on: #ffffff;                /* 7.9:1 on the fill */

  /* categorical — never status */
  --ca-chart-1: #ff6b6b;                  /* Pastel Red */
  --ca-chart-2: #feca57;                  /* Casandora Yellow */
  --ca-chart-3: #10ac84;                  /* Dark Mountain Meadow */
  --ca-chart-4: #01a3a4;                  /* Aqua Velvet */
  --ca-chart-5: #48dbfb;                  /* Megaman */
  --ca-chart-6: #c8d6e5;                  /* Light Blue Ballerina */
  --ca-chart-7: #ff9ff3;                  /* Jigglypuff */
  --ca-chart-8: #ee5253;                  /* Amour */

  /* elevation — black, never the brand hue */
  --ca-elevation-1: 0 1px 3px rgb(0 0 0 / 0.12);/* raised */
  --ca-elevation-2: 0 4px 6px rgb(0 0 0 / 0.16);/* hover */
  --ca-elevation-3: 0 10px 20px rgb(0 0 0 / 0.20);/* overlay */
  --ca-elevation-4: 0 16px 32px rgb(0 0 0 / 0.24);/* modal */
}

Notes

Professional tips

  • Candy pastels in the top half, deep indigo and slate in the bottom. The clearest light/dark split in the collection.
  • Darkest value: Imperial Primer #222f3e. Lightest: Light Blue Ballerina #c8d6e5. Between them sits every ramp you could build from this set.
  • Sort the sheet by Hue to find neighbours you can safely put side by side, and by Lightness to find the ones that can carry text. Source order is the designer’s order and tells you about their intent, not about contrast.
  • If you only need one colour from this palette, take it and leave the rest. Adopting twenty because you liked one is how a product ends up with two palettes.

Common mistakes

  • Using the palette at full saturation across a whole screen. These were drawn as accents against neutral ground; twenty of them at once is a swatch page, not an interface.
  • Assuming the names mean something. They are memorable, not systematic — “Light Red” is darker than “Pastel Red” in the palette next door.
  • Copying the hexes into a design file and the CSS separately. They will drift, and the design file will win the argument for about six months.

Real-world recommendations

  • Credit stays attached: this set was drawn by Dmitri Litvinov (@dmitrilitvinov on Dribbble) and published in Flat UI Colors 2 by Ahmet Sülek.
  • Palettes like this one age visibly. A 2013 flat palette reads as 2013 — which is useful when that is the intent and a liability when it is not.
  • The fastest legitimate use is prototyping: grab a palette, get the categorical colours out of the way, and spend the argument you saved on hierarchy instead.

Contrast reference

The measurement behind every derivation above. White and black bound what a colour can do, and reading a row in both directions gives you both answers at once — 4.86:1 on white is equally “this as text on a white page” and “white as a label on this fill”. The last column is what people mean when they ask whether a colour is accessible, and it is almost never both.

ColourOn whiteOn blackInk on
Imperial Primer#222f3eAa13.60AAAAa1.54FailLight only
Bluebell#341f97Aa11.74AAAAa1.79FailLight only
Nasu Purple#5f27cdAa7.90AAAAa2.66FailLight only
Fuel Town#576574Aa5.97AAAa3.52AA LargeLight only
Bleu De France#2e86deAa3.76AA LargeAa5.58AADark only
Amour#ee5253Aa3.52AA LargeAa5.97AADark only
Aqua Velvet#01a3a4Aa3.10AA LargeAa6.78AADark only
Storm Petrel#8395a7Aa3.08AA LargeAa6.82AADark only
Dark Mountain Meadow#10ac84Aa2.89FailAa7.26AAADark only
Pastel Red#ff6b6bAa2.78FailAa7.57AAADark only
Joust Blue#54a0ffAa2.68FailAa7.85AAADark only
Lián Hóng Lotus Pink#f368e0Aa2.67FailAa7.87AAADark only
Cyanite#0abde3Aa2.23FailAa9.40AAADark only
Double Dragon Skin#ff9f43Aa2.04FailAa10.29AAADark only
Wild Caribbean Green#1dd1a1Aa1.96FailAa10.69AAADark only
Jade Dust#00d2d3Aa1.88FailAa11.16AAADark only
Jigglypuff#ff9ff3Aa1.83FailAa11.51AAADark only
Megaman#48dbfbAa1.64FailAa12.80AAADark only
Casandora Yellow#feca57Aa1.52FailAa13.80AAADark only
Light Blue Ballerina#c8d6e5Aa1.48FailAa14.21AAADark only