Design tokens
#227ED1Valuecolor.gulf.60PrimitiveactionSemanticbutton.primary.bgComponentWhat design tokens are
Design tokens are the named decisions behind the brand: every colour, size, space, radius, shadow and timing, stored once and shared by design, code and documents.
Instead of typing #1B6AB1 into a button, we use the token action. When the brand evolves, we change the token once and every product, slide and site that uses it updates. Tokens are how NorthStar, NorthCloud, NorthEdge and this hub stay identical without anyone copying hex codes.
Our tokens live in one file, tokens/north.tokens.json, in the W3C Design Tokens (DTCG) format. A build step turns that file into CSS variables, SCSS, JavaScript, JSON and a Tailwind preset.
Three tiers
Primitive → semantic → component
- Primitive tokens name raw values:
color.gulf.70,space.4,radius.lg. They describe what a value is. - Semantic tokens name a role:
text-body,action,bg-panel. They describe what a value is for, and they switch between light and dark mode. - Component tokens are defined by each product's design system on top of semantic tokens:
button.primary.bg → action.
Rule of thumb: components use semantic tokens. Reach for a primitive only when no role fits, and ask whether a new role is needed.
| Tier | Example | Value (light) | Value (dark) |
|---|---|---|---|
| Primitive | color.gulf.70 | #1B6AB1 | #1B6AB1 |
| Semantic | action | → gulf.70 | → oasis.30 |
| Component | button.primary.bg | → action | → action |
Naming
Category, item, step
Every CSS variable starts with --n- (North), then the category, then the item, then the step.
--n-color-midnight-80--n-space-6--n-radius-xl--n-motion-easing-rise- Semantic roles drop the category:
--n-text-body,--n-action
Colour steps run from 02 (lightest) to 95 (darkest), so a higher number is always darker, in every hue. Space steps are multiples of 4px: space-6 is 24px.
Colour tokens
Primitive colours are the six hue families plus base and status colours. Their values, uses and print codes are on the Colors page. Semantic colour roles for light and dark are on Light/Dark modes. The categorical chart palette is on Data visualization. Sub-brand signal colours are --n-brand-northstar-signal, --n-brand-northcloud-signal and --n-brand-northedge-signal.
Typography tokens
Each text style is a composite token: family, weight, size, line height and letter spacing. In CSS they ship as utility classes (.n-type-heading-1); in Figma, as text styles. The full scale is on Typography.
<h1 class="n-type-heading-1">Model hosting</h1>
<p class="n-type-lead">Residency before capability.</p>
/* or compose from primitives */
.card-title { font-family: var(--n-font-family-display); font-weight: var(--n-font-weight-medium); }Spacing
A 4px rhythm
All spacing is a multiple of 4px. Use small steps inside components (4–16px), medium steps between components (24–48px) and large steps between sections (64–128px).
- Related things sit closer than unrelated things.
- Never use odd values like 13px or 22px.
- Mobile gutter 16px, desktop gutter 32px.
--n-space-00px--n-space-0-52pxHairline offsets.--n-space-14pxIcon-to-label gap.--n-space-28pxTight stacks, chip padding.--n-space-312pxInput padding.--n-space-416pxDefault gap. Mobile page gutter.--n-space-520px--n-space-624pxCard padding.--n-space-832pxPanel padding. Desktop gutter.--n-space-1040px--n-space-1248pxBetween related sections.--n-space-1664pxBetween page sections.--n-space-2080px--n-space-2496pxHero padding.--n-space-32128pxCampaign whitespace.--n-space-40160pxRadius
Radius grows with size
Small things have small corners, big things have big corners: a 16px chip should not have the same radius as a 600px panel.
When you nest a box inside another, the inner radius is the outer radius minus the padding, so the curves stay parallel. A 24px panel with 8px padding holds 16px cards.
none0pxxs4pxsm8pxmd12pxlg16pxxl24px2xl32pxfull9999pxElevation
Shadows tinted with Midnight
Depth shows hierarchy: what floats above what. North shadows are tinted with Midnight, never neutral grey, so they feel like part of the palette.
- 0 flat content on Dune
- 1 resting cards and inputs
- 2 hover, dropdowns
- 3 popovers and floating windows
- 4 dialogs and hero device mock-ups
- glow live AI states on dark
shadow-0Flat. Default for content on Cream.shadow-1Resting cards, inputs.shadow-2Hovered cards, dropdowns.shadow-3Popovers, floating product windows.shadow-4Dialogs, hero device mock-ups.shadow-glowOasis glow for the star and live AI states on dark.Motion tokens
Durations from 80ms to 600ms and four easing curves, including the signature rise. See them animate on Motion.
| Token | Value | Use |
|---|---|---|
--n-motion-duration-instant | 80ms | Colour changes, toggles. |
--n-motion-duration-fast | 140ms | Hovers, small reveals. |
--n-motion-duration-base | 220ms | Menus, accordions, tabs. |
--n-motion-duration-slow | 360ms | Panels, drawers, page transitions. |
--n-motion-duration-deliberate | 600ms | Hero moments, the star rise. Once per screen. |
--n-motion-easing-standard | cubic-bezier(0.2, 0, 0, 1) | Most UI movement. |
--n-motion-easing-enter | cubic-bezier(0, 0, 0.2, 1) | Elements arriving. |
--n-motion-easing-exit | cubic-bezier(0.4, 0, 1, 1) | Elements leaving. |
--n-motion-easing-rise | cubic-bezier(0.22, 1, 0.36, 1) | Signature ease: a long, calm settle, like a star rising. |
Layout tokens
| Token | Value | Use |
|---|---|---|
--n-breakpoint-sm | 640px | Large phones. |
--n-breakpoint-md | 960px | Tablets, small laptops. |
--n-breakpoint-lg | 1280px | Desktops. |
--n-breakpoint-xl | 1600px | Wide screens. |
--n-grid-columns-mobile | 4 | Columns below md. |
--n-grid-columns-tablet | 8 | Columns md–lg. |
--n-grid-columns-desktop | 12 | Columns at lg and up. |
--n-grid-gutter-mobile | 16px | |
--n-grid-gutter-desktop | 32px | |
--n-grid-margin-mobile | 16px | |
--n-grid-margin-desktop | 64px | |
--n-grid-max-width | 1280px | Content max width. |
--n-grid-measure | 68ch | Maximum line length for reading. |
--n-z-base | 0 | Stacking order |
--n-z-raised | 10 | Stacking order |
--n-z-sticky | 100 | Stacking order |
--n-z-overlay | 1000 | Stacking order |
--n-z-modal | 1100 | Stacking order |
--n-z-toast | 1200 | Stacking order |
--n-opacity-disabled | 0.4 | Disabled controls. |
--n-opacity-muted | 0.64 | De-emphasised graphics. |
--n-opacity-scrim | 0.72 | Overlay behind dialogs (Midnight 95). |
Token explorer
All 281 tokens. Search by name, value or purpose; click a name to copy the CSS variable.
Using the tokens
CSS
<link rel="stylesheet" href="https://identity.north.ae/assets/tokens/north-tokens.css">
.button-primary {
background: var(--n-action);
color: var(--n-text-on-action);
border-radius: var(--n-radius-sm);
padding: var(--n-space-3) var(--n-space-5);
transition: background var(--n-motion-duration-fast) var(--n-motion-easing-standard);
}
.button-primary:hover { background: var(--n-action-hover); }
/* Dark mode follows the OS, or pin it: <html data-theme="dark"> */Tailwind
// tailwind.config.js
module.exports = {
presets: [require('./tailwind.preset.cjs')],
};
// <button class="bg-gulf-70 text-base-white rounded-sm px-5 py-3 shadow-1">Install</button>JavaScript and TypeScript
import { tokens, semantic } from './north-tokens.mjs';
chart.setColors([tokens['color-dataviz-light-1'], tokens['color-dataviz-light-2']]);
const action = semantic.dark['action']; // "#95ECF1"Figma
Import north.tokens.json with any DTCG-compatible plugin (for example Tokens Studio) to create colour variables with light and dark modes, text styles and number variables. Keep Figma in sync by re-importing after each release, never by editing values in Figma.
Changing a token
- Propose. Open a request with the brand team: what should change, where it is used, and why.
- Check. Colour changes must keep every semantic pair at its contrast level. The build reports contrast for all roles.
- Release. Edit
tokens/north.tokens.json, runnpm run tokens, and publish with a version number: patch for value tweaks, minor for new tokens, major for renamed or removed tokens. - Announce. Product teams update the package; this hub updates itself.
Last updated on 14 October 2026