mirror of
https://github.com/bitwarden/browser
synced 2026-01-21 11:53:34 +00:00
[CL-913] add new color palette to theme and tailwind config (#17998)
* add new color palette to theme and tailwind config * updated docs color names * remove safelist changes * add missing accent colors to docs * updated color mappings * combined docs in colors.mdx and reference in Claude.md * add variables for white and black * updated docs * updated list rendering style * more specific docs instructions * revert to simpler colors docs reference * remove changes to claude.md * use rgb color variables to compose semantic
This commit is contained in:
@@ -2,127 +2,772 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
||||
|
||||
<Meta title="Documentation/Colors" />
|
||||
|
||||
export const Row = (name) => (
|
||||
<tr class="tw-h-16">
|
||||
<td class="!tw-border-none">{name}</td>
|
||||
<td class={"tw-bg-" + name + " !tw-border-secondary-300"}></td>
|
||||
</tr>
|
||||
);
|
||||
# Color System
|
||||
|
||||
export const Table = (args) => (
|
||||
<table class={"border tw-table-auto !tw-text-main " + args.class}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tw-w-40">General usage</th>
|
||||
<th class="tw-w-20"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Row("background")}
|
||||
{Row("background-alt")}
|
||||
{Row("background-alt2")}
|
||||
{Row("background-alt3")}
|
||||
{Row("background-alt4")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("primary-100")}
|
||||
{Row("primary-300")}
|
||||
{Row("primary-600")}
|
||||
{Row("primary-700")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("secondary-100")}
|
||||
{Row("secondary-300")}
|
||||
{Row("secondary-500")}
|
||||
{Row("secondary-600")}
|
||||
{Row("secondary-700")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("success-100")}
|
||||
{Row("success-600")}
|
||||
{Row("success-700")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("danger-100")}
|
||||
{Row("danger-600")}
|
||||
{Row("danger-700")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("warning-100")}
|
||||
{Row("warning-600")}
|
||||
{Row("warning-700")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("info-100")}
|
||||
{Row("info-600")}
|
||||
{Row("info-700")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("notification-100")}
|
||||
{Row("notification-600")}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{Row("illustration-outline")}
|
||||
{Row("illustration-bg-primary")}
|
||||
{Row("illustration-bg-secondary")}
|
||||
{Row("illustration-bg-tertiary")}
|
||||
{Row("illustration-tertiary")}
|
||||
{Row("illustration-logo")}
|
||||
</tbody>
|
||||
Bitwarden uses a three-tier color token architecture:
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Text</th>
|
||||
<th class="tw-w-20"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Row("text-main")}
|
||||
{Row("text-muted")}
|
||||
{Row("text-contrast")}
|
||||
{Row("text-alt2")}
|
||||
{Row("text-code")}
|
||||
</tbody>
|
||||
- **Primitive Colors** - Raw color values from the Figma design system
|
||||
- **Semantic Tokens** - Meaningful names that reference primitives
|
||||
- **Tailwind Utilities** - CSS classes for components
|
||||
|
||||
</table>
|
||||
);
|
||||
## Color Token Structure
|
||||
|
||||
<style>
|
||||
{`
|
||||
table {
|
||||
border-spacing: 0.5rem;
|
||||
border-collapse: separate !important;
|
||||
}
|
||||
### Primitive Colors (Hex format)
|
||||
|
||||
tr {
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
Location: `libs/components/src/tw-theme.css`
|
||||
|
||||
td, th {
|
||||
color: inherit !important;
|
||||
}
|
||||
- 10 color families: `brand`, `gray`, `red`, `orange`, `yellow`, `green`, `pink`, `coral`, `teal`,
|
||||
`purple`
|
||||
- 11 shades each: `050`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`
|
||||
- Format: `--color-{family}-{shade}` (e.g., `--color-brand-600`)
|
||||
|
||||
th {
|
||||
border: none !important;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
### Semantic Foreground Tokens
|
||||
|
||||
# Colors
|
||||
- **Neutral**: `fg-white`, `fg-dark`, `fg-contrast`, `fg-heading`, `fg-body`, `fg-body-subtle`,
|
||||
`fg-disabled`
|
||||
- **Brand**: `fg-brand-soft`, `fg-brand`, `fg-brand-strong`
|
||||
- **Status**: `fg-success`, `fg-success-strong`, `fg-danger`, `fg-danger-strong`, `fg-warning`,
|
||||
`fg-warning-strong`, `fg-sensitive`
|
||||
- **Accent**: `fg-accent-primary`, `fg-accent-secondary`, `fg-accent-tertiary` (with `-soft` and
|
||||
`-strong` variants)
|
||||
- Format: `--color-fg-{name}`
|
||||
|
||||
Tailwind traditionally has a very large color palette. Bitwarden has their own more limited color
|
||||
palette instead.
|
||||
### Semantic Background Tokens
|
||||
|
||||
This has a couple of advantages:
|
||||
- **Neutral**: `bg-white`, `bg-dark`, `bg-contrast`, `bg-contrast-strong`, `bg-primary`,
|
||||
`bg-secondary`, `bg-tertiary`, `bg-quaternary`, `bg-gray`, `bg-disabled`
|
||||
- **Brand**: `bg-brand-softer`, `bg-brand-soft`, `bg-brand-medium`, `bg-brand`, `bg-brand-strong`
|
||||
- **Status**: `bg-success-soft`, `bg-success-medium`, `bg-success`, `bg-success-strong`,
|
||||
`bg-danger-soft`, `bg-danger-medium`, `bg-danger`, `bg-danger-strong`, `bg-warning-soft`,
|
||||
`bg-warning-medium`, `bg-warning`, `bg-warning-strong`
|
||||
- **Accent**: `bg-accent-primary-soft`, `bg-accent-primary-medium`, `bg-accent-primary`,
|
||||
`bg-accent-secondary-soft`, `bg-accent-secondary-medium`, `bg-accent-secondary`,
|
||||
`bg-accent-tertiary-soft`, `bg-accent-tertiary-medium`, `bg-accent-tertiary`
|
||||
- **Special**: `bg-hover`, `bg-overlay`
|
||||
- Format: `--color-bg-{name}`
|
||||
|
||||
- Promotes consistency across the application.
|
||||
- Easier to maintain and make adjustments.
|
||||
- Allows us to support more than two themes light & dark, should it be needed.
|
||||
### Semantic Border Tokens
|
||||
|
||||
Below are all the permited colors. Please consult design before considering adding a new color.
|
||||
- **Neutral**: `border-muted`, `border-light`, `border-base`, `border-strong`, `border-buffer`
|
||||
- **Brand**: `border-brand-soft`, `border-brand`, `border-brand-strong`
|
||||
- **Status**: `border-success-soft`, `border-success`, `border-success-strong`,
|
||||
`border-danger-soft`, `border-danger`, `border-danger-strong`, `border-warning-soft`,
|
||||
`border-warning`, `border-warning-strong`
|
||||
- **Accent**: `border-accent-primary-soft`, `border-accent-primary`, `border-accent-secondary-soft`,
|
||||
`border-accent-secondary`, `border-accent-tertiary-soft`, `border-accent-tertiary`
|
||||
- **Focus**: `border-focus`
|
||||
- Format: `--color-border-{name}`
|
||||
|
||||
<div class="tw-flex tw-space-x-4">
|
||||
<Table />
|
||||
<Table class="theme_dark tw-bg-background" />
|
||||
## Semantic Color Tokens
|
||||
|
||||
> **Note:** Due to Tailwind's utility naming and our semantic token structure, class names will
|
||||
> appear repetitive (e.g., `tw-bg-bg-primary`). This repetition is intentional:
|
||||
>
|
||||
> - `tw-` = Tailwind prefix
|
||||
> - `bg-` = Tailwind utility type (background)
|
||||
> - `bg-primary` = Our semantic token name
|
||||
|
||||
### Background Colors
|
||||
|
||||
Use `tw-bg-bg-*` for background colors. These tokens automatically adapt to dark mode.
|
||||
|
||||
export const Swatch = ({ name }) => {
|
||||
const swatchClass = `tw-h-10 tw-w-10 tw-shrink-0 tw-rounded-lg tw-border tw-border-border-base tw-bg-${name}`;
|
||||
return <div className={swatchClass} />;
|
||||
};
|
||||
|
||||
export const BackgroundCard = ({ name, primitiveColor }) => {
|
||||
const bgClass = `tw-flex tw-items-center tw-gap-3 tw-rounded-xl tw-p-4 tw-border tw-border-border-base tw-bg-bg-primary`;
|
||||
const swatchClass = `tw-h-10 tw-w-10 tw-shrink-0 tw-rounded-lg tw-border tw-border-base tw-bg-bg-${name}`;
|
||||
return (
|
||||
<div className={bgClass}>
|
||||
<div className="tw-flex-1 tw-min-w-0">
|
||||
<div className="tw-font-mono tw-text-sm tw-font-semibold tw-text-fg-heading">bg-{name}</div>
|
||||
<div className="tw-text-xs tw-text-fg-body-subtle tw-mt-0.5">({primitiveColor})</div>
|
||||
</div>
|
||||
<Swatch name={`bg-${name}`} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<div class="sb-unstyled tw-grid tw-grid-cols-2 tw-gap-8 tw-my-6">
|
||||
<div class="tw-bg-bg-primary tw-p-6 tw-rounded-lg tw-border tw-border-border-base">
|
||||
<h3 class="sb-unstyled sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Light mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Neutral</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="white" primitiveColor="white" />
|
||||
<BackgroundCard name="dark" primitiveColor="gray-800" />
|
||||
<BackgroundCard name="contrast" primitiveColor="gray-800" />
|
||||
<BackgroundCard name="contrast-strong" primitiveColor="gray-950" />
|
||||
<BackgroundCard name="primary" primitiveColor="white" />
|
||||
<BackgroundCard name="secondary" primitiveColor="gray-050" />
|
||||
<BackgroundCard name="tertiary" primitiveColor="gray-050" />
|
||||
<BackgroundCard name="quaternary" primitiveColor="gray-200" />
|
||||
<BackgroundCard name="gray" primitiveColor="gray-300" />
|
||||
<BackgroundCard name="disabled" primitiveColor="gray-100" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Brand</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="brand-softer" primitiveColor="brand-050" />
|
||||
<BackgroundCard name="brand-soft" primitiveColor="brand-100" />
|
||||
<BackgroundCard name="brand-medium" primitiveColor="brand-200" />
|
||||
<BackgroundCard name="brand" primitiveColor="brand-700" />
|
||||
<BackgroundCard name="brand-strong" primitiveColor="brand-800" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Status</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="success-soft" primitiveColor="green-050" />
|
||||
<BackgroundCard name="success-medium" primitiveColor="green-100" />
|
||||
<BackgroundCard name="success" primitiveColor="green-600" />
|
||||
<BackgroundCard name="success-strong" primitiveColor="green-700" />
|
||||
<BackgroundCard name="danger-soft" primitiveColor="red-050" />
|
||||
<BackgroundCard name="danger-medium" primitiveColor="red-100" />
|
||||
<BackgroundCard name="danger" primitiveColor="red-600" />
|
||||
<BackgroundCard name="danger-strong" primitiveColor="red-700" />
|
||||
<BackgroundCard name="warning-soft" primitiveColor="orange-050" />
|
||||
<BackgroundCard name="warning-medium" primitiveColor="orange-100" />
|
||||
<BackgroundCard name="warning" primitiveColor="orange-600" />
|
||||
<BackgroundCard name="warning-strong" primitiveColor="orange-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Accent</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="accent-primary-soft" primitiveColor="teal-050" />
|
||||
<BackgroundCard name="accent-primary-medium" primitiveColor="teal-100" />
|
||||
<BackgroundCard name="accent-primary" primitiveColor="teal-400" />
|
||||
<BackgroundCard name="accent-secondary-soft" primitiveColor="coral-050" />
|
||||
<BackgroundCard name="accent-secondary-medium" primitiveColor="coral-100" />
|
||||
<BackgroundCard name="accent-secondary" primitiveColor="coral-400" />
|
||||
<BackgroundCard name="accent-tertiary-soft" primitiveColor="purple-050" />
|
||||
<BackgroundCard name="accent-tertiary-medium" primitiveColor="purple-100" />
|
||||
<BackgroundCard name="accent-tertiary" primitiveColor="purple-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Hover</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="hover" primitiveColor="rgba" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Overlay</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="overlay" primitiveColor="rgba" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="theme_dark tw-bg-bg-primary tw-p-6 tw-rounded-lg">
|
||||
<h3 class="sb-unstyled sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Dark mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Neutral</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="white" primitiveColor="white" />
|
||||
<BackgroundCard name="dark" primitiveColor="gray-800" />
|
||||
<BackgroundCard name="contrast" primitiveColor="gray-050" />
|
||||
<BackgroundCard name="contrast-strong" primitiveColor="gray-950" />
|
||||
<BackgroundCard name="primary" primitiveColor="gray-900" />
|
||||
<BackgroundCard name="secondary" primitiveColor="gray-800" />
|
||||
<BackgroundCard name="tertiary" primitiveColor="gray-950" />
|
||||
<BackgroundCard name="quaternary" primitiveColor="gray-950" />
|
||||
<BackgroundCard name="gray" primitiveColor="gray-600" />
|
||||
<BackgroundCard name="disabled" primitiveColor="gray-950" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Brand</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="brand-softer" primitiveColor="brand-950" />
|
||||
<BackgroundCard name="brand-soft" primitiveColor="brand-900" />
|
||||
<BackgroundCard name="brand-medium" primitiveColor="brand-800" />
|
||||
<BackgroundCard name="brand" primitiveColor="brand-400" />
|
||||
<BackgroundCard name="brand-strong" primitiveColor="brand-300" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Status</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="success-soft" primitiveColor="green-950" />
|
||||
<BackgroundCard name="success-medium" primitiveColor="green-900" />
|
||||
<BackgroundCard name="success" primitiveColor="green-400" />
|
||||
<BackgroundCard name="success-strong" primitiveColor="green-300" />
|
||||
<BackgroundCard name="danger-soft" primitiveColor="red-950" />
|
||||
<BackgroundCard name="danger-medium" primitiveColor="red-900" />
|
||||
<BackgroundCard name="danger" primitiveColor="red-400" />
|
||||
<BackgroundCard name="danger-strong" primitiveColor="red-300" />
|
||||
<BackgroundCard name="warning-soft" primitiveColor="orange-950" />
|
||||
<BackgroundCard name="warning-medium" primitiveColor="orange-900" />
|
||||
<BackgroundCard name="warning" primitiveColor="orange-400" />
|
||||
<BackgroundCard name="warning-strong" primitiveColor="orange-300" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Accent</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="accent-primary-soft" primitiveColor="teal-950" />
|
||||
<BackgroundCard name="accent-primary-medium" primitiveColor="teal-900" />
|
||||
<BackgroundCard name="accent-primary" primitiveColor="teal-400" />
|
||||
<BackgroundCard name="accent-secondary-soft" primitiveColor="coral-950" />
|
||||
<BackgroundCard name="accent-secondary-medium" primitiveColor="coral-900" />
|
||||
<BackgroundCard name="accent-secondary" primitiveColor="coral-400" />
|
||||
<BackgroundCard name="accent-tertiary-soft" primitiveColor="purple-950" />
|
||||
<BackgroundCard name="accent-tertiary-medium" primitiveColor="purple-900" />
|
||||
<BackgroundCard name="accent-tertiary" primitiveColor="purple-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Hover</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="hover" primitiveColor="rgba" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Overlay</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BackgroundCard name="overlay" primitiveColor="rgba" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
### Foreground Colors
|
||||
|
||||
Use `tw-text-fg-*` for text colors. These tokens automatically adapt to dark mode.
|
||||
|
||||
export const ForegroundCard = ({ name, primitiveColor }) => {
|
||||
const textClass = `tw-text-fg-${name} tw-text-2xl tw-font-bold tw-shrink-0`;
|
||||
return (
|
||||
<div className="tw-flex tw-items-center tw-gap-3 tw-rounded-xl tw-p-4 tw-border tw-border-border-base tw-bg-bg-primary">
|
||||
<div className="tw-flex-1 tw-min-w-0">
|
||||
<div className="tw-font-mono tw-text-sm tw-font-semibold tw-text-fg-heading">fg-{name}</div>
|
||||
<div className="tw-text-xs tw-text-fg-body-subtle tw-mt-0.5">({primitiveColor})</div>
|
||||
</div>
|
||||
<Swatch name={`fg-${name}`} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<div class="sb-unstyled tw-grid tw-grid-cols-2 tw-gap-8 tw-my-6">
|
||||
<div class="tw-bg-bg-primary tw-p-6 tw-rounded-lg tw-border tw-border-border-base">
|
||||
<h3 class="sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Light mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Neutral</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="white" primitiveColor="#ffffff" />
|
||||
<ForegroundCard name="dark" primitiveColor="gray-900" />
|
||||
<ForegroundCard name="contrast" primitiveColor="white" />
|
||||
<ForegroundCard name="heading" primitiveColor="gray-900" />
|
||||
<ForegroundCard name="body" primitiveColor="gray-600" />
|
||||
<ForegroundCard name="body-subtle" primitiveColor="gray-500" />
|
||||
<ForegroundCard name="disabled" primitiveColor="gray-400" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Brand</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="brand-soft" primitiveColor="brand-200" />
|
||||
<ForegroundCard name="brand" primitiveColor="brand-700" />
|
||||
<ForegroundCard name="brand-strong" primitiveColor="brand-900" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Status</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="success" primitiveColor="green-700" />
|
||||
<ForegroundCard name="success-strong" primitiveColor="green-900" />
|
||||
<ForegroundCard name="danger" primitiveColor="red-700" />
|
||||
<ForegroundCard name="danger-strong" primitiveColor="red-900" />
|
||||
<ForegroundCard name="warning" primitiveColor="orange-600" />
|
||||
<ForegroundCard name="warning-strong" primitiveColor="orange-900" />
|
||||
<ForegroundCard name="sensitive" primitiveColor="pink-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Accent</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="accent-primary-soft" primitiveColor="teal-200" />
|
||||
<ForegroundCard name="accent-primary" primitiveColor="teal-400" />
|
||||
<ForegroundCard name="accent-primary-strong" primitiveColor="teal-800" />
|
||||
<ForegroundCard name="accent-secondary-soft" primitiveColor="coral-200" />
|
||||
<ForegroundCard name="accent-secondary" primitiveColor="coral-400" />
|
||||
<ForegroundCard name="accent-secondary-strong" primitiveColor="coral-900" />
|
||||
<ForegroundCard name="accent-tertiary-soft" primitiveColor="purple-200" />
|
||||
<ForegroundCard name="accent-tertiary" primitiveColor="purple-700" />
|
||||
<ForegroundCard name="accent-tertiary-strong" primitiveColor="purple-900" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="theme_dark tw-bg-bg-primary tw-p-6 tw-rounded-lg">
|
||||
<h3 class="sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Dark mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Neutral</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="white" primitiveColor="#ffffff" />
|
||||
<ForegroundCard name="dark" primitiveColor="gray-900" />
|
||||
<ForegroundCard name="contrast" primitiveColor="gray-900" />
|
||||
<ForegroundCard name="heading" primitiveColor="gray-050" />
|
||||
<ForegroundCard name="body" primitiveColor="gray-200" />
|
||||
<ForegroundCard name="body-subtle" primitiveColor="gray-400" />
|
||||
<ForegroundCard name="disabled" primitiveColor="gray-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Brand</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="brand-soft" primitiveColor="brand-500" />
|
||||
<ForegroundCard name="brand" primitiveColor="brand-400" />
|
||||
<ForegroundCard name="brand-strong" primitiveColor="brand-200" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Status</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="success" primitiveColor="green-400" />
|
||||
<ForegroundCard name="success-strong" primitiveColor="green-100" />
|
||||
<ForegroundCard name="danger" primitiveColor="red-400" />
|
||||
<ForegroundCard name="danger-strong" primitiveColor="red-100" />
|
||||
<ForegroundCard name="warning" primitiveColor="orange-400" />
|
||||
<ForegroundCard name="warning-strong" primitiveColor="orange-100" />
|
||||
<ForegroundCard name="sensitive" primitiveColor="pink-300" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Accent</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<ForegroundCard name="accent-primary-soft" primitiveColor="teal-400" />
|
||||
<ForegroundCard name="accent-primary" primitiveColor="teal-300" />
|
||||
<ForegroundCard name="accent-primary-strong" primitiveColor="teal-100" />
|
||||
<ForegroundCard name="accent-secondary-soft" primitiveColor="coral-500" />
|
||||
<ForegroundCard name="accent-secondary" primitiveColor="coral-400" />
|
||||
<ForegroundCard name="accent-secondary-strong" primitiveColor="coral-100" />
|
||||
<ForegroundCard name="accent-tertiary-soft" primitiveColor="purple-500" />
|
||||
<ForegroundCard name="accent-tertiary" primitiveColor="purple-400" />
|
||||
<ForegroundCard name="accent-tertiary-strong" primitiveColor="purple-100" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
### Border Colors
|
||||
|
||||
Use `tw-border-border-*` for border colors. These tokens automatically adapt to dark mode.
|
||||
|
||||
export const BorderCard = ({ name, primitiveColor }) => {
|
||||
return (
|
||||
<div className="tw-flex tw-items-center tw-gap-3 tw-rounded-xl tw-p-4 tw-border tw-border-border-base tw-bg-bg-primary">
|
||||
<div className="tw-flex-1 tw-min-w-0">
|
||||
<div className="tw-font-mono tw-text-sm tw-font-semibold tw-text-fg-heading">
|
||||
border-{name}
|
||||
</div>
|
||||
<div className="tw-text-xs tw-text-fg-body-subtle tw-mt-0.5">({primitiveColor})</div>
|
||||
</div>
|
||||
<Swatch name={`border-${name}`} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<div class="sb-unstyled tw-grid tw-grid-cols-2 tw-gap-8 tw-my-6">
|
||||
<div class="tw-bg-bg-primary tw-p-6 tw-rounded-lg tw-border tw-border-border-base">
|
||||
<h3 class="sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Light mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Neutral</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="muted" primitiveColor="gray-100" />
|
||||
<BorderCard name="light" primitiveColor="gray-200" />
|
||||
<BorderCard name="base" primitiveColor="gray-200" />
|
||||
<BorderCard name="strong" primitiveColor="gray-300" />
|
||||
<BorderCard name="buffer" primitiveColor="gray-100" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Brand</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="brand-soft" primitiveColor="brand-200" />
|
||||
<BorderCard name="brand" primitiveColor="brand-700" />
|
||||
<BorderCard name="brand-strong" primitiveColor="brand-900" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Status</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="success-soft" primitiveColor="green-200" />
|
||||
<BorderCard name="success" primitiveColor="green-700" />
|
||||
<BorderCard name="success-strong" primitiveColor="green-900" />
|
||||
<BorderCard name="danger-soft" primitiveColor="red-200" />
|
||||
<BorderCard name="danger" primitiveColor="red-700" />
|
||||
<BorderCard name="danger-strong" primitiveColor="red-900" />
|
||||
<BorderCard name="warning-soft" primitiveColor="orange-200" />
|
||||
<BorderCard name="warning" primitiveColor="orange-600" />
|
||||
<BorderCard name="warning-strong" primitiveColor="orange-900" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Accent</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="accent-primary-soft" primitiveColor="teal-200" />
|
||||
<BorderCard name="accent-primary" primitiveColor="teal-600" />
|
||||
<BorderCard name="accent-secondary-soft" primitiveColor="coral-200" />
|
||||
<BorderCard name="accent-secondary" primitiveColor="coral-600" />
|
||||
<BorderCard name="accent-tertiary-soft" primitiveColor="purple-200" />
|
||||
<BorderCard name="accent-tertiary" primitiveColor="purple-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Focus</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="focus" primitiveColor="#000000" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="theme_dark tw-bg-bg-primary tw-p-6 tw-rounded-lg">
|
||||
<h3 class="sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Dark mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Neutral</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="muted" primitiveColor="gray-800" />
|
||||
<BorderCard name="light" primitiveColor="gray-700" />
|
||||
<BorderCard name="base" primitiveColor="gray-700" />
|
||||
<BorderCard name="strong" primitiveColor="gray-600" />
|
||||
<BorderCard name="buffer" primitiveColor="gray-900" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Brand</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="brand-soft" primitiveColor="brand-800" />
|
||||
<BorderCard name="brand" primitiveColor="brand-700" />
|
||||
<BorderCard name="brand-strong" primitiveColor="brand-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Status</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="success-soft" primitiveColor="green-800" />
|
||||
<BorderCard name="success" primitiveColor="green-400" />
|
||||
<BorderCard name="success-strong" primitiveColor="green-200" />
|
||||
<BorderCard name="danger-soft" primitiveColor="red-800" />
|
||||
<BorderCard name="danger" primitiveColor="red-400" />
|
||||
<BorderCard name="danger-strong" primitiveColor="red-200" />
|
||||
<BorderCard name="warning-soft" primitiveColor="orange-800" />
|
||||
<BorderCard name="warning" primitiveColor="orange-400" />
|
||||
<BorderCard name="warning-strong" primitiveColor="orange-200" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Accent</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="accent-primary-soft" primitiveColor="teal-800" />
|
||||
<BorderCard name="accent-primary" primitiveColor="teal-600" />
|
||||
<BorderCard name="accent-secondary-soft" primitiveColor="coral-800" />
|
||||
<BorderCard name="accent-secondary" primitiveColor="coral-500" />
|
||||
<BorderCard name="accent-tertiary-soft" primitiveColor="purple-800" />
|
||||
<BorderCard name="accent-tertiary" primitiveColor="purple-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Focus</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<BorderCard name="focus" primitiveColor="#ffffff" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## Usage Guidelines
|
||||
|
||||
### ✅ DO - Use semantic tokens via Tailwind
|
||||
|
||||
```html
|
||||
<!-- Text colors -->
|
||||
<h1 class="tw-text-fg-heading">Heading text</h1>
|
||||
<p class="tw-text-fg-body">Body text</p>
|
||||
<button class="tw-text-fg-brand">Brand action</button>
|
||||
<span class="tw-text-fg-danger">Error message</span>
|
||||
|
||||
<!-- Background colors -->
|
||||
<div class="tw-bg-bg-primary">Primary background</div>
|
||||
<div class="tw-bg-bg-secondary">Secondary background</div>
|
||||
<button class="tw-bg-bg-brand tw-text-fg-white">Brand button</button>
|
||||
<div class="tw-bg-bg-danger-soft tw-text-fg-danger">Danger alert</div>
|
||||
|
||||
<!-- Border colors -->
|
||||
<div class="tw-border tw-border-border-base">Base border</div>
|
||||
<input class="tw-border tw-border-border-light focus:tw-border-border-focus" />
|
||||
<div class="tw-border-2 tw-border-border-brand">Brand border</div>
|
||||
<button class="tw-border tw-border-border-danger">Danger border</button>
|
||||
|
||||
<!-- Combined examples -->
|
||||
<div
|
||||
class="tw-bg-bg-success-soft tw-text-fg-success tw-border tw-border-border-success-soft tw-rounded tw-p-4"
|
||||
>
|
||||
Success alert with matching colors
|
||||
</div>
|
||||
|
||||
<!-- Hover states -->
|
||||
<div class="hover:tw-bg-bg-hover">Hover effect</div>
|
||||
|
||||
<!-- Overlays -->
|
||||
<div class="tw-bg-bg-overlay">Modal overlay</div>
|
||||
```
|
||||
|
||||
### ❌ DON'T - Use primitive colors directly
|
||||
|
||||
```html
|
||||
<!-- Bad: These Tailwind classes don't exist (primitives not exposed) -->
|
||||
<p class="tw-text-brand-900">Text</p>
|
||||
<div class="tw-bg-brand-600">Background</div>
|
||||
|
||||
<!-- Bad: Using primitives with Tailwind bracket notation -->
|
||||
<p class="tw-text-[var(--color-brand-600)]">Text</p>
|
||||
<div class="tw-bg-[var(--color-success-700)]">Background</div>
|
||||
|
||||
<!-- Bad: Using primitive CSS variables bypasses the semantic layer -->
|
||||
<span style="color: var(--color-brand-600)">Text</span>
|
||||
<div style="background: var(--color-success-700)">Background</div>
|
||||
```
|
||||
|
||||
**Why this is wrong:** Primitives aren't semantic and may change. Always use semantic tokens like
|
||||
`tw-text-fg-brand`, `tw-bg-success`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Dark Mode
|
||||
|
||||
- Semantic tokens automatically adapt to dark mode via `.theme_dark` class
|
||||
- No component changes needed when theme switches
|
||||
- The same semantic token name works in both light and dark themes
|
||||
- All color values are automatically swapped based on the active theme
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
- **New components:** Use semantic tokens (`fg-*`, `bg-*`, `border-*`) exclusively
|
||||
- **Existing components:** Keep legacy tokens until refactoring
|
||||
- **When refactoring:** Replace legacy tokens with semantic equivalents
|
||||
|
||||
---
|
||||
|
||||
## Legacy Colors
|
||||
|
||||
**Legacy colors (RGB format)** still exist for backwards compatibility:
|
||||
|
||||
- `primary-*`, `secondary-*`, `success-*`, `danger-*`, `warning-*`, etc.
|
||||
- Use these only when updating existing components
|
||||
- Migrate to new semantic tokens when refactoring
|
||||
|
||||
The following legacy colors are displayed below with both light and dark mode values:
|
||||
|
||||
export const LegacyCard = ({ name }) => {
|
||||
return (
|
||||
<div className="tw-flex tw-items-center tw-gap-3 tw-rounded-xl tw-p-4 tw-border tw-border-border-base tw-bg-bg-primary">
|
||||
<div className="tw-flex-1 tw-min-w-0">
|
||||
<div className="tw-font-mono tw-text-sm tw-font-semibold tw-text-fg-heading">{name}</div>
|
||||
<div className="tw-text-xs tw-text-fg-body-subtle tw-mt-0.5">(legacy RGB format)</div>
|
||||
</div>
|
||||
<Swatch name={name} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<div class="tw-grid tw-grid-cols-2 tw-gap-8">
|
||||
<div class="tw-bg-bg-primary tw-p-6 tw-rounded-lg">
|
||||
<h3 class="sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Light mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">General</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="background" />
|
||||
<LegacyCard name="background-alt" />
|
||||
<LegacyCard name="background-alt2" />
|
||||
<LegacyCard name="background-alt3" />
|
||||
<LegacyCard name="background-alt4" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Primary</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="primary-100" />
|
||||
<LegacyCard name="primary-300" />
|
||||
<LegacyCard name="primary-600" />
|
||||
<LegacyCard name="primary-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">
|
||||
Secondary
|
||||
</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="secondary-100" />
|
||||
<LegacyCard name="secondary-300" />
|
||||
<LegacyCard name="secondary-500" />
|
||||
<LegacyCard name="secondary-600" />
|
||||
<LegacyCard name="secondary-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Success</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="success-100" />
|
||||
<LegacyCard name="success-600" />
|
||||
<LegacyCard name="success-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Danger</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="danger-100" />
|
||||
<LegacyCard name="danger-600" />
|
||||
<LegacyCard name="danger-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Warning</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="warning-100" />
|
||||
<LegacyCard name="warning-600" />
|
||||
<LegacyCard name="warning-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Info</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="info-100" />
|
||||
<LegacyCard name="info-600" />
|
||||
<LegacyCard name="info-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="theme_dark tw-bg-bg-primary tw-p-6 tw-rounded-lg">
|
||||
<h3 class="sb-unstyled tw-mb-6 tw-text-xl tw-font-bold tw-text-fg-heading">Dark mode</h3>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">General</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="background" />
|
||||
<LegacyCard name="background-alt" />
|
||||
<LegacyCard name="background-alt2" />
|
||||
<LegacyCard name="background-alt3" />
|
||||
<LegacyCard name="background-alt4" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Primary</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="primary-100" />
|
||||
<LegacyCard name="primary-300" />
|
||||
<LegacyCard name="primary-600" />
|
||||
<LegacyCard name="primary-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">
|
||||
Secondary
|
||||
</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="secondary-100" />
|
||||
<LegacyCard name="secondary-300" />
|
||||
<LegacyCard name="secondary-500" />
|
||||
<LegacyCard name="secondary-600" />
|
||||
<LegacyCard name="secondary-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Success</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="success-100" />
|
||||
<LegacyCard name="success-600" />
|
||||
<LegacyCard name="success-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Danger</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="danger-100" />
|
||||
<LegacyCard name="danger-600" />
|
||||
<LegacyCard name="danger-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Warning</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="warning-100" />
|
||||
<LegacyCard name="warning-600" />
|
||||
<LegacyCard name="warning-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sb-unstyled tw-mb-6">
|
||||
<h4 class="sb-unstyled tw-mb-3 tw-text-base tw-font-semibold tw-text-fg-heading">Info</h4>
|
||||
<div class="tw-grid tw-grid-cols-1 tw-gap-2">
|
||||
<LegacyCard name="info-100" />
|
||||
<LegacyCard name="info-600" />
|
||||
<LegacyCard name="info-700" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
/* ========================================
|
||||
* LEGACY COLORS (RGB format)
|
||||
* These are the original colors used throughout the app.
|
||||
* Use these for existing components until migration is complete.
|
||||
* ======================================== */
|
||||
|
||||
--color-transparent-hover: rgb(0 0 0 / 0.02);
|
||||
--color-shadow: 168 179 200;
|
||||
|
||||
@@ -74,6 +80,279 @@
|
||||
--color-illustration-bg-tertiary: 255 255 255;
|
||||
--color-illustration-tertiary: 255 191 0;
|
||||
--color-illustration-logo: 23 93 220;
|
||||
|
||||
/* ========================================
|
||||
* NEW COLOR PALETTE (Hex format)
|
||||
* These colors are from the new Figma design system.
|
||||
* Use these for new components and features.
|
||||
* Format: --color-{family}-{shade} where shade ranges from 050 to 950
|
||||
* ======================================== */
|
||||
|
||||
/* Brand Colors */
|
||||
--color-brand-050: #eef6ff;
|
||||
--color-brand-100: #dbeafe;
|
||||
--color-brand-200: #bedbff;
|
||||
--color-brand-300: #8ec5ff;
|
||||
--color-brand-400: #6baefa;
|
||||
--color-brand-500: #418bfb;
|
||||
--color-brand-600: #2a70f4;
|
||||
--color-brand-700: #175ddc;
|
||||
--color-brand-800: #0d43af;
|
||||
--color-brand-900: #0c3276;
|
||||
--color-brand-950: #162455;
|
||||
|
||||
/* Gray Colors */
|
||||
--color-gray-050: #f9fafb;
|
||||
--color-gray-100: #f3f4f6;
|
||||
--color-gray-200: #e5e7eb;
|
||||
--color-gray-300: #d1d5dc;
|
||||
--color-gray-400: #99a1af;
|
||||
--color-gray-500: #6a7282;
|
||||
--color-gray-600: #4a5565;
|
||||
--color-gray-700: #333e4f;
|
||||
--color-gray-800: #1e2939;
|
||||
--color-gray-900: #101828;
|
||||
--color-gray-950: #070b18;
|
||||
--color-gray-950-rgb: 7, 11, 24;
|
||||
|
||||
/* Red Colors */
|
||||
--color-red-050: #fef2f2;
|
||||
--color-red-100: #ffe2e2;
|
||||
--color-red-200: #ffc9c9;
|
||||
--color-red-300: #ffa2a2;
|
||||
--color-red-400: #ff6467;
|
||||
--color-red-500: #fb2c36;
|
||||
--color-red-600: #e7000b;
|
||||
--color-red-700: #c10007;
|
||||
--color-red-800: #9f0712;
|
||||
--color-red-900: #791112;
|
||||
--color-red-950: #460809;
|
||||
|
||||
/* Orange Colors */
|
||||
--color-orange-050: #fff8f1;
|
||||
--color-orange-100: #feecdc;
|
||||
--color-orange-200: #fcd9bd;
|
||||
--color-orange-300: #fdba8c;
|
||||
--color-orange-400: #ff8a4c;
|
||||
--color-orange-500: #ff5a1f;
|
||||
--color-orange-600: #d03801;
|
||||
--color-orange-700: #b43403;
|
||||
--color-orange-800: #8a2c0d;
|
||||
--color-orange-900: #70240b;
|
||||
--color-orange-950: #441306;
|
||||
|
||||
/* Yellow Colors */
|
||||
--color-yellow-050: #fefce8;
|
||||
--color-yellow-100: #fef9c2;
|
||||
--color-yellow-200: #fff085;
|
||||
--color-yellow-300: #ffdf20;
|
||||
--color-yellow-400: #fdc700;
|
||||
--color-yellow-500: #f0b100;
|
||||
--color-yellow-600: #d08700;
|
||||
--color-yellow-700: #a65f00;
|
||||
--color-yellow-800: #894b00;
|
||||
--color-yellow-900: #733e0a;
|
||||
--color-yellow-950: #432004;
|
||||
|
||||
/* Green Colors */
|
||||
--color-green-050: #f0fdf4;
|
||||
--color-green-100: #dcfce7;
|
||||
--color-green-200: #b9f8cf;
|
||||
--color-green-300: #7bf1a8;
|
||||
--color-green-400: #18dc7a;
|
||||
--color-green-500: #0abf52;
|
||||
--color-green-600: #00a63e;
|
||||
--color-green-700: #008236;
|
||||
--color-green-800: #016630;
|
||||
--color-green-900: #0d542b;
|
||||
--color-green-950: #032e15;
|
||||
|
||||
/* Pink Colors */
|
||||
--color-pink-050: #fdf2f8;
|
||||
--color-pink-100: #fce7f3;
|
||||
--color-pink-200: #fccee8;
|
||||
--color-pink-300: #fda5d5;
|
||||
--color-pink-400: #fb64b6;
|
||||
--color-pink-500: #f6339a;
|
||||
--color-pink-600: #e60076;
|
||||
--color-pink-700: #c6005c;
|
||||
--color-pink-800: #a3004c;
|
||||
--color-pink-900: #861043;
|
||||
--color-pink-950: #510424;
|
||||
|
||||
/* Coral Colors */
|
||||
--color-coral-050: #fff2f0;
|
||||
--color-coral-100: #ffe0dc;
|
||||
--color-coral-200: #ffc1b9;
|
||||
--color-coral-300: #ff9585;
|
||||
--color-coral-400: #ff6550;
|
||||
--color-coral-500: #ff4026;
|
||||
--color-coral-600: #e11f05;
|
||||
--color-coral-700: #c71800;
|
||||
--color-coral-800: #a81400;
|
||||
--color-coral-900: #7e0f00;
|
||||
--color-coral-950: #4d0900;
|
||||
|
||||
/* Teal Colors */
|
||||
--color-teal-050: #ecfeff;
|
||||
--color-teal-100: #cefafe;
|
||||
--color-teal-200: #a2f4fd;
|
||||
--color-teal-300: #70ecf5;
|
||||
--color-teal-400: #2cdde9;
|
||||
--color-teal-500: #00c5db;
|
||||
--color-teal-600: #009cb8;
|
||||
--color-teal-700: #007c95;
|
||||
--color-teal-800: #006278;
|
||||
--color-teal-900: #0f495c;
|
||||
--color-teal-950: #042e3e;
|
||||
|
||||
/* Purple Colors */
|
||||
--color-purple-050: #faf5ff;
|
||||
--color-purple-100: #f3e8ff;
|
||||
--color-purple-200: #e9d4ff;
|
||||
--color-purple-300: #dab2ff;
|
||||
--color-purple-400: #c27aff;
|
||||
--color-purple-500: #ad46ff;
|
||||
--color-purple-600: #9810fa;
|
||||
--color-purple-700: #8200db;
|
||||
--color-purple-800: #6e11b0;
|
||||
--color-purple-900: #59168b;
|
||||
--color-purple-950: #3c0366;
|
||||
|
||||
/* White and Black */
|
||||
--color-white: #ffffff;
|
||||
--color-white-rgb: 255, 255, 255;
|
||||
--color-black: #000000;
|
||||
|
||||
/* ========================================
|
||||
* SEMANTIC FOREGROUND COLORS (Light Mode)
|
||||
* These are the tokens that should be exposed to Tailwind
|
||||
* They reference the primitive colors above
|
||||
* ======================================== */
|
||||
|
||||
/* Neutral Foreground */
|
||||
--color-fg-white: var(--color-white);
|
||||
--color-fg-dark: var(--color-gray-900);
|
||||
--color-fg-contrast: var(--color-white);
|
||||
--color-fg-heading: var(--color-gray-900);
|
||||
--color-fg-body: var(--color-gray-600);
|
||||
--color-fg-body-subtle: var(--color-gray-500);
|
||||
--color-fg-disabled: var(--color-gray-400);
|
||||
|
||||
/* Brand Foreground */
|
||||
--color-fg-brand-soft: var(--color-brand-200);
|
||||
--color-fg-brand: var(--color-brand-700);
|
||||
--color-fg-brand-strong: var(--color-brand-900);
|
||||
|
||||
/* Status Foreground */
|
||||
--color-fg-success: var(--color-green-700);
|
||||
--color-fg-success-strong: var(--color-green-900);
|
||||
--color-fg-danger: var(--color-red-700);
|
||||
--color-fg-danger-strong: var(--color-red-900);
|
||||
--color-fg-warning: var(--color-orange-600);
|
||||
--color-fg-warning-strong: var(--color-orange-900);
|
||||
--color-fg-sensitive: var(--color-pink-600);
|
||||
|
||||
/* Accent Foreground */
|
||||
--color-fg-accent-primary-soft: var(--color-teal-200);
|
||||
--color-fg-accent-primary: var(--color-teal-400);
|
||||
--color-fg-accent-primary-strong: var(--color-teal-800);
|
||||
--color-fg-accent-secondary-soft: var(--color-coral-200);
|
||||
--color-fg-accent-secondary: var(--color-coral-400);
|
||||
--color-fg-accent-secondary-strong: var(--color-coral-900);
|
||||
--color-fg-accent-tertiary-soft: var(--color-purple-200);
|
||||
--color-fg-accent-tertiary: var(--color-purple-700);
|
||||
--color-fg-accent-tertiary-strong: var(--color-purple-900);
|
||||
|
||||
/* ========================================
|
||||
* SEMANTIC BACKGROUND COLORS (Light Mode)
|
||||
* ======================================== */
|
||||
|
||||
/* Neutral Background */
|
||||
--color-bg-white: var(--color-white);
|
||||
--color-bg-dark: var(--color-gray-800);
|
||||
--color-bg-contrast: var(--color-gray-800);
|
||||
--color-bg-contrast-strong: var(--color-gray-950);
|
||||
--color-bg-primary: var(--color-white);
|
||||
--color-bg-secondary: var(--color-gray-050);
|
||||
--color-bg-tertiary: var(--color-gray-050);
|
||||
--color-bg-quaternary: var(--color-gray-200);
|
||||
--color-bg-gray: var(--color-gray-300);
|
||||
--color-bg-disabled: var(--color-gray-100);
|
||||
|
||||
/* Brand Background */
|
||||
--color-bg-brand-softer: var(--color-brand-050);
|
||||
--color-bg-brand-soft: var(--color-brand-100);
|
||||
--color-bg-brand-medium: var(--color-brand-200);
|
||||
--color-bg-brand: var(--color-brand-700);
|
||||
--color-bg-brand-strong: var(--color-brand-800);
|
||||
|
||||
/* Status Background */
|
||||
--color-bg-success-soft: var(--color-green-050);
|
||||
--color-bg-success-medium: var(--color-green-100);
|
||||
--color-bg-success: var(--color-green-700);
|
||||
--color-bg-success-strong: var(--color-green-800);
|
||||
--color-bg-danger-soft: var(--color-red-050);
|
||||
--color-bg-danger-medium: var(--color-red-100);
|
||||
--color-bg-danger: var(--color-red-700);
|
||||
--color-bg-danger-strong: var(--color-red-800);
|
||||
--color-bg-warning-soft: var(--color-orange-050);
|
||||
--color-bg-warning-medium: var(--color-orange-100);
|
||||
--color-bg-warning: var(--color-orange-600);
|
||||
--color-bg-warning-strong: var(--color-orange-700);
|
||||
|
||||
/* Accent Background */
|
||||
--color-bg-accent-primary-soft: var(--color-teal-050);
|
||||
--color-bg-accent-primary-medium: var(--color-teal-100);
|
||||
--color-bg-accent-primary: var(--color-teal-400);
|
||||
--color-bg-accent-secondary-soft: var(--color-coral-050);
|
||||
--color-bg-accent-secondary-medium: var(--color-coral-100);
|
||||
--color-bg-accent-secondary: var(--color-coral-400);
|
||||
--color-bg-accent-tertiary-soft: var(--color-purple-050);
|
||||
--color-bg-accent-tertiary-medium: var(--color-purple-100);
|
||||
--color-bg-accent-tertiary: var(--color-purple-600);
|
||||
|
||||
/* Hover & Overlay */
|
||||
--color-bg-hover: rgba(var(--color-gray-950-rgb), 0.05);
|
||||
--color-bg-overlay: rgba(var(--color-gray-950-rgb), 0.3);
|
||||
|
||||
/* ========================================
|
||||
* SEMANTIC BORDER COLORS (Light Mode)
|
||||
* ======================================== */
|
||||
|
||||
/* Neutral Border */
|
||||
--color-border-muted: var(--color-gray-050);
|
||||
--color-border-light: var(--color-gray-100);
|
||||
--color-border-base: var(--color-gray-200);
|
||||
--color-border-strong: var(--color-gray-800);
|
||||
--color-border-buffer: var(--color-white);
|
||||
|
||||
/* Brand Border */
|
||||
--color-border-brand-soft: var(--color-brand-200);
|
||||
--color-border-brand: var(--color-brand-700);
|
||||
--color-border-brand-strong: var(--color-brand-900);
|
||||
|
||||
/* Status Border */
|
||||
--color-border-success-soft: var(--color-green-200);
|
||||
--color-border-success: var(--color-green-700);
|
||||
--color-border-success-strong: var(--color-green-900);
|
||||
--color-border-danger-soft: var(--color-red-200);
|
||||
--color-border-danger: var(--color-red-700);
|
||||
--color-border-danger-strong: var(--color-red-900);
|
||||
--color-border-warning-soft: var(--color-orange-200);
|
||||
--color-border-warning: var(--color-orange-600);
|
||||
--color-border-warning-strong: var(--color-orange-900);
|
||||
|
||||
/* Accent Border */
|
||||
--color-border-accent-primary-soft: var(--color-teal-200);
|
||||
--color-border-accent-primary: var(--color-teal-600);
|
||||
--color-border-accent-secondary-soft: var(--color-coral-200);
|
||||
--color-border-accent-secondary: var(--color-coral-600);
|
||||
--color-border-accent-tertiary-soft: var(--color-purple-200);
|
||||
--color-border-accent-tertiary: var(--color-purple-600);
|
||||
|
||||
/* Focus Border */
|
||||
--color-border-focus: var(--color-black);
|
||||
}
|
||||
|
||||
.theme_light {
|
||||
@@ -140,6 +419,129 @@
|
||||
--color-illustration-bg-tertiary: 243 246 249;
|
||||
--color-illustration-tertiary: 255 191 0;
|
||||
--color-illustration-logo: 255 255 255;
|
||||
|
||||
/* ========================================
|
||||
* SEMANTIC FOREGROUND COLORS (Dark Mode Overrides)
|
||||
* ======================================== */
|
||||
|
||||
/* Neutral Foreground */
|
||||
--color-fg-contrast: var(--color-gray-900);
|
||||
--color-fg-heading: var(--color-gray-050);
|
||||
--color-fg-body: var(--color-gray-200);
|
||||
--color-fg-body-subtle: var(--color-gray-400);
|
||||
--color-fg-disabled: var(--color-gray-600);
|
||||
|
||||
/* Brand Foreground */
|
||||
--color-fg-brand-soft: var(--color-brand-500);
|
||||
--color-fg-brand: var(--color-brand-400);
|
||||
--color-fg-brand-strong: var(--color-brand-200);
|
||||
|
||||
/* Status Foreground */
|
||||
--color-fg-success: var(--color-green-400);
|
||||
--color-fg-success-strong: var(--color-green-100);
|
||||
--color-fg-danger: var(--color-red-400);
|
||||
--color-fg-danger-strong: var(--color-red-100);
|
||||
--color-fg-warning: var(--color-orange-400);
|
||||
--color-fg-warning-strong: var(--color-orange-100);
|
||||
--color-fg-sensitive: var(--color-pink-300);
|
||||
|
||||
/* Accent Foreground */
|
||||
--color-fg-accent-primary-soft: var(--color-teal-400);
|
||||
--color-fg-accent-primary: var(--color-teal-300);
|
||||
--color-fg-accent-primary-strong: var(--color-teal-100);
|
||||
--color-fg-accent-secondary-soft: var(--color-coral-500);
|
||||
--color-fg-accent-secondary: var(--color-coral-400);
|
||||
--color-fg-accent-secondary-strong: var(--color-coral-100);
|
||||
--color-fg-accent-tertiary-soft: var(--color-purple-500);
|
||||
--color-fg-accent-tertiary: var(--color-purple-400);
|
||||
--color-fg-accent-tertiary-strong: var(--color-purple-100);
|
||||
|
||||
/* ========================================
|
||||
* SEMANTIC BACKGROUND COLORS (Dark Mode Overrides)
|
||||
* ======================================== */
|
||||
|
||||
/* Neutral Background */
|
||||
--color-bg-contrast: var(--color-gray-050);
|
||||
--color-bg-contrast-strong: var(--color-gray-050);
|
||||
--color-bg-primary: var(--color-gray-900);
|
||||
--color-bg-secondary: var(--color-gray-800);
|
||||
--color-bg-tertiary: var(--color-gray-950);
|
||||
--color-bg-quaternary: var(--color-gray-700);
|
||||
--color-bg-gray: var(--color-gray-600);
|
||||
--color-bg-disabled: var(--color-gray-950);
|
||||
|
||||
/* Brand Background */
|
||||
--color-bg-brand-softer: var(--color-brand-950);
|
||||
--color-bg-brand-soft: var(--color-brand-900);
|
||||
--color-bg-brand-medium: var(--color-brand-800);
|
||||
--color-bg-brand: var(--color-brand-400);
|
||||
--color-bg-brand-strong: var(--color-brand-300);
|
||||
|
||||
/* Status Background */
|
||||
--color-bg-success-soft: var(--color-green-950);
|
||||
--color-bg-success-medium: var(--color-green-900);
|
||||
--color-bg-success: var(--color-green-400);
|
||||
--color-bg-success-strong: var(--color-green-300);
|
||||
--color-bg-danger-soft: var(--color-red-950);
|
||||
--color-bg-danger-medium: var(--color-red-900);
|
||||
--color-bg-danger: var(--color-red-400);
|
||||
--color-bg-danger-strong: var(--color-red-300);
|
||||
--color-bg-warning-soft: var(--color-orange-950);
|
||||
--color-bg-warning-medium: var(--color-orange-900);
|
||||
--color-bg-warning: var(--color-orange-400);
|
||||
--color-bg-warning-strong: var(--color-orange-300);
|
||||
|
||||
/* Accent Background */
|
||||
--color-bg-accent-primary-soft: var(--color-teal-950);
|
||||
--color-bg-accent-primary-medium: var(--color-teal-900);
|
||||
--color-bg-accent-primary: var(--color-teal-400);
|
||||
--color-bg-accent-secondary-soft: var(--color-coral-950);
|
||||
--color-bg-accent-secondary-medium: var(--color-coral-900);
|
||||
--color-bg-accent-secondary: var(--color-coral-400);
|
||||
--color-bg-accent-tertiary-soft: var(--color-purple-950);
|
||||
--color-bg-accent-tertiary-medium: var(--color-purple-900);
|
||||
--color-bg-accent-tertiary: var(--color-purple-600);
|
||||
|
||||
/* Hover & Overlay */
|
||||
--color-bg-hover: rgba(var(--color-white-rgb), 0.05);
|
||||
--color-bg-overlay: rgba(var(--color-gray-950-rgb), 0.85);
|
||||
|
||||
/* ========================================
|
||||
* SEMANTIC BORDER COLORS (Dark Mode Overrides)
|
||||
* ======================================== */
|
||||
|
||||
/* Neutral Border */
|
||||
--color-border-muted: var(--color-gray-900);
|
||||
--color-border-light: var(--color-gray-800);
|
||||
--color-border-base: var(--color-gray-700);
|
||||
--color-border-strong: var(--color-gray-400);
|
||||
--color-border-buffer: var(--color-gray-950);
|
||||
|
||||
/* Brand Border */
|
||||
--color-border-brand-soft: var(--color-brand-800);
|
||||
--color-border-brand: var(--color-brand-400);
|
||||
--color-border-brand-strong: var(--color-brand-200);
|
||||
|
||||
/* Status Border */
|
||||
--color-border-success-soft: var(--color-green-800);
|
||||
--color-border-success: var(--color-green-400);
|
||||
--color-border-success-strong: var(--color-green-200);
|
||||
--color-border-danger-soft: var(--color-red-800);
|
||||
--color-border-danger: var(--color-red-400);
|
||||
--color-border-danger-strong: var(--color-red-200);
|
||||
--color-border-warning-soft: var(--color-orange-800);
|
||||
--color-border-warning: var(--color-orange-400);
|
||||
--color-border-warning-strong: var(--color-orange-200);
|
||||
|
||||
/* Accent Border */
|
||||
--color-border-accent-primary-soft: var(--color-teal-800);
|
||||
--color-border-accent-secondary-soft: var(--color-coral-800);
|
||||
--color-border-accent-secondary: var(--color-coral-500);
|
||||
--color-border-accent-tertiary-soft: var(--color-purple-800);
|
||||
--color-border-accent-tertiary: var(--color-purple-500);
|
||||
|
||||
/* Focus Border */
|
||||
--color-border-focus: var(--color-white);
|
||||
}
|
||||
|
||||
@layer components {
|
||||
|
||||
@@ -9,9 +9,9 @@ function rgba(color) {
|
||||
module.exports = {
|
||||
prefix: "tw-",
|
||||
content: [
|
||||
"./src/**/*.{html,ts}",
|
||||
"./src/**/*.{html,ts,mdx}",
|
||||
"../../libs/assets/src/**/*.{html,ts}",
|
||||
"../../libs/components/src/**/*.{html,ts}",
|
||||
"../../libs/components/src/**/*.{html,ts,mdx}",
|
||||
"../../libs/key-management-ui/src/**/*.{html,ts}",
|
||||
"../../libs/auth/src/**/*.{html,ts}",
|
||||
],
|
||||
@@ -78,6 +78,46 @@ module.exports = {
|
||||
alt3: rgba("--color-background-alt3"),
|
||||
alt4: rgba("--color-background-alt4"),
|
||||
},
|
||||
bg: {
|
||||
white: "var(--color-bg-white)",
|
||||
dark: "var(--color-bg-dark)",
|
||||
contrast: "var(--color-bg-contrast)",
|
||||
"contrast-strong": "var(--color-bg-contrast-strong)",
|
||||
primary: "var(--color-bg-primary)",
|
||||
secondary: "var(--color-bg-secondary)",
|
||||
tertiary: "var(--color-bg-tertiary)",
|
||||
quaternary: "var(--color-bg-quaternary)",
|
||||
gray: "var(--color-bg-gray)",
|
||||
disabled: "var(--color-bg-disabled)",
|
||||
"brand-softer": "var(--color-bg-brand-softer)",
|
||||
"brand-soft": "var(--color-bg-brand-soft)",
|
||||
"brand-medium": "var(--color-bg-brand-medium)",
|
||||
brand: "var(--color-bg-brand)",
|
||||
"brand-strong": "var(--color-bg-brand-strong)",
|
||||
"success-soft": "var(--color-bg-success-soft)",
|
||||
"success-medium": "var(--color-bg-success-medium)",
|
||||
success: "var(--color-bg-success)",
|
||||
"success-strong": "var(--color-bg-success-strong)",
|
||||
"danger-soft": "var(--color-bg-danger-soft)",
|
||||
"danger-medium": "var(--color-bg-danger-medium)",
|
||||
danger: "var(--color-bg-danger)",
|
||||
"danger-strong": "var(--color-bg-danger-strong)",
|
||||
"warning-soft": "var(--color-bg-warning-soft)",
|
||||
"warning-medium": "var(--color-bg-warning-medium)",
|
||||
warning: "var(--color-bg-warning)",
|
||||
"warning-strong": "var(--color-bg-warning-strong)",
|
||||
"accent-primary-soft": "var(--color-bg-accent-primary-soft)",
|
||||
"accent-primary-medium": "var(--color-bg-accent-primary-medium)",
|
||||
"accent-primary": "var(--color-bg-accent-primary)",
|
||||
"accent-secondary-soft": "var(--color-bg-accent-secondary-soft)",
|
||||
"accent-secondary-medium": "var(--color-bg-accent-secondary-medium)",
|
||||
"accent-secondary": "var(--color-bg-accent-secondary)",
|
||||
"accent-tertiary-soft": "var(--color-bg-accent-tertiary-soft)",
|
||||
"accent-tertiary-medium": "var(--color-bg-accent-tertiary-medium)",
|
||||
"accent-tertiary": "var(--color-bg-accent-tertiary)",
|
||||
hover: "var(--color-bg-hover)",
|
||||
overlay: "var(--color-bg-overlay)",
|
||||
},
|
||||
hover: {
|
||||
default: "var(--color-hover-default)",
|
||||
contrast: "var(--color-hover-contrast)",
|
||||
@@ -92,8 +132,62 @@ module.exports = {
|
||||
tertiary: rgba("--color-illustration-tertiary"),
|
||||
logo: rgba("--color-illustration-logo"),
|
||||
},
|
||||
fg: {
|
||||
white: "var(--color-fg-white)",
|
||||
dark: "var(--color-fg-dark)",
|
||||
contrast: "var(--color-fg-contrast)",
|
||||
heading: "var(--color-fg-heading)",
|
||||
body: "var(--color-fg-body)",
|
||||
"body-subtle": "var(--color-fg-body-subtle)",
|
||||
disabled: "var(--color-fg-disabled)",
|
||||
"brand-soft": "var(--color-fg-brand-soft)",
|
||||
brand: "var(--color-fg-brand)",
|
||||
"brand-strong": "var(--color-fg-brand-strong)",
|
||||
success: "var(--color-fg-success)",
|
||||
"success-strong": "var(--color-fg-success-strong)",
|
||||
danger: "var(--color-fg-danger)",
|
||||
"danger-strong": "var(--color-fg-danger-strong)",
|
||||
warning: "var(--color-fg-warning)",
|
||||
"warning-strong": "var(--color-fg-warning-strong)",
|
||||
sensitive: "var(--color-fg-sensitive)",
|
||||
"accent-primary-soft": "var(--color-fg-accent-primary-soft)",
|
||||
"accent-primary": "var(--color-fg-accent-primary)",
|
||||
"accent-primary-strong": "var(--color-fg-accent-primary-strong)",
|
||||
"accent-secondary-soft": "var(--color-fg-accent-secondary-soft)",
|
||||
"accent-secondary": "var(--color-fg-accent-secondary)",
|
||||
"accent-secondary-strong": "var(--color-fg-accent-secondary-strong)",
|
||||
"accent-tertiary-soft": "var(--color-fg-accent-tertiary-soft)",
|
||||
"accent-tertiary": "var(--color-fg-accent-tertiary)",
|
||||
"accent-tertiary-strong": "var(--color-fg-accent-tertiary-strong)",
|
||||
},
|
||||
border: {
|
||||
muted: "var(--color-border-muted)",
|
||||
light: "var(--color-border-light)",
|
||||
base: "var(--color-border-base)",
|
||||
strong: "var(--color-border-strong)",
|
||||
buffer: "var(--color-border-buffer)",
|
||||
"brand-soft": "var(--color-border-brand-soft)",
|
||||
brand: "var(--color-border-brand)",
|
||||
"brand-strong": "var(--color-border-brand-strong)",
|
||||
"success-soft": "var(--color-border-success-soft)",
|
||||
success: "var(--color-border-success)",
|
||||
"success-strong": "var(--color-border-success-strong)",
|
||||
"danger-soft": "var(--color-border-danger-soft)",
|
||||
danger: "var(--color-border-danger)",
|
||||
"danger-strong": "var(--color-border-danger-strong)",
|
||||
"warning-soft": "var(--color-border-warning-soft)",
|
||||
warning: "var(--color-border-warning)",
|
||||
"warning-strong": "var(--color-border-warning-strong)",
|
||||
"accent-primary-soft": "var(--color-border-accent-primary-soft)",
|
||||
"accent-primary": "var(--color-border-accent-primary)",
|
||||
"accent-secondary-soft": "var(--color-border-accent-secondary-soft)",
|
||||
"accent-secondary": "var(--color-border-accent-secondary)",
|
||||
"accent-tertiary-soft": "var(--color-border-accent-tertiary-soft)",
|
||||
"accent-tertiary": "var(--color-border-accent-tertiary)",
|
||||
focus: "var(--color-border-focus)",
|
||||
},
|
||||
},
|
||||
textColor: {
|
||||
textColor: () => ({
|
||||
main: rgba("--color-text-main"),
|
||||
muted: rgba("--color-text-muted"),
|
||||
contrast: rgba("--color-text-contrast"),
|
||||
@@ -132,7 +226,62 @@ module.exports = {
|
||||
notification: {
|
||||
600: rgba("--color-notification-600"),
|
||||
},
|
||||
},
|
||||
// New semantic fg tokens - manually flattened to generate tw-text-fg-* utilities
|
||||
"fg-white": "var(--color-fg-white)",
|
||||
"fg-dark": "var(--color-fg-dark)",
|
||||
"fg-contrast": "var(--color-fg-contrast)",
|
||||
"fg-heading": "var(--color-fg-heading)",
|
||||
"fg-body": "var(--color-fg-body)",
|
||||
"fg-body-subtle": "var(--color-fg-body-subtle)",
|
||||
"fg-disabled": "var(--color-fg-disabled)",
|
||||
"fg-brand-soft": "var(--color-fg-brand-soft)",
|
||||
"fg-brand": "var(--color-fg-brand)",
|
||||
"fg-brand-strong": "var(--color-fg-brand-strong)",
|
||||
"fg-success": "var(--color-fg-success)",
|
||||
"fg-success-strong": "var(--color-fg-success-strong)",
|
||||
"fg-danger": "var(--color-fg-danger)",
|
||||
"fg-danger-strong": "var(--color-fg-danger-strong)",
|
||||
"fg-warning": "var(--color-fg-warning)",
|
||||
"fg-warning-strong": "var(--color-fg-warning-strong)",
|
||||
"fg-sensitive": "var(--color-fg-sensitive)",
|
||||
"fg-accent-primary-soft": "var(--color-fg-accent-primary-soft)",
|
||||
"fg-accent-primary": "var(--color-fg-accent-primary)",
|
||||
"fg-accent-primary-strong": "var(--color-fg-accent-primary-strong)",
|
||||
"fg-accent-secondary-soft": "var(--color-fg-accent-secondary-soft)",
|
||||
"fg-accent-secondary": "var(--color-fg-accent-secondary)",
|
||||
"fg-accent-secondary-strong": "var(--color-fg-accent-secondary-strong)",
|
||||
"fg-accent-tertiary-soft": "var(--color-fg-accent-tertiary-soft)",
|
||||
"fg-accent-tertiary": "var(--color-fg-accent-tertiary)",
|
||||
"fg-accent-tertiary-strong": "var(--color-fg-accent-tertiary-strong)",
|
||||
}),
|
||||
borderColor: ({ theme }) => ({
|
||||
...theme("colors"),
|
||||
// New semantic border tokens - manually flattened to generate tw-border-border-* utilities
|
||||
"border-muted": "var(--color-border-muted)",
|
||||
"border-light": "var(--color-border-light)",
|
||||
"border-base": "var(--color-border-base)",
|
||||
"border-strong": "var(--color-border-strong)",
|
||||
"border-buffer": "var(--color-border-buffer)",
|
||||
"border-brand-soft": "var(--color-border-brand-soft)",
|
||||
"border-brand": "var(--color-border-brand)",
|
||||
"border-brand-strong": "var(--color-border-brand-strong)",
|
||||
"border-success-soft": "var(--color-border-success-soft)",
|
||||
"border-success": "var(--color-border-success)",
|
||||
"border-success-strong": "var(--color-border-success-strong)",
|
||||
"border-danger-soft": "var(--color-border-danger-soft)",
|
||||
"border-danger": "var(--color-border-danger)",
|
||||
"border-danger-strong": "var(--color-border-danger-strong)",
|
||||
"border-warning-soft": "var(--color-border-warning-soft)",
|
||||
"border-warning": "var(--color-border-warning)",
|
||||
"border-warning-strong": "var(--color-border-warning-strong)",
|
||||
"border-accent-primary-soft": "var(--color-border-accent-primary-soft)",
|
||||
"border-accent-primary": "var(--color-border-accent-primary)",
|
||||
"border-accent-secondary-soft": "var(--color-border-accent-secondary-soft)",
|
||||
"border-accent-secondary": "var(--color-border-accent-secondary)",
|
||||
"border-accent-tertiary-soft": "var(--color-border-accent-tertiary-soft)",
|
||||
"border-accent-tertiary": "var(--color-border-accent-tertiary)",
|
||||
"border-focus": "var(--color-border-focus)",
|
||||
}),
|
||||
fontFamily: {
|
||||
sans: "var(--font-sans)",
|
||||
serif: "var(--font-serif)",
|
||||
|
||||
@@ -11,11 +11,16 @@ config.content = [
|
||||
"bitwarden_license/bit-web/src/**/*.{html,ts,mdx}",
|
||||
".storybook/preview.tsx",
|
||||
];
|
||||
|
||||
// Safelist is required for dynamic color classes in Storybook color documentation (colors.mdx).
|
||||
// Tailwind's JIT compiler cannot detect dynamically constructed class names like `tw-bg-${name}`,
|
||||
// so we must explicitly safelist these patterns to ensure all color utilities are generated.
|
||||
config.safelist = [
|
||||
{
|
||||
pattern: /tw-bg-(.*)/,
|
||||
},
|
||||
];
|
||||
|
||||
config.corePlugins.preflight = true;
|
||||
|
||||
module.exports = config;
|
||||
|
||||
Reference in New Issue
Block a user