Brand ramps

Step CoreAI Azure
10 #030206 #061724
20 #1A1326 #082338
30 #2B1D44 #0a2e4a
40 #38255E #0c3b5e
50 #472E79 #0e4775
60 #553695 #0f548c
70 #643FB2 #115ea3
80 #8251EE #0f6cbd
90 #8251EE #2886de
100 #9263F1 #479ef5
110 #A175F3 #62abf5
120 #AF86F5 #77b7f7
130 #BC98F7 #96c6fa
140 #C9AAF9 #b4d6fa
150 #D5BCFB #cfe4fa
160 #E1CEFC #ebf3fc

Semantic surface and text colors

Role Token Usage CoreAI light CoreAI dark Azure light Azure dark
Background 4 colorNeutralBackground4 Shell and sidebar #f0f0f0 hsl(0, 0%, 6%) #f0f0f0 hsl(0, 0%, 6%)
Background 3 colorNeutralBackground3 Filled-darker areas #f5f5f5 hsl(0, 0%, 8%) #f5f5f5 hsl(0, 0%, 8%)
Background 2 colorNeutralBackground2 Elevated surfaces, cards #fafafa hsl(0, 0%, 10%) #fafafa hsl(0, 0%, 10%)
Background 1 colorNeutralBackground1 Page content #ffffff hsl(0, 0%, 12%) #ffffff hsl(0, 0%, 12%)
Foreground 1 colorNeutralForeground1 Headings, high-emphasis #242424 #ffffff #242424 #ffffff
Foreground 2 colorNeutralForeground2 Body text, default content #424242 #d6d6d6 #424242 #d6d6d6
Foreground 3 colorNeutralForeground3 Timestamps, metadata #616161 #adadad #616161 #adadad
Foreground 4 colorNeutralForeground4 Disabled, placeholder #707070 #999999 #707070 #999999
Brand Foreground colorBrandForeground1 Brand-colored emphasis #8251EE #A175F3 #0f6cbd #479ef5
Brand Link colorBrandForegroundLink Interactive link text #643FB2 #C9AAF9 #115ea3 #479ef5
Brand background colorBrandBackground Brand as background #643FB2 #643FB2 #0f6cbd #125ca9
On brand colorNeutralForegroundOnBrand Text on brand backgrounds #ffffff #ffffff #ffffff #ffffff

Accessibility requirements

Normal text needs a contrast ratio of 4.5:1. Large text and UI need 3:1.

Context Pass example Fail example
Normal text on Grey 12 #EDEDED #555555
Large text/UI on Grey 12 #808080 #3D3D3D
Normal text on white #242424 #BDBDBD
Large text/UI on white #808080 #D4D4D4

Do not rely on color alone. Include labels and redundant status cues. Test the actual foreground/background pair in both themes.

See Theming for providers and custom brand colors.

Data Visualization

Slot Color Usage Value
1 Cornflower Primary series, default single-series charts #637CEF
2 Orchid Secondary series, companion against primary #F393EB
3 Seafoam Tertiary series, three-way comparisons #4EC8AF
4 Sky Fourth series, multi-category breakdowns #3BBAFF
5 Teal Fifth series, extended datasets #2AA0A4
6 Peach Sixth series, dense multi-series displays #F69672
7 Grape Seventh series, maximum category count #9373C0

Apply the CoreAI theme

import {
  CoreAIFluentProvider,
  coreaiLightTheme,
  coreaiDarkTheme,
  Button,
} from '@coreai-ds/react-components';
// Optional: register locally installed Aptos / Aptos Mono (no font downloads).
import '@coreai-ds/react-components/fonts/fonts.css';

export function App() {
  return (
    <CoreAIFluentProvider theme={isDark ? coreaiDarkTheme : coreaiLightTheme}>
      <Button>OK</Button> {/* shape="circular" — CoreAI default */}
    </CoreAIFluentProvider>
  );
}

Apply the Azure theme

import { CoreAIFluentProvider, azureLightTheme, azureDarkTheme } from '@coreai-ds/react-components';
import '@coreai-ds/react-components/fonts/fonts.css';

export function App() {
  return (
    <CoreAIFluentProvider theme={isDark ? azureDarkTheme : azureLightTheme}>
      {/* your app */}
    </CoreAIFluentProvider>
  );
}

Page source

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import * as React from 'react';
import { azureBrandVariants, azureDarkTheme, azureLightTheme } from '@coreai-ds/react-components';
import { Card } from '@coreai-ds/react-components';
import { CoreAIFluentProvider } from '@coreai-ds/react-components';
import {
  coreaiBrandVariants,
  coreaiDarkTheme,
  coreaiLightTheme,
  type CoreAITheme,
} from '@coreai-ds/react-components';
import { Tab, TabList, type SelectTabData, type SelectTabEvent } from '@coreai-ds/react-components';
import { Text } from '@coreai-ds/react-components';
import type { BrandVariants } from '@fluentui/react-components';
import { PageLayout } from '../components/PageLayout';
import { Section } from '../components/Section';
import { dataVizRows, type ColorRow } from '../data/Content';
import { useThemeMode } from '../theme/ThemeProvider';

const brandSteps = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160] as const;

type BrandId = 'coreai' | 'azure';

const brands = {
  coreai: {
    label: 'CoreAI theme',
    variants: coreaiBrandVariants,
    lightTheme: coreaiLightTheme,
    darkTheme: coreaiDarkTheme,
  },
  azure: {
    label: 'Azure theme',
    variants: azureBrandVariants,
    lightTheme: azureLightTheme,
    darkTheme: azureDarkTheme,
  },
} as const;

const surfaceTokens = [
  {
    name: 'Background 4',
    description: 'Shell and sidebar',
    token: 'colorNeutralBackground4',
  },
  {
    name: 'Background 3',
    description: 'Filled-darker areas',
    token: 'colorNeutralBackground3',
  },
  {
    name: 'Background 2',
    description: 'Elevated surfaces, cards',
    token: 'colorNeutralBackground2',
  },
  {
    name: 'Background 1',
    description: 'Page content',
    token: 'colorNeutralBackground1',
  },
] as const;

const textTokens = [
  {
    name: 'Foreground 1',
    description: 'Headings, high-emphasis',
    token: 'colorNeutralForeground1',
  },
  {
    name: 'Foreground 2',
    description: 'Body text, default content',
    token: 'colorNeutralForeground2',
  },
  {
    name: 'Foreground 3',
    description: 'Timestamps, metadata',
    token: 'colorNeutralForeground3',
  },
  {
    name: 'Foreground 4',
    description: 'Disabled, placeholder',
    token: 'colorNeutralForeground4',
  },
  {
    name: 'Brand Foreground',
    description: 'Brand-colored emphasis',
    token: 'colorBrandForeground1',
  },
  {
    name: 'Brand Link',
    description: 'Interactive link text',
    token: 'colorBrandForegroundLink',
  },
] as const;

function getColorRows(
  theme: CoreAITheme,
  rows: ReadonlyArray<{
    name: string;
    description: string;
    token: keyof CoreAITheme;
  }>,
): ColorRow[] {
  return rows.map(({ name, description, token }) => ({
    name,
    description,
    token,
    value: String(theme[token]),
  }));
}

function getBrandStep(variants: BrandVariants, value: string) {
  return brandSteps.find((step) => variants[step] === value);
}

function ColorScale({ variants }: { variants: BrandVariants }) {
  return (
    <div className="color-scale">
      <div className="color-scale__bar">
        {brandSteps.map((step) => (
          <span
            key={step}
            style={{ background: variants[step] }}
            data-copy={variants[step]}
            title={`brandVariants[${step}] · ${variants[step]}`}
          />
        ))}
      </div>
      <div className="color-scale__labels">
        {brandSteps.map((step) => (
          <span key={step}>{step}</span>
        ))}
      </div>
    </div>
  );
}

function PrimaryCards({ theme, variants }: { theme: CoreAITheme; variants: BrandVariants }) {
  const backgroundStep = getBrandStep(variants, theme.colorBrandBackground);
  const foregroundStep = getBrandStep(variants, theme.colorBrandForeground1);

  return (
    <div className="primary-grid">
      <div
        className="primary-card"
        style={{
          background: theme.colorBrandBackground,
          color: theme.colorNeutralForegroundOnBrand,
        }}
        data-copy="colorBrandBackground"
      >
        <div>
          <Text className="primary-card__title" size={400} weight="semibold">
            Brand as background
          </Text>
          <Text className="primary-card__meta" size={200}>
            {backgroundStep ? `brandVariants[${backgroundStep}] · ` : ''}
            colorBrandBackground
          </Text>
        </div>
        <Text className="primary-card__meta" font="monospace" size={200}>
          {theme.colorBrandBackground}
        </Text>
      </div>
      <div
        className="primary-card primary-card--foreground"
        style={{ background: theme.colorNeutralBackground2 }}
        data-copy="colorBrandForeground1"
      >
        <div>
          <Text
            className="primary-card__title"
            size={400}
            weight="semibold"
            style={{ color: theme.colorBrandForeground1 }}
          >
            Brand as foreground
          </Text>
          <Text className="primary-card__meta" size={200}>
            {foregroundStep ? `brandVariants[${foregroundStep}] · ` : ''}
            colorBrandForeground1
          </Text>
        </div>
        <Text className="primary-card__meta" font="monospace" size={200}>
          {theme.colorBrandForeground1}
        </Text>
      </div>
    </div>
  );
}

function SurfaceTable({ rows }: { rows: ColorRow[] }) {
  return (
    <div className="stack-table stack-table--filled">
      {rows.map((r) => (
        <div
          key={r.token}
          className="stack-row"
          data-copy={r.token}
          style={{ background: r.value }}
        >
          <div className="stack-row__swatch" style={{ background: r.value }} />
          <div className="stack-row__main">
            <Text className="stack-row__title" weight="semibold">
              {r.name}
            </Text>
            <Text className="stack-row__desc" foreground={3}>
              {r.description}
            </Text>
          </div>
          <div className="stack-row__meta">
            <Text font="monospace" size={200}>
              {r.token}
            </Text>
            <Text font="monospace" size={200}>
              {r.value}
            </Text>
          </div>
        </div>
      ))}
    </div>
  );
}

function TextTable({ rows }: { rows: ColorRow[] }) {
  return (
    <div className="stack-table stack-table--outline">
      {rows.map((r) => (
        <div key={r.token} className="stack-row" data-copy={r.token}>
          <div
            className="stack-row__swatch stack-row__swatch--text"
            style={{ background: r.value }}
          />
          <div className="stack-row__main">
            <Text className="stack-row__title" weight="semibold">
              {r.name}
            </Text>
            <Text className="stack-row__desc" foreground={3}>
              {r.description}
            </Text>
          </div>
          <div className="stack-row__meta">
            <Text font="monospace" size={200}>
              {r.token}
            </Text>
            <Text font="monospace" size={200}>
              {r.value}
            </Text>
          </div>
        </div>
      ))}
    </div>
  );
}

function DataVizTable() {
  return (
    <div className="stack-table stack-table--outline">
      {dataVizRows.map((r) => (
        <div key={r.slot} className="stack-row" data-copy={r.value}>
          <div className="dataviz-chip" style={{ background: r.value }}>
            <span>{r.slot}</span>
          </div>
          <div className="stack-row__main">
            <Text className="stack-row__title" weight="semibold">
              {r.label}
            </Text>
            <Text className="stack-row__desc" foreground={3}>
              {r.description}
            </Text>
          </div>
          <Text className="stack-row__hex" font="monospace">
            {r.value}
          </Text>
        </div>
      ))}
    </div>
  );
}

function RatioCards({ theme }: { theme: CoreAITheme }) {
  return (
    <div className="ratio-grid">
      <div className="ratio-column">
        <Card className="ratio-card">
          <Text className="ratio-card__value" size={700} weight="semibold">
            95%
          </Text>
          <Text className="ratio-card__label" size={200} foreground={3}>
            Neutral
          </Text>
        </Card>
        <div className="ratio-desc">
          <ul>
            <li>Used for backgrounds, controls, and containers</li>
            <li>Provides clarity, accessibility, and reduces visual fatigue</li>
          </ul>
        </div>
      </div>
      <div className="ratio-column">
        <Card
          className="ratio-card ratio-card--brand"
          style={{ background: theme.colorBrandBackground2 }}
        >
          <Text className="ratio-card__value" size={700} weight="semibold">
            5%
          </Text>
          <Text className="ratio-card__label" size={200} foreground={3}>
            Brand
          </Text>
        </Card>
        <div className="ratio-desc">
          <ul>
            <li>Used for primary actions, key highlights, links, and visual anchors</li>
            <li>Creates recognition and reinforces our brand voice</li>
          </ul>
        </div>
      </div>
    </div>
  );
}

function PassIcon() {
  return (
    <svg
      className="status-pass-icon"
      width="14"
      height="14"
      viewBox="0 0 20 20"
      aria-hidden="true"
      focusable="false"
    >
      <path
        d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16Zm0 1a7 7 0 1 0 0 14 7 7 0 0 0 0-14Zm3.36 4.65c.17.17.2.44.06.63l-.06.07-4 4a.5.5 0 0 1-.64.07l-.07-.06-2-2a.5.5 0 0 1 .63-.77l.07.06L9 11.3l3.65-3.65c.2-.2.51-.2.7 0Z"
        fill="currentColor"
      />
    </svg>
  );
}
function FailIcon() {
  return (
    <svg
      className="status-fail-icon"
      width="14"
      height="14"
      viewBox="0 0 20 20"
      aria-hidden="true"
      focusable="false"
    >
      <path
        d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16Zm0 1a7 7 0 1 0 0 14 7 7 0 0 0 0-14ZM7.8 7.11l.08.06L10 9.3l2.12-2.12a.5.5 0 0 1 .64-.06l.07.06c.17.18.2.44.06.64l-.06.07L10.7 10l2.12 2.12c.17.17.2.44.06.64l-.06.07a.5.5 0 0 1-.64.06l-.07-.06L10 10.7l-2.12 2.12a.5.5 0 0 1-.64.06l-.07-.06a.5.5 0 0 1-.06-.64l.06-.07L9.3 10 7.17 7.88a.5.5 0 0 1-.06-.64l.06-.07a.5.5 0 0 1 .64-.06Z"
        fill="currentColor"
      />
    </svg>
  );
}

function AccessibilityCards() {
  const bigText = {
    fontSize: '20px',
    fontWeight: 600,
    lineHeight: '24px',
  } as const;
  return (
    <>
      <div className="card-grid theme-dark-only">
        <Card className="accessibility-card" appearance="outline">
          <div className="accessibility-card__header">
            <Text className="accessibility-card__ratio" size={500} weight="bold">
              4.5:1
            </Text>
            <Text className="accessibility-card__label" size={200} foreground={3}>
              Normal text
            </Text>
          </div>
          <div className="accessibility-pills">
            <div className="accessibility-pill">
              <PassIcon />
              <span style={{ color: '#EDEDED' }}>Pass: #EDEDED on Grey 12</span>
            </div>
            <div className="accessibility-pill">
              <FailIcon />
              <span style={{ color: '#555555' }}>Fail: #555555 on Grey 12</span>
            </div>
          </div>
        </Card>
        <Card className="accessibility-card" appearance="outline">
          <div className="accessibility-card__header">
            <Text className="accessibility-card__ratio" size={500} weight="bold">
              3:1
            </Text>
            <Text className="accessibility-card__label" size={200} foreground={3}>
              Large text and UI
            </Text>
          </div>
          <div className="accessibility-pills">
            <div className="accessibility-pill">
              <PassIcon />
              <span style={{ color: '#808080', ...bigText }}>Pass: #808080 on Grey 12</span>
            </div>
            <div className="accessibility-pill">
              <FailIcon />
              <span style={{ color: '#3D3D3D', ...bigText }}>Fail: #3D3D3D on Grey 12</span>
            </div>
          </div>
        </Card>
      </div>
      <div className="card-grid theme-light-only">
        <Card className="accessibility-card" appearance="outline" style={{ background: '#FFFFFF' }}>
          <div className="accessibility-card__header">
            <Text className="accessibility-card__ratio" size={500} weight="bold">
              4.5:1
            </Text>
            <Text className="accessibility-card__label" size={200} foreground={3}>
              Normal text
            </Text>
          </div>
          <div className="accessibility-pills">
            <div className="accessibility-pill" style={{ background: '#F5F5F5' }}>
              <PassIcon />
              <span style={{ color: '#242424' }}>Pass: #242424 on White</span>
            </div>
            <div className="accessibility-pill" style={{ background: '#F5F5F5' }}>
              <FailIcon />
              <span style={{ color: '#BDBDBD' }}>Fail: #BDBDBD on White</span>
            </div>
          </div>
        </Card>
        <Card className="accessibility-card" appearance="outline" style={{ background: '#FFFFFF' }}>
          <div className="accessibility-card__header">
            <Text className="accessibility-card__ratio" size={500} weight="bold">
              3:1
            </Text>
            <Text className="accessibility-card__label" size={200} foreground={3}>
              Large text and UI
            </Text>
          </div>
          <div className="accessibility-pills">
            <div className="accessibility-pill" style={{ background: '#F5F5F5' }}>
              <PassIcon />
              <span style={{ color: '#808080', ...bigText }}>Pass: #808080 on White</span>
            </div>
            <div className="accessibility-pill" style={{ background: '#F5F5F5' }}>
              <FailIcon />
              <span style={{ color: '#D4D4D4', ...bigText }}>Fail: #D4D4D4 on White</span>
            </div>
          </div>
        </Card>
      </div>
    </>
  );
}

export function Colors() {
  const { mode, brand: brandId, setBrand } = useThemeMode();
  const brand = brands[brandId];
  const theme = mode === 'dark' ? brand.darkTheme : brand.lightTheme;
  const surfaceRows = getColorRows(theme, surfaceTokens);
  const textRows = getColorRows(theme, textTokens);

  const onBrandSelect = (_event: SelectTabEvent, data: SelectTabData) => {
    setBrand(data.value as BrandId);
  };

  return (
    <PageLayout id="colors">
      <CoreAIFluentProvider
        className="colors-theme-scope"
        theme={theme}
        style={{ background: 'transparent' }}
      >
        <TabList
          className="colors-theme-tabs"
          appearance="elevated"
          selectedValue={brandId}
          onTabSelect={onBrandSelect}
        >
          {Object.entries(brands).map(([id, entry]) => (
            <Tab key={id} value={id}>
              {entry.label}
            </Tab>
          ))}
        </TabList>

        <div className="colors-theme-content">
          <Section title="Brand Color">
            <PrimaryCards theme={theme} variants={brand.variants} />
            <ColorScale variants={brand.variants} />
          </Section>
          <Section title="Surface Colors">
            <SurfaceTable rows={surfaceRows} />
          </Section>
          <Section title="Text Colors">
            <TextTable rows={textRows} />
          </Section>
          <Section title="Data Visualization">
            <DataVizTable />
          </Section>
          <Section title="Color Usage Balance">
            <RatioCards theme={theme} />
          </Section>
          <Section title="Accessibility">
            <AccessibilityCards />
          </Section>
        </div>
      </CoreAIFluentProvider>
    </PageLayout>
  );
}