One set. Always Lucide.
CBC standardises on Lucide — open, MIT-licensed, ~1,500 consistent icons. One set everywhere means one visual language across every product and subsidiary.
The standard
Lucide is the approved icon set for all CBC EMEA work. It is open source under the MIT licence, has ~1,500 icons drawn on a consistent 24 px grid with 2 px stroke, and is actively maintained. The full catalogue is at lucide.dev.
Standardising on one set removes the decision entirely. Every designer and every developer draws from the same catalogue. There are no “close enough” substitutes from other libraries, no redrawn one-offs that happen to look similar, no mixed stroke weights across a single interface. One set.
Developers use lucide-react (already in this project’s dependencies) and import named components: import { Search, X } from 'lucide-react'. Designers use the curated SVG downloads below — no manual fetching from the Lucide site.
Downloads
The 28 most commonly used UI icons, exported as standalone SVGs for design tools. These are unmodified Lucide icons — the MIT licence permits redistribution. Download, copy an import statement, or copy the SVG markup directly.
Dev path — no files needed:
npm i lucide-reactimport { Search } from 'lucide-react'Per-card import buttons give icon-specific statements.
These files use stroke="currentColor" — colour is set by the parent element, not baked into the SVG. Do not hardcode a fill colour inside the file itself.
Usage & styling
Size scale
Colour via tokens
Interactive
Icons that are clickable controls or paired with interactive copy use --action-blue (not CBC Blue). CBC Blue is a display colour reserved for large headings and decorative fills — it fails contrast on small interactive marks.
Body / secondary
Icons used as non-interactive accompaniment to body copy — form labels, informational — use --text-secondary. This keeps them visually subordinate without dropping below contrast.
Rhino (emphasis)
For icons that need to carry weight in a Rhino-heavy layout — strong CTAs, section anchors. --heading resolves to Rhino in light mode and adapts in dark mode.
Never CBC Blue on small marks
#0D9ADD is 2.6:1 on white — it fails WCAG AA at text and icon scale. Reserve it for display-only contexts (headings ≥24 px, accent lines, background fills). Use --action-blue (#0A6E9E, 5.6:1) for anything interactive or small.
Stroke & spacing
- Use Lucide’s default 2 px stroke at all sizes
- Leave at least 4 px gap between an icon and its label
- Align icons optically to the text cap-height, not the baseline
- Use a single icon set throughout a product surface
- Mix Lucide with icons from other libraries (HeroIcons, FontAwesome, etc.)
- Change stroke width — thicker or thinner breaks set coherence
- Use icons smaller than 16 px — details become ambiguous
- Place icons without any adjacent text label on interactive controls
Accessibility
An icon that carries meaning must have an accessible name. An icon that is purely decorative must be hidden from assistive technology. There is no middle ground.
Meaningful icons
If the icon communicates something the user needs to understand, give it an accessible name. In lucide-react: pass aria-label="…" directly on the component, or wrap the icon in a <span> with role="img" aria-label="…". Example: a trash icon in a data table row needs aria-label="Delete row".
Decorative icons
If adjacent text already describes the action or content — a button that says "Download" with a download icon beside it — the icon adds no information. Mark it aria-hidden="true" to hide it from screen readers. In lucide-react: <Download aria-hidden="true" />.
Icon-only controls
Never ship an interactive control — button, link, toggle — that is icon-only with no accessible label. The control must have either visible text, an aria-label, or an aria-labelledby pointing to a visible label. An icon alone is never sufficient.
Focus and contrast
Interactive icons inherit the global focus ring (2 px CBC Blue outline). The icon stroke itself must meet 3:1 contrast against its background at interactive sizes. --action-blue on --surface is 5.6:1 — it passes at all icon sizes.
For the full WCAG 2.1 AA requirements — contrast ratios, semantic structure, and keyboard operability — see Accessibility.
Bespoke icons
The bespoke layer exists to fill gaps Lucide cannot fill — brand- specific glyphs and domain marks that have no general-purpose equivalent. It does not exist to redraw common icons or create a parallel set.
The rule: if Lucide has it, use Lucide. Bespoke icons are drawn only when there is a genuine gap — a concept Lucide cannot represent accurately — and only when that gap causes a real design or brand problem.
Match-Lucide criteria
Bespoke icons must be drawn to these specifications so they sit naturally alongside the Lucide set:
- 24×24 px grid, same as Lucide
- 2 px stroke, round linecap, round linejoin
stroke="currentColor", no hardcoded fill- Optical weight matches Lucide at the same stroke width
- Reviewed against the Lucide set before finalising — if it passes as Lucide, it is Lucide
To-draw list
The following glyphs meet the gap criteria and are queued for the design team. None are in the set yet — they are a planned design task.
Razor / cutting-edge mark
The razor-blade motif used in the brand pattern has no Lucide equivalent. Needed as a small icon for brand hero contexts and domain-specific UI.
Energy / power sector
Lucide's bolt/zap reads 'flash' or 'speed', not 'power infrastructure'. A bespoke mark specific to CBC's energy vertical.
Fintech / transaction
Sector-specific transfer glyph for the fintech vertical — distinct from generic arrow-right-arrow-left swap icons.
CBC monogram icon
A compact CBC lettermark for favicon-scale use and icon grids where the full logo is too wide. Must not be confused with the registered mark.
No bespoke icons exist yet. This list is for the design team. Common icons — search, close, chevrons, check, etc. — must never be redrawn; use Lucide.