System

Design system reference.

Curated component set for CBC emea digital surfaces. All components consume tokens from src/tokens/ and respond to the active theme. Toggle light / dark via the nav control.

Buttons

Primary — Action Blue fill (5.6:1 with white text, AA at any size). Dark — Rhino fill (10.6:1) for contexts where a darker CTA suits. Ghost — heading-colour text, no fill. Never use a CBC Blue fill on button text smaller than 24px — use Action Blue.

Default
Hover
Active
Disabled
Primary
Dark
Ghost
▼ Don’t
3.1:1 — fails AA for button text
Light
Dark surface

Form elements

Presentational reference only — states and layout. Form submission requires a server layer and is explicitly out of scope.

Helper text for additional context.
Enter a valid email address.
Contact form layout
We don’t share your details.

Navigation

Primary nav is documented above. The secondary nav handles within-page or subsidiary-level sections — button elements, no anchor hash links.

Secondary / within-page nav

Accordion

Use for FAQ, progressive disclosure, or grouped content users may skip. One item open at a time; smooth height animation via CSS grid.

Poppins is the display face — headings, labels, button text, navigation. Montserrat carries body copy and captions. Never mix them at the same size or weight; let the hierarchy do the work.

Yes — for primary actions only. The contrast ratio (White on CBC Blue) is approximately 3.1:1, which meets WCAG AA for large UI elements and bold text above 18px. Never use CBC Blue as a background for small body text.

Partner colour is scoped to that partner's own surfaces only — it never touches the CBC chrome (nav, footer, system states). A partner surface is a bounded region; CBC colour governs everything outside it.

Tabs

Use for mutually exclusive content views within the same surface. Keep labels short — three to five words maximum.

The overview tab shows the top-level picture — purpose, scope, and key decisions. Keep this short; link out rather than repeat detail from other tabs.

Alerts / callouts

Exercise the four semantic state tokens. Use contextually — not as decoration. Each colour carries a meaning; misusing warning for info erodes trust.

Information
This feature rolls out to all subsidiaries in Q3. No action required now.
Success
Your asset request was submitted. The Marketing Team will respond within two working days.
Warning
The brand freeze is in effect until 15 August. Non-critical asset updates must wait.
Error
This colour combination fails WCAG AA. Select an approved pairing from the Colour page before proceeding.

Badges / tags

Status pills for data tables and metadata. The Partner badge (dashed border) signals something outside the CBC colour system — see the three-layer model.

DraftActivePendingDeprecatedCBCPartner surface

Breadcrumbs

For deep hierarchies only. Omit on flat sites. Non-navigating crumbs use <button> — not href=“#”.

Data table

Spec and comparison tables for subsidiary product pages. Semantic token badges appear in-table for status.

ModelResolutionIR rangeZoomRatingStatus
AI-8MP PTZ Dome8 MP100 m25×IP67In stock
4K Box Camera8 MP60 mFixedIP66In stock
2MP Fisheye2 MPNone180°IP66Lead time: 3 wk
Thermal + Optical2 MP + 160×120N/AFixedIP67On request

Stat / metric blocks

Key figures for about pages, dashboards, and subsidiary homepages. One stat per block — no decorative embellishment.

40yrs
Years of delivery in Nigeria
6
Subsidiaries under the CBC emea group
99.9%
Network uptime SLA — CBC Communications
24/7
Support coverage across all subsidiaries

Modal / dialog

Use sparingly — for decisions that interrupt flow and require immediate attention. ESC closes; click-outside closes; focus is trapped inside.

Tooltip

CSS-hover tooltip for supplementary labels on icons or abbreviated terms. Keep copy under ten words; hover or focus to reveal.

CBC Blue#0D9ADD · WCAG AA (large text)Clear space ruleBlade height on all four sidesOpens the Colour page

Pagination

For data tables and long content lists. Active page uses CBC Blue fill; ellipsis separates large page ranges.

Product detail card

The card pattern a subsidiary product page would use — category tag, name, description, spec grid, and primary action.

PRODUCT IMAGE
CBC Surveillance
AI-8MP PTZ Dome

Pan-tilt-zoom camera with edge-based AI analytics. Designed for perimeter protection in low-light environments.

Resolution
8 MP
Night range
100 m IR
Protection
IP67, IK10
Optical zoom
25×

Cards / containers

The rounded surface primitive. Clickable cards gain a hover border in CBC Blue. Border-radius from --radius-lg.

Communications

Fibre to the premises

Enterprise-grade last-mile connectivity delivered and supported by CBC Communications.

Energy

Solar + storage

Commercial solar arrays with lithium-ion storage, designed for uninterrupted power in demanding conditions.

Infrastructure

Edge compute rack

Pre-configured server infrastructure for on-premises workloads — deployed and maintained by CBC.

Site footer pattern

Full subsidiary footer — distinct from the site-wide “Where to ask” block. Four-column structure collapses to two then one on mobile.

Mega menu

Documented pattern for deep subsidiary IA. Keyboard-accessible: Escape closes and returns focus to the trigger; click-outside closes; no aria-hidden over focusable items. See the When Not To Use note below.

When NOT to use a mega menu

Shallow information architecture — most subsidiary microsites, landing pages, this site — uses a simple nav. If you have fewer than eight links across two groups, a flat nav is clearer. A mega menu signals depth; don’t fake it.

Token export

Copy the full token set — colour palette, type scale, and radius scale — in CSS variables, JS/TS, or JSON.

:root {
  /* Colours */
  --cbc-blue: #0D9ADD;
  --action-blue: #0A6E9E;
  --rhino: #284156;
  --surface: #FFFFFF;
  --surface-muted: #F4F5F6;
  --surface-inverse: #284156;
  --border: #D9D9D9;
  --text-secondary: #5C6B7A;
  --text-primary: #2D2D2D;
  --heading: #284156;
  --success: #1E9E5A;
  --warning: #D98E04;
  --error: #C42B2B;
  --text-on-dark: #FFFFFF;
  --success-text: #147843;
  --warning-text: #875200;

  /* Radius */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;
}

Logo reel

A horizontal marquee for partner or trust marks on marketing surfaces — shows breadth without dominating the layout. Scrolls continuously and slowly. The circular Pause / Play control is always present — it is the WCAG 2.2.2 discoverable pause mechanism; hover and focus pausing alone do not cover keyboard-only or touch users. Under prefers-reduced-motion, auto-scroll is suppressed entirely and the marks render as a static wrapped row.

Note: Real partner marks are omitted here for IP reasons. The placeholder shapes below show the layout and behaviour only.

Variant A — decorative

Marks are aria-hidden, not focusable. Hovering the reel pauses it — a clean stop, no speed change. Use for partner count / breadth display where individual marks carry no navigation intent. Supports an optional lead-in label (e.g. “Trusted by”) that logos appear to emerge from.

Variant B — actionable

Each mark is a keyboard-reachable <a> link with an accessible name. Hovering or focusing any mark fully pauses the reel — a moving target is hard to click or activate. Use for partner pages, case studies, or subsidiary navigation where each logo goes somewhere.

Variant A — decorative with optional “Trusted by” lead-in label

Variant B — actionable — placeholder links (Tab through to see focus behaviour and auto-pause)

▲ Do
  • Use monochrome marks — --text-secondary ink in both themes
  • Choose decorative when marks have no navigation destination
  • Choose actionable when each logo links to a partner or case study
  • Keep scroll speed slow (≥ 35s per cycle) — background texture, not focal point
  • Render a static wrapped row when prefers-reduced-motion is active
▼ Don’t
  • Use full-colour partner marks — the reel is intentionally restrained
  • Auto-scroll without the Pause / Play control
  • Use actionable variant without real destination URLs in production
  • Set a speed that pulls focus from primary content
  • Display real partner marks without a signed asset agreement

Contact launcher

A persistent floating action button (FAB) that opens a compact panel anchored above it. Used on campaign landing pages and product surfaces to surface direct contact channels without crowding the layout. The panel is a launcher — it routes the visitor to an external channel. It is not a chat client and should never present itself as one.

WhatsApp configuration

Single action: WhatsApp deep-link (wa.me). Use on campaign pages where WhatsApp is the primary or only channel. The phone number is a deployment prop — never hardcoded.

Support configuration

Two actions: WhatsApp + support hub link (Blu Book on-ramp or equivalent). Use on product surfaces where visitors may need either instant messaging or structured ticket / knowledge-base access.

Theming: The FAB accent defaults to --action-blue (CBC base). Subsidiaries may pass their accent via the accent prop — it maps to --cl-accent and is scoped to this component only. WhatsApp green (#25D366) is applied solely to the WhatsApp action icon; it is not a brand token and must never be promoted to one — the same rule as any partner colour.

Accessibility contract: The FAB carries aria-expanded and aria-controls. Opening the panel moves focus to the close button inside it. Focus is trapped within the panel while it is open (Tab cycles through panel elements only). Escape and the close button both dismiss the panel and return focus to the FAB. Click / tap outside closes the panel without moving focus (the user is interacting elsewhere). All channel actions are real <a> links with accessible names.

WhatsApp configuration — placeholder number; tab to the channel link to see focus

Support configuration — WhatsApp + Blu Book support hub

▲ Do
  • Keep the FAB persistent and visible — it should not hide on scroll
  • Return focus to the FAB on Escape or close-button dismissal
  • Configure the phone number and support URL per deployment via props
  • Scope any subsidiary accent to the component via the accent prop
  • Use the panel as a launcher only — route to an existing channel
▼ Don’t
  • Auto-open the panel on page load — it is a visitor nag pattern
  • Trap focus with no Escape or external close mechanism
  • Tokenise WhatsApp green as a brand colour — keep it scoped
  • Hardcode a phone number in the component — use the prop
  • Present the panel as a live chat client if no backend exists